This commit is contained in:
2025-11-03 15:13:53 +08:00
parent 4325bbafb7
commit 1e3622f948
5 changed files with 117 additions and 88 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
[config] [config]
miniQMTPath=D:\Programs\DTQMT\userdata_mini miniQMTPath=D:\\Programs\\DTQMT\\userdata_mini
grid_price=1.665,1.660,1.655,1.650,1.645,1.640,1.635,1.630,1.625,1.620,1.615 grid_price=1.665,1.660,1.655,1.650,1.645,1.640,1.635,1.630,1.625,1.620,1.615
grid_volume = 100 grid_volume = 100
account_no = '99082560' account_no = '99082560'
+37 -22
View File
@@ -1,16 +1,19 @@
# coding:utf-8 # coding:utf-8
from xtquant.xttrader import XtQuantTrader
import time, sys import time, sys
from peewee import ModelSelect from peewee import ModelSelect
import xtquant.xtconstant as xtconstant import xtquant.xtconstant as xtconstant
sys.stdout.reconfigure(encoding='utf-8') # 设置标准输出编码为UTF-8 sys.stdout.reconfigure(encoding='utf-8') # 设置标准输出编码为UTF-8 # type: ignore
import core.strategy_db as strategy_db import core.strategy_db as strategy_db
import sfgrid_constants import sfgrid_constants
from core.sfgrid_trade_controller import StockTradeController from core.sfgrid_trade_controller import StockTradeController
from core.util import getInstrumentName, getStockPosition from core.util import getInstrumentName, getStockPosition
from xtquant.xttrader import XtQuantTrader from xtquant.xttrader import XtQuantTrader
from xtquant.xttype import StockAccount, XtAsset, XtOrder, XtPosition, XtTrade from xtquant.xttype import StockAccount, XtAsset, XtOrder, XtOrderResponse, XtPosition, XtTrade
from xtquant import xtdata from xtquant import xtdata
from xtquant.xttrader import XtQuantTraderCallback from xtquant.xttrader import XtQuantTraderCallback
import datetime import datetime
@@ -20,7 +23,6 @@ class SFGridController(XtQuantTraderCallback):
def __init__(self, account_no: str, miniQmtPath: str): def __init__(self, account_no: str, miniQmtPath: str):
super().__init__() super().__init__()
sfgrid_constants.initConfig()
xtdata.enable_hello = False xtdata.enable_hello = False
strategy_db.db.connect() strategy_db.db.connect()
strategy_db.db.create_tables([strategy_db.TradeTarget]) strategy_db.db.create_tables([strategy_db.TradeTarget])
@@ -28,18 +30,19 @@ class SFGridController(XtQuantTraderCallback):
session_id = int(time.time()) session_id = int(time.time())
self.xt_trader = XtQuantTrader(miniQmtPath, session_id) self.xt_trader: XtQuantTrader = XtQuantTrader(miniQmtPath, session_id)
self.xt_trader.register_callback(self) self.xt_trader.register_callback(self)
self.xt_trader.start() self.xt_trader.start()
connect_result = self.xt_trader.connect() connect_result = self.xt_trader.connect()
print(f'- [{'成功' if self.xt_trader.connected else '失败'}]市场交易连接{connect_result}:') print(f'- [{'成功' if self.xt_trader.connected else '失败'}]市场交易连接{connect_result}--: {miniQmtPath}')
self.account= StockAccount(account_no, 'STOCK') self.account= StockAccount(account_no, 'STOCK')
print(f'- [成功]交易账号对象初始化完成, 账号: {self.account.account_id}') print(f'- [成功]交易账号对象初始化完成, 账号: {self.account.account_id}') # pyright: ignore[reportAttributeAccessIssue]
subscribe_result = self.xt_trader.subscribe(self.account) subscribe_result = self.xt_trader.subscribe(self.account)
print(f'- [{'成功' if subscribe_result == 0 else '失败'}]交易状态订阅') print(f'- [{'成功' if subscribe_result == 0 else '失败'}:{subscribe_result}]交易状态订阅')
self.stock_trade_ctrl = {} self.stock_trade_ctrl = {}
self.init_instrument_pool(self.xt_trader, self.account) self.init_instrument_pool(self.xt_trader, self.account) # type: ignore
self.seq = None self.seq = None
print('- [成功]三疯交易系统初始化完成') print('- [成功]三疯交易系统初始化完成')
@@ -76,12 +79,12 @@ class SFGridController(XtQuantTraderCallback):
new_target.save() new_target.save()
print(f'新增交易标的 {stock_code} {stock_name}, {new_target.id}') print(f'新增交易标的 {stock_code} {stock_name}, {new_target.id}')
# 刷新标的持仓 # 刷新标的持仓
pos = getStockPosition(stock_code, self.xt_trader, self.account) pos = getStockPosition(stock_code, self.xt_trader, self.account) # type: ignore
strategy_db.TradeTarget.update(current_position=pos).where(strategy_db.TradeTarget.stock_code == stock_code).execute() strategy_db.TradeTarget.update(current_position=pos).where(strategy_db.TradeTarget.stock_code == stock_code).execute()
# 更新标的池 # 更新标的池
self.refresh_targets() self.refresh_targets()
# 添加交易控制器 # 添加交易控制器
stockTradeController = StockTradeController(new_target, self.xt_trader, self.account, new_target.enabled) stockTradeController = StockTradeController(new_target, self.xt_trader, self.account, new_target.enabled) # type: ignore
self.stock_trade_ctrl[stock_code] = stockTradeController self.stock_trade_ctrl[stock_code] = stockTradeController
except Exception as e: except Exception as e:
@@ -101,10 +104,10 @@ class SFGridController(XtQuantTraderCallback):
for temp in self.instrument_pool: for temp in self.instrument_pool:
tradeTarget:strategy_db.TradeTarget = temp tradeTarget:strategy_db.TradeTarget = temp
tradeTarget.current_position = getStockPosition(tradeTarget.stock_code, xtTrader, account) tradeTarget.current_position = getStockPosition(tradeTarget.stock_code, xtTrader, account) # type: ignore
result = tradeTarget.save() result = tradeTarget.save()
print(f' |- 同步当前持仓信息 {tradeTarget.stock_code}, {tradeTarget.current_position}, result = {result}') print(f' |- 同步当前持仓信息 {tradeTarget.stock_code}, {tradeTarget.current_position}, result = {result}')
stockTradeController = StockTradeController(tradeTarget, self.xt_trader, self.account, tradeTarget.enabled) stockTradeController = StockTradeController(tradeTarget, self.xt_trader, self.account, tradeTarget.enabled) # type: ignore
self.stock_trade_ctrl[tradeTarget.stock_code] = stockTradeController self.stock_trade_ctrl[tradeTarget.stock_code] = stockTradeController
print(f'- [成功]交易标的信息初始化, 共 {len(self.instrument_pool)} 个标的') print(f'- [成功]交易标的信息初始化, 共 {len(self.instrument_pool)} 个标的')
@@ -120,15 +123,15 @@ class SFGridController(XtQuantTraderCallback):
for i in range(len(self.instrument_pool)): for i in range(len(self.instrument_pool)):
target: strategy_db.TradeTarget = self.instrument_pool[i] target: strategy_db.TradeTarget = self.instrument_pool[i]
status = "新建" if target.status == 0 else "已建初始仓" status = "新建" if target.status == 0 else "已建初始仓"
print(f' [序号-{i}] 股票代码: {target.stock_code}-{target.stock_name} 当前持仓: {getStockPosition(target.stock_code, self.xt_trader, self.account)} 网格索引: {target.grid_index} 基准价格 {sfgrid_constants.grid_price[target.grid_index]} 状态: {status} 启用交易线程: {'自动交易中' if target.enabled else '交易已停止'}') print(f' [序号-{i}] 股票代码: {target.stock_code}-{target.stock_name} 当前持仓: {getStockPosition(target.stock_code, self.xt_trader, self.account)} 网格索引: {target.grid_index} 基准价格 {sfgrid_constants.grid_price[target.grid_index]} 状态: {status} 启用交易线程: {'自动交易中' if target.enabled else '交易已停止'}') # type: ignore
def print_position_info(self): def print_position_info(self):
positions = self.xt_trader.query_stock_positions(self.account) positions:list[XtPosition] = self.xt_trader.query_stock_positions(self.account)
if positions: if positions:
print("\n- 持仓信息") print("\n- 持仓信息")
for temp in positions: for temp in positions:
pos : XtPosition = temp pos : XtPosition = temp
if pos.m_nVolume <=0: if pos.volume <=0:
continue continue
print(f"股票代码: {pos.stock_code}-{getInstrumentName(pos.stock_code)}") print(f"股票代码: {pos.stock_code}-{getInstrumentName(pos.stock_code)}")
print(f"总持仓: {pos.volume}") print(f"总持仓: {pos.volume}")
@@ -140,9 +143,9 @@ class SFGridController(XtQuantTraderCallback):
def print_account_info(self): def print_account_info(self):
temp = self.xt_trader.query_stock_asset(self.account) temp = self.xt_trader.query_stock_asset(self.account)
asset: XtAsset =temp asset: XtAsset = temp # type: ignore
print(f"=== 账户信息 {self.account.account_id} ===") print(f"=== 账户信息 {self.account.account_id} ===") # type: ignore
print(f"可用资金: {asset.cash}") print(f"可用资金: {asset.cash}")
print(f"总资产: {asset.total_asset}") print(f"总资产: {asset.total_asset}")
print(f"证券市值: {asset.market_value}") print(f"证券市值: {asset.market_value}")
@@ -176,7 +179,7 @@ class SFGridController(XtQuantTraderCallback):
print(f"标的交易控制器已存在但未运行,重新启动 {tradeTarget.stock_code} {getInstrumentName(tradeTarget.stock_code)}\n") print(f"标的交易控制器已存在但未运行,重新启动 {tradeTarget.stock_code} {getInstrumentName(tradeTarget.stock_code)}\n")
tradeController.enabledTrading(True) tradeController.enabledTrading(True)
else: else:
stockTradeController = StockTradeController(tradeTarget, self.xt_trader, self.account, tradeTarget.enabled) stockTradeController = StockTradeController(tradeTarget, self.xt_trader, self.account, tradeTarget.enabled) # type: ignore
self.stock_trade_ctrl[tradeTarget.stock_code] = stockTradeController self.stock_trade_ctrl[tradeTarget.stock_code] = stockTradeController
print(f"\t创建标的交易控制器 {tradeTarget.stock_code} {getInstrumentName(tradeTarget.stock_code)}") print(f"\t创建标的交易控制器 {tradeTarget.stock_code} {getInstrumentName(tradeTarget.stock_code)}")
@@ -239,14 +242,14 @@ class SFGridController(XtQuantTraderCallback):
ctrl:StockTradeController = self.stock_trade_ctrl[stockCode] ctrl:StockTradeController = self.stock_trade_ctrl[stockCode]
# 如果存在对应的StockTradeController,则调用其onDataUpdate方法 # 如果存在对应的StockTradeController,则调用其onDataUpdate方法
if ctrl is not None and order.strategy_name == ctrl.getName(): if ctrl is not None and order.strategy_name == ctrl.getName():
ctrl.onOrderTrade(order) ctrl.onOrderTrade(trade=order) # type: ignore
else: else:
print(f"委托下单回调 投资备注 {order.order_remark} 不匹配 {ctrl.getName()}") print(f"委托下单回调 投资备注 orderId: {order.order_sysid} [{order.stock_code}-{order.instrument_name}] volume: {order.order_volume} 订单策略: '{order.strategy_name}'<-->'{ctrl.getName()}'")
def test_sim_trade(self, index: int, orderType: int): def test_sim_trade(self, index: int, orderType: int):
tradeTarget:strategy_db.TradeTarget = self.instrument_pool[index] tradeTarget:strategy_db.TradeTarget = self.instrument_pool[index]
ctrl:StockTradeController = self.stock_trade_ctrl[tradeTarget.stock_code] ctrl:StockTradeController = self.stock_trade_ctrl[tradeTarget.stock_code]
trade: XtTrade = None trade: XtTrade = None # type: ignore
if orderType == xtconstant.STOCK_BUY: if orderType == xtconstant.STOCK_BUY:
trade = XtTrade( trade = XtTrade(
sfgrid_constants.account_no, sfgrid_constants.account_no,
@@ -256,7 +259,7 @@ class SFGridController(XtQuantTraderCallback):
tradeTarget.current_buy_order_no, tradeTarget.current_buy_order_no,
None, ctrl.getName(), None, None, None, None, None, tradeTarget.stock_name) None, ctrl.getName(), None, None, None, None, None, tradeTarget.stock_name)
else: else:
trade = XtTrade(sfgrid_constants.account_no, '300083.SZ', xtconstant.STOCK_SELL, 1, 1, price, sfgrid_constants.grid_volume, 1000, tradeTarget.current_sell_order_no, None, ctrl.getName(), None, None, None, None, None, tradeTarget.stock_name) trade = XtTrade(sfgrid_constants.account_no, '300083.SZ', xtconstant.STOCK_SELL, 1, 1, price, sfgrid_constants.grid_volume, 1000, tradeTarget.current_sell_order_no, None, ctrl.getName(), None, None, None, None, None, tradeTarget.stock_name) # type: ignore
self.on_stock_trade(trade) self.on_stock_trade(trade)
def on_stock_trade(self, trade:XtTrade): def on_stock_trade(self, trade:XtTrade):
@@ -273,6 +276,15 @@ class SFGridController(XtQuantTraderCallback):
else: else:
print(f"委托回调 投资备注 {trade.strategy_name} 不匹配 {ctrl.getName()}") print(f"委托回调 投资备注 {trade.strategy_name} 不匹配 {ctrl.getName()}")
def on_order_stock_async_response(self, response:XtOrderResponse):
stockCode = response.order_remark
ctrl:StockTradeController = self.stock_trade_ctrl[stockCode]
# 如果存在对应的StockTradeController,则调用其onDataUpdate方法
if ctrl is not None and response.strategy_name == ctrl.getName():
ctrl.onAsyncOrderResponse(response)
else:
print(f"委托回调 投资备注 {response.strategy_name} 不匹配 {ctrl.getName()}")
def on_order_error(self, order_error): def on_order_error(self, order_error):
""" """
委托失败推送 委托失败推送
@@ -291,4 +303,7 @@ class SFGridController(XtQuantTraderCallback):
""" """
print(datetime.datetime.now(), sys._getframe().f_code.co_name) print(datetime.datetime.now(), sys._getframe().f_code.co_name)
sfgrid_constants.initConfig()
print(f'{sfgrid_constants.account_no} : {sfgrid_constants.miniQMTPath}')
ctrl = SFGridController(sfgrid_constants.account_no, sfgrid_constants.miniQMTPath) ctrl = SFGridController(sfgrid_constants.account_no, sfgrid_constants.miniQMTPath)
+66 -54
View File
@@ -1,28 +1,27 @@
from core.strategy_db import TradeTarget from core.strategy_db import TradeTarget
from core.util import getStockPosition, is_trading_time, queryPendingOrder from core.util import is_trading_time, queryPendingOrder
from xtquant import xttrader, xtconstant from xtquant import xttrader, xtconstant
from xtquant.xttype import StockAccount, XtOrder, XtTrade from xtquant.xttype import StockAccount, XtOrder, XtOrderResponse, XtTrade
import sfgrid_constants import sfgrid_constants
import datetime
class StockTradeController: class StockTradeController:
def __init__(self, tradeTarget: TradeTarget, xt_trader: xttrader.XtQuantTrader, account: StockAccount, enabled: bool = False): def __init__(self, tradeTarget: TradeTarget, xt_trader: xttrader.XtQuantTrader, account: StockAccount, enabled: bool = False):
self.tradeTarget = tradeTarget self.tradeTarget:TradeTarget = tradeTarget
self.xt_trader: xttrader.XtQuantTrader = xt_trader self.xt_trader: xttrader.XtQuantTrader = xt_trader
self.account:StockAccount = account self.account:StockAccount = account
self.enabledTrading(self.tradeTarget.enabled) self.enabledTrading(enabled)
def getName(self): def getName(self):
return "SFGRID" return "SFGRID"
def enabledTrading(self, enabled: bool): def enabledTrading(self, enabled: bool):
self.tradeTarget.enabled = enabled self.tradeTarget.enabled = enabled # type: ignore
self.tradeTarget.save() self.tradeTarget.save()
pendingOrders = queryPendingOrder(self.tradeTarget.stock_code,self.getName(), self.xt_trader,self.account) pendingOrders = queryPendingOrder(str(self.tradeTarget.stock_code),self.getName(), self.xt_trader,self.account)
if len(pendingOrders) > 0: if len(pendingOrders) > 0:
print(f' |- 已存在{len(pendingOrders)}订单,全部取消,按需要重下。') print(f' |- 已存在{len(pendingOrders)}订单,全部取消,按需要重下。')
@@ -32,16 +31,16 @@ class StockTradeController:
if enabled: if enabled:
print(f" |- 标的{self.tradeTarget.targetName()}交易启动, position {self.tradeTarget.current_position}") print(f" |- 标的{self.tradeTarget.targetName()}交易启动, position {self.tradeTarget.current_position}")
# 建仓状态检查 # 建仓状态检查
if self.tradeTarget.current_position == 0 and self.tradeTarget.status == 0: if int(self.tradeTarget.current_position) == 0 and int(self.tradeTarget.status) == 0: # type: ignore
self.tradeTarget.grid_index = 1 self.tradeTarget.grid_index = 1 # type: ignore
self.tradeTarget.save() self.tradeTarget.save()
self.init_stock_position() 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}") print(f" |- 标的{self.tradeTarget.targetName()}建初始仓 买单已发出 InitBuyOrderId: {self.initBuyOrderId} Price: {sfgrid_constants.grid_price[int(self.tradeTarget.grid_index)]} Volume: {sfgrid_constants.grid_volume}") # type: ignore
else: else:
# 交易阶段,检查仓位,检查现有订单 # 交易阶段,检查仓位,检查现有订单
print(f" |- 标的{self.tradeTarget.targetName()}已有仓位或非初始状态 无需建初始仓 当前仓位: {self.tradeTarget.current_position} 状态: {self.tradeTarget.status}") print(f" |- 标的{self.tradeTarget.targetName()}已有仓位或非初始状态 无需建初始仓 当前仓位: {self.tradeTarget.current_position} 状态: {self.tradeTarget.status}")
minRequirePosition:int = sfgrid_constants.grid_volume * self.tradeTarget.grid_index minRequirePosition:int = sfgrid_constants.grid_volume * int(self.tradeTarget.grid_index) # type: ignore
if minRequirePosition <= self.tradeTarget.current_position: if minRequirePosition <= int(self.tradeTarget.current_position): # type: ignore
print(f' |- 仓位检查: 持仓需求充足, (gridVolume*gridIndex)={minRequirePosition}, 当前持仓:{self.tradeTarget.current_position}') print(f' |- 仓位检查: 持仓需求充足, (gridVolume*gridIndex)={minRequirePosition}, 当前持仓:{self.tradeTarget.current_position}')
else: else:
print(f' |- 仓位检查: 持仓需求不足, (gridVolume*gridIndex)={minRequirePosition}, 当前持仓:{self.tradeTarget.current_position}') print(f' |- 仓位检查: 持仓需求不足, (gridVolume*gridIndex)={minRequirePosition}, 当前持仓:{self.tradeTarget.current_position}')
@@ -50,54 +49,65 @@ class StockTradeController:
def isEnabled(self) -> bool: def isEnabled(self) -> bool:
return self.tradeTarget.enabled return bool(self.tradeTarget.enabled)
def onDataUpdate(self, data): def onDataUpdate(self, data):
if self.isEnabled(): if self.isEnabled():
print(f"\n标的{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name} 行情数据更新 {data[self.tradeTarget.stock_code]}") print(f"\n标的{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name} 行情数据更新 {data[self.tradeTarget.stock_code]}")
def onOrderUpdate(self, order:XtOrder): def onAsyncOrderResponse(self, order:XtOrderResponse):
pass stockCode = order.order_remark
orderSeq = order.seq
if self.tradeTarget.current_buy_order_no == order.seq:
self.tradeTarget.current_buy_order_no = order.order_id
elif self.tradeTarget.current_sell_order_no == order.seq:
self.tradeTarget.current_sell_order_no = order.order_id
else:
print(f' |- 委托回调: 委托单 {order.order_id} {stockCode} {orderSeq} 不在策略监控范围内')
return
rc = self.tradeTarget.save()
print(f' |- 委托回调: 委托单 {order.order_id} {stockCode} {orderSeq} 处理结果: {rc}')
def onOrderTrade(self, trade:XtTrade): def onOrderTrade(self, trade:XtTrade):
indicator = False indicator = False
if self.tradeTarget.status == 0 and trade.order_id == self.initBuyOrderId : if int(self.tradeTarget.status) == 0 and trade.order_id == self.initBuyOrderId : # type: ignore
# 此时为建仓成交 # 此时为建仓成交
self.tradeTarget.current_position += trade.traded_volume # 当前持仓数,账户原有持仓不在策略范围内 self.tradeTarget.current_position = int(self.tradeTarget.current_position) + trade.traded_volume # 当前持仓数,账户原有持仓不在策略范围内 # type: ignore
self.tradeTarget.last_trade_price = trade.traded_price self.tradeTarget.last_trade_price = float(trade.traded_price) # type: ignore
self.tradeTarget.grid_index = 1 self.tradeTarget.grid_index = 1 # type: ignore
self.tradeTarget.status = 1 self.tradeTarget.status = 1 # type: ignore
self.tradeTarget.save() self.tradeTarget.save()
print(f"|- 标的{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name} 建初始仓订单ID: {self.initBuyOrderId}已成交 ") print(f"|- 标的{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name} 建初始仓订单ID: {self.initBuyOrderId}已成交 ")
print(f' 成交价: {trade.traded_price} 成交量: {trade.traded_volume}') print(f' 成交价: {trade.traded_price} 成交量: {trade.traded_volume}')
print(f' 当前持仓: {getStockPosition(self.tradeTarget.stock_code, self.xt_trader, self.account)}') print(f' 当前持仓: {self.tradeTarget.current_position}')
print(f' 网格坐标: {self.tradeTarget.grid_index}') print(f' 网格坐标: {self.tradeTarget.grid_index}')
indicator = True # 双向下单 indicator = True # 双向下单
elif trade.order_id == self.tradeTarget.current_sell_order_no and self.tradeTarget.status == 1: elif trade.order_id == self.tradeTarget.current_sell_order_no and int(self.tradeTarget.status) == 1: # type: ignore
# 上涨一格:此时空单成交 # 上涨一格:此时空单成交
self.tradeTarget.current_position -= trade.traded_volume self.tradeTarget.current_position = int(self.tradeTarget.current_position) - trade.traded_volume # type: ignore
self.tradeTarget.last_trade_price = trade.traded_price self.tradeTarget.last_trade_price = float(trade.traded_price) # type: ignore
self.tradeTarget.grid_index -= 1 self.tradeTarget.grid_index = int(self.tradeTarget.grid_index) - 1 # type: ignore
self.tradeTarget.save() 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"|- 标的{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name} 上涨 卖单已成交 订单ID: {self.tradeTarget.current_sell_order_no} Price: {sfgrid_constants.grid_price[int(self.tradeTarget.grid_index)]} Volume: {sfgrid_constants.grid_volume} 手续费: {trade.commission}\n") # type: ignore
print(f' 成交价: {trade.traded_price} 成交量: {trade.traded_volume}') print(f' 成交价: {trade.traded_price} 成交量: {trade.traded_volume}')
print(f' 当前持仓: {getStockPosition(self.tradeTarget.stock_code, self.xt_trader, self.account)}') print(f' 当前持仓: {self.tradeTarget.current_position}')
print(f' 网格坐标: {self.tradeTarget.grid_index}') print(f' 网格坐标: {self.tradeTarget.grid_index}')
cancelResult = self.xt_trader.cancel_order_stock(self.account, self.tradeTarget.current_sell_order_no) cancelResult = self.xt_trader.cancel_order_stock_async(self.account, self.tradeTarget.current_buy_order_no)
print(f' 上涨一格,空单成交,对侧买单已撤单 cancelResult: {cancelResult == 0}') print(f' 上涨一格,空单成交,对侧买单已撤单 cancelResult: {cancelResult > 0}')
indicator = True # 双向下单 indicator = True # 双向下单
elif trade.order_id == self.tradeTarget.current_buy_order_no and self.tradeTarget.status == 1: elif trade.order_id == self.tradeTarget.current_buy_order_no and int(self.tradeTarget.status) == 1: # type: ignore
# 下跌一格:此时多单成交 # 下跌一格:此时多单成交
self.tradeTarget.current_position += trade.traded_volume self.tradeTarget.current_position = int(self.tradeTarget.current_position) + trade.traded_volume # type: ignore
self.tradeTarget.last_trade_price = trade.traded_price self.tradeTarget.last_trade_price = float(trade.traded_price) # type: ignore
self.tradeTarget.grid_index += 1 self.tradeTarget.grid_index = int(self.tradeTarget.grid_index) + 1 # type: ignore
self.tradeTarget.save() 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"|- 标的{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' 成交价: {trade.traded_price} 成交量: {trade.traded_volume}')
print(f' 当前持仓: {getStockPosition(self.tradeTarget.stock_code, self.xt_trader, self.account)}') print(f' 当前持仓: {self.tradeTarget.current_position}')
print(f' 网格坐标: {self.tradeTarget.grid_index}') print(f' 网格坐标: {self.tradeTarget.grid_index}')
cancelResult = self.xt_trader.cancel_order_stock(self.account, self.tradeTarget.current_buy_order_no) cancelResult = self.xt_trader.cancel_order_stock_async(self.account, self.tradeTarget.current_sell_order_no)
print(f' 下跌一格,多单成交,对侧卖单已撤单 cancelResult: {cancelResult == 0}') print(f' 下跌一格,多单成交,对侧卖单已撤单 cancelResult: {cancelResult > 0}')
indicator = True # 双向下单 indicator = True # 双向下单
else: else:
# 打印订单信息和订单状态 # 打印订单信息和订单状态
@@ -112,45 +122,47 @@ class StockTradeController:
def init_stock_position(self): def init_stock_position(self):
self.initBuyOrderId = self.xt_trader.order_stock( self.initBuyOrderId = self.xt_trader.order_stock(
self.account, self.account,
self.tradeTarget.stock_code, str(self.tradeTarget.stock_code),
xtconstant.STOCK_BUY, xtconstant.STOCK_BUY,
sfgrid_constants.grid_volume, sfgrid_constants.grid_volume,
xtconstant.FIX_PRICE, xtconstant.FIX_PRICE,
sfgrid_constants.grid_price[self.tradeTarget.grid_index], sfgrid_constants.grid_price[int(self.tradeTarget.grid_index)], # type: ignore
'sf_grid', f'{self.tradeTarget.stock_code}_init_buy') '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") print(f"|- 标的{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name} 建初始仓 买单已发出 InitBuyOrderId: {self.initBuyOrderId} Price: {sfgrid_constants.grid_price[int(self.tradeTarget.grid_index)]} Volume: {sfgrid_constants.grid_volume}\n") # type: ignore
# Description: 网格跳格,双向下单 # Description: 网格跳格,双向下单
def two_way_order(self, buy, sell): def two_way_order(self, buy, sell):
print(f'|- 标的{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name} 网格跳格,双向下单')
if buy and self.tradeTarget.grid_index+1 < len(sfgrid_constants.grid_price): # 价格没有超过网格下边界,可以下多单 print(f' |- 网格坐标: {self.tradeTarget.grid_index}, buy:{buy}, sell:{sell}')
currentPrice = sfgrid_constants.grid_price[self.tradeTarget.grid_index] if buy and int(self.tradeTarget.grid_index)+1 < len(sfgrid_constants.grid_price): # 价格没有超过网格下边界,可以下多单 # type: ignore
buyPrice = sfgrid_constants.grid_price[self.tradeTarget.grid_index+1] currentPrice = sfgrid_constants.grid_price[int(self.tradeTarget.grid_index)] # type: ignore
self.tradeTarget.current_buy_order_no = self.xt_trader.order_stock( buyPrice = sfgrid_constants.grid_price[int(self.tradeTarget.grid_index)+1] # type: ignore
self.tradeTarget.current_buy_order_no = self.xt_trader.order_stock_async(
self.account, self.account,
self.tradeTarget.stock_code, str(self.tradeTarget.stock_code),
xtconstant.STOCK_BUY, xtconstant.STOCK_BUY,
sfgrid_constants.grid_volume, sfgrid_constants.grid_volume,
xtconstant.FIX_PRICE, xtconstant.FIX_PRICE,
buyPrice, buyPrice,
self.getName(), # strategy_name self.getName(), # strategy_name
f'{self.tradeTarget.stock_code}_grid_down_{self.tradeTarget.grid_index}_{currentPrice}_{buyPrice}' # remark self.tradeTarget.stock_code # remark # type: ignore
) )
self.tradeTarget.current_buy_price = buyPrice self.tradeTarget.current_buy_price = float(buyPrice) # type: ignore
print(f' |- 下网格多单 OrderId {self.tradeTarget.current_buy_order_no}, 网格基准价 {currentPrice}, 下单价 {buyPrice}, 下单量 {sfgrid_constants.grid_volume}') print(f' |- 下网格多单 OrderId {self.tradeTarget.current_buy_order_no}, 网格基准价 {currentPrice}, 下单价 {buyPrice}, 下单量 {sfgrid_constants.grid_volume}')
if sell and self.tradeTarget.grid_index-1 >=0: # 价格没有超过网格上边界,可以下空单 if sell and int(self.tradeTarget.grid_index)-1 >=0: # 价格没有超过网格上边界,可以下空单 # type: ignore
currentPrice = sfgrid_constants.grid_price[self.tradeTarget.grid_index] currentPrice = sfgrid_constants.grid_price[int(self.tradeTarget.grid_index)] # type: ignore
sellPrice = sfgrid_constants.grid_price[self.tradeTarget.grid_index-1] sellPrice = sfgrid_constants.grid_price[int(self.tradeTarget.grid_index)-1] # type: ignore
self.tradeTarget.current_sell_order_no = self.xt_trader.order_stock( self.tradeTarget.current_sell_order_no = self.xt_trader.order_stock_async(
self.account, self.account,
self.tradeTarget.stock_code, str(self.tradeTarget.stock_code),
xtconstant.STOCK_SELL, xtconstant.STOCK_SELL,
sfgrid_constants.grid_volume, sfgrid_constants.grid_volume,
xtconstant.FIX_PRICE, xtconstant.FIX_PRICE,
sellPrice, sellPrice,
self.getName(), f'{self.tradeTarget.stock_code}_grid_up_{self.tradeTarget.grid_index}_{currentPrice}_{sellPrice}') self.getName(),
self.tradeTarget.current_sell_price = sellPrice self.tradeTarget.stock_code) # type: ignore
self.tradeTarget.current_sell_price = float(sellPrice) # type: ignore
print(f' |- 下网格空单 OrderId {self.tradeTarget.current_sell_order_no}, 网格基准价 {currentPrice}, 下单价 {sellPrice}, 下单量 {sfgrid_constants.grid_volume}') print(f' |- 下网格空单 OrderId {self.tradeTarget.current_sell_order_no}, 网格基准价 {currentPrice}, 下单价 {sellPrice}, 下单量 {sfgrid_constants.grid_volume}')
self.tradeTarget.save() self.tradeTarget.save()
+8 -3
View File
@@ -1,11 +1,13 @@
from typing import List
import configparser import configparser
# miniQMTPath = r'D:\\Programs\\DTQMT_MN\\userdata_mini' # miniQMT软件的安装路径 # miniQMTPath = r'D:\\Programs\\DTQMT_MN\\userdata_mini' # miniQMT软件的安装路径
miniQMTPath = 'D:\\Programs\\DTQMT\\userdata_mini' # miniQMTPath = r'D:\\Programs\\DTQMT\\userdata_mini' # miniQMT软件的安装路径
# miniQMTPath = ''
# grid_price = [11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1] # 网格价格设置,从高到低 # grid_price = [11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1] # 网格价格设置,从高到低
grid_price = [] # 网格价格设置,从高到低 grid_price:List[float] = [] # 网格价格设置,从高到低
grid_volume:int = 100 # 每个网格的交易手数 grid_volume:int = 100 # 每个网格的交易手数
account_no:str = '' # account_no:str = '99082560'
# account_no = '89009170' # 交易账号 # account_no = '89009170' # 交易账号
max_enabled_targets:int = 10 max_enabled_targets:int = 10
@@ -14,9 +16,12 @@ def initConfig():
config = configparser.ConfigParser() config = configparser.ConfigParser()
config.read('config.ini') config.read('config.ini')
miniQMTPath = config.get('config','miniQMTPath') miniQMTPath = config.get('config','miniQMTPath')
print(f'QMTPath: {miniQMTPath}')
str_list = config.get('config','grid_price').split(',') str_list = config.get('config','grid_price').split(',')
grid_price = [float(item) for item in str_list] grid_price = [float(item) for item in str_list]
print(f'网格设置:{grid_price}') print(f'网格设置:{grid_price}')
grid_volume = config.getint('config','grid_volume') grid_volume = config.getint('config','grid_volume')
account_no = config.get('config','account_no') account_no = config.get('config','account_no')
print(f'账号: {account_no}')
max_enabled_targets = config.getint('config','max_enabled_targets') max_enabled_targets = config.getint('config','max_enabled_targets')
print(f'最大启用目标数: {max_enabled_targets}')
+4 -7
View File
@@ -1,6 +1,6 @@
# coding:utf-8 # coding:utf-8
import sys import sys
sys.stdout.reconfigure(encoding='utf-8') # 设置标准输出编码为UTF-8 sys.stdout.reconfigure(encoding='utf-8') # 设置标准输出编码为UTF-8 # type: ignore
from core.main_controller import ctrl from core.main_controller import ctrl
import core.util as util import core.util as util
import sfgrid_constants as sdConstants import sfgrid_constants as sdConstants
@@ -60,10 +60,7 @@ def help():
print(" stockTradeCtrl(index) - 获取标的交易控制器") print(" stockTradeCtrl(index) - 获取标的交易控制器")
print(" ctrl - 访问控制器实例") print(" ctrl - 访问控制器实例")
if __name__ == '__main__': if __name__ == '__main__':
app = ui.ProfessionalTradeUI(trade_targets=ctrl.instrument_pool) # app = ui.ProfessionalTradeUI(trade_targets=ctrl.instrument_pool)
app.run() # app.run()
# InitUI() interact()
# Loop()