量化交易 实战之市值中性化选股

Posted Gendan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了量化交易 实战之市值中性化选股相关的知识,希望对你有一定的参考价值。

可以自己import我们平台支持的第三方python模块,比如pandas、numpy等。

1. 获取市值和市净率因子数据

因子: 极值, 标准化, 中性化处理

2. 选定股票池 (根据方向权重)

市净率小的某些股票

from sklearn.linear_model import LinearRegression

在这个方法中编写任何的初始化逻辑。context对象将会在你的算法策略的任何方法之间做传递。

def init(context):

scheduler.run_weekly(get_data, tradingday=1)
scheduler.run_weekly(trade, tradingday=1)

def get_data(context, bar_dict):

# 查询两个因子的整数结果
q = query(
    fundamentals.eod_derivative_indicator.pb_ratio,
    fundamentals.eod_derivative_indicator.market_cap
).order_by(
    fundamentals.eod_derivative_indicator.pb_ratio
)
fund = get_fundamentals(q)
# 转置
context.fund = fund.T
# 查看fund格式
# logger.info(fund.T)
# 进行因子数据的处理, 去极值, 标准化
treat_data(context)
# 利用市净率进行选股 [PayPal](https://www.gendan5.com/wallet/PayPal.html)(市净率小的表现好)
context.stock_list = context.fund["pb_ratio"][
    context.fund["pb_ratio"] <= context.fund["pb_ratio"].quantile(0.05)  # 取前5%
].index
# 调试输出
logger.info(context.stock_list)
logger.info(context.stock_list.shape)

def treat_data(context):

"""
因子数据的处理逻辑
"""
# 去除NaN
context.fund = context.fund.dropna()
# 对市净率去极极值标准化
context.fund["pb_ratio"] = mad(context.fund["pb_ratio"])
context.fund["pb_ratio"] = stand(context.fund["pb_ratio"])
# 调试输出
logger.info(context.fund.shape)
# 选股的处理, 对市净率进行市值中性化
# 特征值: 市值
# 目标值: 市净率因子
x = context.fund["market_cap"].values.reshape(-1, 1)
y = context.fund["pb_ratio"]
# 建立线性回归, 中性化处理
lr = LinearRegression()
lr.fit(x, y)
y_predict = lr.predict(x)
# 去除残差
context.fund["pb_ratio"] = y - y_predict

before_trading此函数会在每天策略交易开始前被调用,当天只会被调用一次

def before_trading(context):

pass

你选择的证券的数据更新将会触发此段逻辑,例如日或分钟历史数据切片或者是实时数据切片更新

def handle_bar(context, bar_dict):

# TODO: 开始编写你的算法吧!
pass

after_trading函数会在每天交易结束后被调用,当天只会被调用一次

def after_trading(context):

pass

def trade(context, bar_dict):

# ----------------卖出----------------
for stock in context.portfolio.positions.keys():
    # 判断是否还在股票池
    if stock not in context.stock_list:
        order_target_percent(stock, 0)
# ----------------买入-----------------
weight = 1.0 / len(context.stock_list)
for stock in context.stock_list:
    order_target_percent(stock, weight)

绝对偏差

import numpy as np
def mad(factor):

"""
3倍中位数去极值
"""
# 求出因子值的中位数
med = np.median(factor)
# 求出因子值与中位数的差值, 进行绝对值
mad = np.median(abs(factor - med))
# 定义几倍的中位数上下限
high = med + (3 * 1.4826 * mad)
low = med - (3 * 1.4826 * mad)
# 替换上下限以外的值
factor = np.where(factor > high, high, factor)
factor = np.where(factor < low, low, factor)
return factor

标准化

def stand(factor):

"""
自实现标准化
"""
mean = factor.mean()
std = factor.std()
return (factor - mean) / std

以上是关于量化交易 实战之市值中性化选股的主要内容,如果未能解决你的问题,请参考以下文章

量化交易因子数据处理-标准化和市值中性化

股票量化交易策略之选股模拟交易过程

量化交易多因子策略流程

量化交易多因子策略与理论介绍

量化交易:股票量化策略介绍Alpha和Beta

day33 Python与金融量化分析