大类资产配置-长期均衡策略(年化收益8.83\%)
之前ptrade的账号销号了,导致很多策略源码丢了。翻了翻在其他平台写的代码,和ptrade的结构差不多,供大家参考。也欢迎大家讨论。
一、策略原理:
1、黄金ETF、国债ETF、300ETF和纳指ETF月度调仓,长期均衡配置
2、每月第一个交易日调仓
3、根据300指数历史分位决定仓位:
300指数分位数 | 黄金ETF | 国债ETF | 300ETF | 纳指ETF |
---|---|---|---|---|
大于80 | 37% | 37% | 13% | 13% |
[40,80] | 33% | 33% | 17% | 17% |
[20,40) | 29% | 29% | 21% | 21% |
[10,20) | 25% | 25% | 25% | 25% |
[0,10) | 21% | 21% | 29% | 29% |
二、回测结果:
三、源码(共参考学习思路,用于ptrade需要修改部分函数名):
# 股票策略模版
# 初始化函数,全局只运行一次
def init(context):
# 设置基准收益:沪深300指数
set_benchmark('000300.SH')
# 打印日志
log.info('策略开始运行,初始化函数全局只运行一次')
# 设置股票每笔交易的手续费为万分之二(手续费在买卖成交后扣除,不包括税费,税费在卖出成交后扣除)
set_commission(PerShare(type='stock',cost=0.0002))
# 设置股票交易滑点0.5%,表示买入价为实际价格乘1.005,卖出价为实际价格乘0.995
set_slippage(PriceSlippage(0.005))
# 设置日级最大成交比例25%,分钟级最大成交比例50%
# 日频运行时,下单数量超过当天真实成交量25%,则全部不成交
# 分钟频运行时,下单数量超过当前分钟真实成交量50%,则全部不成交
set_volume_limit(0.25,0.5)
# 设置要操作的标的:
context.security = ['511010.SH','518880.SH','510300.SH','513100.SH']
# 回测区间、初始资金、运行频率请在右上方设置
# 记录最近一次调仓日期
g.modify_date=get_datetime().date()
#每日开盘前9:00被调用一次,用于储存自定义参数、全局变量,执行盘前选股等
def before_trading(context):
# 获取日期
date = get_datetime().strftime('%Y-%m-%d %H:%M:%S')
# 打印日期
# log.info('{} 盘前运行'.format(date))
## 开盘时运行函数
def handle_bar(context, bar_dict):
# 获取时间
time = get_datetime().strftime('%Y-%m-%d %H:%M:%S')
# 打印时间
log.info('{} 盘中运行'.format(time))
if is_change_date():
log.info("==============调仓日==============")
pct = get_his_pct("000300.SH")
target_pct = 0.17
if pct > 80:
target_pct = 0.13
if pct<40:
target_pct = 0.21
if pct<20:
target_pct = 0.25
if pct<10:
target_pct = 0.29
target_pct_main = (1-target_pct*2)/2
log.info("pct:",pct)
log.info("rp:",target_pct)
log.info("rpm:",target_pct_main)
g.modify_date=get_datetime().date()
for stock_code in context.security:
if stock_code in ['511010.SH','518880.SH']:
order_id = order_target_percent(stock_code,target_pct_main)
if stock_code in ['510300.SH','513100.SH']:
order_id = order_target_percent(stock_code,target_pct)
## 收盘后运行函数,用于储存自定义参数、全局变量,执行盘后选股等
def after_trading(context):
# # 获取时间
time = get_datetime().strftime('%Y-%m-%d %H:%M:%S')
# # 打印时间
# log.info('{} 盘后运行'.format(time))
# log.info('一天结束')
## 判断当日是不是需要调仓
def is_change_date():
the_day = get_datetime().date()
delta_day = (the_day - g.modify_date).days
if the_day.day == 1 or delta_day>=31:
return True
else:
return False
## 获取指定标的的历史分位数
def get_his_pct(stock_code):
price = history(stock_code, ['close'], 1800, '1d', True, 'pre', is_panel=1)['close']
last = price[-1]
price_sorted = sorted(price)
position = 0
for i, value in enumerate(price_sorted):
if value >= last:
position = i+1
break
percentile_rank = (position / len(price)) * 100
return percentile_rank
2024-12-09 14:17
2024-12-09 12:03