3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在聚宽(joinquant)量化交易平台中,jqfactor 模块提供了丰富的因子库。Skewness60 属于风险因子,表示个股收益的 60 日偏度。偏度用于衡量股票收益率分布的不对称程度,低偏度或负偏度股票通常意味着下行风险已被释放或具备异动潜力。
本文将介绍如何通过 get_factor_values API 获取该因子,并构建一个按月调仓的因子选股策略。
get_factor_values 函数用于快速获取质量、风险、情绪等数百个聚宽因子库数据。
from jqfactor import get_factor_values
factor_data = get_factor_values(securities, factors, start_date, end_date, count)
'Skewness60'。start_date 与 count 二选一。dict),key 为因子名称,value 为 pandas.DataFrame(index 为日期,columns 为股票代码)。以下示例展示如何在指定的交易日获取沪深300成分股的 Skewness60 因子,并按因子值从低到高排序提取前 10 只股票:
import pandas as pd
from jqdata import get_index_stocks
from jqfactor import get_factor_values
# 1. 获取沪深300成分股列表
stocks = get_index_stocks('000300.XSHG')
# 2. 查询 Skewness60 因子(最近 1 个交易日)
factor_data = get_factor_values(
securities=stocks,
factors=['Skewness60'],
end_date='2023-01-01',
count=1
)
# 3. 提取 DataFrame 并处理
df_skew = factor_data['Skewness60'].T
df_skew.columns = ['skew_value']
# 4. 剔除空值并升序排序(选出偏度最小的股票)
top_stocks = df_skew.dropna().sort_values(by='skew_value', ascending=True).head(10)
print(top_stocks)
下面是一个完整的 JoinQuant 策略,逻辑为:每月第一个交易日开盘前,获取沪深300成分股中 Skewness60 最小的 10 只股票进行调仓建仓。
import pandas as pd
from jqdata import *
from jqfactor import get_factor_values
def initialize(context):
# 设置基准
set_benchmark('000300.XSHG')
# 开启动态复权(真实价格)
set_option('use_real_price', True)
# 设置交易税费(股票类)
set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
# 选股参数定义
g.num_stocks = 10
# 设置定时运行函数:每月第一个交易日开盘前运行选股,开盘时执行调仓
run_monthly(before_market_open, monthday=1, time='09:00', reference_security='000300.XSHG')
run_monthly(market_open, monthday=1, time='09:30', reference_security='000300.XSHG')
def before_market_open(context):
# 1. 获取基准成分股作为初始股票池
stocks = get_index_stocks('000300.XSHG', date=context.current_dt)
# 2. 获取前一交易日的 Skewness60 因子数据
factor_data = get_factor_values(
securities=stocks,
factors=['Skewness60'],
end_date=context.previous_date,
count=1
)
df_factor = factor_data['Skewness60'].T
df_factor.columns = ['factor_val']
# 3. 过滤停牌及新股/退市等无效数据,并排序
df_clean = df_factor.dropna()
sorted_stocks = df_clean.sort_values(by='factor_val', ascending=True).index.tolist()
# 4. 选取因子值最小的前 N 只股票
g.target_stocks = sorted_stocks[:g.num_stocks]
log.info("最新选股目标列表: %s" % g.target_stocks)
def market_open(context):
# 1. 卖出不在目标池中的股票
for stock in list(context.portfolio.positions.keys()):
if stock not in g.target_stocks:
order_target(stock, 0)
log.info("卖出股票: %s" % stock)
# 2. 均仓买入目标股票
if len(g.target_stocks) > 0:
target_value = context.portfolio.available_cash / len(g.target_stocks)
for stock in g.target_stocks:
if context.portfolio.positions[stock].closeable_amount == 0:
order_target_value(stock, target_value)
log.info("买入股票: %s" % stock)
end_date 应当设置为 context.previous_date 或上一交易日,严禁传入包含当前调仓日收盘后的时刻。jqfactor 提供的 winsorize(去极值)与 neutralize(行业/市值中性化)函数对因子进一步提纯。因子数 × 股票数 × 交易日数)不能超过 200,000 个,大批量计算时请分批获取。