update for restructure
This commit is contained in:
+20
-116
@@ -1,30 +1,30 @@
|
||||
# coding:utf-8
|
||||
from core.strategy_db import TradeTarget
|
||||
from core.sfgrid.model import TradeTarget
|
||||
from core.eventbus import ActionDisableMarketData, ActionEnableMarketData, ActionEventAddTradeTarget, ActionEventDeleteTradeTarget, ActionEventDisableTrade, ActionEventEnableTrade, EventTradeTargetUpdate, MarketDataUpdate, MarketDataEnabled, MarketDataDisabled, ResultEventTradeDisabled, ResultEventTradeEnabled, ResultEventTradeTargetDeleted, ActionEventGridFix, event_bus
|
||||
from xtquant.xttrader import XtQuantTrader
|
||||
import time
|
||||
from peewee import ModelSelect
|
||||
|
||||
import core.strategy_db as strategy_db
|
||||
import sfgrid_constants
|
||||
from core.sfgrid_strategy import SFGridStrategy
|
||||
import core.sfgrid.model as model
|
||||
import sfgrid_config
|
||||
from core.sfgrid.sfgrid_strategy import SFGridStrategy
|
||||
from core.util import getInstrumentName, getStockPosition, queryPendingOrder
|
||||
from xtquant.xttrader import XtQuantTrader
|
||||
from xtquant.xttype import StockAccount, XtAsset, XtOrder, XtOrderResponse, XtPosition, XtTrade
|
||||
from xtquant.xttype import StockAccount, XtAsset, XtOrder, XtPosition, XtTrade
|
||||
from xtquant import xtdata
|
||||
from xtquant.xttrader import XtQuantTraderCallback
|
||||
import datetime
|
||||
import core.ui as ui
|
||||
import core.sfgrid.ui as ui
|
||||
from core.logger import PrintLog, LogLevel
|
||||
from core.objects import GridFixData
|
||||
from core.sfgrid.objects import GridFixData
|
||||
|
||||
# 量化核心控制对象
|
||||
class SFGridController(XtQuantTraderCallback):
|
||||
class MainController(XtQuantTraderCallback):
|
||||
def __init__(self, account_no: str, miniQmtPath: str):
|
||||
super().__init__()
|
||||
|
||||
self.registerEventHandler()
|
||||
self.appUi = ui.TradeTargetUI()
|
||||
# self.appUi = ui.TradeTargetUI()
|
||||
|
||||
xtdata.enable_hello = False
|
||||
|
||||
@@ -118,13 +118,10 @@ class SFGridController(XtQuantTraderCallback):
|
||||
except Exception as e:
|
||||
PrintLog(LogLevel.ERROR, f"网格修正更新失败: {str(e)}")
|
||||
|
||||
def hold(self):
|
||||
self.appUi.run()
|
||||
|
||||
def startMarketData(self):
|
||||
PrintLog(LogLevel.INFO, '- 启动市场数据订阅')
|
||||
|
||||
self.seq = xtdata.subscribe_whole_quote(['SH', 'SZ'], callback=self.onDataUpdate)
|
||||
# self.seq = xtdata.subscribe_whole_quote(['SH', 'SZ'], callback=self.onDataUpdate)
|
||||
if self.seq == -1:
|
||||
PrintLog(LogLevel.ERROR, '- 市场数据订阅失败')
|
||||
else:
|
||||
@@ -149,12 +146,12 @@ class SFGridController(XtQuantTraderCallback):
|
||||
return
|
||||
|
||||
# 检查是否已存在该标的
|
||||
existing_target = strategy_db.TradeTarget.get_or_none(strategy_db.TradeTarget.stock_code == stock_code)
|
||||
existing_target = model.TradeTarget.get_or_none(model.TradeTarget.stock_code == stock_code)
|
||||
if existing_target:
|
||||
PrintLog(LogLevel.INFO, f'交易标的 {stock_code} {stock_name} 已存在')
|
||||
return
|
||||
|
||||
new_target = strategy_db.TradeTarget.create(
|
||||
new_target = model.TradeTarget.create(
|
||||
stock_name=stock_name,
|
||||
stock_code=stock_code,
|
||||
market_price=0.0,
|
||||
@@ -171,7 +168,7 @@ class SFGridController(XtQuantTraderCallback):
|
||||
PrintLog(LogLevel.INFO, f'新增交易标的 {stock_code} {stock_name}, {new_target.id}')
|
||||
# 刷新标的持仓
|
||||
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()
|
||||
model.TradeTarget.update(current_position=pos).where(model.TradeTarget.stock_code == stock_code).execute()
|
||||
# 更新标的池
|
||||
self.refresh_targets()
|
||||
# 添加交易控制器
|
||||
@@ -189,7 +186,7 @@ class SFGridController(XtQuantTraderCallback):
|
||||
PrintLog(LogLevel.ERROR, f"交易标的 ID {id} 不存在")
|
||||
return
|
||||
|
||||
target: strategy_db.TradeTarget = self.instrument_pool[id]
|
||||
target: model.TradeTarget = self.instrument_pool[id]
|
||||
|
||||
# 如果存在交易控制器,先停止交易
|
||||
if target.stock_code in self.stock_trade_ctrl:
|
||||
@@ -215,9 +212,9 @@ class SFGridController(XtQuantTraderCallback):
|
||||
for id in self.instrument_pool:
|
||||
target:TradeTarget = self.instrument_pool[id]
|
||||
status = "新建" if target.status == 0 else "已建初始仓"
|
||||
PrintLog(LogLevel.INFO, f' [序号-{id}] 股票代码: {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
|
||||
PrintLog(LogLevel.INFO, f' [序号-{id}] 股票代码: {target.stock_code}-{target.stock_name} 当前持仓: {getStockPosition(target.stock_code, self.xt_trader, self.account)} 网格索引: {target.grid_index} 基准价格 {sfgrid_config.grid_price[target.grid_index]} 状态: {status} 启用交易线程: {'自动交易中' if target.enabled else '交易已停止'}') # type: ignore
|
||||
|
||||
tradeTarget:strategy_db.TradeTarget = self.instrument_pool[id]
|
||||
tradeTarget:model.TradeTarget = self.instrument_pool[id]
|
||||
tradeTarget.current_position = getStockPosition(tradeTarget.stock_code, xtTrader, account) # type: ignore
|
||||
result = tradeTarget.save()
|
||||
PrintLog(LogLevel.INFO, f' |- 同步[{target.stock_code}-{target.stock_name}]持仓信息[{'成功' if result == 1 else '失败'}]')
|
||||
@@ -230,10 +227,10 @@ class SFGridController(XtQuantTraderCallback):
|
||||
|
||||
def refresh_targets(self):
|
||||
# 更新标的池
|
||||
results:ModelSelect = strategy_db.TradeTarget.select()
|
||||
self.instrument_pool: dict[int, strategy_db.TradeTarget] = {}
|
||||
results:ModelSelect = model.TradeTarget.select()
|
||||
self.instrument_pool: dict[int, model.TradeTarget] = {}
|
||||
for temp in results:
|
||||
result :strategy_db.TradeTarget = temp
|
||||
result :model.TradeTarget = temp
|
||||
self.instrument_pool[result.get_id()] = result
|
||||
|
||||
def print_position_info(self):
|
||||
@@ -293,7 +290,7 @@ class SFGridController(XtQuantTraderCallback):
|
||||
|
||||
|
||||
def pause_stock_trade(self, id: int):
|
||||
localTarget: strategy_db.TradeTarget = self.instrument_pool[id]
|
||||
localTarget: model.TradeTarget = self.instrument_pool[id]
|
||||
print(f'暂停标的交易 {localTarget.stock_code} - enabled {localTarget.enabled}')
|
||||
if localTarget.stock_code in self.stock_trade_ctrl:
|
||||
tradeController: SFGridStrategy = self.stock_trade_ctrl[localTarget.stock_code]
|
||||
@@ -307,96 +304,3 @@ class SFGridController(XtQuantTraderCallback):
|
||||
else:
|
||||
print(f"标的交易控制器不存在 {localTarget.stock_code} {localTarget.stock_name}\n")
|
||||
|
||||
|
||||
# ====== 市场回调方法 -- 以下方法由XtQuantData调用 ======
|
||||
def onDataUpdate(self, data):
|
||||
# 收集所有市场数据用于市场监控
|
||||
for stock_code, tickData in data.items():
|
||||
if stock_code in self.stock_trade_ctrl:
|
||||
stock_controller: SFGridStrategy = self.stock_trade_ctrl[stock_code]
|
||||
stock_controller.onDataUpdate(data)
|
||||
else:
|
||||
# 非目标交易,发布市场数据更新事件用于市场监控
|
||||
lastPrice = tickData['lastPrice']
|
||||
if lastPrice == 10 or stock_code in self.listening_stock:
|
||||
# 发布市场数据更新事件用于市场监控
|
||||
market_target = TradeTarget()
|
||||
market_target.stock_code = stock_code
|
||||
market_target.stock_name = getInstrumentName(stock_code) # type: ignore
|
||||
market_target.market_price = lastPrice # type: ignore
|
||||
event_bus.publish(MarketDataUpdate, market_target)
|
||||
if stock_code not in self.listening_stock:
|
||||
self.listening_stock.append(stock_code)
|
||||
|
||||
|
||||
# ====== 市场回调方法 -- 以下方法由XtQuantTrader调用 ======
|
||||
def on_connected(self):
|
||||
"""
|
||||
连接成功推送
|
||||
"""
|
||||
print(datetime.datetime.now(), '连接成功回调')
|
||||
|
||||
def on_disconnected(self):
|
||||
"""
|
||||
连接断开
|
||||
:return:
|
||||
"""
|
||||
print(datetime.datetime.now(), '连接断开回调')
|
||||
|
||||
def on_stock_order(self, order:XtOrder):
|
||||
"""
|
||||
委托回报推送
|
||||
:param order: XtOrder对象
|
||||
:return:
|
||||
"""
|
||||
print(f'orderd {order.strategy_name}-{order.stock_code} {order.order_id} {order.order_volume}-{order.order_status}')
|
||||
stockCode = order.stock_code
|
||||
ctrl:SFGridStrategy = self.stock_trade_ctrl[stockCode]
|
||||
# 如果存在对应的StockTradeController,则调用其onDataUpdate方法
|
||||
if ctrl is not None and order.strategy_name == ctrl.getName():
|
||||
print(f'controller info {ctrl.getName()}')
|
||||
ctrl.onAsyncOrderResponse(order) # type: ignore
|
||||
else:
|
||||
print(f"委托下单回调 投资备注 orderId: {order.order_sysid} [{order.stock_code}-{order.instrument_name}] volume: {order.order_volume} 订单策略: '{order.strategy_name}'<-->'{ctrl.getName()}'")
|
||||
|
||||
|
||||
def on_stock_trade(self, trade:XtTrade):
|
||||
"""
|
||||
成交变动推送
|
||||
:param trade: XtTrade对象
|
||||
:return:
|
||||
"""
|
||||
stockCode = trade.stock_code
|
||||
ctrl:SFGridStrategy = self.stock_trade_ctrl[stockCode]
|
||||
# 如果存在对应的StockTradeController,则调用其onDataUpdate方法
|
||||
if ctrl is not None and trade.strategy_name == ctrl.getName():
|
||||
ctrl.onOrderTrade(trade)
|
||||
else:
|
||||
print(f"委托回调 投资备注 {trade.strategy_name} 不匹配 {ctrl.getName()}")
|
||||
|
||||
# def on_order_stock_async_response(self, response:XtOrderResponse):
|
||||
# stockCode = response.order_remark
|
||||
# ctrl:SFGridStrategy = 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):
|
||||
"""
|
||||
委托失败推送
|
||||
:param order_error:XtOrderError 对象
|
||||
:return:
|
||||
"""
|
||||
# print("on order_error callback")
|
||||
# print(order_error.order_id, order_error.error_id, order_error.error_msg)
|
||||
print(f"\n委托报错回调 {order_error.order_remark} {order_error.error_msg}")
|
||||
|
||||
|
||||
def on_account_status(self, status):
|
||||
"""
|
||||
:param response: XtAccountStatus 对象
|
||||
:return:
|
||||
"""
|
||||
print(datetime.datetime.now(), status)
|
||||
Reference in New Issue
Block a user