3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
根据流动比率(Current Ratio)选股是一种基于基本面分析的策略。流动比率衡量的是企业偿还短期债务的能力,计算公式为:流动资产 / 流动负债。通常认为,流动比率越高,企业的短期偿债能力越强。
在 QMT 中,我们可以利用 多因子数据接口 (ContextInfo.get_factor_data) 来获取该指标。
Solvency_and_Capital_Structure.CurrentRatio(偿债能力和资本结构 - 流动比率)。# -*- coding: gbk -*-
import pandas as pd
import numpy as np
def init(ContextInfo):
# 1. 设置策略参数
ContextInfo.target_ratio = 2.0 # 流动比率阈值
ContextInfo.holding_num = 20 # 最大持仓数量(可选,防止资金过于分散)
# 2. 设置股票池 (这里以沪深300为例)
ContextInfo.index_code = '000300.SH'
ContextInfo.set_universe(ContextInfo.get_sector(ContextInfo.index_code))
# 3. 设置账号 (回测模式下会自动使用虚拟账号,实盘需替换为真实账号)
ContextInfo.account_id = 'test_account'
ContextInfo.account_type = 'STOCK'
ContextInfo.set_account(ContextInfo.account_id)
# 4. 初始化全局变量
ContextInfo.rebalance_period = 'monthly' # 调仓周期
ContextInfo.last_rebalance_month = -1
def handlebar(ContextInfo):
# 获取当前K线的时间
bar_index = ContextInfo.barpos
current_time = ContextInfo.get_bar_timetag(bar_index)
current_date_str = timetag_to_datetime(current_time, '%Y%m%d')
current_month = int(current_date_str[4:6])
# -------------------------------------------------------
# 调仓逻辑控制:每月第一个交易日调仓
# -------------------------------------------------------
if ContextInfo.last_rebalance_month == current_month:
return # 本月已调仓,跳过
# 更新调仓月份标记
ContextInfo.last_rebalance_month = current_month
print(f'=== 开始调仓: {current_date_str} ===')
# -------------------------------------------------------
# 1. 获取数据
# -------------------------------------------------------
stock_list = ContextInfo.get_universe()
# 因子名称:偿债能力和资本结构 - 流动比率
factor_name = 'Solvency_and_Capital_Structure.CurrentRatio'
# 获取因子数据
# 注意:get_factor_data 返回的数据结构取决于传入的股票和时间数量
# 传入多只股票、单日时间,返回 DataFrame (index=股票代码, columns=因子名)
factor_data = ContextInfo.get_factor_data(
[factor_name],
stock_list,
current_date_str,
current_date_str
)
# 数据清洗:去除空值
if factor_data.empty:
print("未获取到因子数据")
return
# -------------------------------------------------------
# 2. 选股逻辑
# -------------------------------------------------------
# 筛选流动比率大于阈值的股票
# 注意:factor_data 是一个 DataFrame,列名为因子全名
if factor_name not in factor_data.columns:
print(f"数据中缺少因子列: {factor_name}")
return
# 过滤掉 NaN 值
valid_data = factor_data.dropna(subset=[factor_name])
# 筛选大于阈值的股票
selected_df = valid_data[valid_data[factor_name] > ContextInfo.target_ratio]
# (可选) 排序:例如按流动比率从大到小排序,取前N只
selected_df = selected_df.sort_values(by=factor_name, ascending=False)
target_stocks = selected_df.head(ContextInfo.holding_num).index.tolist()
print(f"选出股票数量: {len(target_stocks)}")
# -------------------------------------------------------
# 3. 交易执行
# -------------------------------------------------------
# 获取当前持仓
positions = get_trade_detail_data(ContextInfo.account_id, ContextInfo.account_type, 'POSITION')
holding_stocks = [obj.m_strInstrumentID for obj in positions if obj.m_nVolume > 0]
# 卖出不在目标列表中的股票
for stock in holding_stocks:
if stock not in target_stocks:
order_target_value(stock, 0, ContextInfo, ContextInfo.account_id)
print(f"卖出: {stock}")
# 买入目标股票
if len(target_stocks) > 0:
# 简单的等权分配资金 (注意:这里使用 order_target_percent 需要在回测设置中设置初始资金)
# 也可以使用 order_target_value 根据总资产计算
weight = 1.0 / len(target_stocks)
for stock in target_stocks:
order_target_percent(stock, weight, ContextInfo, ContextInfo.account_id)
print(f"买入/调仓: {stock}, 目标权重: {weight:.2%}")
数据接口 (get_factor_data):
Solvency_and_Capital_Structure.CurrentRatio 这个字段。pandas.DataFrame,索引是股票代码,列名是因子名称。时间控制:
current_month 和 last_rebalance_month 的对比,实现了月度调仓。交易函数:
order_target_percent(目标比例下单)。这在调仓时非常方便,它会自动计算需要买入或卖出的股数,将仓位调整到指定的权重(例如 5%)。order_target_percent 时,请确保 ContextInfo 能正确获取到账户的总资产数据,否则建议改用 order_target_value 或 order_lots。容错处理:
.dropna() 处理,防止因为某些股票停牌或未发布财报导致数据为空(NaN)而报错。Q: 如何查看还有哪些财务因子可以使用?
A: 在 QMT 的帮助文档或“数据管理”界面中,查看“多因子数据”部分。例如,速动比率是 Solvency_and_Capital_Structure.QuickRatio,资产负债率是 Solvency_and_Capital_Structure.DebtsAssetRatio。
Q: 为什么回测时没有交易?
A:
ContextInfo.index_code 设置的指数成分股在回测区间内是否存在。ContextInfo.target_ratio 阈值是否设置过高,导致选不出股票。Q: 如何结合其他指标(如市盈率 PE)?
A: 可以在 get_factor_data 的第一个参数列表中添加字段,例如 ['Solvency_and_Capital_Structure.CurrentRatio', 'Valuation_and_Market_Cap.PE'],然后在获取到的 DataFrame 中增加额外的筛选逻辑即可(例如 df[(df['...CurrentRatio'] > 2) & (df['...PE'] < 20)])。