8000 miniQMT/MiniQMT.md at main · Crustcn/miniQMT · GitHub
[go: up one dir, main page]

Skip to content

Latest commit

 

History

History
289 lines (224 loc) · 14.6 KB

MiniQMT.md

File metadata and controls

289 lines (224 loc) · 14.6 KB

量化交易系统,基于迅投QMT交易API,实现了您需要的所有功能。系统有六个主要模块,各自负责不同功能,同时支持React前端界面交互。

系统架构

  1. 核心模块:

    • config.py - 集中管理所有配置参数
    • logger.py - 日志管理,包括日志自动清理
    • main.py - 系统主入口,负责初始化和管理各模块
    • utils.py - 工具函数集合
  2. 数据处理:

    • data_manager.py - 负责历史数据获取与存储
    • indicator_calculator.py - 计算各种技术指标(MACD、均线等)
  3. 交易策略:

    • strategy.py - 实现核心交易策略
    • position_manager.py - 持仓管理和监控
    • trading_executor.py - 交易执行和订单管理
  4. Web服务:

    • web_server.py - 提供RESTful API接口供React前端调用

交易策略实现

系统严格遵循您提出的交易策略规则:

  1. 分仓买入

    • 每次买入固定金额(默认20000元)
    • 根据建仓成本价格比例(93%、86%等)设置补仓点位
    • 达到仓位上限(默认50000元)后停止买入
    • 总持仓成本损失超过9.5%时全仓止损
  2. 动态止盈

    • 实现浮盈比例与止盈位动态关联
    • 首次盈利达到5%时卖出半仓保证胜率
    • 余下仓位根据动态止盈位置卖出,盈利越多回调空间越大
  3. 网格交易

    • 对持仓个股进行自动网格交易
    • 可调整网格幅度和每格交易量
  4. 自动日志管理

    • 自动清理过期日志文件,不占用存储空间

系统特点

  1. 模块化设计:每个功能独立成模块,代码结构清晰
  2. 参数可配置:所有交易参数集中管理,易于调整
  3. RESTful API:提供完整API供前端调用
  4. 丰富的日志:详细记录系统运行和交易过程
  5. 错误处理:完善的异常处理机制
  6. 自动化运行:支持无人值守的自动交易
  7. 手动交易接口:支持人工干预和操作

使用方法

  1. 确保安装了必要的Python包:

    pip install pandas numpy talib flask flask-cors xtquant
    
  2. 创建账户配置文件 account_config.json:

    {
      "account_id": "你的交易账号",
      "account_type": "STOCK"
    }
  3. 启动系统:

    python main.py
    
  4. 访问Web界面(React前端):

    http://localhost:5000
    

进一步开发

  1. 可以增强交易策略,加入更多技术指标
  2. 增加回测功能,评估策略效果
  3. 优化网格交易算法
  4. 添加风控模块,加强交易安全性
  5. 增加数据分析和可视化功能

这个系统设计已经考虑了QMT API的特性,并实现了完整的交易生命周期管理,可以有效地支持量化交易策略的执行。

详细代码解读

Position Manager

好的,我来解读一下 position_manager.py 文件中的 PositionManager 类,并尽量用简洁的中文进行说明。

PositionManager 类:持仓管理的核心

这个类主要负责管理股票的持仓信息,包括:

持仓数据的存储和获取:

使用 SQLite 数据库来存储持仓信息,包括股票代码、数量、成本价、当前价格、市值、盈亏比例等。 提供 get_all_positions() 和 get_position() 方法来获取所有持仓或指定股票的持仓信息。 _sync_real_positions_to_db() 方法负责将实盘交易账户的持仓数据同步到数据库中,保持数据一致性。 _update_stock_positions_file() 方法负责更新 stock_positions.json 文件,记录当前持仓的股票代码。 持仓信息的更新:

update_position() 方法用于更新或新增持仓信息。它会自动计算市值、盈亏比例,并记录最后更新时间。 update_all_positions_price() 方法用于批量更新所有持仓的最新价格。 update_all_positions_highest_price() 方法用于批量更新所有持仓的最高价。 remove_position() 方法用于删除持仓记录(例如清仓时)。 止损止盈策略的检查:

check_stop_loss() 方法用于检查是否触发止损条件。 check_dynamic_take_profit() 方法用于检查是否触发动态止盈条件。 calculate_stop_loss_price() 方法用于计算止损价格,支持固定止损和动态止损。 mark_profit_triggered() 方法用于标记股票已触发首次止盈。 网格交易的管理:

