测试与逻辑修正

This commit is contained in:
2025-10-31 16:40:05 +08:00
parent 9f30f392d2
commit 706ed8cffa
5 changed files with 98 additions and 54 deletions
+18 -13
View File
@@ -1,5 +1,4 @@
# coding:utf-8 # coding:utf-8
from os import popen
import time, sys import time, sys
from peewee import ModelSelect from peewee import ModelSelect
@@ -11,7 +10,7 @@ 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, XtOrder, XtTrade from xtquant.xttype import StockAccount, XtAsset, XtOrder, XtPosition, XtTrade
from xtquant import xtdata from xtquant import xtdata
from xtquant.xttrader import XtQuantTraderCallback from xtquant.xttrader import XtQuantTraderCallback
import datetime import datetime
@@ -38,7 +37,7 @@ class SFGridController(XtQuantTraderCallback):
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 '失败'}')
self.stock_trade_ctrl = {} self.stock_trade_ctrl = {}
self.init_instrument_pool() self.init_instrument_pool(self.xt_trader, self.account)
self.seq = None self.seq = None
print('- 三疯交易系统初始化完成') print('- 三疯交易系统初始化完成')
@@ -95,10 +94,14 @@ class SFGridController(XtQuantTraderCallback):
self.refresh_targets() self.refresh_targets()
def init_instrument_pool(self): def init_instrument_pool(self, xtTrader:XtQuantTrader, account:StockAccount):
self.refresh_targets() self.refresh_targets()
for tradeTarget in self.instrument_pool: for temp in self.instrument_pool:
tradeTarget:strategy_db.TradeTarget = temp
tradeTarget.current_position = getStockPosition(tradeTarget.stock_code, xtTrader, account)
result = tradeTarget.save()
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)
self.stock_trade_ctrl[tradeTarget.stock_code] = stockTradeController self.stock_trade_ctrl[tradeTarget.stock_code] = stockTradeController
@@ -121,24 +124,26 @@ class SFGridController(XtQuantTraderCallback):
positions = self.xt_trader.query_stock_positions(self.account) positions = self.xt_trader.query_stock_positions(self.account)
if positions: if positions:
print("\n- 持仓信息") print("\n- 持仓信息")
for pos in positions: for temp in positions:
pos : XtPosition = temp
if pos.m_nVolume <=0: if pos.m_nVolume <=0:
continue continue
print(f"股票代码: {pos.stock_code}-{getInstrumentName(pos.stock_code)}") print(f"股票代码: {pos.stock_code}-{getInstrumentName(pos.stock_code)}")
print(f"总持仓: {pos.m_nVolume}") print(f"总持仓: {pos.volume}")
print(f"可用持仓: {pos.m_nCanUseVolume}") print(f"可用持仓: {pos.can_use_volume}")
print(f"持仓成本: {pos.avg_price}") print(f"持仓成本: {pos.avg_price}")
print("---") print("---")
else: else:
print("\n当前无持仓") print("\n当前无持仓")
def print_account_info(self): def print_account_info(self):
account_info = self.xt_trader.query_stock_asset(self.account) temp = self.xt_trader.query_stock_asset(self.account)
asset: XtAsset =temp
print(f"\n=== 账户信息 {self.account.account_id} ===") print(f"=== 账户信息 {self.account.account_id} ===")
print(f"可用资金: {account_info.m_dCash}") print(f"可用资金: {asset.cash}")
print(f"总资产: {account_info.m_dTotalAsset}") print(f"总资产: {asset.total_asset}")
print(f"证券市值: {account_info.m_dMarketValue}") print(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)
+18 -17
View File
@@ -1,9 +1,10 @@
from core.strategy_db import TradeTarget from core.strategy_db import TradeTarget
from core.util import getStockPosition, queryPendingOrder from core.util import getStockPosition, 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, XtTrade
import sfgrid_constants import sfgrid_constants
import datetime
class StockTradeController: class StockTradeController:
@@ -29,7 +30,7 @@ class StockTradeController:
self.xt_trader.cancel_order_stock(self.account, order.order_id) self.xt_trader.cancel_order_stock(self.account, order.order_id)
if enabled: if enabled:
print(f" |- 标的交易启动 {self.tradeTarget.stock_code}-{self.tradeTarget.stock_name}") print(f" |- 标的交易启动 {self.tradeTarget.stock_code}-{self.tradeTarget.stock_name}, position {self.tradeTarget.current_position}")
# 建仓状态检查 # 建仓状态检查
if self.tradeTarget.current_position == 0 and self.tradeTarget.status == 0: if self.tradeTarget.current_position == 0 and self.tradeTarget.status == 0:
print(f" |- 标的{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name} 建初始仓 买单准备中...") print(f" |- 标的{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name} 建初始仓 买单准备中...")
@@ -39,17 +40,15 @@ class StockTradeController:
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}") 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}")
else: else:
# 交易阶段,检查仓位,检查现有订单 # 交易阶段,检查仓位,检查现有订单
print(f" |- 标的{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name} 已有仓位或非初始状态 无需建初始仓 当前仓位: {getStockPosition(self.tradeTarget.stock_code, self.xt_trader, self.account)} 状态: {self.tradeTarget.status}") print(f" |- 标的{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name} 已有仓位或非初始状态 无需建初始仓 当前仓位: {self.tradeTarget.current_position} 状态: {self.tradeTarget.status}")
currentPosition = getStockPosition(self.tradeTarget.stock_code, self.xt_trader, self.account) if sfgrid_constants.grid_volume * self.tradeTarget.grid_index <= self.tradeTarget.current_position:
if sfgrid_constants.grid_volume * TradeTarget.current_position >= currentPosition: print(f' |- 仓位检查: 持仓需求充足, (gridVolume*gridIndex)={sfgrid_constants.grid_volume * self.tradeTarget.grid_index}, 当前持仓:{self.tradeTarget.current_position}')
print(f' |- 仓位检查: 持仓需求充足, (gridVolume*gridIndex)={sfgrid_constants.grid_volume * self.tradeTarget.current_position}, 当前持仓:{currentPosition}')
else: else:
print(f' |- 仓位检查: 持仓需求不足, (gridVolume*gridIndex)={sfgrid_constants.grid_volume * self.tradeTarget.current_position}, 当前持仓:{currentPosition}') print(f' |- 仓位检查: 持仓需求不足, (gridVolume*gridIndex)={sfgrid_constants.grid_volume * self.tradeTarget.grid_index}, 当前持仓:{self.tradeTarget.current_position}')
if is_trading_time():
self.two_way_order(True, True) self.two_way_order(True, True)
def isEnabled(self) -> bool: def isEnabled(self) -> bool:
return self.tradeTarget.enabled return self.tradeTarget.enabled
@@ -64,7 +63,7 @@ class StockTradeController:
indicator = False indicator = False
if self.tradeTarget.status == 0 and trade.order_id == self.initBuyOrderId : if self.tradeTarget.status == 0 and trade.order_id == self.initBuyOrderId :
# 此时为建仓成交 # 此时为建仓成交
self.tradeTarget.current_position += sfgrid_constants.grid_volume # 当前持仓数,账户原有持仓不在策略范围内 self.tradeTarget.current_position += trade.traded_volume # 当前持仓数,账户原有持仓不在策略范围内
self.tradeTarget.last_trade_price = trade.traded_price self.tradeTarget.last_trade_price = trade.traded_price
self.tradeTarget.grid_index = 1 self.tradeTarget.grid_index = 1
self.tradeTarget.status = 1 self.tradeTarget.status = 1
@@ -76,7 +75,7 @@ class StockTradeController:
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 self.tradeTarget.status == 1:
# 上涨一格:此时空单成交 # 上涨一格:此时空单成交
self.tradeTarget.current_position = -sfgrid_constants.grid_volume self.tradeTarget.current_position -= trade.traded_volume
self.tradeTarget.last_trade_price = trade.traded_price self.tradeTarget.last_trade_price = trade.traded_price
self.tradeTarget.grid_index -= 1 self.tradeTarget.grid_index -= 1
self.tradeTarget.save() self.tradeTarget.save()
@@ -89,11 +88,11 @@ class StockTradeController:
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 self.tradeTarget.status == 1:
# 下跌一格:此时多单成交 # 下跌一格:此时多单成交
self.tradeTarget.current_position = +sfgrid_constants.grid_volume self.tradeTarget.current_position += trade.traded_volume
self.tradeTarget.last_trade_price = trade.traded_price self.tradeTarget.last_trade_price = trade.traded_price
self.tradeTarget.grid_index += 1 self.tradeTarget.grid_index += 1
self.tradeTarget.save() self.tradeTarget.save()
print(f"|- 标的{self.tradeTarget.stock_code}-{self.tradeTarget.stock_name} 下跌 买单已成交 订单ID: {self.tradeTarget.current_buy_order_no} Price: {sfgrid_constants.grid_price[self.tradeTarget.grid_index]} 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' 当前持仓: {getStockPosition(self.tradeTarget.stock_code, self.xt_trader, self.account)}')
print(f' 网格坐标: {self.tradeTarget.grid_index}') print(f' 网格坐标: {self.tradeTarget.grid_index}')
@@ -104,7 +103,8 @@ class StockTradeController:
# 打印订单信息和订单状态 # 打印订单信息和订单状态
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}')
if indicator and self.isEnabled(): if indicator and self.isEnabled() and is_trading_time():
print(f'goto two way order')
self.two_way_order(True, True) # 双向下单 self.two_way_order(True, True) # 双向下单
@@ -123,7 +123,6 @@ class StockTradeController:
# Description: 网格跳格,双向下单 # Description: 网格跳格,双向下单
def two_way_order(self, buy, sell): def two_way_order(self, buy, sell):
# print(f'current grid index = {self.tradeTarget.grid_index}, grid count = {len(sfgrid_constants.grid_price)}')
if buy and self.tradeTarget.grid_index+1 < len(sfgrid_constants.grid_price): # 价格没有超过网格下边界,可以下多单 if buy and self.tradeTarget.grid_index+1 < len(sfgrid_constants.grid_price): # 价格没有超过网格下边界,可以下多单
currentPrice = sfgrid_constants.grid_price[self.tradeTarget.grid_index] currentPrice = sfgrid_constants.grid_price[self.tradeTarget.grid_index]
@@ -135,7 +134,9 @@ class StockTradeController:
sfgrid_constants.grid_volume, sfgrid_constants.grid_volume,
xtconstant.FIX_PRICE, xtconstant.FIX_PRICE,
buyPrice, buyPrice,
self.getName(), f'{self.tradeTarget.stock_code}_grid_down_{self.tradeTarget.grid_index}_{currentPrice}_{buyPrice}') self.getName(), # strategy_name
f'{self.tradeTarget.stock_code}_grid_down_{self.tradeTarget.grid_index}_{currentPrice}_{buyPrice}' # remark
)
self.tradeTarget.current_buy_price = buyPrice self.tradeTarget.current_buy_price = buyPrice
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}')
@@ -151,5 +152,5 @@ class StockTradeController:
sellPrice, sellPrice,
self.getName(), f'{self.tradeTarget.stock_code}_grid_up_{self.tradeTarget.grid_index}_{currentPrice}_{sellPrice}') self.getName(), f'{self.tradeTarget.stock_code}_grid_up_{self.tradeTarget.grid_index}_{currentPrice}_{sellPrice}')
self.tradeTarget.current_sell_price = sellPrice self.tradeTarget.current_sell_price = sellPrice
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()
+39 -3
View File
@@ -1,7 +1,41 @@
import sfgrid_constants import sfgrid_constants
import xtquant.xtconstant as xtconstant import xtquant.xtconstant as xtconstant
from xtquant import xtdata, xttrader from xtquant import xtdata, xttrader
from xtquant.xttype import StockAccount, XtOrder from xtquant.xttype import StockAccount, XtPosition
import datetime
def is_trading_time():
"""
判断当前时间是否在周一至周五的9:30~11:30或13:00~15:00时间段内
返回: True(在交易时间内) 或 False(不在交易时间内)
"""
# 获取当前时间
now = datetime.datetime.now()
# 获取星期几 (0=周一, 1=周二, ..., 4=周五)
weekday = now.weekday()
# 判断是否为周一到周五 (0-4)
if weekday < 5:
current_time = now.time()
# 第一个时间段: 9:30~11:30
morning_start = datetime.time(9, 30)
morning_end = datetime.time(11, 30)
# 第二个时间段: 13:00~15:00
afternoon_start = datetime.time(13, 0)
afternoon_end = datetime.time(15, 0)
# 判断是否在第一个时间段内
if morning_start <= current_time <= morning_end:
return True
# 判断是否在第二个时间段内
if afternoon_start <= current_time <= afternoon_end:
return True
return False
def getInstrumentName(stock_code): def getInstrumentName(stock_code):
# print(f"getInstrumentName: 获取标的名称 {stock_code}") # print(f"getInstrumentName: 获取标的名称 {stock_code}")
@@ -13,10 +47,12 @@ def getStockPosition(stock_code: str, xt_trader: xttrader.XtQuantTrader, account
volume = 0 volume = 0
positions = xt_trader.query_stock_positions(account) positions = xt_trader.query_stock_positions(account)
if positions: if positions:
for pos in positions: for temp in positions:
pos:XtPosition = temp
if pos.stock_code == stock_code: if pos.stock_code == stock_code:
volume = pos.m_nVolume volume = pos.volume
break break
return volume return volume
def minPosition(gridIndex:int): def minPosition(gridIndex:int):
+18 -6
View File
@@ -1,8 +1,20 @@
miniQMTPath = r'D:\\Programs\\DTQMT_MN\\userdata_mini' # miniQMT软件的安装路径 # miniQMTPath = r'D:\\Programs\\DTQMT_MN\\userdata_mini' # miniQMT软件的安装路径
# D:\Programs\DTQMT_MN\userdata_mini miniQMTPath = r'D:\\Programs\\DTQMT\\userdata_mini'
# 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 = [10.05, 10.00, 9.95, 9.90, 9.85, 9.80, 9.75, 9.70, 9.65, 9.60, 9.55] # 网格价格设置,从高到低 grid_price = [
grid_volume = 100 # 每个网格的交易手数 1.665,
# account_no = '99082560' 1.660,
account_no = '89009170' # 交易账号 1.655,
1.650,
1.645,
1.640,
1.635,
1.630,
1.625,
1.620,
1.615
] # 网格价格设置,从高到低
grid_volume = 200 # 每个网格的交易手数
account_no = '99082560'
# account_no = '89009170' # 交易账号
max_enabled_targets = 10 max_enabled_targets = 10
+2 -12
View File
@@ -1,11 +1,10 @@
# coding:utf-8 # coding:utf-8
import sys import sys
import chardet
# from ui.ui import InitUI, Loop
sys.stdout.reconfigure(encoding='utf-8') # 设置标准输出编码为UTF-8 sys.stdout.reconfigure(encoding='utf-8') # 设置标准输出编码为UTF-8
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
from xtquant import xtdata
def interact(): def interact():
"""执行后进入repl模式""" """执行后进入repl模式"""
@@ -42,14 +41,6 @@ def pauseTrade(index:int):
def stockTradeCtrl(index: int): def stockTradeCtrl(index: int):
return ctrl.stock_trade_ctrl[ctrl.instrument_pool[index].stock_code] return ctrl.stock_trade_ctrl[ctrl.instrument_pool[index].stock_code]
def importCsv(path:str):
with open(path, 'r', encoding='utf-8', errors='replace') as infile:
result = chardet.detect(infile)
print(result['encoding'])
# reader = csv.reader(infile)
# data = [row for row in reader]
# print(data)
def help(): def help():
print("基础指令:") print("基础指令:")
@@ -63,7 +54,6 @@ def help():
print(" positionInfo() - 打印持仓信息\n") print(" positionInfo() - 打印持仓信息\n")
print(" startTrade(index) - 启动标的交易") print(" startTrade(index) - 启动标的交易")
print(" pauseTrade(index) - 暂停标的交易") print(" pauseTrade(index) - 暂停标的交易")
print(" importCsv(path) - 导入CSV文件")
print(" ===================================================") print(" ===================================================")
print("内部指令:") print("内部指令:")
print(" stockTradeCtrl(index) - 获取标的交易控制器") print(" stockTradeCtrl(index) - 获取标的交易控制器")