数据
使用的数据IF合约的日数据:
链接:https://pan.baidu.com/s/1XGfITsSWdP_c1_wFepUs0A
提取码:b880
主力合约计算规则:
1. 每个品种只选出唯一一个主力合约
2. 日成交量和持仓量都为最大的合约,确定为新的主力合约,于下一交易日进行指向切换
3. 按照第二条规定产生新的主力合约之前,维持原来的主力合约不变
4. 若出现当前主力合约的成交量和持仓量都不是最大的情况,当前指向合约在下一个交易日必须让出主力合约身份,新主力指向成交量最大的合约
计算方法:
1. 读入所有IF合约的日数据,合并到一张表中
2. 按日期进行分组,每组中的数据为当天所有在交易的合约
3. 对每组的数据按成交量和持仓量进行降序排序,排序的优先级为先成交量再持仓量
4. 取每组的第一行数据拼成一个新的表
5. 对新生成的表进行检查,看是否存在合约不连续的情况,检查方法为:
5.1 对表按时间进行升序排序
5.2 按合约进行分组
5.3 检查前一组的所有日期都在早于后一组最早的日期(也就是后一组第一行的日期)
开始计算
初始数据路径 ./if_list/
import os
import numpy as np
import pandas as pd
1. 读入所有的IF合约数据,合并成一张表
dir = r'./if_list/'
file_list = os.listdir(dir)
all_df = None
for file_name in file_list:
ticker = file_name[0:-4]
file_path = dir + file_name
df = pd.read_csv(file_path,encoding='utf-8',header=0,names=['date','open','close','low','high','volume','money','factor','high_limit','low_limit','avg','pre_close','paused','open_interest'])
df['ticker'] = ticker
if all_df is None:
all_df = df
else:
all_df = pd.concat([all_df,df])
2. 按日期分组,取每组成交量和持仓量最大的一行组成一个新表
# 这个方法是对 成交量 和 持仓量 进行降序排序(即由大到小),排序优先级为先成交量后持仓量;排序后把第一行返回
def get_biggest_openinterest(x):
df = x.sort_values(['volume','open_interest'],ascending=[False,False])
return df.iloc[0,:]
# 对所有合约合成的大表 all_df 按日期进行分组,每个日期的组里提取出成交量和持仓量最大的行 组成一个新的表 res_pd
all_df['date'] = pd.to_datetime(all_df['date'])
all_df.sort_values(by='date')
res_pd = all_df.groupby('date').apply(get_biggest_openinterest)
3. 检查合约是否连续
# 对表 res_pd 进行升序排列(即有小到大)
res_pd.sort_index(inplace=True)
# 对表 res_pd 按合约进行分组
res_group = res_pd.groupby('ticker')
# 提取每组的日期存入列表,然后对日期进行校验,确保每一组最早的那个日期都不会早于前一组的所有的日期,满足这个条件说明是连续合约
results_list = []
for name,group in res_group:
results_list.append(group['date'].tolist())
for i in range(len(results_list)-1):
pre_list = results_list[i]
now_first = results_list[i+1][0]
for item in pre_list:
if item >= now_first:
print(item,now_first)
break
至此,res_pd是if的主力合约