from core.strategy_db import TradeTarget from core.util import getStockPosition, is_trading_time, queryPendingOrder from xtquant import xttrader, xtconstant from xtquant.xttype import StockAccount, XtOrder, XtTrade import sfgrid_constants import datetime class StockTradeController: def __init__(self, tradeTarget: TradeTarget, xt_trader: xttrader.XtQuantTrader, account: StockAccount, enabled: bool = False): self.tradeTarget = tradeTarget self.xt_trader: xttrader.XtQuantTrader = xt_trader self.account:StockAccount = account self.enabledTrading(self.tradeTarget.enabled) def getName(self): return "SFGRID" def enabledTrading(self, enabled: bool): self.tradeTarget.enabled = enabled self.tradeTarget.save() pendingOrders = queryPendingOrder(self.tradeTarget.stock_code,self.getName(), self.xt_trader,self.account) if len(pendingOrders) > 0: print(f' |- 已存在{len(pendingOrders)}订单,全部取消,按需要重下。') for order in pendingOrders: self.xt_trader.cancel_order_stock(self.account, order.order_id) if enabled: print(f" |- 标的{self.tradeTarget.targetName()}交易启动, position {self.tradeTarget.current_position}") # 建仓状态检查 if self.tradeTarget.current_position == 0 and self.tradeTarget.status == 0: self.tradeTarget.grid_index = 1 self.tradeTarget.save() self.init_stock_position() print(f" |- 标的{self.tradeTarget.targetName()}建初始仓 买单已发出 InitBuyOrderId: {self.initBuyOrderId} Price: {sfgrid_constants.grid_price[self.tradeTarget.grid_index]} Volume: {sfgrid_constants.grid_volume}") else: # 交易阶段,检查仓位,检查现有订单 print(f" |- 标的{self.tradeTarget.targetName()}已有仓位或非初始状态 无需建初始仓 当前仓位: {self.tradeTarget.current_position} 状态: {self.tradeTarget.status}") minRequirePosition:int = sfgrid_constants.grid_volume * self.tradeTarget.grid_index if minRequirePosition <= self.tradeTarget.current_position: print(f' |- 仓位检查: 持仓需求充足, (gridVolume*gridIndex)={minRequirePosition}, 当前持仓:{self.tradeTarget.current_position}') else: print(f' |- 仓位检查: 持仓需求不足, (gridVolume*gridIndex)={minRequirePosition}, 当前持仓:{self.tradeTarget.current_position}') if is_trading_time(): self.two_way_order(True, True) def isEnabled(self) -> bool: return self.tradeTarget.enabled def onDataUpdate(self, data): if self.isEnabled(): print(f"\n标的{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name} 行情数据更新 {data[self.tradeTarget.stock_code]}") def onOrderUpdate(self, order:XtOrder): pass def onOrderTrade(self, trade:XtTrade): indicator = False if self.tradeTarget.status == 0 and trade.order_id == self.initBuyOrderId : # 此时为建仓成交 self.tradeTarget.current_position += trade.traded_volume # 当前持仓数,账户原有持仓不在策略范围内 self.tradeTarget.last_trade_price = trade.traded_price self.tradeTarget.grid_index = 1 self.tradeTarget.status = 1 self.tradeTarget.save() print(f"|- 标的{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name} 建初始仓订单ID: {self.initBuyOrderId}已成交 ") print(f' 成交价: {trade.traded_price} 成交量: {trade.traded_volume}') print(f' 当前持仓: {getStockPosition(self.tradeTarget.stock_code, self.xt_trader, self.account)}') print(f' 网格坐标: {self.tradeTarget.grid_index}') indicator = True # 双向下单 elif trade.order_id == self.tradeTarget.current_sell_order_no and self.tradeTarget.status == 1: # 上涨一格:此时空单成交 self.tradeTarget.current_position -= trade.traded_volume self.tradeTarget.last_trade_price = trade.traded_price self.tradeTarget.grid_index -= 1 self.tradeTarget.save() print(f"|- 标的{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name} 上涨 卖单已成交 订单ID: {self.tradeTarget.current_sell_order_no} Price: {sfgrid_constants.grid_price[self.tradeTarget.grid_index]} Volume: {sfgrid_constants.grid_volume} 手续费: {trade.commission}\n") print(f' 成交价: {trade.traded_price} 成交量: {trade.traded_volume}') print(f' 当前持仓: {getStockPosition(self.tradeTarget.stock_code, self.xt_trader, self.account)}') print(f' 网格坐标: {self.tradeTarget.grid_index}') cancelResult = self.xt_trader.cancel_order_stock(self.account, self.tradeTarget.current_sell_order_no) print(f' 上涨一格,空单成交,对侧买单已撤单 cancelResult: {cancelResult == 0}') indicator = True # 双向下单 elif trade.order_id == self.tradeTarget.current_buy_order_no and self.tradeTarget.status == 1: # 下跌一格:此时多单成交 self.tradeTarget.current_position += trade.traded_volume self.tradeTarget.last_trade_price = trade.traded_price self.tradeTarget.grid_index += 1 self.tradeTarget.save() print(f"|- 标的{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name} 下跌 买单已成交 订单ID: {self.tradeTarget.current_buy_order_no} Price: {trade.traded_price} Volume: {sfgrid_constants.grid_volume} 手续费: {trade.commission}") print(f' 成交价: {trade.traded_price} 成交量: {trade.traded_volume}') print(f' 当前持仓: {getStockPosition(self.tradeTarget.stock_code, self.xt_trader, self.account)}') print(f' 网格坐标: {self.tradeTarget.grid_index}') cancelResult = self.xt_trader.cancel_order_stock(self.account, self.tradeTarget.current_buy_order_no) print(f' 下跌一格,多单成交,对侧卖单已撤单 cancelResult: {cancelResult == 0}') indicator = True # 双向下单 else: # 打印订单信息和订单状态 print(f'|- 非策略内部订单,或订单状态不满足监控条件 {trade.order_id} {trade.stock_code}-{trade.instrument_name} {trade.commission}') if indicator and self.isEnabled() and is_trading_time(): print(f'goto two way order') self.two_way_order(True, True) # 双向下单 # Description: 新标的,建基础仓 def init_stock_position(self): self.initBuyOrderId = self.xt_trader.order_stock( self.account, self.tradeTarget.stock_code, xtconstant.STOCK_BUY, sfgrid_constants.grid_volume, xtconstant.FIX_PRICE, sfgrid_constants.grid_price[self.tradeTarget.grid_index], 'sf_grid', f'{self.tradeTarget.stock_code}_init_buy') print(f"|- 标的{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name} 建初始仓 买单已发出 InitBuyOrderId: {self.initBuyOrderId} Price: {sfgrid_constants.grid_price[self.tradeTarget.grid_index]} Volume: {sfgrid_constants.grid_volume}\n") # Description: 网格跳格,双向下单 def two_way_order(self, buy, sell): if buy and self.tradeTarget.grid_index+1 < len(sfgrid_constants.grid_price): # 价格没有超过网格下边界,可以下多单 currentPrice = sfgrid_constants.grid_price[self.tradeTarget.grid_index] buyPrice = sfgrid_constants.grid_price[self.tradeTarget.grid_index+1] self.tradeTarget.current_buy_order_no = self.xt_trader.order_stock( self.account, self.tradeTarget.stock_code, xtconstant.STOCK_BUY, sfgrid_constants.grid_volume, xtconstant.FIX_PRICE, buyPrice, self.getName(), # strategy_name f'{self.tradeTarget.stock_code}_grid_down_{self.tradeTarget.grid_index}_{currentPrice}_{buyPrice}' # remark ) self.tradeTarget.current_buy_price = buyPrice print(f' |- 下网格多单 OrderId {self.tradeTarget.current_buy_order_no}, 网格基准价 {currentPrice}, 下单价 {buyPrice}, 下单量 {sfgrid_constants.grid_volume}') if sell and self.tradeTarget.grid_index-1 >=0: # 价格没有超过网格上边界,可以下空单 currentPrice = sfgrid_constants.grid_price[self.tradeTarget.grid_index] sellPrice = sfgrid_constants.grid_price[self.tradeTarget.grid_index-1] self.tradeTarget.current_sell_order_no = self.xt_trader.order_stock( self.account, self.tradeTarget.stock_code, xtconstant.STOCK_SELL, sfgrid_constants.grid_volume, xtconstant.FIX_PRICE, sellPrice, self.getName(), f'{self.tradeTarget.stock_code}_grid_up_{self.tradeTarget.grid_index}_{currentPrice}_{sellPrice}') self.tradeTarget.current_sell_price = sellPrice print(f' |- 下网格空单 OrderId {self.tradeTarget.current_sell_order_no}, 网格基准价 {currentPrice}, 下单价 {sellPrice}, 下单量 {sfgrid_constants.grid_volume}') self.tradeTarget.save()