股指期货合约的解读及交易参数的计算——julia回测
前言:
自己写代码进行回测的时候,在对期货进行交易仿真时,与股票的回测相比,需要注意更多的问题。
1、举例:需要买入股指期货对冲的时候:【某时点】需要做空【某股指期货】进行对冲,给定对冲的【合约价值】,如何通过当时的参数来计算需要准备多少资金?
需要考虑的因素:
【建仓时点的单位报价(比如当时沪深300股指的每点报价为5400)】
【交易方向(买涨,买跌,也就是多、空)】,多空的手续费率跟保证金可能不一样
【合约乘数】
【手续计算的类型】——例如:(1)依合约价值按比例收取,(2)按每手收取,(3)按每吨收取
【保证金(杠杆率)】
1.1、【可买的手数】 = 【指定的合约价值】 / 【合约乘数】 / 【单位报价】,然后再取floor值(向下取整)
1.2、【真实的合约价值】 = 【可买手数】×【合约乘数】×【单位报价】
1.3、手续费的计算方法,比较复杂,大概分成三种:按照【费率】、【每手】、【每股(点、吨...)】来计算。按【费率】计算的意思就是:【手续费】 = 【合约价值】×【费率】,其中费率又分为【做空的费率】以及【做多的费率】
1.3.1、按费率计算手续费:
【手续费】 = 【合约价值】 × 【(做多或者做空的)费率】
1.3.2、按照每手计算:
【手续费】 = 【可买手数】×【没收的收费标准】
1.3.3、按照每股(例如按照每吨)计算:
【手续费】= 【可买手数】×【合约乘数】×【每吨(股、点)收费标准】
一、股指期货介绍
《股指期货介绍》为转载,原帖地址来自证监会官网【http://www.csrc.gov.cn/xiamen/xxfw/mtzy/201003/t20100329_178834.htm】
股指期货交易的既不是商品也不是股指,而是一张除了价格之外都事先约定好了的合约,是一种标准化的协议。因而了解股指期货应该从了解它的合约设计开始。
“合约标的”,即中金所上市股指期货的标的物是沪深300股票价格指数,是由沪市和深市流通市值排名在前300 位的股票组成,相对沪证指数和深成指更能反映中国股市总体走势情况。
“合约价值”即合约的总价值等于合约乘数乘以股指期货点数。其中,指数每一个点代表一定的货币金额,这个固定金额就是“合约乘数”。沪深300 股指期货合约的固定乘数是300 元;如果合约总价再乘以保证金比例,就得到交易一手股指期货合约的“合约交易保证金数额”了。中金所当前的交易所保证金比率是12%。但实际交易中,期货公司还会在交易所保证金上加收3 — 5 个百分点,因此投资者最终保证金水平大致在15% —18%。“最小变动价位”是指股指期货合约的报价指数点的最小变化刻度,沪深 300 指数期货最小变动价位为0.2 个点。
“合约月份”指股指期货合约到期交割的月份。沪深300 指数在同一时间会有4份合约进行交易,分别是当月合约、下月合约以及最近两个季度月份合约;近月合约是投资者交易需求最大的合约,也是功能发挥最充分的合约,同时,稍远一点的季月合约比较适合中长期投资者的投资方式,同时也能够满足机构投资者为股票持仓进行长期保值的要求,减少在套期保值过程中因期货合约期限太短而频繁转仓的不便。这种兼顾远近的设计方式能够较好地满足市场各类投资者的参与需求。
交易时间,在一般交易日,股指期货开盘时间为 9 :15 -11:30 ,13:00 -15:15 。相比股票市场的交易时间,早开盘15分钟,晚收盘15分钟。这样设置的好处在于:早开15分钟,更充分的体现股指期货发现价格的作用,帮助现货市场在未开市前建立均衡价格,从而减低现货市场开市时的波幅。晚收15分钟,有利于减低现货市场收市时的波幅,在现货市场收市后,为投资者提供对冲工具,同时方便一些根据现货市场收市价作指标的套期保值盘。在到期交割日,即最后交易日交易时间,股指期货开盘时间为9:15 -11:30 ,13:00 -15:00。
“最低交易保证金”,投资者要想购买股票,必须要用100%的资金,而股指期货交易采用保证金制度,用较少的资金就可以买卖一手金额比保证金大几倍的合约。目前中金股指期货合约中拟定的一手合约,按最近沪深300指数的点位,乘以每点300元,则一手合约的价值就近94万元。按16%的保证金比例,买卖一手所需的资金得有15万元。
“最后交易日”,股指期货合约具有期限性,在进入到期日时会对合约持仓进行交割处理,在最后结算日进行“现金交割”结算,同时合约退出交易。注意各合约的到期日为合约月份的第3 个周五,遇法定节假日顺延。“每日价格最大波动限制”,我国股指期货采用涨跌停板制度,幅度为上一交易日结算价的10%。
二、股指期货合约介绍(以沪深300股指期货为例)
本部分摘自中国金融期货交易所网站 http://www.cffex.com.cn/hs300/(2021-07-03)
1、沪深300股指的介绍
【沪深300指数】是由上海和深圳证券市场中市值大、流动性好的300只A股作为样本编制而成的成份股指数,具有良好的市场代表性。沪深300指数是沪深证券交易所第一次联合发布的反映A股市场整体走势的指数。它的推出,丰富了市场现有的指数体系,增加了一项用于观察市场走势的指标,有利于投资者全面把握市场运行状况,也进一步为指数投资产品的创新和发展提供了基础条件。沪深300指数相关内容请参考中证指数有限公司官方网站http://www.csindex.com.cn。
2、沪深300股指期货合约表
沪深300股指期货合约表包含以下信息
合约标的: 沪深300指数
最低交易保证金: 合约价值的8%
合约乘数: 每点300元
最后交易日: 合约到期月份的第三个周五,遇国家法定假日顺延
报价单位: 指数点
交割日期: 同最后交易日
最小变动价位: 0.2点
交割方式: 现金交割
合约月份: 当月、下月及随后两个季月
交易代码: IF
交易时间: 上午:9:30-11:30,下午:13:00-15:00
上市交易所: 中国金融期货交易所
每日价格最大波动限制:上一个交易日结算价的±10%

