Bootstrap

大模型自主完成量化交易策略的开发与回测验证

1 大模型的优势

        随着人工智能技术的飞速发展,大模型(如 GPT、BERT 等)在金融领域的应用逐渐深入,大模型在策略定制与编码中的优势显而易见。它不仅提高了策略开发的效率和精度,还降低了成本,减少了人为偏差。随着技术的进一步发展,大模型将在金融领域发挥越来越重要的作用,成为投资者不可或缺的工具。

        相比人类,大模型在策略开发中具有以下优点:

1. 高效性与速度

        大模型能够在极短的时间内完成策略的设计、优化和编码。传统上,人类开发者需要花费数天甚至数周的时间研究市场数据、编写代码并测试策略,而大模型可以在几分钟内生成完整的策略代码,并快速迭代优化。这种高效性极大地缩短了策略开发周期,使投资者能够更快地响应市场变化。

2. 强大的数据处理能力

        大模型能够处理海量的历史数据和实时市场信息,从中提取出复杂的模式和规律。人类在面对大量数据时容易受到认知限制,而大模型可以轻松分析数百万条数据点,识别出潜在的趋势和相关性,从而生成更精准的策略。

3. 多样化的策略生成

        大模型能够基于不同的市场条件和投资目标,生成多样化的策略。无论是趋势跟踪、均值回归还是套利策略,大模型都可以根据需求快速生成相应的代码。相比之下,人类开发者往往受限于经验和知识范围,难以覆盖所有可能的策略类型。

4. 自动化优化与回测

        大模型可以自动进行策略参数的优化和历史回测,找到最优的参数组合。人类开发者需要手动调整参数并运行回测,耗时且容易出错。大模型则可以通过算法快速遍历参数空间,找到最佳配置,同时生成详细的绩效报告。

5. 减少人为偏差

        人类在策略开发中容易受到情绪、认知偏差和经验局限的影响,导致策略设计不够客观。大模型基于数据和算法,能够完全客观地生成策略,避免人为因素的干扰,从而提高策略的稳定性和可靠性。

6. 持续学习与迭代

        大模型具有持续学习的能力,可以根据最新的市场数据和反馈不断优化策略。人类开发者需要不断学习和更新知识,而大模型可以自动从新数据中学习,保持策略的时效性和竞争力。

7. 低成本与可扩展性

        使用大模型开发策略可以显著降低人力成本和时间成本。此外,大模型可以同时为多个市场、多种资产生成策略,具有极强的可扩展性。人类开发者则需要投入大量资源才能实现类似的效果。

实际应用场景

  • 量化投资:大模型可以快速生成并优化量化交易策略,帮助机构投资者提高收益。

  • 个性化策略:根据投资者的风险偏好和投资目标,大模型可以定制个性化的策略。

  • 实时调整:大模型可以实时监控市场变化,动态调整策略参数,适应不同的市场环境。

 

2 代码实现

          我们要为代理(agent)配置了两个工具和一个智能大模型:

回测工具(run_pybroker):用于评估策略的表现。
信息获取工具 (ExecContext_Info):帮助编写符合规范的策略代码,降低错误率。
大模型 (如 deepseek):辅助策略开发和决策。

运行流程如下:

        1. 代理首先使用 `ExecContext_Info` 获取代码编写规范,以减少错误。
        2. 编写策略后,调用回测工具`run_pybroker`评估策略效果。
        3. 根据回测返回盈亏率、sharpe值等回测评估指标,代理评估收益是否满足预期,若否,则调整策略,并重新回测。
        4. 这一过程会持续迭代,直到策略满足预期或达到预设的最大迭代次数为止。

       本示例的策略在回测期间表现优秀,总收益率高达 72.36%,胜率也达到 77.61%。

 

1.基础工具

  1. run_pybroker:用于策略回测,使Agent能评估交易策略的表现。
  2. ExecContext_Info:为Agent提供策略代码编写指导,让Agent编写代码,减少出错的概率。

部分代码如下:

@tool 
def run_pybroker(stock_code: str, start_date: str, end_date: str, Strategy_Sring: str) -> str:
    """
    运行 PyBroker 回测框架,使用指定的交易策略进行股票回测。

    Args:
        stock_code: 股票代码(例如:"601088")
        start_date: 回测开始日期,格式为 YYYYMMDD(例如:"20210101")
        end_date: 回测结束日期,格式为 YYYYMMDD(例如:"20241129")
        Strategy_Sring: PyBroker的交易函数定义代码逻辑,定义了买卖逻辑。格式:字符串格式;函数定义为:def Strategy_Func(ctx: ExecContext)。
    
    Returns:
        str: 键绩效指标(KPIs)
    """

    from pybroker.ext.data import AKShare
    from pybroker import StrategyConfig, Strategy

    # 创建策略配置对象,设置初始现金为500,000元
    strategyconfig = StrategyConfig(initial_cash=100000)

    # 创建策略对象,设置数据源为AKShare,开始日期为'20230801',结束日期为'20230830',策略配置为my_config
    strategy = Strategy(
        data_source=AKShare(),
        start_date=start_date,
        end_date=end_date,
        config=strategyconfig
    )

    # 在这里执行策略函数
    ......

    # 执行回测
    result = strategy.backtest(calc_bootstrap=True)

    import json
    result_dict = result.metrics_df.to_dict(orient='records')  
    result_json = json.dumps(result_dict, ensure_ascii=False)

    return result_json

        ExecContext_Info工具代码片段:


