程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长

+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

指数增强是什么意思?(附:策略源码)

发布于2019-08-05 18:35     阅读(1843)     评论(0)     点赞(3)     收藏(4)


指数增强是什么意思?

​ 指数增强策略并不是被动的跟踪某个指数波动,而是采用量化增强模型,利用多因子alpha模型预测股票超额回报,同时力求进行有效的风险控制、降低交易成本、优化投资组合。指数增强策略不会对跟踪标的成分股进行完全复制,而是会对部分看好的股票增加权重,不看好的股票则减少权重,甚至完全去掉。通过对交易成本模型的不断监测,尽可能让交易成本降到最小。综合来看,就是既做到超额收益,又控制主动风险。

策略实现(基于掘金量化平台)

策略思想

• 本策略以0.8为初始权重跟踪指数标的沪深300中权重大于0.35%的成份股。

• 个股所占的百分比为:(0.8 X 成份股权重) /选择的成分股权重总和 X 100%。

• 然后根据个股是否连续上涨5天;连续下跌5天,来判定个股是否为强势股/弱势股,并对其把权重由0.8调至1.0或0.6

策略主要步骤实现

获取沪深300成分股及信息

stock300 = get_history_constituents(index='SHSE.000300', 

start_date=last_day,end_date=last_day)[0]['constituents']

获取指数成分股可调用函数get_history_constituents或者get_constituents,返回值类型为list[dict],字典的键为股票代码,值为所占权重。这里调用get_history_constituents是因为再回测时需要获取上一交易日的成分股,而get_constituents只能获取最新的成分股:

• index需要设置获取指数的代码。

• start_dateend_date需设置获取成分股的开始与结束日期。

订阅数据

subscribe(symbols=stock300_symbol, frequency='1d', count=5, wait_group=True)

订阅数据需要在定义init函数里面设置,并调用subscribe函数,这里注意,我们需要通过计算前三十根bars来作为开平仓的标准,并在当前bar上做出开平仓操作,所以需要获取31根bar:

• symbols 需要设置订阅的标的代码。

• frequency需设置订阅数据的周期级别,这里设置1d 表示以一天为周期。

• count需要设置获取的bar的数量

数据获取

recent_data = context.data(symbol=symbol, frequency='1d', count=5, fields='close')['close'].tolist()

订阅数据之后,需要获取已经订阅的数据来进行操作,这时需调用context.data函数:

• symbols 需要设置订阅的标的代码。

• frequency需设置订阅数据的周期级别,这里设置1d表示以一天为周期。

• count需要设置获取的bar的数量

• fields需要设置返回值的种类

获取持仓信息

position = context.account().position(symbol=symbol, side=PositionSide_Long)

在判断平仓或者加仓条件时,需要获取持仓信息,这就需要调用context.account().position函数:

• symbols 需要设置订阅的标的代码。

• side需要设置持仓方向,有PositionSide_LongPositionSide_Short两个选择。

回测报告

分析

​ 我们选取了2017年10月至2017年12月作为回测周期,可以看出:

• 胜率(具有盈利的平仓次数与总平仓次数之比)达到了66%。

• 卡玛比率(年化收益率与历史最大回撤之比)是使用最大回撤率来衡量风险。采用最大回撤率来衡量风险,关注的是最极端的情况。卡玛比率越高表示策略承受每单位最大损失获得的报酬越高。在这里卡玛比率达到了6.7。

• 夏普比率(年化收益率减无风险收益率的差收益波动率之比)达到2.77。

• 策略收益曲线与沪深三百指数具有很大相关性,指数增强策略的关键点在于选出成分股中优质的股票,以达到增强指数收益的目的。

附:指数增强策略源码

# coding=utf-8
from __future__ import print_function, absolute_import, unicode_literals

import numpy as np
from gm.api import *
from pandas import DataFrame

'''
本策略以0.8为初始权重跟踪指数标的沪深300中权重大于0.35%的成份股.
个股所占的百分比为(0.8*成份股权重)*100%.然后根据个股是否
连续上涨5天;连续下跌5天
来判定个股是否为强势股/弱势股,并对其把权重由0.8调至1.0或0.6
回测数据为:SHSE.000300中权重大于0.35%的成份股
回测时间为:2017-07-01 08:50:00到2017-10-01 17:00:00
'''