3、沪深300股指合约信息表
合约代码 | 上市日 | 最后交易日 | 挂牌基准价
IF2107 | 20210524 | 20210716 | 5110.4
IF2108 | 20210621 | 20210820 | 5073.6
IF2109 | 20210118 | 20210917 | 5413.4
IF2112 | 20210419 | 20211217 | 4807.6
4、结算业务参数

三、回测时,期货相关的函数设计
1、品种合约费率信息表
不同证券类型,它们的【合约乘数】、【手续费类型】、【收费标准】各不相同

2、读取合约费率信息
"""
功能:读取合约的信息【费率类型,收费标准,合约乘数,杠杆率】
输入:
——————————————————————————————————————————————————————————————————————————————————
参数名字 | 参数类型 | 参数说明
----------------------------------------------------------------------------------
security = securities_type.股票 ,可选关键字参数 , 证券类型,股票、股指(股指期货)、期货(商品期货)
contract = "" ,可选关键字参数 , 合约标的,期货的标的,股票为空
direction = deal_dir.多 ,可选关键字参数 , 交易方向——多、空
ct = context ,可选关键字参数 , 回测参数对象
——————————————————————————————————————————————————————————————————————————————————
输出:
——————————————————————————————————————————————————————————————————————————————————
return (
measurement_per_share = measurement_per_share , #每股报价单位
fee_type = fee_type , #费率类型 fee_type
dealFeeRatio = dealFeeRatio , #收费标准
unit_per_hand = unit_per_hand , #每手的股数【合约乘数】
leverage = leverage , #杠杆率
)
——————————————————————————————————————————————————————————————————————————————————
"""
function get_security_contract_info(;
security = Main.context.securities_type.股票,
contract = "",
direction = Main.context.deal_dir.多,
ct = Main.context,
)
if security == ct.securities_type.股票
r = ct.security_contract_dict[ct.securities_type.股票]
elseif security == ct.securities_type.基金
r = ct.security_contract_dict[ct.securities_type.基金]
elseif security == ct.securities_type.期货
r = ct.security_contract_dict[ct.securities_type.期货][contract]
elseif security == ct.securities_type.股指
r = ct.security_contract_dict[ct.securities_type.股指][contract]
else
throw("get_secrity_contract_info(),证券类型$(security)有误")
end
measurement_per_share = r.报价单位 #报价单位,每股的计量单位,股、吨、克
fee_type = r.手续费类型
dealFeeRatio = r.交易手续费标准
unit_per_hand = r.合约乘数
leverage = begin #保证金率计算
if security in [ct.securities_type.股票, ct.securities_type.基金]
r.多头保证金
elseif security in [ct.securities_type.股指, ct.securities_type.期货]
if direction == ct.deal_dir.多
r.多头保证金
elseif direction == ct.deal_dir.空
r.空头保证金
else
throw("get_secrity_contract_info(),给定的【交易方向】$(direction)有错误")
end
end
end
return (
measurement_per_share = measurement_per_share,
fee_type = fee_type,
dealFeeRatio = dealFeeRatio,
unit_per_hand = unit_per_hand,
leverage = leverage,
)
end
举例:
security_type = "股指" #股指期货 ⭐⭐⭐⭐⭐⭐
stockID = "IF" #股票代码,合约代号 ⭐⭐⭐⭐⭐⭐
direction = "空" #交易方向 【多】、【空】⭐⭐⭐⭐⭐⭐
#读取合约信息 ci = contract info
ci = hc.get_security_contract_info(
security = security_type,
contract = stockID,
direction = direction,
)
ci |> println
运行结果:
measurement_per_share = "点", fee_type = "费率", dealFeeRatio = 2.3e-5, unit_per_hand = 300, leverage = 0.12)
3、其它函数的设计
如果交易里面有【底仓】或者【对冲仓】的时候,需要对【底仓】和【对冲仓】的【资金使用】情况以及【持仓情况】进行记录,此时只需要增加一组【资金表】、【持仓表】即可,不需要更改原有交易逻辑代码。
好比两个人合用一个证券帐号进行交易,实际上【交易逻辑】和【资金账号】、【交易持仓】用的都是一份,需要做的就是,对每个人的资金、交易、持仓另建一个账册进行记录。
"""
根据给定的交易id,判断当前的交易是否是底仓
id = 交易id,格式为:【证券代码】#【日期】#【交易批次序号】#【交易备注】
159987#2020-10-30#1#pt pt = 普通——普通仓
510630#2020-10-30#1#dc dc = 底仓——底仓
"""
function is_dicang(id::String)
id_ary = split(id,"#")
rtn = begin
if id_ary[4] == "dc"
true
else
false
end
end
end
"""
功能:建仓资金,买入耗费资金(没有算上手续费),带杠杆
股票、基金、期货适用
输入:
hands_can_buy ,能买的手数
unit_per_hand ,每手多少股
kc_price ,开仓价格(每股【点、吨】,多少钱)
leverage ,杠杆率
输出:
开仓投入的资金
"""
function get_deal_money_kc(hands_can_buy, unit_per_hand, kc_price, leverage)
hands_can_buy * unit_per_hand * kc_price * leverage
end
"""
功能:计算成交的合约金额[合约价值],如果是股票或者基金,则此处计算值为股票市值,如果股票建仓时调用,则为成交金额【不包含手续费】
输入:
hands_can_buy ,能买的手数
unit_per_hand ,每手多少股
kc_price ,开仓价格(每股【点、吨】,多少钱)
输出:
开仓时成交的合约的合约价值
"""
function get_contract_amount_kc(hands_can_buy, unit_per_hand, kc_price)
hands_can_buy * unit_per_hand * kc_price
end
"""
要买入给定【合约价值】的期货,需要准备多少钱【成交金额+交易费用】
期货适用
====in===
contract_amount , 要买入的市值 , 关键字参数 ,
kc_price , 买入的价格 , 关键字参数 ,
security_type , 证券类型 , 关键字参数 ,
stockID , 合约代码 , 关键字参数 ,
direction , 交易的方向 , 关键字参数 ,
====out====
"""
function get_dealMoneyFee_via_contractAmount(;
contract_amount = 0.0,
kc_price = 0.0,
security_type = "股指",
stockID = "IF",
direction = "空",
)
#读取合约信息 ci = contract info
ci = hc.get_security_contract_info(
security = security_type,
contract = stockID,
direction = direction,
)
#ci |> println
#计算可买手数
hands = hc.get_hands_via_contract_amount(
contract_amount,
kc_price,
ci.unit_per_hand,
)
value = hands * ci.unit_per_hand * kc_price #【可买手数】下的合约市值
money = value * ci.leverage #需要多少资金[不含手续费]
#println(" value:",value," dealFeeRatio:",ci.dealFeeRatio," fee_type:",ci.fee_type," unit_per_hand:",ci.unit_per_hand," leverage:",ci.leverage," hands:",hands)
fee = hc.get_kc_fee( #需要多少手续费
value,
ci.dealFeeRatio,
feeType = ci.fee_type,
unit_per_hand = ci.unit_per_hand,
leverage = ci.leverage,
hands_can_buy = hands,
)
all_money = money + fee #总计投入资金是多少
end