多因子,就是多个指标,指标就是ROE、PE、PS等等衡量一只股票某些方面好坏的量,可以使用已有指标,也可以发明一些新指标。
多因子投资组合:选择指标,设置根据指标买卖的规则,每天或每星期或每月运行一次,把不符合指标的股票卖掉,把符合指标的股票买入。
对冲:买入股票的同时,买入股指期货做对冲。买入股票,是期望股票可以涨,如果跌了,股指期货还能挽救一点损失。
至此,量化的技术花招就这么多了,剩下的是发现各种指标、使用各种规则和政策,赚钱。
import numpy as np
import math
"""
多因子对冲:根据多因子调整持仓组合,同时做股指期货对冲
"""
def init(context):
#选取板块
context.stks=[]
context.stks.append(sector("consumer discretionary"))
context.stks.append(sector("consumer staples"))
context.stks.append(sector("health care"))
context.stks.append(sector("telecommunication services"))
context.stks.append(sector("utilities"))
context.stks.append(sector("materials"))
context.flag=True
# 确定运行频率,每天调整持仓
scheduler.run_daily(rebalance)
# 手动添加银行板块
context.stocks = ['000001.XSHE','002142.XSHE','600000.XSHG','600015.XSHG','600016.XSHG','600036.XSHG','601009.XSHG','601166.XSHG','601169.XSHG','601288.XSHG','601328.XSHG','601398.XSHG','601818.XSHG','601939.XSHG','601988.XSHG','601998.XSHG']
#选股
def get_stocks(context, bar_dict):
#存储选股结果
stocks=set([])
#遍历每个板块
for i in range(0,len(context.stks)):
# 在这个循环里,首先获取每个板块的财务数据
#先查询所有数据,再根据板块里的标的过滤,再过滤掉某些因子值太低的标的
fundamental_df = get_fundamentals(
query(fundamentals.financial_indicator.adjusted_return_on_equity_weighted_average, fundamentals.eod_derivative_indicator.pb_ratio,fundamentals.eod_derivative_indicator.pe_ratio
).filter(
fundamentals.income_statement.stockcode.in_(context.stks[i])
).filter(
fundamentals.eod_derivative_indicator.pe_ratio<999
).order_by(
fundamentals.eod_derivative_indicator.pb_ratio
)
)
# 使用pandas对财务数据进行排名并打分
df=fundamental_df.T
df=df.sort_values('pb_ratio')
df['pb_score']=list(range(1,len(df)+1))
df=df.sort_values('pe_ratio')
df['pe_score']=list(range(1,len(df)+1))
scores=[]
for stock in df.T.columns.values:
scores.append(df.loc[stock,'pe_score']+df.loc[stock,'pb_score'])
df['scores']=list(scores)
df=df.sort_values('scores')
#取得分最低的三个股票
df=df.head(3)
#logger.info(df)
#把选中的标的放到stocks
stocks = stocks | set(df.T.columns.values)
#logger.info(i)
# 银行板块单独按照市净率取市净率最低的两个
fundamental_df = get_fundamentals(
query(fundamentals.financial_indicator.adjusted_return_on_equity_weighted_average, fundamentals.eod_derivative_indicator.pb_ratio,
).filter(
fundamentals.income_statement.stockcode.in_(context.stocks)
).order_by(
fundamentals.eod_derivative_indicator.pb_ratio
).limit(
2
)
)
# 把银行标的和其他标的合并起来
stocks =stocks | set(fundamental_df.columns.values)
return stocks
#下单调整投资组合
def rebalance(context, bar_dict):
#计算获取标的
stocks = get_stocks(context, bar_dict)
#获取现在持仓
holdings = set(get_holdings(context))
#计算买入和卖出标的
to_buy = stocks - holdings
to_sell = holdings - stocks
to_buy2= stocks - holdings
#卖
for stock in to_sell:
if bar_dict[stock].suspended == False:
order_target_percent(stock , 0)
#买
if len(to_buy) == 0:
return
to_buy = get_trading_stocks(to_buy, context, bar_dict)
cash = context.portfolio.cash
total_value=context.portfolio.total_value
if len(to_buy) >0:
average_value = total_value *0.025
if average_value > total_value/len(to_buy):
average_value = total_value/len(to_buy)
for stock in to_buy:
if (bar_dict[stock].suspended == False)and(context.portfolio.cash>average_value):
order_target_value(stock, average_value)
# IF88是沪深300指数期货主力连续合约
# 开一手沪深300主力连续合约 IF88 ,保证金倍率为 1倍
if context.flag==True :
sell_open('IF88', 1)
context.flag=False
# 得到交易的股票
def get_trading_stocks(to_buy, context, bar_dict):
trading_stocks = []
for stock in to_buy:
if bar_dict[stock].suspended == False:
trading_stocks.append(stock)
return trading_stocks
# 持仓的股票
def get_holdings(context):
positions = context.portfolio.stock_account.positions
holdings = []
for position in positions:
if positions[position].quantity > 0:
holdings.append(position)
return holdings
def handle_bar(context, bar_dict):
# TODO: 开始编写你的算法吧!
pass