无法统一的合约参数
合约参数中的保证金比例率和手续费是最难搞定的。
- 保证金率:交易所有统一的保证金率,期货公司可以在交易所的基础上加收保证金,这些东西也是可以谈判的,导致因人而异的保证金率,但这就是现实。
- 手续费分两种:1)按手数计算的,开仓手续费,平仓手续费和平今仓手续费;2)按交易金额计算的,开仓手续费率,平仓手续费率和平今仓手续费率。
## 合约参数中最无法统一的是保证金比例和手续费率。
虽然交易所在某个时段内会统一发布上线合约的保证金率和手续费(率),可是这些信息对普通投资者没有多大意义,因为不同的期货公司出于安全的考虑,会在交易所发布合约保证金率的基础上加收额外的比例的保证金,另外由于投资者找到的不同经纪人、不同的期货公司,会得到不同的交易手续费,另外即使你找到同一家期货公司的同一个经纪人,也会因为统治者资金实力不同,谈判技巧的不同而造成交易手续费(率)的不同。这导致你不要通话网络从服务器获得交易合约的保证金比例和手续费率,因为他们通常是提供你开户的网址上公布的,或者文件,手机短信的方式通知的。
这对我们的策略在计算账户剩余可用资金方面带来了巨大的不便!怎么办?方法总是比困难多!
合约参数维护
本贴介绍一种本人研究出来的一种办法:
1)手工创建合约参数文件(格式为json文件),内容包含:合约代码,市场,合约名称,类别,多头保证金率,空头保证金率,开仓手续费(率),平仓手续费(率),平今仓手续费(率)。
2)创建合约参数类,它的功能是从json文件夹中加载合约参数到合约参数字典,然后为外部提供合约参数查询功能。
3)当合约保证金率或者手续费(率)发生变化时,及时手动修改该json的内容就可以。
实现代码
[.vntrader]\contract_param.json文件内容
{
"rb2010.SHFE": {
"inverse":false,
"margin_rate": 0.15,
"open_fee":{"费率":0.001},
"close_fee":{"费率":0.001},
"close_today_fee":{"费率":0.001}
},
"ag2012.SHFE": {
"inverse":false,
"margin_rate": 0.15,
"open_fee":{"费率":0.005},
"close_fee":{"费率":0.005},
"close_today_fee":{"费率":0.005}
},
"ap2012.SHFE": {
"inverse":false,
"margin_rate": 0.15,
"open_fee":{"每手":5},
"close_fee":{"每手":5},
"close_today_fee":{"每手":5}
},
"al2010.SHFE": {
"inverse":false,
"margin_rate": 0.15,
"open_fee":{"每手":3},
"close_fee":{"每手":3},
"close_today_fee":{"每手":0}
}
}
vnpy\usertools\contract_param.py文件内容
from dataclasses import dataclass
from enum import Enum
from typing import Tuple,List,Dict,Union,Set,Sequence,Optional
from vnpy.trader.utility import load_json, save_json, extract_vt_symbol
from vnpy.trader.constant import Direction, Exchange, Interval, Offset, Status,Product, OptionType, OrderType
import datetime
import rqdatac as rq
from rqdatac.utils import to_date
''' 获得上市日期 '''
def get_listed_date(symbol:str):
info = rq.instruments(symbol)
return to_date(info.listed_date)
''' 获得交割日期 '''
def get_de_listed_date(symbol:str):
info = rq.instruments(symbol)
return to_date(info.de_listed_date)
def str2date(date_str:str):
'''
日期字符串转化到datetme.date()
'''
return datetime.datetime.strptime(date_str,"%Y-%m-%d").date()
class FeeType(Enum):
"""
Commission fee type.
"""
LOT = "每手" # 手续费 :LOT per lot
RATE = "费率" # 手续费率 :RATE%
@dataclass
class ContractParameter():
"""
合约参数,包含:
合约代码,市场,合约名称,类别,
多头保证金率,空头保证金率,
开仓手续费(率),平仓手续费(率),平今仓手续费(率),
"""
symbol:str # 合约代码
exchange:Exchange # 交易所
name:str # 合约名称
product:Product # 类别
listed_date:datetime.date # 上市日期
maturity_date:datetime.date # 到期日期
de_listed_date:datetime.date # 交割日期
size : int # 合约乘数
# 以下来自手工json文件
inverse:bool # 反向合约
margin_rate:float # 保证金率(%)
# FeeType.LOT: 手续费;FeeType.RATE:手续费率(%)
open_fee:Tuple[FeeType,float] # 开仓手续费(率)
close_fee:Tuple[FeeType,float] # 平仓手续费(率)
close_today_fee:Tuple[FeeType,float] # 平今仓手续费(率)
def __post_init__(self):
""" """
self.vt_symbol = f"{self.symbol}.{self.exchange.value}"
class ContractParameters():
"""
合约参数类,从json文件读取合约参数
注意:对包含保证金率和手续费(率)的json文件的处理只有加载操作,没有修改和删除操作。
修改和删除合约参数操作通过手工操作就可以了。
"""
contract_parameters_file = "contract_param.json"
contract_parameters:Dict[str,ContractParameter] = {}
def __init__(self):
self.load_contract_paramters()
def load_contract_paramters(self):
""" 读取contract_param.json中的合约参数列表 """
parameters = load_json(self.contract_parameters_file)
for vt_symbol,param in parameters.items():
symbol,exchange = extract_vt_symbol(vt_symbol)
contract = rq.instruments(symbol.upper())
# print(f"{contract}")
cparam = ContractParameter(
symbol = symbol,
exchange = exchange,
product = contract.product,
name = contract.symbol,
listed_date = str2date(contract.listed_date),
maturity_date = str2date(contract.maturity_date),
de_listed_date = str2date(contract.de_listed_date),
size = contract.contract_multiplier,
inverse = param["inverse"],
margin_rate = param['margin_rate'],
open_fee = param['open_fee'],
close_fee = param['close_fee'],
close_today_fee = param.get("close_today_fee",{})
)
self.contract_parameters[cparam.vt_symbol] = cparam
def get_paramter(self,vt_symbol:str):
return self.contract_parameters.get(vt_symbol,{})
if __name__ == "__main__":
rq.init('18096678138','Rq131466',("rqdatad-pro.ricequant.com",16011))
contract_parameters = ContractParameters()
# print(f"{contract_parameters.contract_parameters}")
vt_symbols = ['rb2010.SHFE','ag2012.SHFE','ap2012.SHFE','al2010.SHFE','cu2010.SHFE']
for vt_symbol in vt_symbols:
param = contract_parameters.get_paramter(vt_symbol)
print(f"\n{vt_symbol}'s contract parameters: \n{param}")
# last_trade_date = rq.get_latest_trading_date()
# instruments = rq.all_instruments(type='Future',date=last_trade_date,market='cn')
# print(f"{last_trade_date} {type(instruments)} ")
# for idx,instrument in instruments.iterrows():
# # print(f"{type(instrument)} {instrument}")
# order_book_id = instrument['order_book_id']
# symbol = instrument['symbol']
# trading_hours = instrument['trading_hours']
# # print(f"{order_book_id,symbol,trading_hours}")
# if trading_hours.find("09:01-10:15") < 0:
# print(f"合约代码:{order_book_id} 名称:{symbol} 交易时间段:{trading_hours}")
# print(f"finished")
测试结果
contract_param.py文件中自带测试代码,直接运行可以得到如下结果:
rb2010.SHFE's contract parameters:
ContractParameter(symbol='rb2010', exchange=<Exchange.SHFE: 'SHFE'>, name='螺纹钢2010', product='Commodity', listed_date=datetime.date(2019, 10, 16), maturity_date=datetime.date(2020, 10, 15), de_listed_date=datetime.date(2020, 10, 15), size=10.0, inverse=False, margin_rate=0.15, open_fee={'费率': 0.001}, close_fee={'费率': 0.001}, close_today_fee={'费率': 0.001})
ag2012.SHFE's contract parameters:
ContractParameter(symbol='ag2012', exchange=<Exchange.SHFE: 'SHFE'>, name='白银2012', product='Commodity', listed_date=datetime.date(2019, 12, 17), maturity_date=datetime.date(2020, 12, 15), de_listed_date=datetime.date(2020, 12, 15), size=15.0, inverse=False, margin_rate=0.15, open_fee={'费率': 0.005}, close_fee={'费率': 0.005}, close_today_fee={'费率': 0.005})
ap2012.SHFE's contract parameters:
ContractParameter(symbol='ap2012', exchange=<Exchange.SHFE: 'SHFE'>, name='鲜苹果2012', product='Commodity', listed_date=datetime.date(2019, 12, 16), maturity_date=datetime.date(2020, 12, 14), de_listed_date=datetime.date(2020, 12, 14), size=10.0, inverse=False, margin_rate=0.15, open_fee={'每手': 5}, close_fee={'每手': 5}, close_today_fee={'每手': 5})
al2010.SHFE's contract parameters:
ContractParameter(symbol='al2010', exchange=<Exchange.SHFE: 'SHFE'>, name='铝2010', product='Commodity', listed_date=datetime.date(2019, 10, 16), maturity_date=datetime.date(2020, 10, 15), de_listed_date=datetime.date(2020, 10, 15), size=5.0, inverse=False, margin_rate=0.15, open_fee={'每手': 3}, close_fee={'每手': 3}, close_today_fee={'每手': 0})
cu2010.SHFE's contract parameters:
{}
1800定律:
在一个领域钻研超过1800小时,你就是专家!