商品期货分层数据结构

时间:2013-06-18 20:25:53

标签: python pandas hierarchical-data trading algorithmic-trading

我为我的生活似乎无法得到我想要的结构并让它正常运作,所以我很生气地来找你们。

设定: 我有一个名为Futures_Contracts的目录,里面有大约30个文件夹,全部用底层资产命名,最后在csv格式的6个最近的到期合同中。每个csv的格式相同,包含Date,O,H,L,C,V,OI,Expiration Month。

注意:O H L C V OI是开盘价,高价,低价,收盘价,成交量,持仓量(对于那些不熟悉的人)也假设收盘价与下方结算的同义词

Folder Structure

任务:从这里开始的目标是将期货数据加载到多指数熊猫数据框中,使得顶级指数是基础商品符号,中级指数是到期月 - 年,最后是OHLC数据。最终目标是拥有一些我可以开始在zipline模块上进行黑客操作以使其在期货上运行的东西。 所以视觉上: enter image description here

我的微弱尝试:

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from pandas import DataFrame, Series
import datetime
plt.figsize(16,8)

deliveries = {}
commoidities = {}
columns = 'open', 'high', 'low', 'settle', 'volume', 'interest', 'delivery' #Contract fields
path = os.getcwdu()+'/Futures_Contracts/' #Futures Path
for sym in os.listdir(path):
    if sym[0] != '.': #Weed out hidden files
        deliveries[sym] = []
        i = 0
        for contract in os.listdir(path + sym):
            temp = pd.io.parsers.read_csv(path + sym + '/' + contract, index_col=0, parse_dates = True, names = columns)#pull in the csv
            deliveries[sym].append(str(contract[:-4][-1] + contract[:-4][:-1][-2:])) #add contract to dict in form of MonthCode-YY
            commodities[sym] = deliveries[sym]
            commodities[sym][i] = temp
            i += 1

这有点奏效,但这实际上是一个嵌套的dict,最后会保存一个数据帧。因此,切片非常笨重:

commodities['SB2'][0]['settle'].plot()
commodities['SB2'][3]['settle'].plot()
commodities['SB2'][4]['settle'].plot()
commodities['SB2'][3]['settle'].plot()
commodities['SB2'][4]['settle'].plot()
commodities['SB2'][5]['settle'].plot()

并收益enter image description here

最理想的是,我将能够对每个索引进行切片,以便我可以跨资产,到期,日期和值来比较数据。此外,标注我正在查看的内容,正如您在matplotlib图表中看到的,一切都简称为“定居”

肯定有办法做到这一点,但我不够聪明,无法弄明白。

2 个答案:

答案 0 :(得分:2)

我认为将这个放入一个DataFrame会好得多,所以请考虑使用MultiIndex。这是一个玩具示例,我认为这将很好地转换为您的代码:

In [11]: dfN13 = pd.DataFrame([[1, 2]], columns=[['N13', 'N13'], ['a', 'b']])

In [12]: dfM13 = pd.DataFrame([[3, 4]], columns=[['M13', 'M13'], ['a', 'b']])

这些是您示例中的DataFrame,但列的第一级只是资产名称。

In [13]: df = pd.concat([dfN13, dfM13], axis=1)

In [14]: df
Out[14]:
   N13     M13
     a  b    a  b
0    1  2    3  4

为方便起见,我们可以标记列级别和索引。

In [15]: df.columns.names = ['asset', 'chart']

In [16]: df.index.names = ['date']  # well, not in this toy example

In [17]: df
Out[17]:
asset  N13     M13
chart    a  b    a  b
date
0        1  2    3  4

注意:这看起来很像您的电子表格。

我们可以使用xs

获取特定图表(例如ohlc)
In [18]: df.xs('a', level='chart', axis=1)
Out[18]:
asset  N13  M13
date
0        1    3

In [19]: df.xs('a', level='chart', axis=1).plot()  # win

答案 1 :(得分:1)

好的,这似乎有效。

commodities = {}
columns = 'open', 'high', 'low', 'settle', 'volume', 'interest', 'delivery' #Contract fields
path = os.getcwdu()+'/Futures_Contracts/' #Futures Path
for sym in os.listdir(path):
    if sym[0] != '.': #Weed out hidden files
        i = 0
        c_expirations = {}
        for contract in os.listdir(path + sym):
            expiry = (contract[:-4][-1].encode('ascii', 'ignore') + contract[:-4][:-1][-2:].encode('ascii', 'ignore'))
            c_expirations[expiry] = pd.io.parsers.read_csv(path + sym + '/' + contract, index_col=0, parse_dates = True, names = columns)
        commodities[sym] = pd.concat(c_expirations, axis =1)
df_data = pd.concat(commodities, axis=1)
df_data.columns.names = 'asset', 'expiry', 'data'

并查看它的打印内容

print df_data


<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 1568 entries, 2007-04-16 00:00:00 to 2013-06-17 00:00:00
Columns: 1197 entries, (CC2, H14, open) to (ZW, Z13, delivery)
dtypes: float64(1197)

真的只是想要修补安迪的建议,然后大规模应用