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

ptrade 平台如何利用应收账款指标进行财务选股与防爆雷?(附 Python 源码)

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

问题描述

ptrade 财务选股:利用资产负债表应收账款指标防范爆雷风险指南
如何在 ptrade 中使用 get_fundamentals 提取资产负债表中的应收账款(account_receivable)数据来过滤基本面有风险的股票?

解决方案

ptrade 财务选股:利用资产负债表应收账款指标防范爆雷风险指南

在A股市场中,**应收账款(Accounts Receivable)**过高往往是企业财务爆雷的前兆。如果一家企业的应收账款占总资产或营业收入的比例过高,可能意味着其销售回款困难、坏账风险极高,甚至存在虚增利润的嫌疑。

在 ptrade 量化交易平台中,我们可以利用 get_fundamentals 接口轻松获取上市公司的财务报表数据。本指南将教你如何提取资产负债表中的应收账款(account_receivable)资产总计(total_assets),并计算其比例,从而在选股时剔除高风险股票。


一、核心 API 介绍

要获取应收账款数据,我们需要调用 ptrade 的财务数据接口 get_fundamentals,定位到资产负债表(balance_statement)。

接口定义

get_fundamentals(security, table, fields=None, date=None, start_year=None, end_year=None, report_types=None, date_type=None, merge_type=None)

关键参数说明

  • security: 股票代码列表,例如 ['600570.SS', '000001.SZ']
  • table: 设为 'balance_statement'(资产负债表)。
  • fields: 传入我们需要提取的字段:
    • 'account_receivable': 应收账款(单位:元)
    • 'total_assets': 资产总计(单位:元)
  • date: 查询日期,格式为 'YYYYMMDD'。在回测中默认取当前回测交易日。

二、防爆雷选股逻辑

  1. 获取股票池:获取目标板块(如沪深300或全A股)的所有股票。
  2. 查询财务数据:获取最新的应收账款和总资产数据。
  3. 计算风险指标
    $$\text{应收账款占比} = \frac{\text{应收账款 (account_receivable)}}{\text{资产总计 (total_assets)}}$$
  4. 阈值过滤:剔除应收账款占比超过 30%(可根据风险偏好调整)的股票,保留财务状况更健康的标的进行交易。

三、ptrade 策略源码实现

以下是一个完整且可运行的 ptrade 策略示例。策略在盘前(before_trading_start)进行财务数据清洗与过滤,并在盘中对筛选出的安全股票进行买入操作。

import pandas as pd
import numpy as np

def initialize(context):
    # 设置基准
    set_benchmark('000300.SS')
    # 设定操作的股票池(以沪深300成分股为例)
    g.security_pool = get_index_stocks('000300.XBHS')
    set_universe(g.security_pool)
    
    # 风险控制阈值:应收账款占总资产比例不能超过 25%
    g.max_ar_ratio = 0.25 
    # 筛选后的安全股票池
    g.safe_stocks = []

def before_trading_start(context, data):
    log.info("------ 盘前开始进行财务风险过滤 ------")
    
    # 1. 获取当前交易日
    current_date = context.blotter.current_dt.strftime('%Y%m%d')
    
    # 2. 获取股票池的资产负债表数据
    fields = ['account_receivable', 'total_assets']
    try:
        df_finance = get_fundamentals(security=g.security_pool, 
                                      table='balance_statement', 
                                      fields=fields, 
                                      date=current_date)
    except Exception as e:
        log.error("获取财务数据失败: %s" % e)
        return
        
    if df_finance is None or df_finance.empty:
        log.warning("未获取到财务数据,保持原安全股票池")
        return

    # 3. 计算应收账款占比并过滤
    g.safe_stocks = []
    for stock in g.security_pool:
        if stock in df_finance.index:
            ar = df_finance.loc[stock, 'account_receivable']
            assets = df_finance.loc[stock, 'total_assets']
            
            # 排除数据缺失或总资产为负的异常情况
            if pd.isna(ar) or pd.isna(assets) or assets <= 0:
                continue
                
            ar_ratio = ar / assets
            
            # 过滤掉应收账款占比过高的股票
            if ar_ratio < g.max_ar_ratio:
                g.safe_stocks.append(stock)
            else:
                log.info("股票 %s 因应收账款占比过高 (%.2f%%) 被剔除" % (stock, ar_ratio * 100))
                
    log.info("原始股票池数量: %d, 过滤后安全股票数量: %d" % (len(g.security_pool), len(g.safe_stocks)))

def handle_data(context, data):
    # 简单交易逻辑:每日等权买入筛选出的前5只安全股票
    if not g.safe_stocks:
        return
        
    target_list = g.safe_stocks[:5]
    cash = context.portfolio.cash
    
    if cash > 10000:
        target_value = cash / len(target_list)
        for stock in target_list:
            if data[stock].is_open > 0:
                order_value(stock, target_value)
                log.info("买入安全财务标的: %s, 金额: %.2f" % (stock, target_value))

四、注意事项与避坑指南

  1. 网络流控限制get_fundamentals 属于在线 HTTP 请求接口。ptrade 平台对其有流量限制(通常每秒不超过100次,单次最大调用量5万条数据)。在处理全A股等超大股票池时,建议在 before_trading_start 中一次性传入整个 list,避免在循环中单只股票重复调用。
  2. 停牌与退市处理:财务选股后,在盘中下单前务必使用 data[stock].is_open > 0get_stock_status 检查股票是否处于停牌或退市整理期,防止废单。
  3. 行业特性差异:不同行业的应收账款占比差异巨大。例如,建筑、重工业、医药分销等行业应收账款比例普遍偏高,而零售、食品饮料等行业现金流较好。建议在实际应用中,结合 get_stock_blocks 进行同行业内部对比,效果更佳。