hbdmapi / huobi_futures_Python

An Asynchronous Event-driven High-frequency Trading System,huobi future,huobi coin margined swap, huobi usdt margined swap included.
MIT License
267 stars 113 forks source link

Double execution of loop inside async place_orders #32

Closed igkoh closed 4 years ago

igkoh commented 4 years ago

Loop of batch orders inside async place_orders is: _async def place_orders(self):

for loop 10 of batch order of size 10
  self.trader.create_orders(orders_data)_

async/await seem to enter the above loop before completing , instead of waiting for completion of the loop.

Thus I solved in ad hoc way as

_async def place_orders(self): ...if bPaceOrdersExecuted==False: ......loop 50 of batch order of size 10 .........bPaceOrdersExecuted=True #<----- tell the program that loop has already started .........self.trader.create_orders(ordersdata) ......bPaceOrdersExecuted=False #<----- tell the program that loop has completed and safe to enter again

We tell the program that loop has begun its loop by boolean bPaceOrdersExecuted of PlaceOrders EXECUTED as True. I want to understand async/await and its handling of loop such that it is completed before other intrudes again. The result of instead of 10x10=100 but twice the size 200.

I googled but failed to find intuitive articles to learn solving this particular problem.

Best regards, Ingyu

foonsun commented 4 years ago

@igkoh Hi,You can try the async locker decorator to avoid entering the above loop before completing,such as async_method_locker("place_order",wait=True) https://github.com/hbdmapi/hbdm_Python/blob/master/alpha/utils/decorator.py#L20

igkoh commented 4 years ago

@foonsun,

What a great joy. Erratic behavior of double execution, strange cancellation disappear with decorator async_method_locker, modifying behavior of place_orders and cancel_orders with lock.

After importing _from alpha.utils.decorator import async_methodlocker in strategy.py, behaviors of place_orders and cancel_orders are modified to be locked.

_@async_method_locker('place_ordersLocker1')
async def place_orders(self): ...loop of n batch of 10 orders createorders<--- no interruption from other methods

_@async_method_locker('CancLocker')
async def cancel_orders(self): ...loop of n bach of 10 revokeorder<--- no interruption from other methods

I have tested with unusually large numbers (100 of 10 batch orders) and obtained clean results. Your clean instructions really give me joy.

Best regards, Ingyu

foonsun commented 4 years ago

@igkoh Great!