def send_order( self, algo: AlgoTemplate, vt_symbol: str, direction: Direction, price: float, volume: float, order_type: OrderType, offset: Offset ): """""" contract = self.main_engine.get_contract(vt_symbol) if not contract: self.write_log(f'委托下单失败,找不到合约:{vt_symbol}', algo) return volume = round_to(volume, contract.min_volume) if not volume: return "" req = OrderRequest( symbol=contract.symbol, exchange=contract.exchange, direction=direction, type=order_type, volume=volume, price=price, offset=offset, reference=f"{APP_NAME}_{algo.algo_name}" ) vt_orderid = self.main_engine.send_order(req, contract.gateway_name) self.orderid_algo_map[vt_orderid] = algo return vt_orderid
def connect( self, key: str, secret: str, session_number: int, proxy_host: str, proxy_port: int, ): """ Initialize connection to REST server. """ self.key = key self.secret = secret self.connect_time = int(datetime.now().strftime("%y%m%d%H%M%S")) self.init(REST_HOST_TRADE, proxy_host, proxy_port) self.start(session_number) self.gateway.write_log("ZB 交易 REST API 启动成功") self.query_account() # 指定要查询的交易对 self.query_order(symbol="usdt_qc") # 测试接口 req = OrderRequest(symbol="usdt_qc", exchange=Exchange.ZB, direction=Direction.LONG, type=OrderType.LIMIT, volume=0.01) # 价格 req.price = 6.9 req.offset = Offset.NONE self.send_order(req)
def send_order( self, vt_symbol: str, price: float, volume: float, direction: Direction, offset: Offset, order_type: OrderType ) -> str: """""" contract = self.get_contract(vt_symbol) if not contract: return "" req = OrderRequest( symbol=contract.symbol, exchange=contract.exchange, direction=direction, type=order_type, volume=volume, price=price, offset=offset ) vt_orderid = self.main_engine.send_order(req, contract.gateway_name) return vt_orderid
def send_order(self) -> None: """""" symbol = self.symbol_line.text() contract = self.contracts.get(symbol, None) if not contract: return price_text = self.price_line.text() volume_text = self.volume_line.text() if not price_text or not volume_text: return price = float(price_text) volume = int(volume_text) direction = Direction(self.direction_combo.currentText()) offset = Offset(self.offset_combo.currentText()) req = OrderRequest(symbol=contract.symbol, exchange=contract.exchange, direction=direction, type=OrderType.LIMIT, offset=offset, volume=volume, price=price) self.main_engine.send_order(req, contract.gateway_name)
def send_order( self, strategy: StrategyTemplate, vt_symbol: str, direction: Direction, offset: Offset, price: float, volume: float, lock: bool, net: bool, ): """ Send a new order to server. """ contract: ContractData = self.main_engine.get_contract(vt_symbol) if not contract: self.write_log(f"委托失败,找不到合约:{vt_symbol}", strategy) return "" # Round order price and volume to nearest incremental value price = round_to(price, contract.pricetick) volume = round_to(volume, contract.min_volume) # Create request and send order. original_req = OrderRequest( symbol=contract.symbol, exchange=contract.exchange, direction=direction, offset=offset, type=OrderType.LIMIT, price=price, volume=volume, reference=f"{APP_NAME}_{strategy.strategy_name}") # Convert with offset converter req_list = self.offset_converter.convert_order_request( original_req, lock, net) # Send Orders vt_orderids = [] for req in req_list: req.reference = strategy.strategy_name # Add strategy name as order reference vt_orderid = self.main_engine.send_order(req, contract.gateway_name) # Check if sending order successful if not vt_orderid: continue vt_orderids.append(vt_orderid) self.offset_converter.update_order_request(req, vt_orderid) # Save relationship between orderid and strategy. self.orderid_strategy_map[vt_orderid] = strategy return vt_orderids
def send_order(self, algo: SpreadAlgoTemplate, vt_symbol: str, price: float, volume: float, direction: Direction, lock: bool) -> List[str]: """""" holding = self.offset_converter.get_position_holding(vt_symbol) contract = self.main_engine.get_contract(vt_symbol) if direction == Direction.LONG: available = holding.short_pos - holding.short_pos_frozen else: available = holding.long_pos - holding.long_pos_frozen # If no position to close, just open new if not available: offset = Offset.OPEN # If enougth position to close, just close old elif volume < available: offset = Offset.CLOSE # Otherwise, just close existing position else: volume = available offset = Offset.CLOSE original_req = OrderRequest(symbol=contract.symbol, exchange=contract.exchange, direction=direction, offset=offset, type=OrderType.LIMIT, price=price, volume=volume, reference=f"{APP_NAME}_{algo.spread_name}") # Convert with offset converter req_list = self.offset_converter.convert_order_request( original_req, lock) # Send Orders vt_orderids = [] for req in req_list: vt_orderid = self.main_engine.send_order(req, contract.gateway_name) # Check if sending order successful if not vt_orderid: continue vt_orderids.append(vt_orderid) self.offset_converter.update_order_request(req, vt_orderid) # Save relationship between orderid and algo. self.order_algo_map[vt_orderid] = algo return vt_orderids
def send_server_order( self, strategy: CtaTemplate, contract: ContractData, direction: Direction, offset: Offset, price: float, volume: float, type: OrderType, lock: bool ): """ Send a new order to server. """ # Create request and send order. original_req = OrderRequest( symbol=contract.symbol, exchange=contract.exchange, direction=direction, offset=offset, type=type, price=price, volume=volume, ) # Convert with offset converter req_list = self.offset_converter.convert_order_request(original_req, lock) # Send Orders vt_orderids = [] if not req_list: self.write_log("转换后[]为空,策略没有成交",strategy) for req in req_list: req.reference = strategy.strategy_name # Add strategy name as order reference vt_orderid = self.main_engine.send_order( req, contract.gateway_name) # Check if sending order successful if not vt_orderid: continue vt_orderids.append(vt_orderid) self.offset_converter.update_order_request(req, vt_orderid) # Save relationship between orderid and strategy. self.orderid_strategy_map[vt_orderid] = strategy self.strategy_orderid_map[strategy.strategy_name].add(vt_orderid) return vt_orderids
def send_order(self, algo: ElectronicEyeAlgo, vt_symbol: str, direction: Direction, offset: Offset, price: float, volume: int) -> str: """""" contract = self.main_engine.get_contract(vt_symbol) req = OrderRequest(contract.symbol, contract.exchange, direction, OrderType.LIMIT, volume, price, offset) vt_orderid = self.main_engine.send_order(req, contract.gateway_name) self.order_algo_map[vt_orderid] = algo return vt_orderid
def send_order( self, strategy: SpreadStrategyTemplate, vt_symbol: str, price: float, volume: float, direction: Direction, offset: Offset, lock: bool ) -> List[str]: contract = self.main_engine.get_contract(vt_symbol) original_req = OrderRequest( symbol=contract.symbol, exchange=contract.exchange, direction=direction, offset=offset, type=OrderType.LIMIT, price=price, volume=volume, reference=f"{APP_NAME}_{strategy.strategy_name}" ) # Convert with offset converter req_list = self.offset_converter.convert_order_request( original_req, lock) # Send Orders vt_orderids = [] for req in req_list: vt_orderid = self.main_engine.send_order( req, contract.gateway_name) # Check if sending order successful if not vt_orderid: continue vt_orderids.append(vt_orderid) self.offset_converter.update_order_request(req, vt_orderid) # Save relationship between orderid and strategy. self.order_strategy_map[vt_orderid] = strategy return vt_orderids
def send_server_order( self, strategy: CtaTemplate, contract: ContractData, direction: Direction, offset: Offset, price: float, volume: float, type: OrderType, lock: bool ): """ Send a new order to server. """ # Create request and send order. original_req = OrderRequest( symbol=contract.symbol, exchange=contract.exchange, direction=direction, offset=offset, type=type, price=price, volume=volume, ) # Convert with offset converter req_list = self.offset_converter.convert_order_request(original_req, lock) # Send Orders vt_orderids = [] for req in req_list: # 通过此处发送订单 vt_orderid = self.main_engine.send_order( req, contract.gateway_name) # 记录上报的订单的编号 vt_orderids.append(vt_orderid) self.offset_converter.update_order_request(req, vt_orderid) # Save relationship between orderid and strategy. self.orderid_strategy_map[vt_orderid] = strategy # 将开单的信息保存到对应的策略下 self.strategy_orderid_map[strategy.strategy_name].add(vt_orderid) return vt_orderids
def send_order( self, vt_symbol: str, direction: Direction, offset: Offset, payup: int, volume: float, ): """ Send a new order to server. """ contract: ContractData = self.main_engine.get_contract(vt_symbol) tick: TickData = self.main_engine.get_tick(vt_symbol) offset_converter: OffsetConverter = self.cta_engine.offset_converter if direction == Direction.LONG: price = tick.ask_price_1 + contract.pricetick * payup else: price = tick.bid_price_1 - contract.pricetick * payup original_req: OrderRequest = OrderRequest( symbol=contract.symbol, exchange=contract.exchange, direction=direction, offset=offset, type=OrderType.LIMIT, price=price, volume=volume, reference=f"{APP_NAME}_Rollover") req_list = offset_converter.convert_order_request( original_req, False, False) vt_orderids = [] for req in req_list: vt_orderid = self.main_engine.send_order(req, contract.gateway_name) if not vt_orderid: continue vt_orderids.append(vt_orderid) offset_converter.update_order_request(req, vt_orderid) msg = f"发出委托{vt_symbol},{direction.value} {offset.value},{volume}@{price}" self.write_log(msg)
def order_test(self, symbol): volume = (self.cash_avail * 20.0 / 20) / self.data_quote[symbol].ask_price_1 if self.data_quote[symbol].min_volume == 1: volume = int(volume) * 1.0 else: len_volume = len( str(self.data_quote[symbol].min_volume).split(".")[1]) volume = round(volume, len_volume) thisorder = OrderRequest( symbol=symbol, exchange=self.main_engine.gateways[self.enginename].exchanges[0], direction=Direction.LONG, type=OrderType.LIMIT, price=self.data_quote[symbol].bid_price_5, volume=volume, offset=Offset.OPEN) this_order_id = self.main_engine.send_order(thisorder, self.enginename) return this_order_id
def send_limit_order( self, strategy: CtaTemplate, order_type: CtaOrderType, price: float, volume: float, ): """ Send a new order. """ contract = self.main_engine.get_contract(strategy.vt_symbol) if not contract: self.write_log(f"委托失败,找不到合约:{strategy.vt_symbol}", strategy) return "" direction, offset = ORDER_CTA2VT[order_type] # Create request and send order. req = OrderRequest( symbol=contract.symbol, exchange=contract.exchange, dierction=direction, offset=offset, price_type=PriceType.LIMIT, price=price, volume=volume, ) vt_orderid = self.main_engine.send_order(req, contract.gateway_name) # Save relationship between orderid and strategy. self.orderid_strategy_map[vt_orderid] = strategy vt_orderids = self.strategy_orderid_map[strategy.strategy_name] vt_orderids.add(vt_orderid) return vt_orderid
def get_trading(self): this_info = self.futures_info[self.symbol_timer] # today long if this_info.position_today > 0: if this_info.position_yesterday == 0: open_volume = this_info.position_today - this_info.position_yesterday thisorder = OrderRequest(symbol=self.symbol_timer, exchange=self.main_engine.gateways[ self.engine_name].exchanges[0], direction=Direction.LONG, type=OrderType.LIMIT, price=this_info.market_price, volume=open_volume, offset=Offset.OPEN) thisorderid = self.main_engine.send_order( thisorder, self.engine_name) this_info.cost_price = this_info.market_price elif this_info.position_yesterday > 0: change_volume = this_info.position_today - this_info.position_yesterday if change_volume >= 1: thisorder = OrderRequest( symbol=self.symbol_timer, exchange=self.main_engine.gateways[ self.engine_name].exchanges[0], direction=Direction.LONG, type=OrderType.LIMIT, price=this_info.market_price, volume=abs(change_volume), offset=Offset.OPEN) thisorderid = self.main_engine.send_order( thisorder, self.engine_name) this_info.cost_price = ( this_info.cost_price * abs(this_info.position_yesterday) + this_info.market_price * abs(change_volume)) / (abs( this_info.position_yesterday) + abs(change_volume)) elif change_volume <= -1: thisorder = OrderRequest( symbol=self.symbol_timer, exchange=self.main_engine.gateways[ self.engine_name].exchanges[0], direction=Direction.SHORT, type=OrderType.LIMIT, price=this_info.market_price, volume=abs(change_volume), offset=Offset.CLOSE) thisorderid = self.main_engine.send_order( thisorder, self.engine_name) # this_info.cost_price = this_info.cost_price #cost_price does not change elif this_info.position_yesterday < 0: close_volume = this_info.position_yesterday open_volume = this_info.position_today thisorder = OrderRequest(symbol=self.symbol_timer, exchange=self.main_engine.gateways[ self.engine_name].exchanges[0], direction=Direction.LONG, type=OrderType.LIMIT, price=this_info.market_price, volume=abs(close_volume), offset=Offset.CLOSE) thisorderid = self.main_engine.send_order( thisorder, self.engine_name) time.sleep(1) thisorder = OrderRequest(symbol=self.symbol_timer, exchange=self.main_engine.gateways[ self.engine_name].exchanges[0], direction=Direction.LONG, type=OrderType.LIMIT, price=this_info.market_price, volume=abs(open_volume), offset=Offset.OPEN) thisorderid = self.main_engine.send_order( thisorder, self.engine_name) this_info.cost_price = this_info.market_price # today zero if this_info.position_today == 0: if this_info.position_yesterday == 0: pass elif this_info.position_yesterday > 0: close_volume = this_info.position_yesterday thisorder = OrderRequest(symbol=self.symbol_timer, exchange=self.main_engine.gateways[ self.engine_name].exchanges[0], direction=Direction.SHORT, type=OrderType.LIMIT, price=this_info.market_price, volume=abs(close_volume), offset=Offset.CLOSE) this_info.cost_price = 0 thisorderid = self.main_engine.send_order( thisorder, self.engine_name) elif this_info.position_yesterday < 0: close_volume = this_info.position_yesterday thisorder = OrderRequest(symbol=self.symbol_timer, exchange=self.main_engine.gateways[ self.engine_name].exchanges[0], direction=Direction.LONG, type=OrderType.LIMIT, price=this_info.market_price, volume=abs(close_volume), offset=Offset.CLOSE) this_info.cost_price = 0 thisorderid = self.main_engine.send_order( thisorder, self.engine_name) # today short if this_info.position_today < 0: if this_info.position_yesterday == 0: open_volume = this_info.position_today - this_info.position_yesterday thisorder = OrderRequest(symbol=self.symbol_timer, exchange=self.main_engine.gateways[ self.engine_name].exchanges[0], direction=Direction.SHORT, type=OrderType.LIMIT, price=this_info.market_price, volume=abs(open_volume), offset=Offset.OPEN) this_info.cost_price = this_info.market_price thisorderid = self.main_engine.send_order( thisorder, self.engine_name) elif this_info.position_yesterday < 0: change_volume = this_info.position_today - this_info.position_yesterday if change_volume <= -1: thisorder = OrderRequest( symbol=self.symbol_timer, exchange=self.main_engine.gateways[ self.engine_name].exchanges[0], direction=Direction.SHORT, type=OrderType.LIMIT, price=this_info.market_price, volume=abs(change_volume), offset=Offset.OPEN) thisorderid = self.main_engine.send_order( thisorder, self.engine_name) this_info.cost_price = ( this_info.cost_price * abs(this_info.position_yesterday) + this_info.market_price * abs(change_volume)) / (abs( this_info.position_yesterday) + abs(change_volume)) elif change_volume >= 1: thisorder = OrderRequest( symbol=self.symbol_timer, exchange=self.main_engine.gateways[ self.engine_name].exchanges[0], direction=Direction.LONG, type=OrderType.LIMIT, price=this_info.market_price, volume=abs(change_volume), offset=Offset.CLOSE) thisorderid = self.main_engine.send_order( thisorder, self.engine_name) # this_info.cost_price = this_info.cost_price elif this_info.position_yesterday > 0: close_volume = this_info.position_yesterday open_volume = this_info.position_today thisorder = OrderRequest(symbol=self.symbol_timer, exchange=self.main_engine.gateways[ self.engine_name].exchanges[0], direction=Direction.SHORT, type=OrderType.LIMIT, price=this_info.market_price, volume=abs(close_volume), offset=Offset.CLOSE) thisorderid = self.main_engine.send_order( thisorder, self.engine_name) time.sleep(1) thisorder = OrderRequest(symbol=self.symbol_timer, exchange=self.main_engine.gateways[ self.engine_name].exchanges[0], direction=Direction.SHORT, type=OrderType.LIMIT, price=this_info.market_price, volume=abs(open_volume), offset=Offset.OPEN) thisorderid = self.main_engine.send_order( thisorder, self.engine_name) this_info.cost_price = this_info.market_price
def run(self) -> None: """""" if not self.check_order_finished(): self.cancel_all() return delta_max = self.delta_target + self.delta_range delta_min = self.delta_target - self.delta_range # Do nothing if portfolio delta is in the allowed range portfolio = self.option_engine.get_portfolio(self.portfolio_name) if delta_min <= portfolio.pos_delta <= delta_max: return # Calculate volume of contract to hedge delta_to_hedge = self.delta_target - portfolio.pos_delta instrument = self.option_engine.get_instrument(self.vt_symbol) hedge_volume = delta_to_hedge / instrument.theo_delta # Send hedge orders tick = self.main_engine.get_tick(self.vt_symbol) contract = self.main_engine.get_contract(self.vt_symbol) holding = self.option_engine.get_position_holding(self.vt_symbol) if hedge_volume > 0: price = tick.ask_price_1 + contract.pricetick * self.hedge_payup direction = Direction.LONG if holding: available = holding.short_pos - holding.short_pos_frozen else: available = 0 else: price = tick.bid_price_1 - contract.pricetick * self.hedge_payup direction = Direction.SHORT if holding: available = holding.long_pos - holding.long_pos_frozen else: available = 0 order_volume = abs(hedge_volume) req = OrderRequest( symbol=contract.symbol, exchange=contract.exchange, direction=direction, type=OrderType.LIMIT, volume=order_volume, price=round_to(price, contract.pricetick), ) # Close positon if opposite available is enough if available > order_volume: req.offset = Offset.CLOSE vt_orderid = self.main_engine.send_order(req, contract.gateway_name) self.active_orderids.add(vt_orderid) # Open position if no oppsite available elif not available: req.offset = Offset.OPEN vt_orderid = self.main_engine.send_order(req, contract.gateway_name) self.active_orderids.add(vt_orderid) # Else close all opposite available and open left volume else: close_req = copy(req) close_req.offset = Offset.CLOSE close_req.volume = available close_orderid = self.main_engine.send_order( close_req, contract.gateway_name) self.active_orderids.add(close_orderid) open_req = copy(req) open_req.offset = Offset.OPEN open_req.volume = order_volume - available open_orderid = self.main_engine.send_order(open_req, contract.gateway_name) self.active_orderids.add(open_orderid)
def order_logic(self, symbol): for strat_id in STRAT_IDS: this_strat_data = self.strat_class[symbol][strat_id] this_signal = 0 if strat_id == 'ma_cross': this_signal, msg = strat_ma_cross( self.data_hist[symbol], self.data_quote[symbol], self.params[symbol][strat_id]) # print(strat_id + '---' + msg) elif strat_id == 'breakout_volume': this_signal, msg = strat_breakout_volume( self.data_hist[symbol], self.data_quote[symbol], self.params[symbol][strat_id]) # print(strat_id + '---' + msg) elif strat_id == 'needle': this_signal, msg = strat_needle(self.data_hist[symbol], self.data_quote[symbol], self.params[symbol][strat_id]) # print(strat_id + '---' + msg) elif strat_id == 'many_bars': this_signal, msg = strat_many_bars( self.data_hist[symbol], self.data_quote[symbol], self.params[symbol][strat_id]) # print(strat_id + '---' + msg) elif strat_id == 'breakout_three_doji': this_signal, msg = strat_breakout_three_doji( self.data_hist[symbol], self.data_quote[symbol], self.params[symbol][strat_id]) elif strat_id == 'pullback': this_signal, msg = strat_pullback( self.data_hist[symbol], self.data_quote[symbol], self.params[symbol][strat_id]) # print(strat_id + '---' + msg) # if currently have no positions if this_strat_data.position == 0: if this_signal == 1: # first 20.0 is leverage, second 20 is how much percent volume = (self.cash_avail * 20.0 / PCT) / self.data_quote[symbol].ask_price_1 if self.data_quote[symbol].min_volume == 1: volume = int(volume) * 1.0 else: len_volume = len( str(self.data_quote[symbol].min_volume).split(".") [1]) volume = round(volume, len_volume) thisorder = OrderRequest( symbol=symbol, exchange=self.main_engine.gateways[ self.enginename].exchanges[0], direction=Direction.LONG, type=OrderType.LIMIT, price=self.data_quote[symbol].ask_price_5, volume=volume, offset=Offset.OPEN) this_order_id = self.main_engine.send_order( thisorder, self.enginename) this_strat_data.strat_id = strat_id this_strat_data.order_id = this_order_id this_strat_data.openprice = self.data_quote[ symbol].ask_price_1 this_strat_data.volume = volume this_strat_data.trade = 1 this_strat_data.position = 1 this_strat_data.time = pd.Timestamp.now().strftime( '%Y-%m-%d %H:%M:%S') self.logger.info( 'strat_id {} -- symbol {} open long position'.format( strat_id, symbol)) print( 'strat_id {} -- symbol {} open long position'.format( strat_id, symbol)) send_wechat( 'strat_id {} -- symbol {} open long position'.format( strat_id, symbol)) self.trade_record = self.trade_record.append( pd.DataFrame({ 'strat_id': [strat_id], 'symbol': [symbol], 'position': [this_strat_data.position], 'trade': [this_strat_data.trade], 'price': [this_strat_data.openprice], 'volume': [this_strat_data.volume], 'order_id': [this_strat_data.order_id], 'time': [this_strat_data.time] })) self.trade_record.to_csv( PATH + '\\save_strategy\\trade_record.csv', index=None) # send order if this_signal == -1: volume = (self.cash_avail * 20.0 / PCT) / self.data_quote[symbol].bid_price_1 if self.data_quote[symbol].min_volume == 1: volume = int(volume) else: len_volume = len( str(self.data_quote[symbol].min_volume).split(".") [1]) volume = round(volume, len_volume) thisorder = OrderRequest( symbol=symbol, exchange=self.main_engine.gateways[ self.enginename].exchanges[0], direction=Direction.SHORT, type=OrderType.LIMIT, price=self.data_quote[symbol].bid_price_5, volume=volume, offset=Offset.OPEN) this_order_id = self.main_engine.send_order( thisorder, self.enginename) this_strat_data.strat_id = strat_id this_strat_data.order_id = this_order_id this_strat_data.openprice = self.data_quote[ symbol].bid_price_1 this_strat_data.volume = volume this_strat_data.trade = -1 this_strat_data.position = -1 this_strat_data.time = pd.Timestamp.now().strftime( '%Y-%m-%d %H:%M:%S') self.logger.info( 'strat_id {} -- symbol {} open short position'.format( strat_id, symbol)) print( 'strat_id {} -- symbol {} open short position'.format( strat_id, symbol)) send_wechat( 'strat_id {} -- symbol {} open short position'.format( strat_id, symbol)) self.trade_record = self.trade_record.append( pd.DataFrame({ 'strat_id': [strat_id], 'symbol': [symbol], 'position': [this_strat_data.position], 'trade': [this_strat_data.trade], 'price': [this_strat_data.openprice], 'volume': [this_strat_data.volume], 'order_id': [this_strat_data.order_id], 'time': [this_strat_data.time] })) self.trade_record.to_csv( PATH + '\\save_strategy\\trade_record.csv', index=None) # send order elif this_strat_data.position == 1: try: cur_price = self.data_quote[symbol].bid_price_1 except: pass pass_time = pd.Timestamp.now() - pd.to_datetime( this_strat_data.time) pass_time = pass_time.seconds print( 'current strat_id {} symbol {} position is {}, time passed {}' .format(strat_id, symbol, this_strat_data.position, pass_time)) bool_exit = False # stop loss if cur_price < this_strat_data.openprice * (1 - 0.008): bool_exit = True self.logger.info( 'strat_id {} -- symbol {} stop loss '.format( strat_id, symbol)) print('strat_id {} -- symbol {} stop loss '.format( strat_id, symbol)) send_wechat('strat_id {} -- symbol {} stop loss '.format( strat_id, symbol)) # stop profit elif cur_price > this_strat_data.openprice * (1 + 0.025): bool_exit = True self.logger.info( 'strat_id {} -- symbol {} stop profit '.format( strat_id, symbol)) print('strat_id {} -- symbol {} stop profit '.format( strat_id, symbol)) send_wechat( 'strat_id {} -- symbol {} stop profit '.format( strat_id, symbol)) elif pass_time > 60 * self.params[symbol][strat_id]['buy'][ 'interval'] * 5: bool_exit = True self.logger.info( 'strat_id {} -- symbol {} time decay '.format( strat_id, symbol)) print('strat_id {} -- symbol {} time decay '.format( strat_id, symbol)) send_wechat('strat_id {} -- symbol {} time decay '.format( strat_id, symbol)) if bool_exit: volume = this_strat_data.volume print('{} price {}'.format( symbol, self.data_quote[symbol].bid_price_5)) thisorder = OrderRequest( symbol=symbol, exchange=self.main_engine.gateways[ self.enginename].exchanges[0], direction=Direction.SHORT, type=OrderType.LIMIT, price=self.data_quote[symbol].bid_price_5, volume=volume, offset=Offset.CLOSE) this_order_id = self.main_engine.send_order( thisorder, self.enginename) this_strat_data.strat_id = strat_id this_strat_data.order_id = this_order_id this_strat_data.openprice = self.data_quote[ symbol].bid_price_1 this_strat_data.volume = volume this_strat_data.trade = -1 this_strat_data.position = 0 this_strat_data.time = pd.Timestamp.now().strftime( '%Y-%m-%d %H:%M:%S') self.trade_record = self.trade_record.append( pd.DataFrame({ 'strat_id': [strat_id], 'symbol': [symbol], 'position': [this_strat_data.position], 'trade': [this_strat_data.trade], 'price': [this_strat_data.openprice], 'volume': [this_strat_data.volume], 'order_id': [this_strat_data.order_id], 'time': [this_strat_data.time] })) self.trade_record.to_csv( PATH + '\\save_strategy\\trade_record.csv', index=None) elif this_strat_data.position == -1: try: cur_price = self.data_quote[symbol].ask_price_1 except: pass pass_time = pd.Timestamp.now() - pd.to_datetime( this_strat_data.time) pass_time = pass_time.seconds print( 'current strat_id {} symbol {} position is {}, time passed {}' .format(strat_id, symbol, this_strat_data.position, pass_time)) bool_exit = False # stop loss if cur_price > this_strat_data.openprice * (1 + 0.008): bool_exit = True self.logger.info( 'strat_id {} -- symbol {} stop loss '.format( strat_id, symbol)) print('strat_id {} -- symbol {} stop loss '.format( strat_id, symbol)) send_wechat('strat_id {} -- symbol {} stop loss '.format( strat_id, symbol)) # stop profit elif cur_price < this_strat_data.openprice * (1 - 0.025): bool_exit = True self.logger.info( 'strat_id {} -- symbol {} stop profit '.format( strat_id, symbol)) print('strat_id {} -- symbol {} stop profit '.format( strat_id, symbol)) send_wechat( 'strat_id {} -- symbol {} stop profit '.format( strat_id, symbol)) elif pass_time > 60 * self.params[symbol][strat_id]['sell'][ 'interval'] * 5: bool_exit = True self.logger.info( 'strat_id {} -- symbol {} time decay '.format( strat_id, symbol)) print('strat_id {} -- symbol {} time decay '.format( strat_id, symbol)) send_wechat('strat_id {} -- symbol {} time decay '.format( strat_id, symbol)) if bool_exit: volume = this_strat_data.volume print('{} price {}'.format( symbol, self.data_quote[symbol].ask_price_5)) thisorder = OrderRequest( symbol=symbol, exchange=self.main_engine.gateways[ self.enginename].exchanges[0], direction=Direction.LONG, type=OrderType.LIMIT, price=self.data_quote[symbol].ask_price_5, volume=volume, offset=Offset.CLOSE) this_order_id = self.main_engine.send_order( thisorder, self.enginename) this_strat_data.strat_id = strat_id this_strat_data.order_id = this_order_id this_strat_data.openprice = self.data_quote[ symbol].ask_price_1 this_strat_data.volume = volume this_strat_data.trade = 1 this_strat_data.position = 0 this_strat_data.time = pd.Timestamp.now().strftime( '%Y-%m-%d %H:%M:%S') self.trade_record = self.trade_record.append( pd.DataFrame({ 'strat_id': [strat_id], 'symbol': [symbol], 'position': [this_strat_data.position], 'trade': [this_strat_data.trade], 'price': [this_strat_data.openprice], 'volume': [this_strat_data.volume], 'order_id': [this_strat_data.order_id], 'time': [this_strat_data.time] })) self.trade_record.to_csv(PATH + 'save_strategy\\trade_record.csv', index=None)
def compare_pos(self, strategy_pos_list=[], auto_balance=False): """ 对比账号&策略的持仓,不同的话则发出邮件提醒 """ # 当前没有接入网关 if len(self.main_engine.gateways) == 0: return False, u'当前没有接入网关' self.write_log(u'开始对比账号&策略的持仓') # 获取当前策略得持仓 if len(strategy_pos_list) == 0: strategy_pos_list = self.get_all_strategy_pos() self.write_log(u'策略持仓清单:{}'.format(strategy_pos_list)) none_strategy_pos = self.get_none_strategy_pos_list() if len(none_strategy_pos) > 0: strategy_pos_list.extend(none_strategy_pos) # 需要进行对比得合约集合(来自策略持仓/账号持仓) vt_symbols = set() # 账号的持仓处理 => compare_pos compare_pos = dict() # vt_symbol: {'账号多单': xx, '账号空单':xxx, '策略空单':[], '策略多单':[]} for position in list(self.positions.values()): # gateway_name.symbol.exchange => symbol.exchange vt_symbol = position.vt_symbol vt_symbols.add(vt_symbol) compare_pos[vt_symbol] = OrderedDict( { "账号净仓": position.volume, '策略空单': 0, '策略多单': 0, '空单策略': [], '多单策略': [] } ) # 逐一根据策略仓位,与Account_pos进行处理比对 for strategy_pos in strategy_pos_list: for pos in strategy_pos.get('pos', []): vt_symbol = pos.get('vt_symbol') if not vt_symbol: continue vt_symbols.add(vt_symbol) symbol_pos = compare_pos.get(vt_symbol, None) if symbol_pos is None: self.write_log(u'账号持仓信息获取不到{},创建一个'.format(vt_symbol)) symbol_pos = OrderedDict( { "账号净仓": 0, '策略空单': 0, '策略多单': 0, '空单策略': [], '多单策略': [] } ) if pos.get('direction') == 'short': symbol_pos.update({'策略空单': round(symbol_pos.get('策略空单', 0) + abs(pos.get('volume', 0)), 7)}) symbol_pos['空单策略'].append( u'{}({})'.format(strategy_pos['strategy_name'], abs(pos.get('volume', 0)))) self.write_log(u'更新{}策略持空仓=>{}'.format(vt_symbol, symbol_pos.get('策略空单', 0))) if pos.get('direction') == 'long': symbol_pos.update({'策略多单': round(symbol_pos.get('策略多单', 0) + abs(pos.get('volume', 0)), 7)}) symbol_pos['多单策略'].append( u'{}({})'.format(strategy_pos['strategy_name'], abs(pos.get('volume', 0)))) self.write_log(u'更新{}策略持多仓=>{}'.format(vt_symbol, symbol_pos.get('策略多单', 0))) pos_compare_result = '' # 精简输出 compare_info = '' for vt_symbol in sorted(vt_symbols): # 发送不一致得结果 symbol_pos = compare_pos.pop(vt_symbol, None) if not symbol_pos: self.write_error(f'持仓对比中,找不到{vt_symbol}') continue net_symbol_pos = round(round(symbol_pos['策略多单'], 7) - round(symbol_pos['策略空单'], 7), 7) # 多空都一致 if round(symbol_pos['账号净仓'], 7) == net_symbol_pos: msg = u'{}多空都一致.{}\n'.format(vt_symbol, json.dumps(symbol_pos, indent=2, ensure_ascii=False)) self.write_log(msg) compare_info += msg else: pos_compare_result += '\n{}: {}'.format(vt_symbol, json.dumps(symbol_pos, indent=2, ensure_ascii=False)) self.write_error(u'{}不一致:{}'.format(vt_symbol, json.dumps(symbol_pos, indent=2, ensure_ascii=False))) compare_info += u'{}不一致:{}\n'.format(vt_symbol, json.dumps(symbol_pos, indent=2, ensure_ascii=False)) diff_volume = round(symbol_pos['账号净仓'], 7) - net_symbol_pos # 账号仓位> 策略仓位, sell if diff_volume > 0 and auto_balance: contract = self.main_engine.get_contract(vt_symbol) req = OrderRequest( symbol=contract.symbol, exchange=contract.exchange, direction=Direction.SHORT, offset=Offset.CLOSE, type=OrderType.MARKET, price=0, volume=round(diff_volume,7) ) self.write_log(f'卖出{vt_symbol} {req.volume},平衡仓位') self.main_engine.send_order(req, contract.gateway_name) # 账号仓位 < 策略仓位 ,buy elif diff_volume < 0 and auto_balance: contract = self.main_engine.get_contract(vt_symbol) req = OrderRequest( symbol=contract.symbol, exchange=contract.exchange, direction=Direction.LONG, offset=Offset.OPEN, type=OrderType.MARKET, price=0, volume=round(-diff_volume, 7) ) self.write_log(f'买入{vt_symbol} {req.volume},平衡仓位') self.main_engine.send_order(req, contract.gateway_name) # 不匹配,输入到stdErr通道 if pos_compare_result != '': msg = u'账户{}持仓不匹配: {}' \ .format(self.engine_config.get('accountid', '-'), pos_compare_result) self.send_email(msg) ret_msg = u'持仓不匹配: {}' \ .format(pos_compare_result) self.write_error(ret_msg) return True, compare_info + ret_msg else: self.write_log(u'账户持仓与策略一致') return True, compare_info
def send_server_order( self, strategy: CtaTemplate, contract: ContractData, direction: Direction, offset: Offset, price: float, volume: float, type: OrderType, lock: bool, net: bool ): """ Send a new order to server. """ # Create request and send order. original_req = OrderRequest( symbol=contract.symbol, exchange=contract.exchange, direction=direction, offset=offset, type=type, price=price, volume=volume, reference=f"{APP_NAME}_{strategy.strategy_name}" ) # Convert with offset converter req_list = self.offset_converter.convert_order_request(original_req, lock, net) # Send Orders vt_orderids = [] for req in req_list: vt_orderid = self.main_engine.send_order(req, contract.gateway_name) # Check if sending order successful if not vt_orderid: continue vt_orderids.append(vt_orderid) self.offset_converter.update_order_request(req, vt_orderid) # Save relationship between orderid and strategy. self.orderid_strategy_map[vt_orderid] = strategy # 新增,用于追踪本地停止单触发后发出的限价单的追踪 if req.offset == Offset.OPEN and req.direction == Direction.LONG: strategy.buy_lvt_orderids.append(vt_orderid) elif req.offset == Offset.OPEN and req.direction == Direction.SHORT: strategy.short_lvt_orderids.append(vt_orderid) elif (req.offset in [Offset.CLOSE, Offset.CLOSETODAY, Offset.CLOSEYESTERDAY]) and req.direction == Direction.SHORT: strategy.sell_lvt_orderids.append(vt_orderid) elif (req.offset in [Offset.CLOSE, Offset.CLOSETODAY, Offset.CLOSEYESTERDAY]) and req.direction == Direction.LONG: strategy.cover_lvt_orderids.append(vt_orderid) self.strategy_orderid_map[strategy.strategy_name].add(vt_orderid) return vt_orderids