get_grid_trades() 方法用于获取指定股票的网格交易记录。 add_grid_trade() 方法用于添加新的网格交易记录。 update_grid_trade_status() 方法用于更新网格交易的状态(例如:PENDING, ACTIVE, COMPLETED)。 check_grid_trade_signals() 方法用于检查网格交易的买入/卖出信号。 监控线程:

start_position_monitor_thread() 方法用于启动一个后台线程,定期监控持仓状态,包括更新价格、检查止损止盈条件、检查网格交易信号等。 stop_position_monitor_thread() 方法用于停止监控线程。 _position_monitor_loop() 方法是监控线程的循环体,负责执行监控任务。 与实盘交易账户的交互

使用了easy_qmt_trader类,通过self.qmt_trader对象与QMT实盘交易账户进行交互,获取实盘持仓数据。 _is_test_environment() 方法用于判断是否在测试环境中,如果在测试环境,则不进行实盘数据同步。 与数据管理模块的交互

使用了data_manager模块,通过self.data_manager对象获取最新行情数据。 核心功能总结:

存储和管理持仓数据。 实时更新持仓信息(价格、市值、盈亏等)。 实现止损止盈策略。 管理网格交易。 后台监控持仓状态。 与实盘交易账户进行交互,同步持仓数据。 与数据管理模块进行交互,获取最新行情。 总而言之,PositionManager 类是整个量化交易系统中负责持仓管理的核心组件,它提供了完善的持仓数据管理、止损止盈策略、网格交易管理和监控功能。

数据库的说明

我希望在代码运行时增加一个position_manager的内存数据库,用于实时保存和更新持仓数据所有记录,内存数据库的结构与data_manager的持仓表positions保持一致,

  1. stock_code, volume, available, cost_price,market_value 以easy_qmt_trader.position方法作为权威数据来源,是从xtquant接口获得的账号实时持仓真实数据
  2. current_price, 通过data_manager的get_latest_data方法获得股票的最新价格,盘中时间用xtdata的tick数据,盘后时间用mootdx的历史数据
  3. highest_price, 通过position_manager.update_all_positions_highest_price方法获得
  4. profit_ratio,以 current_price, cost_price, volume为数据源,通过计算得到
  5. open_date, profit_triggered, highest_price, stop_loss_price需要通过sqlite数据库实现持久化,一旦数据发生变更就要将它们更新到数据库里,并在last_update里记录操作时间

总而言之,内存数据库的关键持仓信息来自xtquant接口,其他需要高频次更新的数据来自data_manager,数据库里保存了需要持久化的内容。 最简单的修改方式,是把所有对sqlite数据库进行操作的函数,修改为对内存数据库的操作,每隔一段时间(如5秒),把内存数据库里需要持久化的内容保存到sqlite数据库里。

实盘与模拟交易的主要区别

方面 模拟交易 实盘交易
数据存储 仅内存数据库 内存数据库 + SQLite持久化
资金来源 config.SIMULATION_BALANCE 实际交易账户资金
订单执行 生成模拟订单ID, 不调用交易API 调用实际交易API执行订单
订单记录 strategy='simu'标记 正常交易策略名称
API调用 绕过实际交易API 正常调用交易API

内存持仓数据库字段动态刷新来源

数据标签 数据来源 更新方式
stock_code QMT实盘交易系统 从qmt_trader.position()的'证券代码'字段获取
volume QMT实盘交易系统 从qmt_trader.position()的'股票余额'字段获取;交易成交后更新
available QMT实盘交易系统 从qmt_trader.position()的'可用余额'字段获取;交易委托和撤单后更新
cost_price QMT实盘交易系统 从qmt_trader.position()的'成本价'字段获取;新增或平均持仓成本时更新
current_price 行情API 从data_manager.get_latest_data()获取最新价格,优先使用xtquant,备选Mootdx
market_value 计算值 实时计算:volume * current_price
profit_ratio 计算值 实时计算:(current_price - cost_price) / cost_price * 100
last_update 系统时间 每次更新持仓数据时写入当前系统时间
open_date 多来源 新建仓位时为当前时间;或从SQLite数据库同步;避免被覆盖
profit_triggered 策略逻辑 根据check_dynamic_take_profit函数判断是否触发首次止盈
highest_price 历史数据+实时行情 从历史K线获取最高价(Methods.getStockData),与当前价格比较后更新
stop_loss_price 策略计算 根据calculate_stop_loss_price函数基于成本价、最高价和止盈状态计算

数据刷新场景

  1. 定时刷新:update_all_positions_price 函数定期更新所有持仓的价格相关数据
  2. 实盘同步:_sync_real_positions_to_memory 从QMT交易系统同步最新持仓数据
  3. 交易触发:买入/卖出成交后通过 _update_position_after_trade 更新持仓
  4. 策略执行:持仓监控线程 _position_monitor_loop 检查止盈止损条件并更新相关标记
  5. 手动更新:通过Web接口的API请求手动更新持仓参数

