跨品种套利

钢材生产流程大致分为三个阶段,分别为炼铁、炼钢和轧钢,生产成本主要包括原料成本、能源成本、人工成本、折旧和财务成本等。从原材料上来看, 生产1吨螺纹钢大致需要1.6吨铁矿石和0.5吨焦炭。因此,我们可以通过期货市场来大致模拟钢厂的生产过程,通过结合相关品种在期货市场的利润以及现货市场供需基本面数据,把握品种间的套利机会。通过成本估算,当前阶段:

螺纹钢成本≈1.6×铁矿石+0.5×焦炭+加工成本
利润≈螺纹钢期货价格-螺纹钢成本
炼铁、炼钢和轧钢三个阶段的总加工费大概在1100元左右。下图是2013.10-2016.7虚拟钢厂利润走势,在-200~300的范围内波动,利润中枢在100左右。

从价格走势图来看,利润走势不可能持续维持在高位或低位。这是因为,当利润达到极高值时,一方面钢厂会加速生产,供给增加则价格降低,另一方面铁矿石,焦炭等原材料价格会上涨,从而压缩利润空间;当利润达到极低值时,一方面钢厂会因持续亏损而减产,产量减少将支撑价格,另一方面上游企业议价能力更弱,原材料价格承压走低,从而使利润逐渐回升。当盘面利润超过300元时,可以做空利润,即卖螺纹,买铁矿石和焦炭,当盘面利润低于200元时,又可以做多利润,即买螺纹,卖铁矿石和焦炭。

首先,从产业结构计算产出比,比如螺纹:铁矿:焦炭=1吨:1.6吨:0.5吨;其次,按照合约规定的实际数量的1:1来确定,当前螺纹:铁矿:焦炭=1:10:10(螺纹期货合约为10吨/手,铁矿和焦炭期货合约均为100吨/手。最后,确定套利比例也需要考虑各品种的波动率的不同。综合上述因素,这样大致可以确定螺纹、铁矿、焦炭三者的手数配比为20:3:1。初始资金设为15w。

合约选取:

螺纹,铁矿,焦炭主力合约
策略逻辑:

当盘面利润高于300时,做空螺纹,做多铁矿石与焦炭;当盘面利润低于100时,若螺纹有空仓,则平掉所有仓位。
当盘面利润低于-200时,做多螺纹,做空铁矿石与焦炭;当盘面利润高于100时,若螺纹有多仓,则平掉所有仓位。
当主力切换时,平掉所有仓位
初始资金:

30w
回测时间:

自铁矿石品种上市以来
universe = [‘RBM0’, ‘IM0’, ‘JM0’] # 策略期货合约
start = ‘2013-11-01’ # 回测开始时间
end = ‘2016-11-18’ # 回测结束时间
capital_base = 300000 # 初试可用资金
refresh_rate = 1 # 调仓周期
freq = ‘d’ # 调仓频率:m-> 分钟;d-> 日

marg

diff = deque([], maxlen=10)

def initialize(futures_account): # 初始化虚拟期货账户,一般用于设置计数器,回测辅助变量等。
futures_account.symbol0 = ‘RB1405’
futures_account.symbol1 = ‘I1405’
futures_account.symbol2 = ‘J1405’
pass

def handle_data(futures_account): # 回测调仓逻辑,每个调仓周期运行一次,可在此函数内实现信号生产,生成调仓指令。
long_position_0 = futures_account.position.get(futures_account.symbol0, dict()).get(‘long_position’, 0)
short_position_0 = futures_account.position.get(futures_account.symbol0, dict()).get(‘short_position’, 0)

long_position_1 = futures_account.position.get(futures_account.symbol1, dict()).get('long_position', 0)
short_position_1 = futures_account.position.get(futures_account.symbol1, dict()).get('short_position', 0)


long_position_2 = futures_account.position.get(futures_account.symbol2, dict()).get('long_position', 0)
short_position_2 = futures_account.position.get(futures_account.symbol2, dict()).get('short_position', 0)

if get_symbol(universe[0]) != futures_account.symbol0 or get_symbol(universe[1]) != futures_account.symbol1 or get_symbol(universe[2]) != futures_account.symbol2:
    if long_position_0 != 0:
        # print futures_account.current_date, '主力更换, 平仓'
        order(futures_account.symbol0, -long_position_0, 'close')
        order(futures_account.symbol1, short_position_1, 'close')
        order(futures_account.symbol2, short_position_2, 'close')


    if short_position_0 != 0:
        # print futures_account.current_date, '主力更换, 平仓'
        order(futures_account.symbol0, short_position_0, 'close')
        order(futures_account.symbol1, -long_position_1, 'close')
        order(futures_account.symbol2, -long_position_2, 'close')

    futures_account.symbol0 = get_symbol(universe[0])
    futures_account.symbol1 = get_symbol(universe[1])
    futures_account.symbol2 = get_symbol(universe[2])
else:
    futures_account.symbol0 = get_symbol(universe[0])
    futures_account.symbol1 = get_symbol(universe[1])
    futures_account.symbol2 = get_symbol(universe[2])


    close_hist0 = get_symbol_history(symbol=futures_account.symbol0, field=['closePrice'], time_range=1)
    close_hist1 = get_symbol_history(symbol=futures_account.symbol1, field=['closePrice'], time_range=1)
    close_hist2 = get_symbol_history(symbol=futures_account.symbol2, field=['closePrice'], time_range=1)


    close0 = np.array(close_hist0[futures_account.symbol0]['closePrice'])[-1]
    close1 = np.array(close_hist1[futures_account.symbol1]['closePrice'])[-1]
    close2 = np.array(close_hist2[futures_account.symbol2]['closePrice'])[-1]

    if short_position_0  == 0 and close0 - 1.6 * close1 - 0.5 * close2 - 1100 > 300:
        # print futures_account.current_date,  '做空螺纹'
        # print close0 - 1.6 * close1 - 0.5 * close2 - 1100
        order(futures_account.symbol0, -20, 'open')
        order(futures_account.symbol1, 3, 'open')
        order(futures_account.symbol2, 1, 'open')

    if long_position_0  == 0 and close0 - 1.6 * close1 - 0.5 * close2 - 1100 < -250:
        # print futures_account.current_date,  '做多螺纹'
        # print close0 - 1.6 * close1 - 0.5 * close2 - 1100
        order(futures_account.symbol0, 20, 'open')
        order(futures_account.symbol1, -3, 'open')
        order(futures_account.symbol2, -1, 'open')

    # 平仓 
    if close0 - 1.6 * close1 - 0.5 * close2 - 1100 < 100:
        if short_position_0 != 0:
            # print futures_account.current_date, '平仓'
            # print close0 - 1.6 * close1 - 0.5 * close2 - 1100
            order(futures_account.symbol0, short_position_0, 'close')
        if long_position_1 != 0:
            order(futures_account.symbol1, -long_position_1, 'close')
        if long_position_2 != 0:
            order(futures_account.symbol2, -long_position_2, 'close')
    if close0 - 1.6 * close1 - 0.5 * close2 - 1100 > 100:
        if long_position_0 != 0:
            # print futures_account.current_date, '平仓'
            # print close0 - 1.6 * close1 - 0.5 * close2 - 1100
            order(futures_account.symbol0, short_position_0, 'close')
        if short_position_1 != 0:
            order(futures_account.symbol1, -long_position_1, 'close')
        if short_position_2 != 0:
            order(futures_account.symbol2, -long_position_2, 'close')
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值