forked from robcarver17/pysystemtrade
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dict_of_futures_per_contract_prices.py
152 lines (111 loc) · 4.61 KB
/
dict_of_futures_per_contract_prices.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import datetime
import numpy as np
import pandas as pd
from syscore.constants import arg_not_supplied
from syscore.exceptions import missingData
from sysobjects.contract_dates_and_expiries import listOfContractDateStr
class dictFuturesContractFinalPrices(dict):
def __repr__(self):
object_repr = "Dict of final futures contract prices with %d contracts" % len(
self.keys()
)
return object_repr
def sorted_contract_date_str(self):
"""
Time sorted contract ids
:return:
"""
try:
all_contract_date_str_sorted = getattr(
self, "_all_contract_date_str_sorted"
)
except AttributeError:
all_contract_date_str_sorted = self._get_and_set_sorted_contract_date_str()
return all_contract_date_str_sorted
def _get_and_set_sorted_contract_date_str(self):
all_contract_date_str = listOfContractDateStr(self.keys())
all_contract_date_str_sorted = all_contract_date_str.sorted_date_str()
self._all_contract_date_str_sorted = all_contract_date_str_sorted
return all_contract_date_str_sorted
def last_contract_date_str(self):
all_contract_date_str_sorted = self.sorted_contract_date_str()
return all_contract_date_str_sorted.final_date_str()
def joint_data(self):
joint_data = [
pd.Series(prices, name=contractid) for contractid, prices in self.items()
]
joint_data = pd.concat(joint_data, axis=1)
return joint_data
def matched_prices(self, contracts_to_match=arg_not_supplied) -> pd.DataFrame:
# Return pd.DataFrame where we only have prices in all contracts
if contracts_to_match is arg_not_supplied:
contracts_to_match = self.keys()
joint_data = self.joint_data()
joint_data_to_match = joint_data[contracts_to_match]
matched_data = joint_data_to_match.dropna()
if len(matched_data) == 0:
# This will happen if there are no matches
raise missingData
return matched_data
class dictFuturesContractVolumes(dictFuturesContractFinalPrices):
def __repr__(self):
object_repr = "Dict of futures contract volumes with %d contracts" % len(
self.keys()
)
return object_repr
class dictFuturesContractPrices(dict):
"""
A dict of futures contract prices
Keys are contract_objects
We can use standard dict methods, but convenience methods are included
"""
def __repr__(self):
object_repr = "Dict of futures contract prices with %d contracts" % len(
self.keys()
)
return object_repr
def final_prices(self) -> dictFuturesContractFinalPrices:
"""
:return: dict of final prices
"""
all_contract_ids = list(self.keys())
final_price_dict_as_list = []
for contract_id in all_contract_ids:
final_prices = self[contract_id].return_final_prices()
final_prices.name = contract_id
final_price_dict_as_list.append((contract_id, final_prices))
final_prices_dict = dictFuturesContractFinalPrices(final_price_dict_as_list)
return final_prices_dict
def daily_volumes(self) -> dictFuturesContractVolumes:
"""
:return: dict of daily volumes
"""
all_contract_ids = list(self.keys())
volume_dict_as_list = []
for contract_id in all_contract_ids:
volumes = self[contract_id].daily_volumes()
volumes.name = contract_id
volume_dict_as_list.append((contract_id, volumes))
volumes_dict = dictFuturesContractVolumes(volume_dict_as_list)
return volumes_dict
def get_last_matched_date_and_prices_for_contract_list(
dict_of_prices: dictFuturesContractPrices,
contracts_to_match: list,
list_of_contract_date_str: list,
) -> (datetime.datetime, list):
dict_of_final_prices = dict_of_prices.final_prices()
try:
matched_final_prices = dict_of_final_prices.matched_prices(
contracts_to_match=contracts_to_match
)
except missingData:
# This will happen if there are no matching prices
# We just return the last row
matched_final_prices = dict_of_final_prices.joint_data()
last_matched_prices = list(matched_final_prices.iloc[-1].values)
last_matched_date = matched_final_prices.index[-1]
# pad with extra nan values
last_matched_prices = last_matched_prices + [np.nan] * (
len(list_of_contract_date_str) - len(last_matched_prices)
)
return last_matched_date, last_matched_prices