🚀 AI 一键生成 ptrade 策略代码

PTrade 情绪指标:心理线(PSY)人气指标策略编写

ptrade | 发布时间: 2025/12/30
以下内容由 EasyQuant 生成。

问题描述

请帮我写一个基于心理线 PSY 指标的交易策略。

解决方案

这是一个基于 心理线 (PSY, Psychological Line) 指标的 PTrade 量化交易策略。

策略原理

心理线 (PSY) 是一种建立在研究投资人心理趋向基础上,分析某段期间内多空双方力量对比,从而判断股价未来走势的技术指标。

  • 计算公式
    $$PSY(N) = \frac{A}{N} \times 100$$
    • $N$:周期(通常为 12 天)。
    • $A$:周期内上涨的天数(收盘价 > 前一日收盘价)。
  • 交易逻辑(反转策略)
    • 买入信号(超卖):当 PSY 值低于 25(或 20)时,表示市场过度悲观,属于超卖区域,可能出现反弹,执行买入。
    • 卖出信号(超买):当 PSY 值高于 75(或 80)时,表示市场过度乐观,属于超买区域,可能出现回调,执行卖出。

PTrade 策略代码

import numpy as np

def initialize(context):
    """
    策略初始化函数
    """
    # 设置我们要操作的股票,这里以恒生电子为例
    g.security = '600570.SS'
    # 设置股票池
    set_universe(g.security)
    
    # --- 策略参数设置 ---
    # PSY计算周期,通常为12
    g.psy_period = 12
    # 买入阈值(超卖线),通常为25
    g.buy_threshold = 25
    # 卖出阈值(超买线),通常为75
    g.sell_threshold = 75
    
    # 设置滑点和手续费(可选,回测更精准)
    set_slippage(slippage=0.002)
    set_commission(commission_ratio=0.0003, min_commission=5.0)

def handle_data(context, data):
    """
    按周期运行的策略逻辑(日线级别)
    """
    security = g.security
    
    # 1. 获取历史数据
    # 我们需要计算过去 N 天的涨跌情况,因此需要 N+1 个收盘价来计算 N 个差值
    # count 设置为 g.psy_period + 1
    hist_data = get_history(g.psy_period + 1, frequency='1d', field='close', security_list=security, fq='pre')
    
    # 检查数据长度是否足够,不足则不计算
    if len(hist_data) < g.psy_period + 1:
        log.info("历史数据不足,跳过计算")
        return
    
    # 获取收盘价序列
    close_prices = hist_data['close'].values
    
    # 2. 计算 PSY 指标
    # 计算每日涨跌:今日收盘 - 昨日收盘
    # np.diff 会计算相邻元素的差值,结果长度为 len(close_prices) - 1
    price_diff = np.diff(close_prices)
    
    # 统计上涨天数 (差值 > 0 的天数)
    up_days_count = np.sum(price_diff > 0)
    
    # 计算 PSY 值
    psy_value = (up_days_count / g.psy_period) * 100
    
    # 打印日志方便调试
    log.info("日期: %s, 标的: %s, PSY值: %.2f" % (context.blotter.current_dt, security, psy_value))
    
    # 3. 获取当前持仓和资金
    position = context.portfolio.positions[security].amount
    available_cash = context.portfolio.cash
    
    # 4. 交易逻辑判断
    
    # 信号:PSY <= 买入阈值 (超卖,看涨) 且 当前无持仓
    if psy_value <= g.buy_threshold and position == 0:
        log.info("PSY值 (%.2f) 进入超卖区,触发买入信号" % psy_value)
        # 全仓买入
        order_value(security, available_cash)
        
    # 信号:PSY >= 卖出阈值 (超买,看跌) 且 当前有持仓
    elif psy_value >= g.sell_threshold and position > 0:
        log.info("PSY值 (%.2f) 进入超买区,触发卖出信号" % psy_value)
        # 清仓卖出
        order_target(security, 0)

代码解析

  1. 初始化 (initialize):

    • 定义了全局变量 g.psy_period (12天)、g.buy_threshold (25) 和 g.sell_threshold (75)。
    • 设置了单一标的 600570.SS
  2. 数据获取 (get_history):

    • PSY 需要判断过去 N 天是涨还是跌。
    • 为了判断 N 天的涨跌,我们需要 N+1 天的收盘价数据(因为第1天的涨跌需要对比第0天的价格)。
    • 使用 numpy.diff 快速计算价格差分。
  3. 指标计算:

    • np.sum(price_diff > 0):统计上涨的天数。
    • 公式:(上涨天数 / 周期) * 100
  4. 交易执行:

    • 买入:当 PSY 低于 25 时,认为市场恐慌过度,全仓买入。
    • 卖出:当 PSY 高于 75 时,认为市场过热,清仓止盈。

注意事项

  • Python 版本兼容性:代码使用了 Python 3.5 兼容的字符串格式化 % 语法,避免了 f-string,确保在 PTrade 旧版本环境中也能运行。
  • 数据复权get_history 中使用了 fq='pre'(前复权),这是技术指标计算的标准做法,防止分红派息导致的价格缺口影响涨跌判断。
  • 风险提示:PSY 是一个震荡指标,在单边大牛市或大熊市中可能会出现“钝化”(即长期停留在超买或超卖区),建议结合均线(MA)或趋势指标一起使用以过滤假信号。

Q&A

Q1: 如何修改 PSY 的计算周期,例如改为 24 天?
A1: 在 initialize 函数中,将 g.psy_period = 12 修改为 g.psy_period = 24 即可。

Q2: 这个策略可以用于分钟级别回测吗?
A2: 可以。代码逻辑是通用的。只需在回测配置界面将频率设置为“分钟”,或者在 get_history 中将 frequency='1d' 改为 frequency='1m' (或其他分钟周期),并相应调整阈值,因为分钟级别的波动频率与日线不同。

Q3: 为什么使用 np.diff 而不是循环计算涨跌?
A3: numpy 是 Python 中用于科学计算的库,np.diff 属于向量化操作,比 Python 原生的 for 循环计算速度快得多,且代码更简洁,非常适合量化交易中的指标计算。