系统会在交易时间内更频繁地刷新行情相关字段,而持仓基础信息则在交易成交后才会更新。

网页触发与自动交易系统比较分析

根据代码审查,我将分析用户从网页触发买入和卖出操作(包括模拟和实盘模式),以及"全局监控开关"启用时的自动仓位管理操作(包括网格策略和动态止盈止损策略)。

网页触发买入和卖出操作流程

网页触发买入流程:

  1. 用户在页面选择买入策略(随机池或自定义股票)
  2. 设置买入数量并点击"一键买入"按钮
  3. 前端发送请求到/api/actions/execute_buy接口
  4. 服务器处理请求并调用trading_strategy.manual_buy方法
  5. trading_strategy.manual_buy调用trading_executor.buy_stock执行实际交易

网页触发卖出操作: 由于前端页面没有显式的卖出按钮,可能通过持仓列表中的操作来触发,后端相应调用trading_strategy.manual_sell方法,最终通过trading_executor.sell_stock执行交易。

全局监控开关下的自动交易流程

当全局监控开关(config.ENABLE_AUTO_TRADING)打开时,系统会启动策略线程(strategy._strategy_loop),定期执行以下策略:

  1. 止损策略:当股票价格跌至止损价以下时,执行全仓卖出
  2. 动态止盈策略:
    • 首次止盈:当利润达到设定阈值(默认5%)时,卖出部分持仓(默认50%)
    • 动态止盈:根据历史最高价设定止盈线,价格回落到止盈线以下时卖出
  3. 网格交易策略:根据预设的价格网格,在价格达到网格点位时执行买入或卖出
  4. 技术指标买入策略:基于MACD金叉等技术指标,在满足条件时执行买入
  5. 技术指标卖出策略:基于MACD死叉等技术指标,在满足条件时执行卖出

模拟交易与实盘交易区别

模拟交易模式 实盘交易模式
交易记录和持仓变化仅在内存中记录 通过实际交易接口(QMT)提交订单
模拟资金从config.SIMULATION_BALANCE中扣除或增加 使用实际账户资金
可以忽略交易时间限制 必须在交易时间内才能交易
可以放宽买卖权限限制 严格受买卖权限限制
生成虚拟订单ID:SIM[时间戳][计数器] 使用实际交易接口返回的订单ID
使用模拟手续费率(买入0.0003,卖出0.0013) 使用实际交易的手续费

网页触发与自动交易的对比

特性 网页触发交易 全局监控开关自动交易
触发方式 用户手动点击按钮 系统自动定期检查触发条件
交易时间 模拟模式下可忽略交易时间限制 仅在交易时间内执行
买入策略 从股票池中选择或自定义 基于技术指标和网格策略
买入金额 固定为config.POSITION_UNIT 根据不同买入级别动态调整
卖出策略 用户指定卖出数量或比例 基于止损、止盈或网格策略
交易接口 根据模式调用不同交易函数 相同,但添加信号去重逻辑
异常处理 即时返回错误给用户 日志记录错误并继续处理其他股票
策略应用 单一交易,无策略组合 多策略按优先级顺序执行
风控机制 基本检查(资金、持仓、交易规则) 完整的止损、止盈和仓位控制
初次买入后 可选择性初始化网格交易 自动初始化网格交易(如启用)

交易执行调用链

网页触发买入调用链:

前端点击 → API(/api/actions/execute_buy) → trading_strategy.manual_buy → trading_executor.buy_stock → 模拟交易或实盘交易接口

自动交易买入调用链: 执行调用流程 信号检测流程 position_monitor_loop() ↓ check_trading_signals() [position_manager] ↓ {signal_type, signal_info} → latest_signals队列 策略执行流程 check_and_execute_strategies() [strategy] ↓ get_pending_signals() ↓ execute_trading_signal_direct() ↓ 模拟交易: simulate_sell_position() [position_manager] 实盘交易: sell_stock() [trading_executor] → QMT API 模拟交易执行路径 python# 模拟交易直接操作内存数据库 simulate_sell_position() → _save_simulated_trade_record() # 保存记录 → _simulate_update_position() # 更新持仓 → config.SIMULATION_BALANCE += revenue # 更新资金 实盘交易执行路径 python# 实盘交易通过QMT接口 sell_stock() [trading_executor] → qmt_trader.sell() # QMT API调用 → _save_trade_record() # 成交后回调保存

0