🚀 AI 一键生成 ptrade 策略代码

PTrade 风控策略:基于产权比率 (Debt-Equity Ratio) 的避雷指南

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

问题描述

如何筛选低产权比率的股票?

解决方案

在PTrade中,筛选低产权比率(Debt-to-Equity Ratio)的股票,主要通过获取财务数据接口 get_fundamentals 来实现。

核心概念

  1. 产权比率:属于偿债能力指标,计算公式为 负债总额 / 股东权益。该指标越低,表明企业长期偿债能力越强,债权人权益的保障程度越高,承担的风险越小。
  2. 数据获取
    • 表名debt_paying_ability(偿债能力表)
    • 字段名debt_equity_ratio(产权比率)

策略实现思路

  1. 确定股票池:例如选取沪深300指数成分股。
  2. 获取数据:在 before_trading_start 中调用 get_fundamentals 获取成分股的 debt_equity_ratio
  3. 排序筛选:对获取的数据进行升序排列(从小到大),选取排名前N只股票(即产权比率最低的股票)。
  4. 交易执行:在 handle_data 中买入筛选出的股票,卖出不在列表中的持仓。

PTrade 策略代码示例

以下是一个完整的策略代码,该策略每天从沪深300中筛选出产权比率最低的10只股票进行轮动持有。

def initialize(context):
    """
    初始化函数,设置基准和全局变量
    """
    # 设置回测基准为沪深300
    set_benchmark('000300.SS')
    # 设置要操作的股票池范围(这里仅作为初始标记,实际在before_trading_start获取)
    g.index_code = '000300.SS'
    # 设置持仓数量
    g.stock_count = 10
    # 待买入股票列表
    g.target_stocks = []

def before_trading_start(context, data):
    """
    盘前处理:获取财务数据并筛选股票
    """
    # 1. 获取股票池(沪深300成分股)
    # 注意:get_index_stocks 建议在 before_trading_start 中调用
    stocks = get_index_stocks(g.index_code)
    
    if not stocks:
        log.info("未获取到成分股数据")
        return

    # 2. 获取前一个交易日的日期,避免未来函数
    # get_fundamentals 默认在回测中取回测日期,但在实盘或为了严谨,通常指定日期
    last_date = get_trading_day(-1)
    date_str = last_date.strftime('%Y%m%d')

    # 3. 查询偿债能力表中的产权比率
    # 表名: debt_paying_ability, 字段: debt_equity_ratio
    df = get_fundamentals(
        stocks, 
        'debt_paying_ability', 
        'debt_equity_ratio', 
        date=date_str
    )
    
    # 4. 数据处理与筛选
    if df is not None and not df.empty:
        # 剔除空值
        df = df.dropna()
        
        # 对产权比率进行升序排列(越低越好)
        # 注意:PTrade返回的DataFrame索引是股票代码,列名是字段名
        df_sorted = df.sort_values(by='debt_equity_ratio', ascending=True)
        
        # 取前 N 只股票
        g.target_stocks = df_sorted.index[:g.stock_count].tolist()
        
        log.info("今日筛选出的低产权比率股票: %s" % g.target_stocks)
    else:
        g.target_stocks = []
        log.info("今日未获取到财务数据")

def handle_data(context, data):
    """
    盘中处理:执行交易
    """
    if not g.target_stocks:
        return

    # 1. 卖出不在目标列表中的持仓
    # context.portfolio.positions.keys() 获取当前持仓的股票代码
    for security in list(context.portfolio.positions.keys()):
        if security not in g.target_stocks:
            # 卖出该股票,目标持仓调整为0
            order_target_value(security, 0)
            log.info("卖出不再符合条件的股票: %s" % security)

    # 2. 买入目标列表中的股票
    # 简单的等权重分配资金
    position_count = len(g.target_stocks)
    if position_count > 0:
        # 获取当前总资产(可用现金 + 持仓市值)
        total_value = context.portfolio.portfolio_value
        # 计算每只股票的目标市值
        target_value = total_value / position_count
        
        for security in g.target_stocks:
            # 只有当股票正常交易(非停牌)时才下单
            if data[security].is_open:
                order_target_value(security, target_value)
                # log.info("买入/调整股票: %s, 目标市值: %s" % (security, target_value))

代码关键点解析

  1. get_fundamentals 函数

    • 这是获取财务数据的核心函数。
    • 'debt_paying_ability':指定查询偿债能力表。
    • 'debt_equity_ratio':指定查询产权比率字段。
    • date 参数:传入前一个交易日,确保使用的是当时已发布的数据,避免回测中的“未来函数”问题。
  2. 数据排序

    • 使用 Pandas 的 sort_values(by='debt_equity_ratio', ascending=True) 进行升序排序。产权比率越低,代表企业自有资本占比较高,财务结构相对稳健。
  3. Python 版本兼容性

    • 代码使用了标准的 Python 语法,兼容 Python 3.5 及以上版本(避免了 f-string 等新特性),确保在 PTrade 环境中稳定运行。

常见问题 Q&A

Q: 产权比率的数据单位是什么?
A: 在 PTrade 的 debt_paying_ability 表中,debt_equity_ratio 通常以百分比数值形式返回(例如返回 50.5 代表 50.5%),具体数值大小可直接用于排序比较。

Q: 为什么要用 get_trading_day(-1)
A: 财务数据通常在收盘后更新。在回测或交易当天的开盘前(before_trading_start),我们通常基于截止到昨天已有的信息做决策。虽然 PTrade 回测引擎会自动处理数据可见性,但显式指定日期是更严谨的做法。

Q: 如何结合其他指标(如市盈率)一起筛选?
A: 可以在 get_fundamentals 中同时查询多个表的数据,或者多次调用获取不同的 DataFrame,然后使用 Pandas 的 concatmerge 方法合并数据,再进行多重条件筛选。