完成预下单优化
This commit is contained in:
@@ -119,19 +119,16 @@ class QmtV(XtQuantTraderCallback):
|
||||
# ====== 市场回调方法 -- 以下方法由XtQuantData调用 ======
|
||||
def onDataUpdate(self, data):
|
||||
# 收集所有市场数据用于市场监控
|
||||
PrintLog(LogLevel.INFO, f'- [市场数据更新] {len(data)}')
|
||||
eBus.event_bus.publish(eBus.MarketDataUpdate, data)
|
||||
now = time.time()
|
||||
if now - self.lastMarketDataUpdateTimestamp < 5:
|
||||
self.isMarketActive = True
|
||||
PrintLog(LogLevel.INFO, f'- [市场状态变更] 市场已 Active') # 市场已 inactive
|
||||
self.lastMarketDataUpdateTimestamp = now
|
||||
|
||||
def marketStatusNotifier(self):
|
||||
# 市场状态通知器
|
||||
tmpMarketStatus = False
|
||||
while True:
|
||||
PrintLog(LogLevel.INFO, f'- [市场状态检查器] {self.isMarketActive}')
|
||||
tmpTime = time.time()
|
||||
time.sleep(10)
|
||||
if tmpMarketStatus != self.isMarketActive and tmpTime - self.lastMarketDataUpdateTimestamp < 5:
|
||||
|
||||
@@ -24,8 +24,16 @@ class SFGridStrategy:
|
||||
self.todayDownStopPrice=qmtv.dailyDownStop(tradeTarget.stock_code) # type: ignore
|
||||
PrintLog(LogLevel.INFO, f'|- 标的{tradeTarget.targetName()}初始化: 停涨价 {self.todayUpStopPrice}, 停跌价 {self.todayDownStopPrice}')
|
||||
self.orderGrid = {} # grid index, order_seq | order_id
|
||||
self.loadExistOrders()
|
||||
self.enabledTrading(tradeTarget.enabled) # type: ignore
|
||||
self.dataUpdateLock = threading.Lock()
|
||||
|
||||
def loadExistOrders(self):
|
||||
orders = qmtv.queryPendingOrder(self.tradeTarget.stock_code, self.getName()) # type: ignore
|
||||
for order in orders:
|
||||
gridIdx = int(order.order_remark.split(',')[1])
|
||||
self.orderGrid[gridIdx] = order.order_id
|
||||
PrintLog(LogLevel.INFO, f'|- 标的[{self.tradeTarget.targetName()}] 初始化: 加载现有订单, grid-{gridIdx} order_id:{self.orderGrid[gridIdx]}')
|
||||
|
||||
def onMarketActiveSwitch(self, isActive: bool):
|
||||
if isActive and self.tradeTarget.enabled:
|
||||
@@ -48,39 +56,50 @@ class SFGridStrategy:
|
||||
OrderTypeInit, # remark # type: ignore
|
||||
self.getName(), # strategy_name
|
||||
)
|
||||
self.orderGrid[xtconstant.STOCK_BUY] = tmpOrderSeq # seq
|
||||
self.orderGrid[1] = tmpOrderSeq # seq
|
||||
PrintLog(LogLevel.INFO, f'|- 标的[{self.tradeTarget.targetName()}] 初始化: 建仓单,建仓价: {price:.3f}')
|
||||
else:
|
||||
currentIdx = self.tradeTarget.grid_index # type: ignore
|
||||
orders = qmtv.queryPendingOrder(self.tradeTarget.stock_code, self.getName()) # type: ignore
|
||||
|
||||
# 向上下一单,向下下一单
|
||||
if currentIdx > 0: # 可以下空单
|
||||
sellPrice = self.tradeTarget.getPriceGrid()[currentIdx - 1]
|
||||
tmpOrderSeq = qmtv.orderAsync(
|
||||
str(self.tradeTarget.stock_code),
|
||||
self.tradeTarget.grid_volume,
|
||||
xtconstant.STOCK_SELL,
|
||||
sellPrice,
|
||||
xtconstant.FIX_PRICE,
|
||||
OrderTypeSell, # remark # type: ignore
|
||||
self.getName(), # strategy_name
|
||||
)
|
||||
self.orderGrid[xtconstant.STOCK_SELL] = tmpOrderSeq # seq
|
||||
PrintLog(LogLevel.INFO, f'|- 标的[{self.tradeTarget.targetName()}] 初始化: 下空单,价格: {sellPrice:.3f}')
|
||||
sellIdx = currentIdx - 1
|
||||
sellPrice = self.tradeTarget.getPriceGrid()[sellIdx]
|
||||
remark = f'{OrderTypeSell},{sellIdx}'
|
||||
if len([order for order in orders if order.order_type == xtconstant.STOCK_SELL and order.price == sellPrice]) == 0:
|
||||
# 不存在策略内同价位订单,下单
|
||||
tmpOrderSeq = qmtv.orderAsync(
|
||||
str(self.tradeTarget.stock_code),
|
||||
self.tradeTarget.grid_volume,
|
||||
xtconstant.STOCK_SELL,
|
||||
sellPrice,
|
||||
xtconstant.FIX_PRICE,
|
||||
remark, # remark # type: ignore
|
||||
self.getName(), # strategy_name
|
||||
)
|
||||
self.orderGrid[sellIdx] = tmpOrderSeq # seq
|
||||
PrintLog(LogLevel.INFO, f'|- 标的[{self.tradeTarget.targetName()}] 初始化: 下空单,价格: {sellPrice:.3f}')
|
||||
else:
|
||||
PrintLog(LogLevel.INFO, f'|- 标的[{self.tradeTarget.targetName()}] 初始化: 已存在同价位空单,跳过下单')
|
||||
if currentIdx < len(self.tradeTarget.getPriceGrid()) - 1: # 可以下多单
|
||||
buyPrice = self.tradeTarget.getPriceGrid()[currentIdx + 1]
|
||||
tmpOrderSeq = qmtv.orderAsync(
|
||||
buyIdx = currentIdx + 1
|
||||
buyPrice = self.tradeTarget.getPriceGrid()[buyIdx]
|
||||
remark = f'{OrderTypeBuy},{buyIdx}'
|
||||
if len([order for order in orders if order.order_type == xtconstant.STOCK_BUY and order.price == buyPrice]) == 0:
|
||||
tmpOrderSeq = qmtv.orderAsync(
|
||||
str(self.tradeTarget.stock_code),
|
||||
self.tradeTarget.grid_volume,
|
||||
xtconstant.STOCK_BUY,
|
||||
buyPrice,
|
||||
xtconstant.FIX_PRICE,
|
||||
OrderTypeBuy, # remark # type: ignore
|
||||
remark, # remark # type: ignore
|
||||
self.getName(), # strategy_name
|
||||
)
|
||||
self.orderGrid[xtconstant.STOCK_BUY] = tmpOrderSeq # seq
|
||||
PrintLog(LogLevel.INFO, f'|- 标的[{self.tradeTarget.targetName()}] 初始化: 下多单,价格: {buyPrice:.3f}')
|
||||
|
||||
self.orderGrid[buyIdx] = tmpOrderSeq # seq
|
||||
PrintLog(LogLevel.INFO, f'|- 标的[{self.tradeTarget.targetName()}] 初始化: 下多单,价格: {buyPrice:.3f}')
|
||||
else:
|
||||
PrintLog(LogLevel.INFO, f'|- 标的[{self.tradeTarget.targetName()}] 初始化: 已存在同价位多单,跳过下单')
|
||||
|
||||
def deleteTradeTarget(self, tradeTarget:model.SFGridTradeTarget):
|
||||
PrintLog(LogLevel.INFO, f'|- 标的{tradeTarget.targetName()}信息删除: START')
|
||||
@@ -96,18 +115,18 @@ class SFGridStrategy:
|
||||
self.tradeTarget.enabled = enabled # type: ignore
|
||||
|
||||
if enabled:
|
||||
print(f" |- 标的{self.tradeTarget.targetName()}交易启动, 持仓量:{self.tradeTarget.current_position}")
|
||||
PrintLog(LogLevel.INFO, f" |- 标的{self.tradeTarget.targetName()}交易启动, 持仓量:{self.tradeTarget.current_position}")
|
||||
if self.tradeTarget.status == 0: # 未建仓
|
||||
print(f" |- 标的{self.tradeTarget.targetName()}初始状态, 设置网格序号 1,")
|
||||
PrintLog(LogLevel.INFO, f" |- 标的{self.tradeTarget.targetName()}初始状态, 设置网格序号 1,")
|
||||
self.tradeTarget.grid_index = 1 # pyright: ignore[reportAttributeAccessIssue]
|
||||
else: # 已建仓
|
||||
# 交易阶段,检查仓位,检查现有订单
|
||||
print(f" |- 标的{self.tradeTarget.targetName()}已有仓位或非初始状态 无需建初始仓 当前仓位: {self.tradeTarget.current_position} 状态: {self.tradeTarget.status}")
|
||||
PrintLog(LogLevel.INFO, f" |- 标的{self.tradeTarget.targetName()}已有仓位或非初始状态 无需建初始仓 当前仓位: {self.tradeTarget.current_position} 状态: {self.tradeTarget.status}")
|
||||
minRequirePosition:int = self.tradeTarget.grid_volume * int(self.tradeTarget.grid_index) # type: ignore
|
||||
if minRequirePosition <= int(self.tradeTarget.current_position): # type: ignore
|
||||
print(f' |- 仓位检查: 持仓需求充足, (gridVolume*gridIndex)={minRequirePosition}, 当前持仓:{self.tradeTarget.current_position}')
|
||||
PrintLog(LogLevel.INFO, f' |- 仓位检查: 持仓需求充足, (gridVolume*gridIndex)={minRequirePosition}, 当前持仓:{self.tradeTarget.current_position}')
|
||||
else:
|
||||
print(f' |- 仓位检查: 持仓需求不足, (gridVolume*gridIndex)={minRequirePosition}, 当前持仓:{self.tradeTarget.current_position}, 交易启动失败')
|
||||
PrintLog(LogLevel.INFO, f' |- 仓位检查: 持仓需求不足, (gridVolume*gridIndex)={minRequirePosition}, 当前持仓:{self.tradeTarget.current_position}, 交易启动失败')
|
||||
self.tradeTarget.enabled = False # type: ignore
|
||||
self.refreshGridOrder()
|
||||
else:
|
||||
@@ -128,11 +147,10 @@ class SFGridStrategy:
|
||||
self.dataUpdateLock.acquire()
|
||||
try:
|
||||
if response.strategy_name == self.getName() and response.seq == self.tradeTarget.current_order_no:
|
||||
print(f"委托创建通知 onOrderCreateAsync[{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name}]: {response.order_id}")
|
||||
for gridIdx, orderNo in self.orderGrid.items():
|
||||
if orderNo == response.seq:
|
||||
self.orderGrid[gridIdx] = response.order_id
|
||||
break
|
||||
PrintLog(LogLevel.INFO, f"委托创建通知 onOrderCreateAsync[{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name}]: {response.order_id}")
|
||||
idx = response.order_remark.split(',')[1]
|
||||
self.orderGrid[idx] = response.order_id
|
||||
PrintLog(LogLevel.INFO, f"委托创建通知 onOrderCreateAsync 更新 grid-{idx} seq:{response.seq} -> order_id:{response.order_id}")
|
||||
except Exception as e:
|
||||
PrintLog(LogLevel.ERROR, f"|- 委托创建通知 onOrderCreateAsync[{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name}]: {response.order_id} - {str(e)}")
|
||||
finally:
|
||||
@@ -159,24 +177,23 @@ class SFGridStrategy:
|
||||
if tmpOrderNo == trade.order_id:
|
||||
if idx > self.tradeTarget.grid_index:
|
||||
type = "下移一格"
|
||||
self.tradeTarget.grid_index +=1
|
||||
elif idx < self.tradeTarget.grid_index:
|
||||
type = "上移一格"
|
||||
self.tradeTarget.grid_index -= 1
|
||||
elif idx == self.tradeTarget.grid_index:
|
||||
type = "保持格, 理论上不应该输出"
|
||||
self.tradeTarget.grid_index = idx
|
||||
self.saveProxy()
|
||||
break
|
||||
PrintLog(LogLevel.INFO, f'|- 委托成交通知[{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name} - 原网格位置 {oriIdx}, 现网格位置 {self.tradeTarget.grid_index}')
|
||||
self.saveProxy()
|
||||
self.printTradeReport(trade, type)
|
||||
|
||||
PrintLog(LogLevel.INFO, f"|- 成交报告[{self.tradeTarget.targetName()}] : ====================================")
|
||||
PrintLog(LogLevel.INFO, f"|- 标的[{self.tradeTarget.targetName()}] {type}-单号{self.tradeTarget.current_order_no}已成交 ")
|
||||
PrintLog(LogLevel.INFO, f' 成交价: {trade.traded_price} 成交量: {trade.traded_volume}')
|
||||
PrintLog(LogLevel.INFO, f' 手续费 : {trade.commission:.3f}')
|
||||
self.refreshGridOrder() # 更新网格订单
|
||||
finally:
|
||||
self.dataUpdateLock.release()
|
||||
|
||||
def printTradeReport(self, trade:XtTrade, type:str):
|
||||
PrintLog(LogLevel.INFO, f"|- 成交报告[{self.tradeTarget.targetName()}] : ====================================")
|
||||
PrintLog(LogLevel.INFO, f"|- 标的[{self.tradeTarget.targetName()}] {type}-单号{self.tradeTarget.current_order_no}已成交 ")
|
||||
PrintLog(LogLevel.INFO, f' 成交价: {trade.traded_price} 成交量: {trade.traded_volume}')
|
||||
PrintLog(LogLevel.INFO, f' 手续费 : {trade.commission:.3f}')
|
||||
|
||||
|
||||
def getName(self):
|
||||
|
||||
@@ -57,10 +57,10 @@ class TradeTargetUI(ttk.Frame):
|
||||
if stock_code in self.stockCodeIdMap:
|
||||
id:int = self.stockCodeIdMap[stock_code]
|
||||
tradeTarget = self.tradeTargetData[id]
|
||||
timeStr = datetime.fromtimestamp(tickData['time']/1000)
|
||||
PrintLog(LogLevel.INFO, f'|- 市价更新[{tradeTarget.targetName()}] - {timeStr.strftime("%H:%M:%S")} 市场数据更新======================={id}')
|
||||
# timeStr = datetime.fromtimestamp(tickData['time']/1000)
|
||||
lastPrice = float("{:.3f}".format(tickData['lastPrice']))
|
||||
tradeTarget.market_price = lastPrice # type: ignore
|
||||
# PrintLog(LogLevel.INFO, f'|- 市价更新[{tradeTarget.targetName()}] - {timeStr.strftime("%H:%M:%S")} 市价更新: {lastPrice}======================{id}')
|
||||
self.updateTradeTarget(tradeTarget, False) # 市价更新
|
||||
else:
|
||||
# 非目标交易,发布市场数据更新事件用于市场监控
|
||||
@@ -151,7 +151,7 @@ class TradeTargetUI(ttk.Frame):
|
||||
while True:
|
||||
self.after(0, self.refresh_table)
|
||||
self.after(0, self.populate_market_table)
|
||||
time.sleep(0.2) # 每0.5秒刷新一次
|
||||
time.sleep(0.5) # 每0.5秒刷新一次
|
||||
|
||||
|
||||
def create_tables_area(self, parent):
|
||||
|
||||
Reference in New Issue
Block a user