Files
qsforex/QSForex详细说明文档.md
T
2026-07-07 20:25:32 +00:00

30 KiB
Raw Blame History

QSForex 详细说明文档


一、项目简介

QSForex 是一个开源的、基于事件驱动架构的外汇(Forex)量化交易系统,支持回测实盘交易。项目由 QuantStart.com 创始人 Michael Halls-Moore 于 2015 年开发,采用 MIT 开源许可证,目前处于 "alpha" 阶段。

核心特性

特性 说明
事件驱动架构 回测与实盘使用同一套事件接口,策略无需修改即可从回测切换到实盘
Tick 级精度 支持逐 tick 级别的多日、多货币对回测
交易成本 回测中默认包含点差(Spread)成本
多货币对 支持同时交易多个货币对
实盘交易 通过 OANDA Brokerage API 进行实盘交易
绩效分析 支持权益曲线、收益率、最大回撤等指标计算与可视化
单元测试 核心计算逻辑有完整的单元测试覆盖

二、项目目录结构

qsforex/
├── __init__.py                     # 顶层包入口
├── settings.py                     # 全局配置(OANDA 凭证、数据路径、杠杆等)
├── logging.conf                    # 日志配置
├── requirements.txt                # Python 依赖包列表
│
├── event/                          # ====== 事件系统(核心通信机制) ======
│   ├── __init__.py
│   └── event.py                    # 定义 TickEvent / SignalEvent / OrderEvent
│
├── data/                           # ====== 数据层 ======
│   ├── __init__.py
│   ├── price.py                    # 历史 CSV 数据读取器(回测用)
│   └── streaming.py               # OANDA Streaming API 实时数据流(实盘用)
│
├── strategy/                       # ====== 策略层 ======
│   ├── __init__.py
│   └── strategy.py                 # TestStrategy + MovingAverageCrossStrategy
│
├── portfolio/                      # ====== 组合与仓位管理 ======
│   ├── __init__.py
│   ├── portfolio.py                # 资金管理、风险控制、信号执行
│   ├── position.py                 # 单个仓位的 P&L 计算
│   ├── portfolio_test.py           # 组合模块单元测试
│   └── position_test.py            # 仓位模块单元测试
│
├── execution/                      # ====== 执行层 ======
│   ├── __init__.py
│   └── execution.py                # SimulatedExecution + OANDAExecutionHandler
│
├── backtest/                       # ====== 回测引擎 ======
│   ├── __init__.py
│   ├── backtest.py                 # Backtest 主循环
│   └── output.py                   # 可视化输出(权益曲线、回撤图)
│
├── performance/                    # ====== 绩效计算 ======
│   ├── __init__.py
│   └── performance.py              # 最大回撤(MDD)计算
│
├── trading/                        # ====== 实盘交易 ======
│   ├── __init__.py
│   └── trading.py                  # 多线程实时交易循环
│
├── examples/                       # ====== 示例 ======
│   ├── __init__.py
│   └── mac.py                      # 移动平均线交叉策略回测示例
│
└── scripts/                        # ====== 辅助脚本 ======
    ├── generate_simulated_pair.py  # 生成模拟外汇 tick 数据
    └── test_performance.py         # 绩效计算调试脚本

三、事件驱动架构详解

3.1 概述

