感谢分享!我从去年以来也在做IC贴水的套利,最近在想怎么能规避18年那种下跌,远期贴水减少的情况,想能否开2手合约,最近月和最远月,然后每个月滚动替换,始终持有最近和最远的两个
(二)100万资金开仓2手IC的回测结果
从图中可见,还是和预期一样。与我前面文章中的结论是一脉相承的。
$上证指数(SH000001)$ $中证500(SH000905)$ $沪深300(SH000300)$
最后,代码文本如下:
#
# 股指期货贴水收益回测
#
# 策略:始终持有股指期货IC,吃贴水;每月初,卖出当月合约,买入下月合约,实现移仓
# 回测平台:米筐量化 网页链接
# 作者微信公众号:北京耳东陈
# 雪球主页: 网页链接
#
import datetime
from dateutil.relativedelta import relativedelta
# 在这个方法中编写任何的初始化逻辑。context对象将会在你的算法策略的任何方法之间做传递。
def init(context):
# context内引入全局变量
context.first_day = True
context.month = 0
context.trading_days = -99
# 实时打印日志
#logger.info("RunInfo: {}".format(context.run_info))
# before_trading此函数会在每天交易开始前被调用,当天只会被调用一次
def before_trading(context):
pass
# 返回下个月的合约代码
def next_month_code(context, future_name):
d = context.now + relativedelta(months=+1)
return future_name + d.strftime("%y%m")
# 始终持有股指期货合约,每月移仓只下月合约
# 月初换下月,如:2月初,换3月合约
def holding(context, bar_dict, future_name, stock):
# 持有的合约数量;为了便于测试,假设100万本金,开仓 NUMBER_OF_CONTRACT 手
NUMBER_OF_CONTRACT = 2
# 获取下个月的合约代码
future_code = next_month_code(context, future_name)
# 初始状态是:持仓
# 程序运行的第一天,开仓买入
if context.first_day:
buy_open(future_code, NUMBER_OF_CONTRACT)
print("初始开仓买入", future_code, "买入价格", current_snapshot(future_code).last)
context.first_day = False
context.month = context.now.month
return
# 进入一个新的自然月
if context.now.month != context.month:
context.month = context.now.month
context.trading_days = 1
return
# 交易日计数
context.trading_days += 1
# 每月的第2个交易日移仓至下月合约
if context.trading_days == 2:
# 平仓现有的当月合约
for fid in context.future_account.positions:
sell_close(fid, NUMBER_OF_CONTRACT)
# 开仓下月合约
buy_open(future_code, NUMBER_OF_CONTRACT)
future_price = current_snapshot(future_code).last
print("开仓买入", future_code,
"买入价格", future_price,
"买入时的贴水", "%.2f" % (current_snapshot(stock).last - future_price))
pass
# 你选择的证券的数据更新将会触发此段逻辑,例如日或分钟历史数据切片或者是实时数据切片更新
def handle_bar(context, bar_dict):
# 持有股指期货IC
holding(context, bar_dict, "IC", "000905.XSHG")
# 也可以回测持有股指期货IH与IF,但由于后两种贴水少,超额收益少于持有IC
#holding(context, bar_dict, "IH", "000016.XSHG")
#holding(context, bar_dict, "IF", "000300.XSHG")
# after_trading函数会在每天交易结束后被调用,当天只会被调用一次
def after_trading(context):
pass