def loads_trade(self, trade_id, trade_type, data, operations): """ Load a strategy trader trade and its operations. @todo Need to check the validity of the trade : - existings orders, create, sell, limit, stop, position - and eventually the free margin, asset quantity There is many scenarii where the trade state changed, trade executed, order modified or canceled... """ trade = None if trade_type == StrategyTrade.TRADE_BUY_SELL: trade = StrategyAssetTrade(0) elif trade_type == StrategyTrade.TRADE_MARGIN: trade = StrategyMarginTrade(0) elif trade_type == StrategyTrade.TRADE_POSITION: trade = StrategyPositionTrade(0) elif trade_type == StrategyTrade.TRADE_IND_MARGIN: trade = StrategyIndMarginTrade(0) else: error_logger.error("During loads, usupported trade type %i" % (trade_type, )) return trade.loads(data, self.strategy.service) # operations for op in operations: if op['name'] in self.strategy.service.tradeops: try: operation = self.strategy.service.tradeops[op['name']]() operation.loads(op) if operation.check(trade): # append the operation to the trade trade.add_operation(operation) else: error_logger.error( "During loads, operation checking error %s" % (op_name, )) except Exception as e: error_logger.error(repr(e)) else: error_logger.error("During loads, region checking error %s" % (r['name'], )) # check orders/position/quantity before adding trader = self.strategy.trader() if trade.check(trader, self.instrument): self.add_trade(trade)
def process_entry(self, timestamp, price, take_profit, stop_loss, timeframe, partial_tp): trader = self.strategy.trader() quantity = 0.0 direction = Order.LONG # entry is always a long # large limit price because else miss the pumping markets price = price + self.instrument.market_spread * ( 1 if trader.paper_mode else 5) # signal price + spread # date_time = datetime.fromtimestamp(timestamp) # date_str = date_time.strftime('%Y-%m-%d %H:%M:%S') # ajust max quantity according to free asset of quote, and convert in asset base quantity if trader.has_asset(self.instrument.quote): # quantity = min(quantity, trader.asset(self.instrument.quote).free) / self.instrument.market_ofr if trader.has_quantity(self.instrument.quote, self.instrument.trade_quantity): quantity = self.instrument.adjust_quantity( self.instrument.trade_quantity / price) # and adjusted to 0/max/step else: Terminal.inst().notice( "Not enought free quote asset %s, has %s but need %s" % (self.instrument.quote, self.instrument.format_quantity( trader.asset(self.instrument.quote).free), self.instrument.format_quantity( self.instrument.trade_quantity)), view='status') # # create an order # # only if active do_order = self.activity order_quantity = 0.0 order_price = None order_type = None order_leverage = 1.0 # simply set the computed quantity order_quantity = quantity # prefered in limit order at the current best price, and with binance in market INSUFISCENT BALANCE can occurs with market orders... order_type = Order.ORDER_LIMIT # limit price order_price = float(self.instrument.format_price(price)) # order_price = self.instrument.adjust_price(price) # # cancelation of the signal # if order_quantity <= 0 or order_quantity * price < self.instrument.min_notional: # min notional not reached do_order = False if self.trades: self.lock() if len(self.trades) >= self.max_trades: # no more than max simultaneous trades do_order = False # for trade in self.trades: # if trade.timeframe == timeframe: # do_order = False # if self.trades and (self.trades[-1].dir == direction) and ((timestamp - self.trades[-1].entry_open_time) < self.trade_delay): #if self.trades and (self.trades[-1].dir == direction) and ((timestamp - self.trades[-1].entry_open_time) < timeframe): # # the same order occurs just after, ignore it # do_order = False self.unlock() # # execution of the order # if do_order: trade = StrategyAssetTrade(timeframe) # the new trade must be in the trades list if the event comes before, and removed after only it failed self.add_trade(trade) trade.partial_tp = partial_tp if trade.open(trader, self.instrument.market_id, direction, order_type, order_price, order_quantity, take_profit, stop_loss, order_leverage): # notify self.strategy.notify_order( trade.id, trade.dir, self.instrument.market_id, self.instrument.format_price(price), timestamp, trade.timeframe, 'entry', None, self.instrument.format_price(trade.sl), self.instrument.format_price(trade.tp)) # want it on the streaming if self._global_streamer: # @todo remove me after notify manage that self._global_streamer.member('buy-entry').update( price, timestamp) else: self.remove_trade(trade) else: # notify a signal only self.strategy.notify_order( -1, Order.LONG, self.instrument.market_id, self.instrument.format_price(price), timestamp, timeframe, 'entry', None, self.instrument.format_price(stop_loss), self.instrument.format_price(take_profit))