完善UI操作逻辑

This commit is contained in:
2025-11-06 18:13:10 +08:00
parent 1ee8f0426e
commit d988f5eb48
9 changed files with 188 additions and 151 deletions
+4
View File
@@ -10,8 +10,12 @@ ActionDisableMarketData = "disable_market_data"
MarketDataEnabled = "market_data_enabled" MarketDataEnabled = "market_data_enabled"
MarketDataDisabled = "market_data_disabled" MarketDataDisabled = "market_data_disabled"
# 删除交易标的事件 # 删除交易标的事件
ActionEventAddTradeTarget = "add_trade_target"
ResultEventTradeTargetAdded = "trade_target_added"
ActionEventDeleteTradeTarget = "delete_trade_target" ActionEventDeleteTradeTarget = "delete_trade_target"
ResultEventTradeTargetDeleted = "trade_target_deleted" ResultEventTradeTargetDeleted = "trade_target_deleted"
# Pring Log
EventPrintLog = "print_log"
class EventBus: class EventBus:
+19
View File
@@ -0,0 +1,19 @@
from enum import Enum
from core.eventbus import EventPrintLog, event_bus
class LogLevel(Enum):
DEBUG = "DEBUG"
INFO = "INFO"
WARNING = "WARNING"
ERROR = "ERROR"
CRITICAL = "CRITICAL"
class LogData:
def __init__(self, level:LogLevel, message:str):
self.level = level
self.message = message
def PrintLog(level:LogLevel, message:str):
data = LogData(level, message)
event_bus.publish(EventPrintLog, data)
+51 -51
View File
@@ -1,6 +1,6 @@
# coding:utf-8 # coding:utf-8
from core.strategy_db import TradeTarget from core.strategy_db import TradeTarget
from core.eventbus import ActionDisableMarketData, ActionEnableMarketData, ActionEventDeleteTradeTarget, ActionEventDisableTrade, ActionEventEnableTrade, MarketDataUpdate, MarketDataEnabled, MarketDataDisabled, ResultEventTradeDisabled, ResultEventTradeEnabled, ResultEventTradeTargetDeleted, event_bus from core.eventbus import ActionDisableMarketData, ActionEnableMarketData, ActionEventAddTradeTarget, ActionEventDeleteTradeTarget, ActionEventDisableTrade, ActionEventEnableTrade, MarketDataUpdate, MarketDataEnabled, MarketDataDisabled, ResultEventTradeDisabled, ResultEventTradeEnabled, ResultEventTradeTargetDeleted, event_bus
from xtquant.xttrader import XtQuantTrader from xtquant.xttrader import XtQuantTrader
import time import time
from peewee import ModelSelect from peewee import ModelSelect
@@ -15,6 +15,7 @@ from xtquant import xtdata
from xtquant.xttrader import XtQuantTraderCallback from xtquant.xttrader import XtQuantTraderCallback
import datetime import datetime
import core.ui as ui import core.ui as ui
from core.logger import PrintLog, LogLevel
# 量化核心控制对象 # 量化核心控制对象
class SFGridController(XtQuantTraderCallback): class SFGridController(XtQuantTraderCallback):
@@ -31,8 +32,8 @@ class SFGridController(XtQuantTraderCallback):
self.xt_trader: XtQuantTrader = 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() self.xt_trader.connect()
print(f'- [{'成功' if self.xt_trader.connected else '失败'}]市场交易连接{connect_result}--: {miniQmtPath}') PrintLog(LogLevel.INFO, f'- [{'成功' if self.xt_trader.connected else '失败'}]市场交易连接: {miniQmtPath}')
if self.xt_trader.connected == False: if self.xt_trader.connected == False:
self.inited: bool = False self.inited: bool = False
return return
@@ -40,9 +41,9 @@ class SFGridController(XtQuantTraderCallback):
self.inited = True self.inited = True
self.account= StockAccount(account_no, 'STOCK') self.account= StockAccount(account_no, 'STOCK')
print(f'- [成功]交易账号对象初始化完成, 账号: {self.account.account_id}') # pyright: ignore[reportAttributeAccessIssue] PrintLog(LogLevel.INFO, 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 '失败'}:{subscribe_result}]交易状态订阅') PrintLog(LogLevel.INFO, f'- [{'成功' if subscribe_result == 0 else '失败'}:{subscribe_result}]交易状态订阅')
if subscribe_result == 0: if subscribe_result == 0:
self.inited = True self.inited = True
else: else:
@@ -52,15 +53,15 @@ class SFGridController(XtQuantTraderCallback):
self.init_instrument_pool(self.xt_trader, self.account) # type: ignore self.init_instrument_pool(self.xt_trader, self.account) # type: ignore
self.seq = None self.seq = None
print('- [成功]三疯交易系统初始化完成') PrintLog(LogLevel.INFO, '- [成功]三疯交易系统初始化完成')
# self.startMarketData() self.startMarketData()
def registerEventHandler(self): def registerEventHandler(self):
event_bus.subscribe(ActionEventEnableTrade, self.onEnableTrade) event_bus.subscribe(ActionEventEnableTrade, self.onEnableTrade)
event_bus.subscribe(ActionEventDisableTrade, self.onDisableTrade) event_bus.subscribe(ActionEventDisableTrade, self.onDisableTrade)
event_bus.subscribe(ActionEnableMarketData, self.onMarketDataEnabled) event_bus.subscribe(ActionEnableMarketData, self.onMarketDataEnabled)
event_bus.subscribe(ActionDisableMarketData, self.onMarketDataDisabled) event_bus.subscribe(ActionDisableMarketData, self.onMarketDataDisabled)
event_bus.subscribe("add_trade_target", self.onAddTradeTarget) event_bus.subscribe(ActionEventAddTradeTarget, self.onAddTradeTarget)
event_bus.subscribe(ActionEventDeleteTradeTarget, self.onDeleteTradeTarget) event_bus.subscribe(ActionEventDeleteTradeTarget, self.onDeleteTradeTarget)
def onDeleteTradeTarget(self, id: int): def onDeleteTradeTarget(self, id: int):
@@ -91,17 +92,20 @@ class SFGridController(XtQuantTraderCallback):
self.appUi.run() self.appUi.run()
def startMarketData(self): def startMarketData(self):
print('- 启动市场数据订阅') 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: if self.seq == -1:
print('- 市场数据订阅失败') PrintLog(LogLevel.ERROR, '- 市场数据订阅失败')
else: else:
event_bus.publish(MarketDataEnabled, True) event_bus.publish(MarketDataEnabled, True)
print(f'- 市场数据订阅成功, 订阅号={self.seq}') PrintLog(LogLevel.INFO, f'- 市场数据订阅成功, 订阅号={self.seq}')
def stopMarketData(self): def stopMarketData(self):
print('- 停止市场数据订阅') PrintLog(LogLevel.INFO, '- 停止市场数据订阅')
if self.seq is not None and self.seq > 0: if self.seq is not None and self.seq > 0:
xtdata.unsubscribe_quote(self.seq) xtdata.unsubscribe_quote(self.seq)
event_bus.publish(MarketDataDisabled, False) event_bus.publish(MarketDataDisabled, False)
@@ -111,13 +115,13 @@ class SFGridController(XtQuantTraderCallback):
try: try:
stock_name = getInstrumentName(stock_code) stock_name = getInstrumentName(stock_code)
if not stock_name: if not stock_name:
print(f'无法获取股票代码 {stock_code} 的名称,请检查代码是否正确') PrintLog(LogLevel.ERROR, f'无法获取股票代码 {stock_code} 的名称,请检查代码是否正确')
return return
# 检查是否已存在该标的 # 检查是否已存在该标的
existing_target = strategy_db.TradeTarget.get_or_none(strategy_db.TradeTarget.stock_code == stock_code) existing_target = strategy_db.TradeTarget.get_or_none(strategy_db.TradeTarget.stock_code == stock_code)
if existing_target: if existing_target:
print(f'交易标的 {stock_code} {stock_name} 已存在') PrintLog(LogLevel.INFO, f'交易标的 {stock_code} {stock_name} 已存在')
return return
new_target = strategy_db.TradeTarget.create( new_target = strategy_db.TradeTarget.create(
@@ -134,7 +138,7 @@ class SFGridController(XtQuantTraderCallback):
current_order_type='' current_order_type=''
) )
new_target.save() new_target.save()
print(f'新增交易标的 {stock_code} {stock_name}, {new_target.id}') PrintLog(LogLevel.INFO, f'新增交易标的 {stock_code} {stock_name}, {new_target.id}')
# 刷新标的持仓 # 刷新标的持仓
pos = getStockPosition(stock_code, self.xt_trader, self.account) # type: ignore 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()
@@ -145,14 +149,14 @@ class SFGridController(XtQuantTraderCallback):
self.stock_trade_ctrl[stock_code] = stockTradeController self.stock_trade_ctrl[stock_code] = stockTradeController
except Exception as e: except Exception as e:
print(f'新增交易标的失败 {stock_code} {e}') PrintLog(LogLevel.ERROR, f'新增交易标的失败 {stock_code} {e}')
def del_trade_target(self, id:int): def del_trade_target(self, id:int):
try: try:
# 检查标的是否存在 # 检查标的是否存在
if id not in self.instrument_pool: if id not in self.instrument_pool:
print(f"交易标的 ID {id} 不存在") PrintLog(LogLevel.ERROR, f"交易标的 ID {id} 不存在")
return return
target: strategy_db.TradeTarget = self.instrument_pool[id] target: strategy_db.TradeTarget = self.instrument_pool[id]
@@ -171,23 +175,27 @@ class SFGridController(XtQuantTraderCallback):
# 刷新标的池 # 刷新标的池
self.refresh_targets() self.refresh_targets()
print(f"已删除交易标的: {target.stock_code} - {target.stock_name}") PrintLog(LogLevel.INFO, f"已删除交易标的: {target.stock_code} - {target.stock_name}")
except Exception as e: except Exception as e:
print(f"删除交易标的失败 ID {id}: {str(e)}") PrintLog(LogLevel.ERROR, f"删除交易标的失败 ID {id}: {str(e)}")
def init_instrument_pool(self, xtTrader:XtQuantTrader, account:StockAccount): def init_instrument_pool(self, xtTrader:XtQuantTrader, account:StockAccount):
self.refresh_targets() self.refresh_targets()
for id in self.instrument_pool: 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
tradeTarget:strategy_db.TradeTarget = self.instrument_pool[id] tradeTarget:strategy_db.TradeTarget = self.instrument_pool[id]
tradeTarget.current_position = getStockPosition(tradeTarget.stock_code, xtTrader, account) # type: ignore 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}') PrintLog(LogLevel.INFO, f' |- 同步[{target.stock_code}-{target.stock_name}]持仓信息[{'成功' if result == 1 else '失败'}]')
stockTradeController = SFGridStrategy(tradeTarget, self.xt_trader, self.account) # type: ignore stockTradeController = SFGridStrategy(tradeTarget, self.xt_trader, self.account) # type: ignore
self.stock_trade_ctrl[tradeTarget.stock_code] = stockTradeController self.stock_trade_ctrl[tradeTarget.stock_code] = stockTradeController
event_bus.publish(MarketDataUpdate, tradeTarget) event_bus.publish(MarketDataUpdate, tradeTarget)
print(f'- [成功]交易标的信息初始化, 共 {len(self.instrument_pool)} 个标的') PrintLog(LogLevel.INFO, f'- [成功]交易标的信息初始化, 共 {len(self.instrument_pool)} 个标的')
def refresh_targets(self): def refresh_targets(self):
@@ -197,55 +205,47 @@ class SFGridController(XtQuantTraderCallback):
for temp in results: for temp in results:
result :strategy_db.TradeTarget = temp result :strategy_db.TradeTarget = temp
self.instrument_pool[result.get_id()] = result self.instrument_pool[result.get_id()] = result
self.print_pool()
def print_pool(self):
print("- [信息]标的池信息")
for id in self.instrument_pool:
target: strategy_db.TradeTarget = self.instrument_pool[id]
status = "新建" if target.status == 0 else "已建初始仓"
print(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
def print_position_info(self): def print_position_info(self):
positions:list[XtPosition] = 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- 持仓信息") PrintLog(LogLevel.INFO, "\n- 持仓信息")
for temp in positions: for temp in positions:
pos : XtPosition = temp pos : XtPosition = temp
if pos.volume <=0: if pos.volume <=0:
continue continue
print(f"股票代码: {pos.stock_code}-{getInstrumentName(pos.stock_code)}") PrintLog(LogLevel.INFO, f"股票代码: {pos.stock_code}-{getInstrumentName(pos.stock_code)}")
print(f"总持仓: {pos.volume}") PrintLog(LogLevel.INFO, f"总持仓: {pos.volume}")
print(f"可用持仓: {pos.can_use_volume}") PrintLog(LogLevel.INFO, f"可用持仓: {pos.can_use_volume}")
print(f"持仓成本: {pos.avg_price}") PrintLog(LogLevel.INFO, f"持仓成本: {pos.avg_price}")
print("---") PrintLog(LogLevel.INFO, "---")
else: else:
print("\n当前无持仓") PrintLog(LogLevel.INFO, "\n当前无持仓")
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 # type: ignore asset: XtAsset = temp # type: ignore
print(f"=== 账户信息 {self.account.account_id} ===") # type: ignore PrintLog(LogLevel.INFO, f"=== 账户信息 {self.account.account_id} ===") # type: ignore
print(f"可用资金: {asset.cash}") PrintLog(LogLevel.INFO, f"可用资金: {asset.cash}")
print(f"总资产: {asset.total_asset}") PrintLog(LogLevel.INFO, f"总资产: {asset.total_asset}")
print(f"证券市值: {asset.market_value}") PrintLog(LogLevel.INFO, f"证券市值: {asset.market_value}")
def print_stock_orders(self): def print_stock_orders(self):
orders = self.xt_trader.query_stock_orders(self.account, cancelable_only=True) orders = self.xt_trader.query_stock_orders(self.account, cancelable_only=True)
if orders: if orders:
print("\n=== 委托信息 ===") PrintLog(LogLevel.INFO, "\n=== 委托信息 ===")
for order in orders: for order in orders:
print(f"委托编号: {order.order_id}") PrintLog(LogLevel.INFO, f"委托编号: {order.order_id}")
print(f"股票代码: {order.stock_code} {getInstrumentName(order.stock_code)}") PrintLog(LogLevel.INFO, f"股票代码: {order.stock_code} {getInstrumentName(order.stock_code)}")
print(f"委托方向: {order.offset_flag} ") PrintLog(LogLevel.INFO, f"委托方向: {order.offset_flag} ")
print(f"委托价格: {order.price}") PrintLog(LogLevel.INFO, f"委托价格: {order.price}")
print(f"委托数量: {order.order_volume}") PrintLog(LogLevel.INFO, f"委托数量: {order.order_volume}")
print(f"已成交数量: {order.traded_volume}") PrintLog(LogLevel.INFO, f"已成交数量: {order.traded_volume}")
print(f"委托状态: {order.order_status} ") PrintLog(LogLevel.INFO, f"委托状态: {order.order_status} ")
print("---") PrintLog(LogLevel.INFO, "---")
else: else:
print("\n当前无委托记录") PrintLog(LogLevel.INFO, "\n当前无委托记录")
# 初始化指定标的交易控制器 # 初始化指定标的交易控制器
@@ -259,7 +259,7 @@ class SFGridController(XtQuantTraderCallback):
self.instrument_pool[id] = tradeTarget self.instrument_pool[id] = tradeTarget
event_bus.publish(ResultEventTradeEnabled, tradeTarget) event_bus.publish(ResultEventTradeEnabled, tradeTarget)
else: else:
print(f"\t创建标的交易控制器 {tradeTarget.stock_code} {getInstrumentName(tradeTarget.stock_code)}") PrintLog(LogLevel.INFO, f"\t创建标的交易控制器 {tradeTarget.stock_code} {getInstrumentName(tradeTarget.stock_code)}")
def pause_stock_trade(self, id: int): def pause_stock_trade(self, id: int):
+72 -53
View File
@@ -1,10 +1,13 @@
from peewee import IntegerField
from core import strategy_db from core import strategy_db
from core.eventbus import MarketDataUpdate, event_bus from core.eventbus import MarketDataUpdate, event_bus
from core.strategy_db import TradeTarget from core.strategy_db import OrderTypeBuy, OrderTypeInit, OrderTypeSell, TradeTarget
from core.util import queryPendingOrder from core.util import queryPendingOrder
from xtquant import xttrader, xtconstant from xtquant import xttrader, xtconstant
from xtquant.xttype import StockAccount, XtOrder, XtOrderResponse, XtTrade from xtquant.xttype import StockAccount, XtOrder, XtTrade
import sfgrid_constants import sfgrid_constants
import threading import threading
@@ -16,8 +19,9 @@ class SFGridStrategy:
self.xt_trader: xttrader.XtQuantTrader = xt_trader self.xt_trader: xttrader.XtQuantTrader = xt_trader
self.account:StockAccount = account self.account:StockAccount = account
self.enabledTrading(bool(tradeTarget.enabled)) # 修复类型兼容性问题 self.enabledTrading(bool(tradeTarget.enabled)) # 修复类型兼容性问题
event_bus.publish(MarketDataUpdate, self.tradeTarget)
self.dataUpdateLock = threading.Lock() self.dataUpdateLock = threading.Lock()
print(f'标的{self.tradeTarget.targetName()}交易启动状态 {self.tradeTarget.enabled}')
def enabledTrading(self, enabled: bool) -> TradeTarget: def enabledTrading(self, enabled: bool) -> TradeTarget:
@@ -25,26 +29,11 @@ class SFGridStrategy:
self.saveProxy() self.saveProxy()
if enabled: if enabled:
self.refreshPlanPrice()
print(f" |- 标的{self.tradeTarget.targetName()}交易启动, 持仓量:{self.tradeTarget.current_position}") print(f" |- 标的{self.tradeTarget.targetName()}交易启动, 持仓量:{self.tradeTarget.current_position}")
if self.tradeTarget.status == 0: # 未建仓 if self.tradeTarget.status == 0: # 未建仓
print(f" |- 标的{self.tradeTarget.targetName()}初始状态,检查订单") print(f" |- 标的{self.tradeTarget.targetName()}初始状态, 设置网格序号 1")
orders = queryPendingOrder(str(self.tradeTarget.stock_code),self.getName(), self.xt_trader,self.account)
if len([order for order in orders if order.order_type == xtconstant.STOCK_BUY and order.price == sfgrid_constants.grid_price[1]]) > 0:
# 已存在未交易的多单
order = [order for order in orders if order.order_type == xtconstant.STOCK_BUY and order.price == sfgrid_constants.grid_price[1]][0]
print(f' |- 已存在未交易的建仓单,不重复下单:{order.order_id}')
else:
# 建仓
self.tradeTarget.grid_index = 1 # pyright: ignore[reportAttributeAccessIssue] self.tradeTarget.grid_index = 1 # pyright: ignore[reportAttributeAccessIssue]
self.tradeTarget.current_order_no = self.xt_trader.order_stock_async(
self.account,
str(self.tradeTarget.stock_code),
xtconstant.STOCK_BUY,
sfgrid_constants.grid_volume,
xtconstant.FIX_PRICE,
sfgrid_constants.grid_price[int(self.tradeTarget.grid_index)], # type: ignore
self.getName(), strategy_db.OrderTypeInit)
print(f"|- 标的{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name} 建初始仓 买单已发出 InitBuyOrderSeq: {self.tradeTarget.current_order_no} Price: {sfgrid_constants.grid_price[int(self.tradeTarget.grid_index)]} Volume: {sfgrid_constants.grid_volume}\n") # 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}")
@@ -52,7 +41,9 @@ class SFGridStrategy:
if minRequirePosition <= int(self.tradeTarget.current_position): # type: ignore 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}, 交易启动失败')
self.tradeTarget.enabled = False # type: ignore
self.saveProxy()
else: else:
print(f" |- 标的{self.tradeTarget.targetName()}交易监控暂停") print(f" |- 标的{self.tradeTarget.targetName()}交易监控暂停")
return self.tradeTarget return self.tradeTarget
@@ -68,61 +59,72 @@ class SFGridStrategy:
self.tradeTarget.market_price = lastPrice # type: ignore self.tradeTarget.market_price = lastPrice # type: ignore
self.saveProxy() self.saveProxy()
if not(self.tradeTarget.enabled and self.tradeTarget.status == 1): # 建仓,常规自动交易 if not self.tradeTarget.enabled: # 建仓,自动交易暂停
print(f"|- 市价更新[{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name}] - 未建仓或交易监控暂停,不进行自动交易") print(f"|- 市价更新[{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name}] - 未建仓或交易监控暂停,不进行自动交易")
return return
self.dataUpdateLock.acquire() self.dataUpdateLock.acquire()
print(f'|- 市价更新[{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name}] - LOCKED') print(f'|- 市价更新[{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name}] - LOCKED')
try: try:
index = self.tradeTarget.grid_index orderPrice:float = -1
price = -1 if index>=len(sfgrid_constants.grid_price) else sfgrid_constants.grid_price[int(index)] # pyright: ignore[reportArgumentType] orderType = -1
index: int = self.tradeTarget.grid_index # pyright: ignore[reportAssignmentType]
orderRemark= ""
gridBasePrice = -1 if index>=len(sfgrid_constants.grid_price) or index < 0 else sfgrid_constants.grid_price[int(index)] # pyright: ignore[reportArgumentType]
if self.tradeTarget.enabled and self.tradeTarget.status == 0: # 已启用,未建仓,建仓
orderPrice = sfgrid_constants.grid_price[index]
orderType = xtconstant.STOCK_BUY
orderRemark = OrderTypeInit
if self.tradeTarget.enabled and self.tradeTarget.status == 1: # 已启用,已建仓,网格单
lowPrice = -1 if index+1>=len(sfgrid_constants.grid_price) else sfgrid_constants.grid_price[int(index) + 1] # pyright: ignore[reportArgumentType] lowPrice = -1 if index+1>=len(sfgrid_constants.grid_price) else sfgrid_constants.grid_price[int(index) + 1] # pyright: ignore[reportArgumentType]
highPrice = sfgrid_constants.grid_price[int(index) - 1] # pyright: ignore[reportArgumentType] highPrice = sfgrid_constants.grid_price[index - 1]
if lastPrice <= lowPrice: # 下下方多单 if lastPrice <= lowPrice: # 下下方多单
orderPrice = lowPrice
orderType = xtconstant.STOCK_BUY
orderRemark = OrderTypeBuy
elif lastPrice >= highPrice: # 下上方空单
orderPrice = highPrice
orderType = xtconstant.STOCK_SELL
orderRemark = OrderTypeSell
if orderType != -1:
orders = queryPendingOrder(str(self.tradeTarget.stock_code), self.getName(), self.xt_trader, self.account) orders = queryPendingOrder(str(self.tradeTarget.stock_code), self.getName(), self.xt_trader, self.account)
if len([order for order in orders if order.order_type == xtconstant.STOCK_BUY and order.price == lowPrice]) > 0: if len([order for order in orders if order.order_type == orderType and order.price == orderPrice]) > 0:
# 已存在未交易的多单 # 已存在未交易的多单
print(f' |- 已存在未交易的多单,不重复下单') print(f' |- 已存在未交易的{"多单" if orderType == xtconstant.STOCK_BUY else "空单"},不重复下单')
else: else:
print(f' |- 下网格多单') print(f' |- 下网格{"多单" if orderType == xtconstant.STOCK_BUY else "空单"}')
self.tradeTarget.current_order_no = self.xt_trader.order_stock_async( self.tradeTarget.current_order_no = self.xt_trader.order_stock_async(
self.account, self.account,
str(self.tradeTarget.stock_code), str(self.tradeTarget.stock_code),
xtconstant.STOCK_BUY, orderType,
sfgrid_constants.grid_volume, sfgrid_constants.grid_volume,
xtconstant.FIX_PRICE, xtconstant.FIX_PRICE,
lowPrice, orderPrice,
self.getName(), # strategy_name self.getName(), # strategy_name
strategy_db.OrderTypeBuy # remark # type: ignore orderRemark # remark # type: ignore
) )
self.tradeTarget.plan_buy_price = float(lowPrice) # type: ignore orderTypeName = ""
print(f' |- 下网格多单号 {self.tradeTarget.current_order_no}, 网格基准价 {price}, 下单价 {lowPrice}, 下单量 {sfgrid_constants.grid_volume}') if orderRemark == OrderTypeBuy:
elif lastPrice == highPrice: # 下上方空单 orderTypeName = "多单"
orders = queryPendingOrder(str(self.tradeTarget.stock_code), self.getName(), self.xt_trader, self.account) elif orderRemark == OrderTypeSell:
if len([order for order in orders if order.order_type == xtconstant.STOCK_SELL and order.price == highPrice]) > 0: orderTypeName = "空单"
# 已存在未交易的空单 elif orderRemark == OrderTypeInit:
print(f' |- 已存在未交易的空单,不重复下单') orderTypeName = "建仓单"
else: print(f' |- {orderTypeName}委托, 单号 {self.tradeTarget.current_order_no}, 网格基准价 {gridBasePrice}, 下单价 {orderPrice}, 下单量 {sfgrid_constants.grid_volume}')
print(f' |- 下网格空单')
self.tradeTarget.current_order_no = self.xt_trader.order_stock_async(
self.account,
str(self.tradeTarget.stock_code),
xtconstant.STOCK_SELL,
sfgrid_constants.grid_volume,
xtconstant.FIX_PRICE,
highPrice,
self.getName(),
strategy_db.OrderTypeBuy) # type: ignore
self.tradeTarget.plan_sell_price = float(highPrice) # type: ignore
print(f' |- 下网格空单号 {self.tradeTarget.current_order_no}, 网格基准价 {price}, 下单价 {highPrice}, 下单量 {sfgrid_constants.grid_volume}')
finally: finally:
print(f'|- 市价更新[{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name}] - release lock') print(f'|- 市价更新[{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name}] - release lock')
self.saveProxy() self.saveProxy()
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 onAsyncOrderResponse(self, order:XtOrder): def onAsyncOrderResponse(self, order:XtOrder):
print(f' |- 委托回调[{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name}-{order.order_id}]:START') print(f' |- 委托回调[{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name}-{order.order_id}]:START')
self.dataUpdateLock.acquire() self.dataUpdateLock.acquire()
@@ -153,6 +155,8 @@ class SFGridStrategy:
self.tradeTarget.current_position = int(self.tradeTarget.current_position) + trade.traded_volume # 当前持仓数,账户原有持仓不在策略范围内 # type: ignore self.tradeTarget.current_position = int(self.tradeTarget.current_position) + trade.traded_volume # 当前持仓数,账户原有持仓不在策略范围内 # type: ignore
self.tradeTarget.last_trade_price = float(trade.traded_price) # type: ignore self.tradeTarget.last_trade_price = float(trade.traded_price) # type: ignore
self.tradeTarget.grid_index = 1 # type: ignore self.tradeTarget.grid_index = 1 # type: ignore
self.tradeTarget.plan_buy_price = float(sfgrid_constants.grid_price[2]) # type: ignore
self.tradeTarget.plan_sell_price = float(sfgrid_constants.grid_price[0]) # type: ignore
self.tradeTarget.status = 1 # type: ignore self.tradeTarget.status = 1 # type: ignore
self.saveProxy() self.saveProxy()
print(f"|- 标的{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name} 建初始仓订单ID: {self.tradeTarget.current_order_no}已成交 ") print(f"|- 标的{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name} 建初始仓订单ID: {self.tradeTarget.current_order_no}已成交 ")
@@ -164,7 +168,6 @@ class SFGridStrategy:
self.tradeTarget.current_position = int(self.tradeTarget.current_position) - trade.traded_volume # type: ignore self.tradeTarget.current_position = int(self.tradeTarget.current_position) - trade.traded_volume # type: ignore
self.tradeTarget.last_trade_price = float(trade.traded_price) # type: ignore self.tradeTarget.last_trade_price = float(trade.traded_price) # type: ignore
self.tradeTarget.grid_index = int(self.tradeTarget.grid_index) - 1 # type: ignore self.tradeTarget.grid_index = int(self.tradeTarget.grid_index) - 1 # type: ignore
self.saveProxy()
print(f"|- 标的{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name} 上涨 卖单已成交 订单ID: {self.tradeTarget.current_order_no} Price: {sfgrid_constants.grid_price[int(self.tradeTarget.grid_index)]} Volume: {sfgrid_constants.grid_volume} 手续费: {trade.commission}\n") # type: ignore print(f"|- 标的{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name} 上涨 卖单已成交 订单ID: {self.tradeTarget.current_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' 当前持仓: {self.tradeTarget.current_position}') print(f' 当前持仓: {self.tradeTarget.current_position}')
@@ -174,7 +177,6 @@ class SFGridStrategy:
self.tradeTarget.current_position = int(self.tradeTarget.current_position) + trade.traded_volume # type: ignore self.tradeTarget.current_position = int(self.tradeTarget.current_position) + trade.traded_volume # type: ignore
self.tradeTarget.last_trade_price = float(trade.traded_price) # type: ignore self.tradeTarget.last_trade_price = float(trade.traded_price) # type: ignore
self.tradeTarget.grid_index = int(self.tradeTarget.grid_index) + 1 # type: ignore self.tradeTarget.grid_index = int(self.tradeTarget.grid_index) + 1 # type: ignore
self.saveProxy()
print(f"|- 标的{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name} 下跌 买单已成交 订单ID: {self.tradeTarget.current_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_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' 当前持仓: {self.tradeTarget.current_position}') print(f' 当前持仓: {self.tradeTarget.current_position}')
@@ -183,10 +185,27 @@ class SFGridStrategy:
# 打印订单信息和订单状态 # 打印订单信息和订单状态
print(f'|- 非策略内部订单,或订单状态不满足监控条件 {trade.order_id} {trade.stock_code}-{trade.instrument_name} {trade.commission}') print(f'|- 非策略内部订单,或订单状态不满足监控条件 {trade.order_id} {trade.stock_code}-{trade.instrument_name} {trade.commission}')
finally: finally:
self.refreshPlanPrice()
print(f' |- 委托成交通知[{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name}-{trade.order_id}]:release lock') print(f' |- 委托成交通知[{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name}-{trade.order_id}]:release lock')
self.dataUpdateLock.release() self.dataUpdateLock.release()
print(f' |- 委托成交通知[{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name}-{trade.order_id}]:END') print(f' |- 委托成交通知[{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name}-{trade.order_id}]:END')
def refreshPlanPrice(self):
if self.tradeTarget.status == 1:
buyIdx: int = self.tradeTarget.grid_index + 1 # pyright: ignore[reportAssignmentType]
sellIdx: int = self.tradeTarget.grid_index - 1
if self.tradeTarget.grid_index > 0: # 可以下空单
self.tradeTarget.plan_sell_price = float(sfgrid_constants.grid_price[sellIdx]) # pyright: ignore[reportAttributeAccessIssue]
else:
self.tradeTarget.plan_sell_price = -1.0 # type: ignore
if self.tradeTarget.grid_index < len(sfgrid_constants.grid_price) - 1:
self.tradeTarget.plan_buy_price = float(sfgrid_constants.grid_price[buyIdx]) # pyright: ignore[reportAttributeAccessIssue]
else:
self.tradeTarget.plan_buy_price = -1.0 # pyright: ignore[reportAttributeAccessIssue]
else:
self.tradeTarget.plan_buy_price = 10.0 # type: ignore
self.tradeTarget.plan_sell_price = -1.0 # type: ignore
self.saveProxy()
def getName(self): def getName(self):
return "SFGRID" return "SFGRID"
+1 -1
View File
@@ -13,7 +13,7 @@ class BaseModel(Model):
OrderTypeBuy = f'{xtconstant.STOCK_BUY}' # 买 OrderTypeBuy = f'{xtconstant.STOCK_BUY}' # 买
OrderTypeSell = f'{xtconstant.STOCK_SELL}' # 卖 OrderTypeSell = f'{xtconstant.STOCK_SELL}' # 卖
OrderTypeInit = "0" # 建仓 OrderTypeInit = "0" # 建仓
OrderTypeNone = "None" # 建仓 OrderTypeNone = "None"
# 定义Target类,对应targets表 # 定义Target类,对应targets表
class TradeTarget(BaseModel): class TradeTarget(BaseModel):
+33 -32
View File
@@ -3,7 +3,8 @@ from tkinter import ttk, messagebox, filedialog
from datetime import datetime from datetime import datetime
import threading import threading
import time import time
from core.eventbus import ActionDisableMarketData, ActionEnableMarketData, ActionEventDeleteTradeTarget, ActionEventDisableTrade, ActionEventEnableTrade, MarketDataUpdate, MarketDataEnabled, MarketDataDisabled, ResultEventTradeDisabled, ResultEventTradeEnabled, ResultEventTradeTargetDeleted, event_bus import core.eventbus as eBus
from core.logger import LogData, LogLevel
from core.strategy_db import TradeTarget from core.strategy_db import TradeTarget
import configparser import configparser
import sfgrid_constants import sfgrid_constants
@@ -28,12 +29,13 @@ class TradeTargetUI:
# 不再自动启动刷新线程,由市场数据开关控制 # 不再自动启动刷新线程,由市场数据开关控制
def registerEventHandler(self): def registerEventHandler(self):
event_bus.subscribe(MarketDataUpdate, self.onTradeTargetUpdated) eBus.event_bus.subscribe(eBus.MarketDataUpdate, self.onTradeTargetUpdated)
event_bus.subscribe(ResultEventTradeEnabled, self.onTradeEnabled) eBus.event_bus.subscribe(eBus.ResultEventTradeEnabled, self.onTradeEnabled)
event_bus.subscribe(ResultEventTradeDisabled, self.onTradeDisabled) eBus.event_bus.subscribe(eBus.ResultEventTradeDisabled, self.onTradeDisabled)
event_bus.subscribe(MarketDataEnabled, self.onMarketDataToggled) eBus.event_bus.subscribe(eBus.MarketDataEnabled, self.onMarketDataToggled)
event_bus.subscribe(MarketDataDisabled, self.onMarketDataToggled) eBus.event_bus.subscribe(eBus.MarketDataDisabled, self.onMarketDataToggled)
event_bus.subscribe(ResultEventTradeTargetDeleted, self.onTradeTargetDeleted) eBus.event_bus.subscribe(eBus.ResultEventTradeTargetDeleted, self.onTradeTargetDeleted)
eBus.event_bus.subscribe(eBus.EventPrintLog, self.onLog)
def start_refresh_thread(self): def start_refresh_thread(self):
"""启动刷新线程""" """启动刷新线程"""
@@ -59,11 +61,11 @@ class TradeTargetUI:
if id in self.data: if id in self.data:
del self.data[id] del self.data[id]
# 添加日志 # 添加日志
self.add_log("INFO", f"交易标的已删除,ID: {id}") self.add_log(LogLevel.INFO, f"交易标的已删除,ID: {id}")
def onMarketDataToggled(self, data:bool): def onMarketDataToggled(self, data:bool):
self.market_data_enabled = self.market_data_switch_var.get() self.market_data_enabled = self.market_data_switch_var.get()
self.add_log("INFO", "市场数据监听已" + ("启用" if data else "禁用")) self.add_log(LogLevel.INFO, "市场数据监听已" + ("启用" if data else "禁用"))
# 同步UI刷新线程状态 # 同步UI刷新线程状态
if data: if data:
self.start_ui_refresh() self.start_ui_refresh()
@@ -71,10 +73,10 @@ class TradeTargetUI:
self.stop_ui_refresh() self.stop_ui_refresh()
def onTradeEnabled(self, target:TradeTarget): def onTradeEnabled(self, target:TradeTarget):
self.add_log("INFO", f"交易启用: {target.stock_code} - {target.stock_name}") self.add_log(LogLevel.INFO, f"交易启用: {target.stock_code} - {target.stock_name}")
def onTradeDisabled(self, target:TradeTarget): def onTradeDisabled(self, target:TradeTarget):
self.add_log("INFO", f"交易禁用: {target.stock_code} - {target.stock_name}") self.add_log(LogLevel.INFO, f"交易禁用: {target.stock_code} - {target.stock_name}")
def onTradeTargetUpdated(self, target: TradeTarget): def onTradeTargetUpdated(self, target: TradeTarget):
@@ -137,11 +139,11 @@ class TradeTargetUI:
print(f'市场数据监听开关') print(f'市场数据监听开关')
self.market_data_enabled = self.market_data_switch_var.get() self.market_data_enabled = self.market_data_switch_var.get()
if self.market_data_enabled: if self.market_data_enabled:
event_bus.publish(ActionEnableMarketData, True) eBus.event_bus.publish(eBus.ActionEnableMarketData, True)
# 同步开启UI刷新线程 # 同步开启UI刷新线程
self.start_ui_refresh() self.start_ui_refresh()
else: else:
event_bus.publish(ActionDisableMarketData, True) eBus.event_bus.publish(eBus.ActionDisableMarketData, True)
# 同步关闭UI刷新线程 # 同步关闭UI刷新线程
self.stop_ui_refresh() self.stop_ui_refresh()
@@ -150,14 +152,14 @@ class TradeTargetUI:
if not self.refresh_thread_running: if not self.refresh_thread_running:
self.refresh_thread_running = True self.refresh_thread_running = True
self.start_refresh_thread() self.start_refresh_thread()
self.add_log("INFO", "UI刷新线程已启动") self.add_log(LogLevel.INFO, "UI刷新线程已启动")
def stop_ui_refresh(self): def stop_ui_refresh(self):
"""停止UI刷新线程""" """停止UI刷新线程"""
if self.refresh_thread_running: if self.refresh_thread_running:
self.stop_refresh_thread() self.stop_refresh_thread()
self.refresh_thread_running = False self.refresh_thread_running = False
self.add_log("INFO", "UI刷新线程已停止") self.add_log(LogLevel.INFO, "UI刷新线程已停止")
def create_menu_bar(self): def create_menu_bar(self):
"""创建菜单栏""" """创建菜单栏"""
@@ -330,7 +332,7 @@ class TradeTargetUI:
if selected: if selected:
item = selected[0] item = selected[0]
values = self.trade_table.item(item)['values'] values = self.trade_table.item(item)['values']
self.add_log("DEBUG", f"双击查看详情: {values[0]} - {values[1]}") self.add_log(LogLevel.DEBUG, f"双击查看详情: {values[0]} - {values[1]}")
def get_selected_target(self): def get_selected_target(self):
"""获取选中的交易标的""" """获取选中的交易标的"""
@@ -351,10 +353,6 @@ class TradeTargetUI:
return None return None
def onLog(self, level: str, message: str):
"""接收外部日志消息并显示在日志组件中"""
self.add_log(level, message)
def start_selected_trade(self): def start_selected_trade(self):
"""启动选中的交易""" """启动选中的交易"""
target = self.get_selected_target() target = self.get_selected_target()
@@ -374,12 +372,12 @@ class TradeTargetUI:
if result: if result:
target.enabled = True # type: ignore target.enabled = True # type: ignore
event_bus.publish(ActionEventEnableTrade, target.get_id()) eBus.event_bus.publish(eBus.ActionEventEnableTrade, target.get_id())
# self.add_log("INFO", f"已启动交易: {target.stock_code} - {target.stock_name}") # self.add_log("INFO", f"已启动交易: {target.stock_code} - {target.stock_name}")
# messagebox.showinfo("启动成功", f"已启动 {target.stock_code} ({target.stock_name}) 的交易") # messagebox.showinfo("启动成功", f"已启动 {target.stock_code} ({target.stock_name}) 的交易")
def on_trade_enabled(self, target: TradeTarget): def on_trade_enabled(self, target: TradeTarget):
event_bus.publish(ActionEventEnableTrade, target) eBus.event_bus.publish(eBus.ActionEventEnableTrade, target)
def pause_selected_trade(self): def pause_selected_trade(self):
"""暂停选中的交易""" """暂停选中的交易"""
@@ -400,7 +398,7 @@ class TradeTargetUI:
if result: if result:
target.enabled = False # type: ignore target.enabled = False # type: ignore
event_bus.publish(ActionEventDisableTrade, target.get_id()) eBus.event_bus.publish(eBus.ActionEventDisableTrade, target.get_id())
# self.add_log("INFO", f"已暂停交易: {target.stock_code} - {target.stock_name}") # self.add_log("INFO", f"已暂停交易: {target.stock_code} - {target.stock_name}")
# messagebox.showinfo("暂停成功", f"已暂停 {target.stock_code} ({target.stock_name}) 的交易") # messagebox.showinfo("暂停成功", f"已暂停 {target.stock_code} ({target.stock_name}) 的交易")
@@ -421,8 +419,8 @@ class TradeTargetUI:
if result: if result:
# 通过事件总线发出删除动作 # 通过事件总线发出删除动作
event_bus.publish(ActionEventDeleteTradeTarget, target.get_id()) eBus.event_bus.publish(eBus.ActionEventDeleteTradeTarget, target.get_id())
self.add_log("INFO", f"已发送删除请求: {target.stock_code} - {target.stock_name}") self.add_log(LogLevel.INFO, f"已发送删除请求: {target.stock_code} - {target.stock_name}")
def add_trade_target(self): def add_trade_target(self):
"""添加新的交易标的""" """添加新的交易标的"""
@@ -463,7 +461,7 @@ class TradeTargetUI:
return return
# 发布事件通知主控制器添加标的 # 发布事件通知主控制器添加标的
event_bus.publish("add_trade_target", stock_code) eBus.event_bus.publish(eBus.ActionEventAddTradeTarget, stock_code)
add_window.destroy() add_window.destroy()
def cancel_add(): def cancel_add():
@@ -476,7 +474,7 @@ class TradeTargetUI:
# 绑定回车键确认 # 绑定回车键确认
stock_code_entry.bind('<Return>', lambda event: confirm_add()) stock_code_entry.bind('<Return>', lambda event: confirm_add())
self.add_log("INFO", "点击添加交易标的按钮") self.add_log(LogLevel.INFO, "点击添加交易标的按钮")
def toggle_log_panel(self): def toggle_log_panel(self):
"""切换日志面板的显示/隐藏""" """切换日志面板的显示/隐藏"""
@@ -515,17 +513,20 @@ class TradeTargetUI:
if values and values[0] in selected_values: if values and values[0] in selected_values:
self.trade_table.selection_add(item) self.trade_table.selection_add(item)
def add_log(self, level, message): def onLog(self, data:LogData):
self.add_log(data.level, data.message)
def add_log(self, level:LogLevel, message):
"""添加日志记录""" """添加日志记录"""
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
self.log_table.insert('', 0, values=(timestamp, level, message)) self.log_table.insert('', 0, values=(timestamp, level.value, message))
def clear_logs(self): def clear_logs(self):
"""清空日志记录""" """清空日志记录"""
# 删除所有日志项 # 删除所有日志项
for item in self.log_table.get_children(): for item in self.log_table.get_children():
self.log_table.delete(item) self.log_table.delete(item)
self.add_log("INFO", "日志已清空") self.add_log(LogLevel.DEBUG, "日志已清空")
def system_settings(self): def system_settings(self):
"""系统设置""" """系统设置"""
@@ -813,12 +814,12 @@ class TradeTargetUI:
sfgrid_constants.initConfig() sfgrid_constants.initConfig()
messagebox.showinfo("成功", f"配置已保存!\n网格价格序列: {grid_price_str}\n部分配置可能需要重启程序后生效。") messagebox.showinfo("成功", f"配置已保存!\n网格价格序列: {grid_price_str}\n部分配置可能需要重启程序后生效。")
self.add_log("INFO", f"系统配置已更新 - 网格数量: {len(grid_prices)}") self.add_log(LogLevel.INFO, f"系统配置已更新 - 网格数量: {len(grid_prices)}")
settings_window.destroy() settings_window.destroy()
except Exception as e: except Exception as e:
messagebox.showerror("错误", f"保存配置失败:{str(e)}") messagebox.showerror("错误", f"保存配置失败:{str(e)}")
self.add_log("ERROR", f"保存配置失败: {str(e)}") self.add_log(LogLevel.ERROR, f"保存配置失败: {str(e)}")
def cancel_settings(): def cancel_settings():
"""取消设置""" """取消设置"""
BIN
View File
Binary file not shown.
-5
View File
@@ -16,12 +16,7 @@ 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}')
grid_volume = config.getint('config','grid_volume') grid_volume = config.getint('config','grid_volume')
# 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}')
+2 -3
View File
@@ -1,6 +1,7 @@
# coding:utf-8 # coding:utf-8
from core import strategy_db from core import strategy_db
from core.main_controller import SFGridController from core.main_controller import SFGridController
from core.logger import LogLevel, PrintLog
import sfgrid_constants as sdConstants import sfgrid_constants as sdConstants
def startTrade(index: int): def startTrade(index: int):
@@ -13,9 +14,7 @@ if __name__ == '__main__':
sdConstants.initConfig() sdConstants.initConfig()
strategy_db.db.connect() strategy_db.db.connect()
strategy_db.db.create_tables([strategy_db.TradeTarget]) strategy_db.db.create_tables([strategy_db.TradeTarget])
print('- [成功]数据库模块初始化') PrintLog(LogLevel.INFO, '- [成功]数据库模块初始化')
print(f'{sdConstants.account_no} : {sdConstants.miniQMTPath}')
ctrl: SFGridController = SFGridController(sdConstants.account_no, sdConstants.miniQMTPath) ctrl: SFGridController = SFGridController(sdConstants.account_no, sdConstants.miniQMTPath)
ctrl.hold() ctrl.hold()