-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
105 lines (90 loc) · 3.85 KB
/
main.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
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import requests
import datetime
import schedule
import time
from sklearn.metrics import r2_score
# Define Global Variables
EXCHANGE_URL = "https://www.deribit.com/api/v2/public"
INSTRUMENTS_END_POINT = "/get_instruments"
ORDER_BOOK_END_POINT = "/get_order_book_by_instrument_id"
CURRENCY = "BTC"
KIND = "option"
CONTRACT_MONTH = "2022-06-24"
RATE_LIMIT = 5
STRIKE_PRICE_EXCLUDE_ABOVE = 60000
# Define Helper Function(s)
def unix_to_date_str(unix_timestamp):
return datetime.datetime.utcfromtimestamp(unix_timestamp/1000).strftime('%Y-%m-%d')
# Decorator for request error encounter
def retry(func):
def repeat_every_five_sec(*args, **kwargs):
while True:
try:
return func(*args, **kwargs)
except:
print("Error. Try again in 5 secs.")
time.sleep(5)
continue
break
return repeat_every_five_sec
@retry
def send_request(baseURL, endpoint, payloads, timeout):
return requests.get(f"{baseURL}{endpoint}",params=payloads,timeout=timeout)
# Main Function to be schedule
def run():
# Simply Get all options contract First
payloads = {"currency": CURRENCY, "kind": KIND }
res = send_request(EXCHANGE_URL, INSTRUMENTS_END_POINT, payloads, 10)
option_list = res.json()['result']
time.sleep(1)
#Step 1: Filter by Contract Month
relevant_options = [option for option in option_list if unix_to_date_str(option['expiration_timestamp']) == CONTRACT_MONTH]
#Step 2: For each option contract, take their intrument unique id and get the mark IV from order book data and store it
results = []
count = 0
for option in relevant_options:
if count % RATE_LIMIT == 0:
print(f"Querying Option Chain Data... {(count/len(relevant_options)*100):.2f}% Complete")
time.sleep(1)
payloads = {"instrument_id": option['instrument_id']}
res = send_request(EXCHANGE_URL, ORDER_BOOK_END_POINT, payloads, 10)
strike_price = option['strike']
option_type = option['option_type']
mark_iv = res.json()['result']['mark_iv']
results.append([option_type, strike_price, mark_iv])
count += 1
# Step 3: Take those calls and puts and sorted by strike price and fit a quadratic curve on the mark IV array
calls = [i for i in results if i[0] == 'call']
calls = sorted(calls,key=lambda l:l[1], reverse=False)
calls_x = [call[1] for call in calls if call[1] <= STRIKE_PRICE_EXCLUDE_ABOVE] #<=60000 just for better r-square
calls_y = [call[2] for call in calls if call[1] <= STRIKE_PRICE_EXCLUDE_ABOVE]
call_model = np.poly1d(np.polyfit(calls_x,calls_y, 2))
puts = [i for i in results if i[0] == 'put']
puts = sorted(puts,key=lambda l:l[1], reverse=False)
puts_x = [put[1] for put in puts if put[1] <= STRIKE_PRICE_EXCLUDE_ABOVE]
puts_y = [put[2] for put in puts if put[1] <= STRIKE_PRICE_EXCLUDE_ABOVE]
put_model = np.poly1d(np.polyfit(puts_x,puts_y, 2))
# Deliver the output in console
print("\n")
print("\n")
print("--------------------CALL volatility curve Equation-----------------------")
print(f"Equation: {call_model}")
print(f"R-Square: {r2_score(calls_y, call_model(calls_x))}")
print("\n")
print("--------------------PUT volatility curve Equation-----------------------")
print(f"Equation: {put_model}")
print(f"R-Square: {r2_score(puts_y, put_model(puts_x))}")
print("\n")
print("Check out the visualization in Walk Through.ipynb!!!")
print("Now wait for another 5 mins zzz...")
if __name__ == '__main__':
# Print the equation every 5 min
schedule.every(5).minutes.do(run)
print("Task: Print the quadratic equation generated by mark IV every 5 min")
run()
while True:
schedule.run_pending()
time.sleep(1)