This commit is contained in:
2025-11-14 15:52:03 +08:00
parent a18c7be7eb
commit cd67c9ad60
6 changed files with 23 additions and 18 deletions
+1
View File
@@ -1,5 +1,6 @@
[config] [config]
miniqmtpath = D:/Programs/DTQMT/userdata_mini miniqmtpath = D:/Programs/DTQMT/userdata_mini
account_no = 99082560 account_no = 99082560
log_level = INFO
; account_no = 89009170 ; account_no = 89009170
+3 -1
View File
@@ -7,6 +7,7 @@ miniQMTPath = r'D:\\Programs\\DTQMT\\userdata_mini' # miniQMT软件的安装路
# miniQMTPath = '' # miniQMTPath = ''
account_no:str = '99082560' account_no:str = '99082560'
console_log = True console_log = True
log_level = "INFO"
def get_config_path() -> Path: def get_config_path() -> Path:
"""获取配置文件的正确路径(兼容开发环境和打包后的可执行文件)""" """获取配置文件的正确路径(兼容开发环境和打包后的可执行文件)"""
@@ -26,7 +27,8 @@ def create_default_config():
config = configparser.ConfigParser() config = configparser.ConfigParser()
config['config'] = { config['config'] = {
'miniQMTPath': r'D:/Programs/QMT/userdata_mini', 'miniQMTPath': r'D:/Programs/QMT/userdata_mini',
'account_no': '00000000' 'account_no': '00000000',
'log_level' : 'INFO'
} }
config_path = get_config_path() config_path = get_config_path()
with open(config_path, 'w') as configfile: with open(config_path, 'w') as configfile:
+3 -2
View File
@@ -165,7 +165,7 @@ class QmtV(XtQuantTraderCallback):
:param order: XtOrder对象 :param order: XtOrder对象
:return: :return:
""" """
print(f"委托回调 on_stock_order 投资备注 {order.strategy_name} {order.order_remark}") print(f"委托回调 on_stock_order 投资备注 {order.order_id} {order.strategy_name} {order.order_remark}")
# print(f'orderd {order.strategy_name}-{order.stock_code} {order.order_id} {order.order_volume}-{order.order_status}') # print(f'orderd {order.strategy_name}-{order.stock_code} {order.order_id} {order.order_volume}-{order.order_status}')
# stockCode = order.stock_code # stockCode = order.stock_code
# ctrl:SFGridStrategy = self.stock_trade_ctrl[stockCode] # ctrl:SFGridStrategy = self.stock_trade_ctrl[stockCode]
@@ -193,7 +193,8 @@ class QmtV(XtQuantTraderCallback):
# print(f"委托回调 投资备注 {trade.strategy_name} 不匹配 {ctrl.getName()}") # print(f"委托回调 投资备注 {trade.strategy_name} 不匹配 {ctrl.getName()}")
def on_order_stock_async_response(self, response:XtOrderResponse): def on_order_stock_async_response(self, response:XtOrderResponse):
print(f"委托回调 on_order_stock_async_response 投资备注 {response.error_msg}{response.strategy_name} {response.order_remark}") print(f"委托回调 on_order_stock_async_response 投资备注 {response.order_id} {response.seq} {response.error_msg}{response.strategy_name} {response.order_remark}")
eBus.event_bus.publish(eBus.MarketOrderCreated, response)
# stockCode = response.order_remark # stockCode = response.order_remark
# ctrl:SFGridStrategy = self.stock_trade_ctrl[stockCode] # ctrl:SFGridStrategy = self.stock_trade_ctrl[stockCode]
+11 -12
View File
@@ -8,7 +8,7 @@ from core.constants import OrderTypeBuy, OrderTypeInit, OrderTypeSell
from core.util import is_trading_time from core.util import is_trading_time
from xtquant import xtconstant from xtquant import xtconstant
from xtquant.xttype import XtOrder, XtOrderResponse, XtTrade from xtquant.xttype import XtOrderResponse, XtTrade
import threading import threading
import core.eventbus as eBus import core.eventbus as eBus
@@ -18,6 +18,7 @@ class SFGridStrategy:
def __init__(self, tradeTarget: model.SFGridTradeTarget): def __init__(self, tradeTarget: model.SFGridTradeTarget):
self.tradeTarget:model.SFGridTradeTarget = tradeTarget self.tradeTarget:model.SFGridTradeTarget = tradeTarget
self.enabledTrading(tradeTarget.enabled) # type: ignore self.enabledTrading(tradeTarget.enabled) # type: ignore
event_bus.subscribe(eBus.MarketOrderCreated, self.onOrderCreateAsync)
event_bus.subscribe(eBus.MarketOrderTraded, self.onOrderTrade) event_bus.subscribe(eBus.MarketOrderTraded, self.onOrderTrade)
self.refreshPlanPrice() self.refreshPlanPrice()
self.dataUpdateLock = threading.Lock() self.dataUpdateLock = threading.Lock()
@@ -91,7 +92,7 @@ class SFGridStrategy:
PrintLog(LogLevel.INFO, f'|- 市价更新[{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name}] - 计划买入价{self.tradeTarget.plan_buy_price}, 计划卖出价{self.tradeTarget.plan_sell_price}') PrintLog(LogLevel.INFO, f'|- 市价更新[{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name}] - 计划买入价{self.tradeTarget.plan_buy_price}, 计划卖出价{self.tradeTarget.plan_sell_price}')
if self.tradeTarget.enabled and self.tradeTarget.status == 0 and lastPrice <= inTradeTarget.getPriceGrid()[1]: # 已启用,未建仓,准备建仓单信息 if self.tradeTarget.enabled and self.tradeTarget.status == 0 and lastPrice <= inTradeTarget.getPriceGrid()[1]: # 已启用,未建仓,准备建仓单信息
PrintLog(LogLevel.INFO, f'|- 市价更新[{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name}] - 准备建仓单信息') PrintLog(LogLevel.INFO, f'|- 市价更新[{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name}] - 准备建仓单信息')
orderPrice = inTradeTarget.getPriceGrid()[index] orderPrice = inTradeTarget.getPriceGrid()[1]
orderType = xtconstant.STOCK_BUY orderType = xtconstant.STOCK_BUY
orderRemark = OrderTypeInit orderRemark = OrderTypeInit
elif self.tradeTarget.enabled and self.tradeTarget.status == 1 and self.tradeTarget.plan_buy_price > 0 and lastPrice <= self.tradeTarget.plan_buy_price: elif self.tradeTarget.enabled and self.tradeTarget.status == 1 and self.tradeTarget.plan_buy_price > 0 and lastPrice <= self.tradeTarget.plan_buy_price:
@@ -139,17 +140,15 @@ class SFGridStrategy:
self.dataUpdateLock.release() self.dataUpdateLock.release()
print(f'|- 市价更新[{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name}] - END') print(f'|- 市价更新[{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name}] - END')
def onOrderCreate(self, order:XtOrder):
if order.strategy_name == self.getName():
print(f"委托创建通知 onOrderCreate[{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name}]: {order.order_id}")
self.tradeTarget.current_order_no = order.order_id
self.saveProxy()
def onOrderCreateAsync(self, response:XtOrderResponse): def onOrderCreateAsync(self, response:XtOrderResponse):
if response.strategy_name == self.getName(): self.dataUpdateLock.acquire()
print(f"委托创建通知 onOrderCreateAsync[{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name}]: {response.order_id}") try:
self.tradeTarget.current_order_no = response.order_id if response.strategy_name == self.getName() and response.seq == self.tradeTarget.current_order_no:
self.saveProxy() print(f"委托创建通知 onOrderCreateAsync[{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name}]: {response.order_id}")
self.tradeTarget.current_order_no = response.order_id
self.saveProxy()
finally:
self.dataUpdateLock.release()
def onOrderTrade(self, trade:XtTrade): def onOrderTrade(self, trade:XtTrade):
if trade.strategy_name != self.getName(): if trade.strategy_name != self.getName():
+4 -2
View File
@@ -54,7 +54,7 @@ class TradeTargetUI(ttk.Frame):
tradeTarget = self.tradeTargetData[id] tradeTarget = self.tradeTargetData[id]
lastPrice = float("{:.3f}".format(tickData['lastPrice'])) lastPrice = float("{:.3f}".format(tickData['lastPrice']))
tradeTarget.market_price = lastPrice # type: ignore tradeTarget.market_price = lastPrice # type: ignore
self.updateTradeTarget(tradeTarget, False) self.updateTradeTarget(tradeTarget, False, True)
else: else:
# 非目标交易,发布市场数据更新事件用于市场监控 # 非目标交易,发布市场数据更新事件用于市场监控
lastPrice = tickData['lastPrice'] lastPrice = tickData['lastPrice']
@@ -82,7 +82,7 @@ class TradeTargetUI(ttk.Frame):
self.tradeTargetData[id] = target self.tradeTargetData[id] = target
def updateTradeTarget(self, target: SFGridTradeTarget, save: bool = True): def updateTradeTarget(self, target: SFGridTradeTarget, save: bool = True, priceChange:bool = False):
if save: if save:
target.save() target.save()
@@ -98,6 +98,8 @@ class TradeTargetUI(ttk.Frame):
self.strategy_ctrl[id] = SFGridStrategy(target) # pyright: ignore[reportArgumentType] self.strategy_ctrl[id] = SFGridStrategy(target) # pyright: ignore[reportArgumentType]
else: else:
self.strategy_ctrl[id].updateTradeTarget(target) self.strategy_ctrl[id].updateTradeTarget(target)
if priceChange:
self.strategy_ctrl[id].onDataUpdate(target)
# UI CREATE # UI CREATE
def create_ui(self): def create_ui(self):
+1 -1
View File
@@ -5,7 +5,7 @@ a = Analysis(
pathex=[], pathex=[],
binaries=[], binaries=[],
datas=[('config.ini', '.')], # 明确包含配置文件 datas=[('config.ini', '.')], # 明确包含配置文件
hiddenimports=[], hiddenimports=['brotli', 'brotli.encoding'],
hookspath=[], hookspath=[],
hooksconfig={}, hooksconfig={},
runtime_hooks=[], runtime_hooks=[],