@tool
def ExecContext_Info() -> str:
    """
    获取 ExecContext 类的变量说明,用于在编写 pybroker 策略代码时提取变量。
    Returns:
        str: ExecContext 类的源代码,包含类的定义、属性、方法及其实现细节。
    """


    desc_str='''
以下是 `ExecContext` 类的变量和函数信息:

---
### **功能说明**
- **变量**:主要包括股票代码、买卖价格、持仓数量、止损止盈设置等。
- **函数**:主要包括获取数据、操作持仓、设置止损止盈、取消订单等功能。
- **用途**:`ExecContext` 类用于在策略执行期间管理交易上下文,提供丰富的接口用于访问市场数据和执行交易操作。

### **类变量**
1. `_stop_id: int = 0`  
   - 用于生成唯一的止损 ID。

---

### **实例变量**
1. **股票与交易相关**:
   - `symbol: str`:当前执行的股票代码。
   - `buy_fill_price`:买入订单的成交价格。
   - `buy_shares`:买入的股票数量。
   - `buy_limit_price`:买入订单的限价。
   - `sell_fill_price`:卖出订单的成交价格。
   - `sell_shares`:卖出的股票数量。
   - `sell_limit_price`:卖出订单的限价。
   - `hold_bars: Optional[int]`:持仓的 bar 数量,超过后自动平仓。
   - `score: Optional[float]`:用于对股票进行排名的分数。

2. **自定义数据与会话**:
   - `session: MutableMapping`:用于存储自定义数据的字典。

3. **止损与止盈设置**:
   - `stop_loss`:止损点数。
   - `stop_loss_pct`:止损百分比。

......

       2.定义代理

        定义代理:`agent = CodeAgent`,其参数作用如下:

- `tool`: 列出为代理配备的工具,如回测和信息获取工具。
- `model`: 指定用于辅助代码生成或决策的大模型。
- `max_iterations`: 设置最大迭代次数,以避免无限循环。
- `additional_authorized_imports`: 授权导入特定的Python算法包,丰富代理的代码编写环境。

        这样配置后,代理能够在受限且安全的环境中执行任务,同时具备必要的功能和资源来完成复杂的编程工作。

agent = CodeAgent(
        tools = [run_pybroker,ExecContext_Info],
        model= model,
        max_iterations = 10,  # 添加最大迭代次数限制
        additional_authorized_imports=["pybroker","typing",'datetime', 'statistics', 'time', 'collections', 'queue', 'pybroker', 'itertools', 'random', 're', 'unicodedata', 'typing', 'math', 'stat','pandas_ta']
)

       3.启动代理

        完成工具和模型的配置后,可以通过调用 agent.run() 函数来启动代理,使其开始执行任务。本示例我们给代理定的目标是:编写一个交易策略函数 Strategy_Func,用于测试股票代码为 {601088} 的股票在 {20200101} 到 {20231231} 这段时间内的表现,目标是实现总回报率 ≥10%。

fe9a079937494ebdbea6aa37da5582f3.png

 


agent.run(f"""
# 编写一个交易策略函数 Strategy_Func,用于测试股票代码为 {symbol} 的股票在 {start_date} 到 {end_date} 这段时间内的表现,目标是实现总回报率 ≥10%。

# 第一步1. 定义交易策略函数的代码字字符变量
-- 代码必须按照 pybroker 的规范来写。 
-- 注意:交易策略函数必须写成字符串格式,函数名称必须是 def Strategy_Func(ctx: ExecContext),不能改名字。
-- 使用ExecContext_Info工具,获取参数ctx的变量和函数信息。
-- 参考下面的模板:
```
    # 你要导入的包
    from pybroker import ExecContext

    def Strategy_Func(ctx: ExecContext):
    # 策略的说明
    # 你要实现的策略代码
```

# 2. 使用该策略执行回测
-- 注意:回测框架`run_pybroker`已经被定义,请勿更改此名称。
-- 回测框架`run_pybroker`已经被定义,接下来我将使用这个策略执行回测,以评估其在给定时间段内的表现。
run_pybroker(
    stock_code={symbol}, 
    start_date={start_date}, 
    end_date={end_date}, 
    Strategy_Sring=[交易策略函数代码字符串]
)

# 3. 分析回测结果
# 回测完成后,返回以下关键绩效指标(KPIs):
 - 总交易次数: trade_count
 - 初始市场价值: initial_market_value
 - 结束市场价值: end_market_value
 - 总盈亏(PnL): total_pnl
 - 未实现盈亏: unrealized_pnl

# 4. 结果输出
# 输出格式:必须包含三个元素:最优的交易策略函数`Strategy_Func`、策略说明、KPIs。

""")

       运行过程

        Step 0:执行ExecContext_Info工具,获取编写符合规范

ae4e27045d0441eb8be8e2dc6697678c.png

        Step 1:编写策略函数Strategy_Func

eb47d9963bfa41e78ec0d9d8ad928ccb.png

        Step 2:对策略函数进行回测

e9a0bb94363e4e3a90befd7f82b56ecd.png

        Step 3-4:评估回测效果(策略的总收益率为 72.36%,达到预期),结束任务并输出。

c38984a892a54a8bb20877f6d44dcd68.png

73408d3c6f5d4405b7ab655d4572a22b.png

        4.回测结果解析

        Strategy_Func:策略函数

from pybroker import ExecContext

def Strategy_Func(ctx: ExecContext):
    # Calculate the 50-day moving average
    ma_50 = ctx.close[-50:].mean()
    
    # Buy if the current price is below the 50-day moving average
    if ctx.close[-1] < ma_50:
        ctx.buy_shares = ctx.calc_target_shares(0.1)  # Allocate 10% of the portfolio to this trade
    
    # Sell if the current price is above the 50-day moving average
    elif ctx.close[-1] > ma_50 and ctx.long_pos():
        ctx.sell_all_shares()
  1. 计算 50 日移动平均线

    • 使用最近 50 个交易日的收盘价计算移动平均线(ma_50)。

    • ma_50 = ctx.close[-50:].mean()

  2. 买入条件

    • 如果当前价格(ctx.close[-1])低于 50 日移动平均线(ma_50),则生成买入信号。

    • 买入时,使用投资组合的 10% 资金(ctx.calc_target_shares(0.1))进行交易。

  3. 卖出条件

    • 如果当前价格(ctx.close[-1])高于 50 日移动平均线(ma_50),并且当前有持仓(ctx.long_pos()),则生成卖出信号。

    • 卖出时,平掉所有持仓(ctx.sell_all_shares())。


   Strategy_Explanation:策略解释

The strategy is a mean-reversion strategy that buys when the stock price is below its 50-day moving average and sells when the price is above the moving average. It allocates 10% of the portfolio to each trade.

翻译:

这是一个 均值回归策略。当股票价格低于 50 日移动平均线时买入,假设价格会回归均值。当股票价格高于 50 日移动平均线时卖出,假设价格会从高点回落。每次交易使用投资组合的 10% 资金。


     KPIs:关键绩效指标

'KPIs': {
    'Total Return': 72.36,           # 总收益率(%)
    'Total Trades': 202,             # 总交易次数
    'Win Rate': 77.61,               # 胜率(%)
    'Loss Rate': 22.39,              # 亏损率(%)
    'Max Drawdown': -17.57,          # 最大回撤(%)
    'Sharpe Ratio': 0.067,           # 夏普比率
    'Profit Factor': 1.38,           # 盈利因子
    'Average PnL per Trade': 358.21, # 每笔交易的平均盈亏(金额)
    'Average Return per Trade': 3.18, # 每笔交易的平均收益率(%)
    'Largest Win': 19.21,            # 最大盈利(%)
    'Largest Loss': -11.44           # 最大亏损(%)
}
  1. 总收益率(Total Return

    • 策略的总收益率为 72.36%,表现非常优秀。

  2. 交易次数(Total Trades

    • 总交易次数为 202 次,表明策略交易频率较高。

  3. 胜率(Win Rate

    • 胜率为 77.61%,说明大部分交易是盈利的。

  4. 亏损率(Loss Rate

    • 亏损率为 22.39%,与胜率互补,表明亏损交易占比较低。

  5. 最大回撤(Max Drawdown

    • 最大回撤为 -17.57%,表明策略在回测期间的最大资金回撤幅度为 17.57%。

  6. 夏普比率(Sharpe Ratio

    • 夏普比率为 0.067,较低,表明策略的风险调整后收益不高。

  7. 盈利因子(Profit Factor

    • 盈利因子为 1.38,大于 1,表明策略的盈利总额大于亏损总额。

  8. 每笔交易的平均盈亏(Average PnL per Trade

    • 每笔交易的平均盈亏为 358.21(金额单位)。

  9. 每笔交易的平均收益率(Average Return per Trade

    • 每笔交易的平均收益率为 3.18%

  10. 最大盈利(Largest Win

    • 单笔交易的最大盈利为 19.21%

  11. 最大亏损(Largest Loss

    • 单笔交易的最大亏损为 -11.44%

        5.模型定义的策略评价

优点

  1. 高胜率:胜率高达 77.61%,表明策略的盈利交易比例很高。

  2. 高总收益率:总收益率为 72.36%,表现非常优秀。

  3. 简单易实现:策略逻辑清晰,仅依赖 50 日移动平均线,适合初学者理解和实现。

缺点

  1. 夏普比率低:夏普比率为 0.067,表明策略的风险调整后收益较低。

  2. 最大回撤较高:最大回撤为 -17.57%,可能存在较大的资金波动风险。

  3. 交易频率高:总交易次数为 202 次,可能导致较高的交易成本。