🚀 AI 一键生成 ptrade 策略代码
立即体验
👉 AI 生成代码 👈

PTrade量化平台计算移动平均价(MA)的完整指南

ptrade | 发布时间: 2026/6/1
以下内容由 EasyQuant 生成。

问题描述

PTrade中如何根据历史数据计算移动平均价?

解决方案

移动平均价(MA)在PTrade中的计算方法

在量化交易中,移动平均价(Moving Average, MA)是最基础且最常用的技术指标之一。在PTrade量化平台中,计算移动平均价主要依赖于获取历史行情数据的API:get_historyget_price。结合Python强大的数据处理库(如Pandas和Numpy),我们可以非常方便地计算出各种周期的均线。

以下是几种在PTrade中计算移动平均价的常用方法:

方法一:使用 get_history 和 Pandas 计算(最常用)

这是最直接的方法,适用于日线或分钟级别的策略。通过 get_history 获取过去N根K线的收盘价,然后使用Pandas的 .mean() 方法求平均值。

def initialize(context):
    g.security = '600570.SS'
    set_universe(g.security)
    
def handle_data(context, data):
    security = g.security
    
    # 取得过去5天的历史价格数据(不包含当前周期)
    # fq=None 表示不复权,实盘中通常建议使用前复权 fq='pre'
    df = get_history(5, '1d', 'close', security, fq='pre', include=False)
    
    # 计算5日均线价格,并保留3位小数
    ma5 = round(df['close'].mean(), 3)
    
    # 取得过去10天的历史价格数据
    df10 = get_history(10, '1d', 'close', security, fq='pre', include=False)
    ma10 = round(df10['close'].mean(), 3)
    
    log.info(f"当前5日均线: {ma5}, 10日均线: {ma10}")

方法二:结合实时最新价计算动态均线(适用于Tick级别)

如果你在做Tick级别的交易(使用 tick_datarun_interval),你可能需要将过去N-1天的历史收盘价当前的最新价结合起来,计算出实时的动态均线。

def initialize(context):
    g.security = '600570.SS'
    set_universe(g.security)
    run_interval(context, func, seconds=3)

# 盘前准备历史数据,避免盘中频繁调用长周期历史数据
def before_trading_start(context, data):
    # 获取过去10天的历史收盘价
    history = get_history(10, '1d', 'close', g.security, fq='pre', include=False)
    g.close_array = history['close'].values

# 自定义计算实时均线的函数
def get_MA_day(days, close_array, current_price):
    # 取过去 days-1 天的收盘价之和
    close_sum = close_array[-(days-1):].sum()
    # 加上当前最新价,除以 days
    MA = (current_price + close_sum) / days
    return MA

def func(context):
    stock = g.security
    
    # 获取最新价
    snapshot = get_snapshot(stock)
    if not snapshot or stock not in snapshot:
        return
    current_price = snapshot[stock]['last_px']
    
    # 计算实时的5日和10日均线
    ma5 = get_MA_day(5, g.close_array, current_price)
    ma10 = get_MA_day(10, g.close_array, current_price)
    
    log.info(f"实时最新价: {current_price}, 动态MA5: {ma5}, 动态MA10: {ma10}")

完整策略示例:经典双均线策略

基于上述计算方法,我们可以轻松实现一个经典的双均线策略:当短期均线(5日)上穿长期均线(10日)时买入,下穿时卖出

def initialize(context):
    g.security = '600570.SS'
    set_universe(g.security)
    
def handle_data(context, data):
    security = g.security

    # 得到十日历史价格
    df = get_history(10, '1d', 'close', security, fq='pre', include=False)
    
    # 得到五日均线价格
    ma5 = round(df['close'][-5:].mean(), 3)
    # 得到十日均线价格
    ma10 = round(df['close'][-10:].mean(), 3)

    # 取得当前资金余额
    cash = context.portfolio.cash
    
    # 如果五日均线大于十日均线(金叉)
    if ma5 > ma10:
        # 用所有 cash 买入股票
        order_value(security, cash)
        log.info("买入 %s" % security)
        
    # 如果五日均线小于十日均线(死叉),并且目前有头寸
    elif ma5 < ma10 and get_position(security).amount > 0:
        # 全部卖出
        order_target(security, 0)
        log.info("卖出 %s" % security)

💡 关键注意事项

  1. 复权处理 (fq):在计算均线等技术指标时,强烈建议使用前复权 (fq='pre')。如果不复权,当股票发生分红派息或送转股时,价格会出现跳空缺口,导致均线计算严重失真,从而触发错误的交易信号。
  2. 包含当前周期 (include)get_historyinclude 参数默认为 False。在 handle_data 中,如果 include=False,获取的是昨天及以前的数据;如果 include=True,则包含当天的未走完的K线数据。通常计算传统日均线时使用 include=False
  3. 性能优化:如果策略需要计算长周期均线(如MA60、MA120),尽量在 before_trading_start 中获取历史数据并缓存到全局变量 g 中,避免在 handle_datatick_data 中高频调用长周期历史数据接口,以提升策略运行效率。