def init(context):
    # 资产配置的初始权重,配比为0.6-0.8-1.0
    context.ratio = 0.8
    # 获取沪深300当时的成份股和相关数据
    stock300 = get_history_constituents(index='SHSE.000300', start_date='2017-06-30', end_date='2017-06-30')[0][
        'constituents']
    stock300_symbol = []
    stock300_weight = []

    for key in stock300:
        # 保留权重大于0.35%的成份股
        if (stock300[key] / 100) > 0.0035:
            stock300_symbol.append(key)
            stock300_weight.append(stock300[key] / 100)

    context.stock300 = DataFrame([stock300_weight], columns=stock300_symbol, index=['weight']).T
    context.sum_weight = np.sum(stock300_weight)
    print('选择的成分股权重总和为: ', context.sum_weight)
    subscribe(symbols=stock300_symbol, frequency='1d', count=5, wait_group=True)


def on_bar(context, bars):
    # 若没有仓位则按照初始权重开仓
    for bar in bars:
        symbol = bar['symbol']
        position = context.account().position(symbol=symbol, side=PositionSide_Long)
        if not position:
            buy_percent = context.stock300['weight'][symbol] / context.sum_weight * context.ratio
            order_target_percent(symbol=symbol, percent=buy_percent, order_type=OrderType_Market,
                                 position_side=PositionSide_Long)
            print(symbol, '以市价单开多仓至仓位:', buy_percent * 100)
        else:
            # 获取过去5天的价格数据,若连续上涨则为强势股,权重+0.2;若连续下跌则为弱势股,权重-0.2
            recent_data = context.data(symbol=symbol, frequency='1d', count=5, fields='close')['close'].tolist()
            if all(np.diff(recent_data) > 0):
                buy_percent = context.stock300['weight'][symbol] / context.sum_weight * (context.ratio + 0.2)
                order_target_percent(symbol=symbol, percent=buy_percent, order_type=OrderType_Market,
                                     position_side=PositionSide_Long)
                print('强势股', symbol, '以市价单调多仓至仓位:', buy_percent * 100)
            elif all(np.diff(recent_data) < 0):
                buy_percent = context.stock300['weight'][symbol] / context.sum_weight * (context.ratio - 0.2)
                order_target_percent(symbol=symbol, percent=buy_percent, order_type=OrderType_Market,
                                     position_side=PositionSide_Long)
                print('弱势股', symbol, '以市价单调多仓至仓位:', buy_percent * 100)


if __name__ == '__main__':
    '''
    本策略基于掘金量化交易平台 网址:www.myquant.cn
    strategy_id策略ID,由系统生成
    filename文件名,请与本文件名保持一致
    mode实时模式:MODE_LIVE回测模式:MODE_BACKTEST
    token绑定计算机的ID,可在系统设置-密钥管理中生成
    backtest_start_time回测开始时间
    backtest_end_time回测结束时间
    backtest_adjust股票复权方式不复权:ADJUST_NONE前复权:ADJUST_PREV后复权:ADJUST_POST
    backtest_initial_cash回测初始资金
    backtest_commission_ratio回测佣金比例
    backtest_slippage_ratio回测滑点比例
    '''
    run(strategy_id='c722244f-eaa9-11e7-8618-9cd21ef04ea9',
        filename='指数增强.py',
        mode=MODE_BACKTEST,
        token='c395247a76e8a5caeee699d668d6f550213bc418',
        backtest_start_time='2017-10-01 08:50:00',
        backtest_end_time='2017-12-01 17:00:00',
        backtest_adjust=ADJUST_PREV,
        backtest_initial_cash=10000000,
        backtest_commission_ratio=0.0001,
        backtest_slippage_ratio=0.0001)

来源:掘金量化 , myquant.cn

推荐阅读:

学习Python量化有哪些书籍?这里有一份书单送给你

量化交易领域最重要的10本参考书推荐!

配对交易—这个股票策略曾年赚5000万美元

一个量化策略师的自白(好文强烈推荐)

网格交易法,一个不容易亏钱的投资策略(附源码)

市面上经典的量化交易策略都在这里了!(源码)

 

 

 

 



所属网站分类: 技术文章 > 博客

作者:jiem

链接:https://www.pythonheidong.com/blog/article/6321/401dacfe0ebec779a3d3/

来源:python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

3 0
收藏该文
已收藏

评论内容:(最多支持255个字符)