def send_leg_order(self, vt_symbol: str, leg_volume: float, borrowmoney=False): """""" leg = self.spread.legs[vt_symbol] leg_contract = self.get_contract(vt_symbol) if leg_volume > 0: if vt_symbol == self.spread.active_leg.vt_symbol: price = round_to( self.spread.active_leg.ask_price + leg_contract.pricetick * self.spread.payup * 10, leg_contract.pricetick) else: price = round_to( self.spread.passive_leg.ask_price + leg_contract.pricetick * self.spread.payup, leg_contract.pricetick) self.send_long_order(leg.vt_symbol, price, abs(leg_volume)) elif leg_volume < 0: if vt_symbol == self.spread.active_leg.vt_symbol: # print(self.algo_engine.spread_engine.data_engine.margin_accounts) price = round_to( self.spread.active_leg.bid_price - leg_contract.pricetick * self.spread.payup * 10, leg_contract.pricetick) else: price = round_to( self.spread.passive_leg.bid_price - leg_contract.pricetick * self.spread.payup, leg_contract.pricetick) self.send_short_order(leg.vt_symbol, price, abs(leg_volume), borrowmoney)
def hedge_passive_leg(self): """ Send orders to hedge all passive legs. """ # 是否有被动腿对冲单挂单,有则不再进行对冲 if not self.check_passive_order_finished(): return active_traded = round_to(self.active_leg.net_pos, self.spread.min_volume) hedge_volume = self.spread.calculate_spread_volume( self.active_leg.vt_symbol, active_traded) # Calculate passive leg target volume and do hedge # passive_traded = self.leg_traded[self.passive_leg.vt_symbol] passive_traded = round_to(self.passive_leg.net_pos, self.spread.min_volume) passive_target = self.spread.calculate_leg_volume( self.passive_leg.vt_symbol, hedge_volume) leg_order_volume = passive_target - passive_traded if abs(leg_order_volume) * self.passive_leg.bids[0, 0] > 12: self.send_passiveleg_order(leg_order_volume) self.write_log( f'hedge_passive_leg active_traded: {active_traded}, passive_target: {passive_target}, passive_traded: {passive_traded}' ) return False return True
def hedge_passive_leg(self): """ Send orders to hedge all passive legs. """ # Calcualte spread volume to hedge # active_leg = self.spread.active_leg # active_traded = self.leg_traded[active_leg.vt_symbol] active_traded = round_to(self.spread.active_leg.net_pos, self.spread.min_volume) hedge_volume = self.spread.calculate_spread_volume( self.spread.active_leg.vt_symbol, active_traded) # Calculate passive leg target volume and do hedge # passive_traded = self.leg_traded[self.spread.passive_leg.vt_symbol] passive_traded = round_to(self.spread.passive_leg.net_pos, self.spread.min_volume) passive_target = self.spread.calculate_leg_volume( self.spread.passive_leg.vt_symbol, hedge_volume) leg_order_volume = passive_target - passive_traded if abs(leg_order_volume) * self.spread.passive_leg.last_price > 12: self.send_leg_order(self.spread.passive_leg.vt_symbol, leg_order_volume) # self.write_log(f'HEDGE PASSIVE LEG>>>spread.bid_price:{self.spread.bid_price}, activeleg.bid_price:{self.spread.active_leg.bid_price}, passiveleg.ask_price:{self.spread.passive_leg.ask_price}, send order:{datetime.now()}, tick datetime: {self.spread.active_leg.tick.datetime}, event_engine size:{self.algo_engine.event_engine.get_qsize()}. active_traded: {active_traded}, passive_traded: {passive_traded}, passive_target: {passive_target}') return False return True
def send_order(self, vt_symbol: str, price: float, volume: float, direction: Direction, borrowmoney=False): """""" # For inverse contract: # calculate contract trading volume from coin trading volume if self.spread.is_inverse(vt_symbol): size = self.spread.get_leg_size(vt_symbol) volume = volume * price / size # Round order volume to min_volume of contract leg = self.spread.legs[vt_symbol] volume = round_to(volume, leg.min_volume) vt_orderids = self.algo_engine.send_order(self, vt_symbol, price, volume, direction, borrowmoney) self.leg_orders[vt_symbol].extend( [[vt_orderid, price, volume, direction] for vt_orderid in vt_orderids]) msg = "发出委托,{},{},{}@{}".format(vt_symbol, direction, volume, price) self.write_log(msg) return vt_orderids[0]
def send_passiveleg_order(self, leg_volume: float, borrowmoney=False, PAYUPN=1): """""" if leg_volume > 0: price = round_to( self.passive_leg.asks[0, 0] * (1 + self.payup * PAYUPN), self.passive_leg.pricetick) self.send_long_order(self.passive_leg.vt_symbol, price, leg_volume) elif leg_volume < 0: price = round_to( self.passive_leg.bids[0, 0] * (1 - self.payup * PAYUPN), self.passive_leg.pricetick) self.send_short_order(self.passive_leg.vt_symbol, price, abs(leg_volume))
def calculate_traded(self): """""" self.traded = 0 # print('algo template calculate_traded>>>>') for n, leg in enumerate(self.spread.legs.values()): leg_traded = self.leg_traded[leg.vt_symbol] trading_multiplier = self.spread.trading_multipliers[leg.vt_symbol] adjusted_leg_traded = leg_traded / trading_multiplier adjusted_leg_traded = round_to(adjusted_leg_traded, self.spread.min_volume) if adjusted_leg_traded > 0: adjusted_leg_traded = floor_to(adjusted_leg_traded, self.spread.min_volume) else: adjusted_leg_traded = ceil_to(adjusted_leg_traded, self.spread.min_volume) if not n: self.traded = adjusted_leg_traded else: if adjusted_leg_traded > 0: self.traded = min(self.traded, adjusted_leg_traded) elif adjusted_leg_traded < 0: self.traded = max(self.traded, adjusted_leg_traded) else: self.traded = 0 self.traded_volume = abs(self.traded) if self.traded == self.target: self.status = Status.ALLTRADED # print("algo calculate_traded: %s status is ALLTRADE" % self.algoid) elif not self.traded: self.status = Status.NOTTRADED # print("algo calculate_traded: %s status is NOTTRADED" % self.algoid) else: self.status = Status.PARTTRADED
def short_active_leg(self, shadow_ask, bestask, vol): # # 10档报价低于要提报价格,则不报。 # if self.active_leg.asks[19,0] < shadow_ask: # if self.submitting_short_dict['order_id'] and self.cancel_short_orderid is None: # if self.submitting_short_dict['status'] in [Status.NOTTRADED, Status.PARTTRADED]: # self.cancel_order(self.submitting_short_dict['order_id']) # self.cancel_short_orderid = self.submitting_short_dict['order_id'] # self.write_log(f"higher then 9th asks, cancel order, oder_id: {self.cancel_short_orderid}, 9th ask: {self.active_leg.asks[9,0]}, shadow_ask :{shadow_ask}", level=DEBUG) # 开始报价 if bestask > shadow_ask: # if shadow_ask < bestask: # # 根据 bestask shadow_ask # shadow_ask = bestask - self.active_leg.pricetick * 2 # shadow_ask = round_to(shadow_ask, self.active_leg.pricetick) # else: shadow_ask = round_to(shadow_ask, self.active_leg.pricetick) # 如果没有报单,则发出委托;否则取消原委托 if self.submitting_short_dict['order_id'] is None and self.hedging: borrow = False if vol > self.algo_engine.margin_accounts[ self.active_leg.vt_symbol].free: # 可借不足,调整数量 if (vol - self.algo_engine.margin_accounts[ self.active_leg.vt_symbol].free ) > self.algo_engine.margin_accounts[ self.active_leg.vt_symbol].max_borrow: vol = self.algo_engine.margin_accounts[ self.active_leg. vt_symbol].free + self.algo_engine.margin_accounts[ self.active_leg.vt_symbol].max_borrow * 0.9 borrow = True self.algo_engine.margin_accounts[ self.active_leg.vt_symbol].free = vol self.algo_engine.margin_accounts[ self.active_leg.vt_symbol].max_borrow -= ( vol - self.algo_engine.margin_accounts[ self.active_leg.vt_symbol].free) # 不足最小金额,立即返回 if shadow_ask * vol < 12: return self.submitting_short_dict['order_id'] = self.send_short_order( self.active_leg.vt_symbol, shadow_ask, vol, borrow) self.submitting_short_dict['price'] = shadow_ask self.submitting_short_dict['status'] = Status.SUBMITTING self.submitting_short_dict['vol'] = vol if borrow: self.cancel_short_orderid = self.submitting_short_dict[ 'order_id'] else: if self.submitting_short_dict['status'] in [ Status.NOTTRADED, Status.PARTTRADED ]: if (abs(self.submitting_short_dict['price'] - shadow_ask) > shadow_ask * 0.0002) and self.cancel_short_orderid is None: self.cancel_order( self.submitting_short_dict['order_id']) self.cancel_short_orderid = self.submitting_short_dict[ 'order_id'] self.write_log( f"short more than 2%%, last short: {self.submitting_short_dict['price']}, this shadow_ask: {shadow_ask}" ) else: if self.submitting_short_dict[ 'order_id'] and self.submitting_short_dict['status'] in [ Status.NOTTRADED, Status.PARTTRADED ] and self.cancel_short_orderid is None: if (abs(self.submitting_short_dict['price'] - shadow_ask) > shadow_ask * 0.0002) and self.cancel_short_orderid is None: self.cancel_order(self.submitting_short_dict['order_id']) self.cancel_short_orderid = self.submitting_short_dict[ 'order_id'] self.write_log( f"price out, bestask: {bestask} short more than 3 tick, last short: {self.submitting_short_dict['price']}, this shadow_ask: {shadow_ask}" )
def long_active_leg(self, shadow_bid, bestbid, vol): # # 10档价格高于预报价,则不报。 # if self.active_leg.bids[19,0] > shadow_bid: # if self.submitting_long_dict['order_id'] and self.cancel_long_orderid is None: # if self.submitting_long_dict['status'] in [Status.NOTTRADED, Status.PARTTRADED]: # self.cancel_order(self.submitting_long_dict['order_id']) # self.cancel_long_orderid = self.submitting_long_dict['order_id'] # self.write_log(f"lower then 9th bids, cancel order, oder_id: {self.cancel_long_orderid}, 9th bids: {self.active_leg.bids[9,0]}, shadow_bid: {shadow_bid}", level=DEBUG) # 开始报价 if bestbid < shadow_bid: # if shadow_bid > bestbid: # # 根据 bestbid 调整shadow_bids # shadow_bid = bestbid + self.active_leg.pricetick * 2 # shadow_bid = round_to(shadow_bid, self.active_leg.pricetick) # else: shadow_bid = round_to(shadow_bid, self.active_leg.pricetick) # 如果没有报单,则发出委托;否则取消原委托 if self.submitting_long_dict['order_id'] is None and self.hedging: # 可用资金不足,调整数量 if shadow_bid * vol > self.algo_engine.margin_accounts[ "USDTUSDT." + self.active_leg.exchange.value].free: vol = self.algo_engine.margin_accounts[ "USDTUSDT." + self.active_leg.exchange.value].free * 0.9 / shadow_bid # 不足最小金额,立即返回 if shadow_bid * vol < 12: return self.submitting_long_dict['order_id'] = self.send_long_order( self.active_leg.vt_symbol, shadow_bid, vol) self.submitting_long_dict['price'] = shadow_bid self.submitting_long_dict['status'] = Status.SUBMITTING self.submitting_long_dict['vol'] = vol else: if self.submitting_long_dict['status'] in [ Status.NOTTRADED, Status.PARTTRADED ]: if (abs(self.submitting_long_dict['price'] - shadow_bid) > shadow_bid * 0.0002) and self.cancel_long_orderid is None: self.cancel_order( self.submitting_long_dict['order_id']) self.cancel_long_orderid = self.submitting_long_dict[ 'order_id'] self.write_log( f"long more than 2%%, last long: {self.submitting_long_dict['price']}, this shadow_bid: {shadow_bid}" ) else: if self.submitting_long_dict[ 'order_id'] and self.submitting_long_dict['status'] in [ Status.NOTTRADED, Status.PARTTRADED ] and self.cancel_long_orderid is None: if (abs(self.submitting_long_dict['price'] - shadow_bid) > shadow_bid * 0.0002) and self.cancel_long_orderid is None: self.cancel_order(self.submitting_long_dict['order_id']) self.cancel_long_orderid = self.submitting_long_dict[ 'order_id'] self.write_log( f"price out bestbid: {bestbid}, long more than 3 tick, last long: {self.submitting_long_dict['price']}, this shadow_bid: {shadow_bid}" )