[量化-004]米矿的第二个程序--多因子组合投资对冲

多因子,就是多个指标,指标就是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   
发布了448 篇原创文章 · 获赞 115 · 访问量 53万+

猜你喜欢

转载自blog.csdn.net/u011539200/article/details/103478150