根据历史数据构建回归调整的连续期货合约
我正在学习Python,所以需要一些指导来解决这个问题。
我正在使用Quandl这个库来下载历史期货数据,比如(ESH2000, ESM2000, ESU2000, ESZ2000, ESH2001, ...., ESU2014)
。现在我想建立一个连续的、经过调整的合约,以便进行绘图和回测。
希望能得到一些建议,告诉我应该使用哪些库来完成这个任务(比如pandas、numpy、纯Python,或者其他库):
Quandl文件的数据结构如下:
Date, Open, High, Low, Last, Change, Settle, Volume, Prev. Day Open Interest
ESH2000 data:
3/1/2000 1372.25 1388.75 1371 1384.5 60887 29558
3/2/2000 1384.25 1390.5 1372.5 1385 62489 30059
3/3/2000 1384.75 1414.5 1383.5 1410.5 65432 29923
3/6/2000 1411 1412.75 1386.25 1395 59860 29549
3/7/2000 1394.5 1404.5 1351 1351.75 85263 31256
3/8/2000 1352.75 1376 1348.5 1366 73911 30916
3/9/2000 1367 1405 1357.5 1404 7153 28164
3/10/2000 1403.25 1415.5 1394.25 1399 3192 27549
3/13/2000 1398 1415.75 1364.75 1383.75 2025 26719
3/14/2000 1380.25 1395.75 1359.5 1359.5 1207 25134
ESM2000 data:
3/1/2000 1396 1404 1389.75 1402.75 52 105
3/2/2000 1400.75 1407.75 1391.25 1402.75 91 147
3/3/2000 1400.75 1433 1400.75 1429.75 183 189
3/6/2000 1424.75 1428.75 1405.25 1415 366 379
3/7/2000 1412.5 1423 1370.25 1370.25 1160 1023
3/8/2000 1372.75 1393.75 1366.25 1384 981 1194
3/9/2000 1384.25 1423.5 1376.75 1423 49536 5974
3/10/2000 1423.25 1434.25 1412 1417.75 65615 9561
3/13/2000 1416.75 1418.25 1381.25 1401.75 69428 11559
3/14/2000 1401.25 1414.25 1376.75 1380.5 77793 12057
我想要根据成交量来“滚动”到新的合约。
补充说明:
因为在2000年3月9日,ESH2000合约的成交量下降,交易者转向ESM2000合约,所以我需要在那时“滚动”到新合约的数据,并且对之前的值进行调整。在这个例子中,2000年3月9日新合约的结算值是1423,而旧合约的结算值是1404,所以我想要把它们匹配起来。因此,我需要通过给旧合约的所有值加上19来进行调整。
补充结束:
我想要的输出结果是:Date, AdjOpen, AdjHigh, AdjLow, AdjClose (Settle), Vol, OI:
3/1/2000 1391.25 1407.75 1390 1403.5 60887 29558 ADJ ESH2000 Data
3/2/2000 1403.25 1409.5 1391.5 1404 62489 30059 ADJ ESH2000 Data
3/3/2000 1403.75 1433.5 1402.5 1429.5 65432 29923 ADJ ESH2000 Data
3/6/2000 1430 1431.75 1405.25 1414 59860 29549 ADJ ESH2000 Data
3/7/2000 1413.5 1423.5 1370 1370.75 85263 31256 ADJ ESH2000 Data
3/8/2000 1371.75 1395 1367.5 1385 73911 30916 ADJ ESH2000 Data
3/9/2000 1384.25 1423.5 1376.75 1423 49536 5974 ESU2000 Data
3/10/2000 1423.25 1434.25 1412 1417.75 65615 9561 ESU2000 Data
3/13/2000 1416.75 1418.25 1381.25 1401.75 69428 11559 ESU2000 Data
3/14/2000 1401.25 1414.25 1376.75 1380.5 77793 12057 ESU2000 Data
我现在正在阅读pandas的文档,但不太确定如何“比较”这两个文件/数据框,以及如何输出文件的子集,然后进行调整,并且对历史中的每个额外合约都这样做。
我并不是在让任何人帮我完成这个,只是希望能得到一些方向,以便集中我的学习精力。
1 个回答
这里有一些粗略的想法,可以帮助你入门——要让这个方法更通用,还需要更多的思考,可能还会有改进的空间。
首先,我将只处理每个合同在2000年3月的数据,假设每个合同的数据都在自己的数据框中。
esm = Quandl.get("CME/ESM2000")['2000-3']
esh = Quandl.get("CME/ESH2000")['2000-3']
我们可以使用 merge
来合并这些数据,这个方法可以根据索引或列来连接数据框。因为日期在两个数据框中都是索引,所以需要指定 left_index
和 right_index
。
combined = esh.merge(esm, left_index=True, right_index=True)
如果有相同的列名,合并后会在左边的列名后加上 _x
,在右边的列名后加上 _y
。要判断 M 合同的交易量是否最高,只需比较这两个数据框的对应列。要找出交易量首次变化的日期,可以用这个比较结果的索引来获取第一个索引值。
m_highest = combined['Volume_y'] > combined['Volume_x']
roll_date = m_highest[m_highest].index[0]
接下来,通过选择每个数据框在该日期的结算数据来计算差距。
roll_gap = esm.loc[roll_date, 'Settle'] - esh.loc[roll_date, 'Settle']
构建合并后的数据框时,从每个数据框中选择正确的日期并进行拼接。
df = pd.concat([esh[esh.index < roll_date], esm[esm.index >= roll_date]])
最后,选择较早的日期,并根据差距进行调整。
df.loc[df.index < roll_date, ['Open','High','Low','Settle']] = (
df.loc[df.index < roll_date, ['Open','High','Low','Settle']] + roll_gap)