-
Notifications
You must be signed in to change notification settings - Fork 4
/
optionChain.py
91 lines (67 loc) · 2.63 KB
/
optionChain.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
from statistics import median
from support import validDateFormat
import alert
class OptionChain:
strikes = 150
def __init__(self, api, asset, date, daysLessAllowed):
self.api = api
self.asset = asset
self.date = date
self.daysLessAllowed = daysLessAllowed
def get(self):
apiData = self.api.getOptionChain(self.asset, self.strikes, self.date, self.daysLessAllowed)
return self.mapApiData(apiData)
def mapApiData(self, data):
# convert api response to data the application can read
map = []
try:
tmp = data['callExpDateMap']
for key, value in tmp.items():
split = key.split(':')
date = split[0]
days = int(split[1])
if not validDateFormat(date):
return alert.botFailed(self.asset, 'Incorrect date format from api: ' + date)
contracts = []
for contractKey, contractValue in value.items():
contracts.extend([
{
'symbol': contractValue[0]['symbol'],
'strike': contractValue[0]['strikePrice'],
'bid': contractValue[0]['bid'],
'ask': contractValue[0]['ask'],
}
])
map.extend([
{
'date': date,
'days': days,
'contracts': contracts
}
])
except KeyError:
return alert.botFailed(self.asset, 'Wrong data from api')
if map:
map = sorted(map, key=lambda d: d['days'])
return map
def sortDateChain(self, chain):
# ensure this is sorted by strike
return sorted(chain, key=lambda d: d['strike'])
def getContractFromDateChain(self, strike, chain):
chain = self.sortDateChain(chain)
# get first contract at or above strike
for contract in chain:
if contract['strike'] >= strike:
return contract
return None
def getContractFromDateChainByMinYield(self, minStrike, maxStrike, minYield, chain):
chain = self.sortDateChain(chain)
# highest strike to lowest
for contract in reversed(chain):
if contract['strike'] > maxStrike:
continue
if contract['strike'] < minStrike:
break
if median([contract['bid'], contract['ask']]) >= minYield:
return contract
return None