整个系统围绕一个事件队列(Event Queue 运转。事件是系统中各组件之间通信的唯一方式。这种设计使得各模块高度解耦,策略代码在回测和实盘之间无需修改即可复用。

3.2 事件类型

系统定义了三种事件,按处理顺序依次流转:

数据源 → TickEvent → 策略 → SignalEvent → 组合 → OrderEvent → 执行引擎

TickEvent(行情事件)

由数据层产生,包含市场报价信息。

class TickEvent(Event):
    def __init__(self, instrument, time, bid, ask):
        self.type = 'TICK'
        self.instrument = instrument   # 货币对,如 "GBPUSD"
        self.time = time               # 时间戳
        self.bid = bid                 # 买价
        self.ask = ask                 # 卖价

SignalEvent(信号事件)

由策略层产生,表示一个交易决策。

class SignalEvent(Event):
    def __init__(self, instrument, order_type, side, time):
        self.type = 'SIGNAL'
        self.instrument = instrument   # 货币对
        self.order_type = order_type   # 订单类型(当前仅支持 "market"
        self.side = side               # 方向:"buy" 或 "sell"
        self.time = time               # 产生信号的 tick 时间

OrderEvent(订单事件)

由组合层产生,表示一个需要发送到经纪商的实际订单。

class OrderEvent(Event):
    def __init__(self, instrument, units, order_type, side):
        self.type = 'ORDER'
        self.instrument = instrument   # 货币对
        self.units = units             # 交易数量
        self.order_type = order_type   # 订单类型
        self.side = side               # 方向

3.3 事件流向图

                          ┌──────────────┐
                          │  数据源      │
                          │ (CSV/OANDA)  │
                          └──────┬───────┘
                                 │ TickEvent
                                 ▼
                     ┌───────────────────────┐
                     │     事件队列 (Queue)   │
                     └───────┬───────────────┘
                             │
              ┌──────────────┼──────────────┐
              ▼              ▼              ▼
        ┌──────────┐  ┌──────────┐  ┌──────────┐
        │  策略     │  │  组合     │  │  执行     │
        │ (Strategy)│  │(Portfolio)│  │(Execution)│
        └─────┬────┘  └─────┬────┘  └──────────┘
              │             │
              │ SignalEvent │ OrderEvent
              └─────────────┘
              (放回事件队列)

四、各模块详细说明

4.1 数据层(data/

4.1.1 PriceHandler(抽象基类)

price.py

所有数据处理器继承自 PriceHandler,提供以下核心功能:

  • _set_up_prices_dict():构建价格字典,同时维护正向和反向汇率对。例如,当交易 GBPUSD 时,系统自动计算并维护 USDGBP 的 bid/ask,用于跨货币对的盈亏换算。
  • invert_prices():将 bid/ask 价格取倒数,生成反向汇率对。

4.1.2 HistoricCSVPriceHandler(历史数据处理器)

price.py

用于回测场景,从 CSV 文件读取历史 tick 数据。

数据格式:兼容 DukasCopy Historical Data Feed 格式,文件名格式为 {货币对}_{YYYYMMDD}.csv,例如 GBPUSD_20140112.csv

CSV 文件内部格式:

Time,Ask,Bid,AskVolume,BidVolume
12.01.2014 22:00:10.123,1.50200,1.50180,1.50,1.50

处理流程

  1. 扫描 CSV_DATA_DIR 目录下所有符合格式的 CSV 文件
  2. 提取所有日期,去重排序
  3. 按天加载数据,使用 Pandas 将多个货币对的数据按时间合并排序
  4. stream_next_tick() 方法每次被调用时,按时间顺序输出下一个 tick
  5. 每输出一个 tick,同时更新正向和反向汇率对的价格

4.1.3 StreamingForexPrices(实时数据流处理器)

streaming.py

用于实盘交易场景,通过 OANDA 的 Streaming API 获取实时价格。

处理流程

  1. 建立到 OANDA streaming 端点的 HTTPS 连接
  2. 使用 requests.Session 的流式传输持续接收数据
  3. 逐行解析 JSON 格式的 tick 数据
  4. 生成 TickEvent 放入事件队列
  5. 同步更新正向和反向汇率对价格

4.2 策略层(strategy/

strategy.py

策略层负责从 TickEvent 中分析市场数据,产生交易信号。所有策略必须实现 calculate_signals(event) 方法。

4.2.1 TestStrategy(测试策略)

简单的测试策略,每 5 个 tick 交替买入/卖出。设计目的是持续"穿越点差",因此必然亏损,仅用于验证系统运行是否正常。

逻辑:
  tick 0-4: 无操作
  tick 5:   BUY  → 持仓
  tick 10:  SELL → 平仓
  tick 15:  BUY  → 持仓
  ...循环

4.2.2 MovingAverageCrossStrategy(双均线交叉策略)

经典的移动平均线交叉策略,仅做多。

参数

参数 默认值 说明
short_window 500 短期 SMA 窗口(tick 数)
long_window 2000 长期 SMA 窗口(tick 数)

信号逻辑

  • 短期 SMA 上穿长期 SMA 且未持仓 → 产生 BUY 信号(开多仓)
  • 短期 SMA 下穿长期 SMA 且已持仓 → 产生 SELL 信号(平多仓)

性能优化:使用滚动 SMA 算法,避免每次重新计算完整均线:

def calc_rolling_sma(self, sma_m_1, window, price):
    return ((sma_m_1 * (window - 1)) + price) / window

该算法将时间复杂度从 O(n) 降为 O(1)。

多货币对支持:通过 pairs_dict 为每个货币对维护独立的 tick 计数、持仓状态和 SMA 值。


4.3 组合与仓位管理(portfolio/

4.3.1 Position(仓位类)

position.py

管理单个货币对的交易仓位,支持多空双向。

核心属性

属性 说明
home_currency 账户计价货币(如 GBP
position_type 仓位方向:"long""short"
currency_pair 交易货币对(如 EURUSD
units 持仓数量
avg_price 平均持仓成本
cur_price 当前市场价格
profit_base 以计价货币计算的浮动盈亏
profit_perc 浮动盈亏百分比

关键方法

方法 说明
calculate_pips() 计算当前盈亏点数
calculate_profit_base() 计算以账户货币计价的盈亏金额
update_position_price() 更新当前价格并重新计算盈亏
add_units(units) 加仓,重新计算平均成本
remove_units(units) 减仓,返回已实现盈亏
close_position() 平仓,返回已实现盈亏

跨货币对换算:对于 EUR/USD 仓位,账户以 GBP 计价时的盈亏计算:

Profit_GBP = Pips × USD/GBP_Rate × Units

4.3.2 Portfolio(组合类)

portfolio.py

管理整个交易组合,负责资金管理、风险控制和信号执行。

核心属性

属性 默认值 说明
equity 100,000.00 账户总权益
balance = equity 当前余额
leverage 20 杠杆倍数
risk_per_trade 0.02 (2%) 单笔交易风险比例
trade_units equity × 0.02 单笔交易头寸规模

关键方法

方法 说明
calc_risk_position_size() 计算基于风险的仓位大小
add_new_position() 创建新仓位
add_position_units() 对已有仓位加仓
remove_position_units() 对已有仓位减仓
close_position() 平掉整个仓位
update_portfolio(tick_event) 更新所有持仓的浮动盈亏
execute_signal(signal_event) 执行交易信号,生成 OrderEvent
output_results() 输出回测结果到 CSV
create_equity_file() 创建回测结果 CSV 文件

信号执行逻辑 execute_signal

信号方向 当前仓位 动作
buy 无仓位 创建多头仓位
buy 有多头仓位 加仓
buy 有空头仓位 若 units 相等则平仓
sell 无仓位 创建空头仓位
sell 有多头仓位 若 units 相等则平仓
sell 有空头仓位 加仓

4.4 执行层(execution/

execution.py

4.4.1 ExecutionHandler(抽象基类)

定义了 execute_order() 接口,所有执行处理器必须实现此方法。

4.4.2 SimulatedExecution(模拟执行)

回测模式下的执行器,execute_order() 方法为空操作。实际的成交处理由 Portfolio 对象直接完成。

4.4.3 OANDAExecutionHandlerOANDA 执行器)

实盘模式下的执行器,通过 OANDA REST API 发送订单。

下单流程

  1. 建立到 OANDA API 域名的 HTTPS 连接
  2. 构造 HTTP POST 请求,包含认证信息和订单参数
  3. 发送到 /v1/accounts/{account_id}/orders 端点
  4. 记录 API 响应日志

4.5 回测引擎(backtest/

4.5.1 Backtest 类

backtest.py

回测引擎的核心类,将所有组件组装在一起运行回测。

初始化参数

参数 说明
pairs 交易货币对列表
data_handler 数据处理器类(如 HistoricCSVPriceHandler
strategy 策略类(如 MovingAverageCrossStrategy
strategy_params 策略参数字典
portfolio 组合管理类
execution 执行处理器类
equity 初始资金
heartbeat 事件循环心跳间隔(秒)
max_iters 最大迭代次数

回测主循环 _run_backtest()

while iters < max_iters and ticker.continue_backtest:
    try:
        event = events.get(False)  # 非阻塞获取事件
    except queue.Empty:
        ticker.stream_next_tick()  # 没有事件则推进下一个 tick
    else:
        if event.type == 'TICK':
            strategy.calculate_signals(event)   # 策略分析
            portfolio.update_portfolio(event)   # 更新盈亏
        elif event.type == 'SIGNAL':
            portfolio.execute_signal(event)     # 执行信号
        elif event.type == 'ORDER':
            execution.execute_order(event)      # 执行订单
    time.sleep(heartbeat)
    iters += 1

关键设计:当事件队列为空时,主动从数据源获取下一个 tick 并放入队列,而非等待。这种"拉取"模式确保回测的确定性和可复现性。

4.5.2 可视化输出

output.py

读取 equity.csv 文件,使用 Matplotlib + Seaborn 绘制三张图表:

  1. 权益曲线(上图):组合价值随时间变化
  2. 期间收益率(中图):每个 tick 的收益率
  3. 回撤曲线(下图):从历史高点的回撤幅度

4.6 绩效计算(performance/

performance.py

create_drawdowns(pnl) 函数:

  • 计算权益曲线的峰值到谷值的最大回撤(Maximum Drawdown, MDD
  • 计算回撤持续时间
  • 返回 (drawdown_series, max_drawdown, max_duration)

4.7 实盘交易(trading/

trading.py

实盘交易的入口,使用双线程架构:

线程 1(价格流): StreamingForexPrices.stream_to_queue()
    └── 持续从 OANDA 接收实时价格,生成 TickEvent 放入队列

线程 2(交易循环): trade()
    └── 从队列获取事件 → 策略 → 组合 → 执行

五、配置文件说明

5.1 settings.py

# OANDA 环境配置
ENVIRONMENTS = {
    "streaming": {
        "real": "stream-fxtrade.oanda.com",
        "practice": "stream-fxpractice.oanda.com",
        "sandbox": "stream-sandbox.oanda.com"
    },
    "api": {
        "real": "api-fxtrade.oanda.com",
        "practice": "api-fxpractice.oanda.com",
        "sandbox": "api-sandbox.oanda.com"
    }
}

# 数据目录和输出目录(从环境变量读取)
CSV_DATA_DIR = os.environ.get('QSFOREX_CSV_DATA_DIR', None)
OUTPUT_RESULTS_DIR = os.environ.get('QSFOREX_OUTPUT_RESULTS_DIR', None)

# 交易环境选择
DOMAIN = "practice"                    # "practice" / "real" / "sandbox"

# OANDA 认证
ACCESS_TOKEN = os.environ.get('OANDA_API_ACCESS_TOKEN', None)
ACCOUNT_ID = os.environ.get('OANDA_API_ACCOUNT_ID', None)

# 账户设置
BASE_CURRENCY = "GBP"                  # 账户基础货币
EQUITY = Decimal("100000.00")          # 初始资金

5.2 logging.conf

logging.conf

配置了 root logger 和 qsforex.trading.trading logger,均输出到控制台,级别为 DEBUG。


六、使用流程

6.1 回测流程

步骤 1: 生成模拟数据
└── python scripts/generate_simulated_pair.py GBPUSD

步骤 2: 运行回测
└── python examples/mac.py

步骤 3: 查看结果
└── python backtest/output.py

6.2 实盘交易流程

步骤 1: 配置 OANDA 凭证(settings.py
步骤 2: 编写策略(继承策略基类)
步骤 3: 启动交易
└── python trading/trading.py

七、技术栈

类别 依赖包 版本
数值计算 numpy 1.9.2
科学计算 scipy 0.15.1
数据处理 pandas 0.16.1
可视化 matplotlib 1.4.3
统计可视化 seaborn 0.5.1
机器学习 scikit-learn 0.16.1
HTTP 请求 requests 2.7.0
测试框架 nose 1.3.6
Mock mock 1.0.1
交互环境 ipython 3.1.0

八、已知问题与改进建议

8.1 兼容性问题

问题 严重程度 说明
Python 2.7 语法 使用 from __future__try: import Queue__metaclass__ 等旧式写法,无法在 Python 3 上直接运行
依赖版本过旧 pandas 0.16、numpy 1.9 发布于 2015 年,存在安全漏洞
OANDA API 版本 使用 OANDA v1 API,该版本已被废弃,需迁移到 v3 REST API

8.2 代码缺陷

问题 位置 说明
缺少 self. 前缀 portfolio.py L165 add_position_units 应为 self.add_position_units,会导致 NameError
无 setup.py 根目录 缺少标准的 Python 包安装配置,无法通过 pip install 安装
硬编码 generate_simulated_pair.py 模拟数据生成的日期、初始价格等参数硬编码

8.3 改进建议

  1. Python 3 迁移:将所有语法升级到 Python 3.6+,移除 from __future__ 导入
  2. 依赖更新:升级到最新版本的 pandas、numpy 等核心依赖
  3. API 升级:将 OANDA API 从 v1 迁移到 v3
  4. 包管理现代化:添加 setup.pypyproject.toml
  5. Bug 修复:修复 portfolio.py 中缺失 self. 的问题
  6. 配置外部化:将模拟数据生成参数从硬编码改为配置文件或命令行参数

九、扩展指南

9.1 编写自定义策略

只需继承或模仿现有策略,实现 calculate_signals(event) 方法:

class MyCustomStrategy(object):
    def __init__(self, pairs, events):
        self.pairs = pairs
        self.events = events
        # 初始化你的策略状态

    def calculate_signals(self, event):
        if event.type == 'TICK':
            # 你的策略逻辑
            # 当满足条件时,生成 SignalEvent
            signal = SignalEvent(pair, "market", "buy", event.time)
            self.events.put(signal)

然后在回测或实盘入口中替换策略类即可。

9.2 添加新的数据源

继承 PriceHandler 基类,实现数据获取和 stream_next_tick() 方法。


十、许可证

MIT License - Copyright (c) 2015 Michael Halls-Moore


风险提示:外汇保证金交易具有高风险,可能不适合所有投资者。过去的表现不代表未来的结果。高杠杆可能对您不利也可能对您有利。在决定投资外汇之前,您应仔细考虑您的投资目标、经验水平和风险承受能力。


十一、可复用模块分析 —— 多项目整合视角

本章节专门为综合多个项目构建自有交易系统的开发者编写,帮助你快速识别 QSForex 中最值得借鉴和复用的模块,以及它在多项目组合中的定位。

11.1 本项目在量化交易系统中的定位

QSForex 的核心价值在于轻量级、教学友好、架构清晰。它不是一个功能完备的生产级系统,而是一个架构原型——用最少的代码完整展示了事件驱动交易系统的骨架。在多项目整合中,QSForex 适合作为:

角色 说明
架构参考蓝图 事件驱动模式是量化交易系统的主流范式,本项目的实现简洁易懂
快速原型验证 当你有一个新策略想法时,可以最快速度搭出回测环境
教学/入门材料 代码量小、注释清晰,适合团队新成员快速理解量化系统全貌

11.2 模块可复用性矩阵

以下按照可复用价值从高到低排列,并标注每个模块在多项目整合中的建议处理方式。

强烈推荐复用/借鉴

模块 核心价值 可复用部分 跨市场适用性
事件驱动架构 整个事件队列 + 事件类型设计 股票/期货/加密货币均可
回测引擎 Backtest._run_backtest() 主循环 通用,只需替换数据源
仓位管理 Position 类的盈亏计算逻辑 外汇特有,但多空双向模式通用
滚动 SMA 算法 calc_rolling_sma() 高效增量计算 所有时间序列策略通用

详细分析

① 事件驱动架构(最核心的复用价值)

事件类型设计 → 事件队列 → 事件分发循环

这是 QSForex 的灵魂。无论你最终使用什么市场、什么语言、什么数据库,这个三层解耦的模式是量化交易系统的事实标准:

数据层 ──TickEvent──→ 策略层 ──SignalEvent──→ 组合层 ──OrderEvent──→ 执行层
  ↑                    ↑                       ↑                    ↑
 可替换               可替换                  可替换               可替换

迁移建议

  • 保留事件类型定义(TickEvent / SignalEvent / OrderEvent),按需扩展(如增加 FillEventRiskEvent
  • 保留事件队列 + while 循环分发的模式
  • 替换各层具体实现即可适配任何市场

② 回测引擎主循环

backtest.py 中的 _run_backtest() 方法是经典的回测主循环模式:

while iters < max_iters and ticker.continue_backtest:
    try:
        event = events.get(False)       # 非阻塞取事件
    except queue.Empty:
        ticker.stream_next_tick()       # 无事件时推进数据
    else:
        if event.type == 'TICK':
            strategy.calculate_signals(event)
            portfolio.update_portfolio(event)
        elif event.type == 'SIGNAL':
            portfolio.execute_signal(event)
        elif event.type == 'ORDER':
            execution.execute_order(event)

迁移建议

  • 这个循环结构可以直接移植到任何市场(股票、期货、加密货币)
  • 只需实现对应市场的 PriceHandler 子类即可
  • 可以扩展为支持 BarEventK线事件)以适配日线级别策略

③ 仓位盈亏计算

position.py 中的 Position 类实现了完整的:

  • 多空双向持仓
  • 平均成本计算(加仓/减仓时重新计算)
  • 已实现/未实现盈亏分离
  • 跨货币换算

迁移建议

  • 外汇特有的汇率换算部分可以剥离,核心的 avg_price 加权平均算法是通用的
  • 期货/股票场景下,需增加保证金计算、合约乘数等字段
  • 加密货币场景几乎可以直接复用

④ 滚动 SMA 增量算法

strategy.py 中的高效均线计算:

def calc_rolling_sma(self, sma_m_1, window, price):
    return ((sma_m_1 * (window - 1)) + price) / window

这个算法将 SMA 计算从 O(n) 优化到 O(1),在高频回测中效果显著。


可借鉴思路,需重新实现

模块 核心价值 需改造的原因
数据层 CSV 多文件按天加载、多货币对按时间归并 格式绑定 DukasCopy,且 Python 2.7 的 pandas 语法已过时
信号执行逻辑 buy/sell 与多空仓位的状态机 逻辑有 Bug(缺少 self.),且不支持部分平仓
绩效计算 最大回撤计算 实现过于简单,现代系统需要 Sharpe/Sortino/Calmar 等
可视化输出 三图布局(权益+收益+回撤) matplotlib 版本过旧,可用 plotly/bokeh 替换

参考价值有限,建议替换

模块 原因
OANDA 执行器 使用已废弃的 OANDA v1 API,必须用 v3 重写或换经纪商
实时数据流 同上,API 版本过时
模拟数据生成 仅生成随机游走数据,无市场微观结构,建议用专业回测数据源
日志配置 可用 structlog 或 loguru 替代

11.3 多项目整合的推荐架构

如果你正在综合多个项目构建自己的交易系统,推荐的分层架构如下:

┌─────────────────────────────────────────────────────┐
│                  策略层 (Strategy)                    │
│   从 QSForex 借鉴:事件接口 + calculate_signals      │
│   从其他项目借鉴:因子计算、ML模型、信号组合          │
├─────────────────────────────────────────────────────┤
│                  组合层 (Portfolio)                   │
│   从 QSForex 借鉴:多空仓位管理 + 风险头寸计算        │
│   从其他项目借鉴:凯利公式、VaR、组合优化             │
├─────────────────────────────────────────────────────┤
│                  执行层 (Execution)                   │
│   从 QSForex 借鉴:SimulatedExecution(回测模式)     │
│   从其他项目借鉴:多经纪商适配、订单路由、智能下单     │
├─────────────────────────────────────────────────────┤
│                  数据层 (Data)                        │
│   从 QSForex 借鉴:多标的按时间归并的思想              │
│   从其他项目借鉴:实时数据库、数据清洗、复权处理       │
├─────────────────────────────────────────────────────┤
│                  事件总线 (Event Bus)                 │
│   从 QSForex 借鉴:Events Queue + 事件类型体系 ★★★   │
│   从其他项目借鉴:Redis/Kafka 分布式事件总线          │
└─────────────────────────────────────────────────────┘

11.4 QSForex 在多项目组合中的角色总结

维度 QSForex 的定位
架构教学 🥇 最佳入门教材——事件驱动模式的最简实现
回测引擎 🥈 可作为快速原型验证工具
策略开发 🥈 内置策略简单,但策略接口设计值得参考
生产就绪度 不适合直接用于生产环境
跨市场支持 仅外汇,需大量改造才能支持股票/期货
代码质量 ⚠️ 有已知 Bug,需要修复后再复用

推荐的复用策略

  1. 提取事件驱动骨架:将 event/ + backtest/ 的核心循环提取为通用框架
  2. 修复并提取仓位管理:修复 portfolio.py 的 Bug,抽象出通用的 Position 基类
  3. 保留策略接口规范:统一 calculate_signals(event) 签名作为所有策略的入口规范
  4. 替换其他所有模块:数据源、执行器、绩效分析、可视化全部用现代方案重新实现

一句话总结QSForex 的事件驱动架构 + 回测主循环 + 仓位管理是最值得带走的核心资产,其余模块建议用其他项目的更成熟实现替代。