Rewrote main.py
This commit is contained in:
112
utils.py
112
utils.py
@@ -1,5 +1,10 @@
|
||||
from typing import NamedTuple
|
||||
import tomllib
|
||||
import tastytrade
|
||||
import re
|
||||
import paho.mqtt.client as mqtt
|
||||
from datetime import datetime
|
||||
from loguru import logger
|
||||
def dict_to_namedtuple(name, dictionary):
|
||||
fields = {}
|
||||
for key, value in dictionary.items():
|
||||
@@ -15,75 +20,48 @@ def load_config():
|
||||
config_dict = tomllib.load(f)
|
||||
config = dict_to_namedtuple("Config", config_dict)
|
||||
return config
|
||||
import webbrowser
|
||||
import requests
|
||||
import threading
|
||||
from flask import Flask, request
|
||||
|
||||
def authenticate(client_id, client_secret, scopes=None, port=5000):
|
||||
"""
|
||||
Opens the browser for OAuth authorization and returns token data.
|
||||
|
||||
Args:
|
||||
client_id (str): Your Tastytrade client ID
|
||||
client_secret (str): Your Tastytrade client secret
|
||||
scopes (list[str]): Optional list of scopes (default: None)
|
||||
port (int): Port for local callback server (default: 5000)
|
||||
|
||||
Returns:
|
||||
dict: Token response JSON (access_token, refresh_token, etc.)
|
||||
"""
|
||||
redirect_uri = f"http://127.0.0.1:{port}/callback"
|
||||
auth_url = "https://api.tastytrade.com/oauth/authorize"
|
||||
token_url = "https://api.tastytrade.com/oauth/token"
|
||||
|
||||
app = Flask(__name__)
|
||||
auth_code_container = {}
|
||||
|
||||
@app.route("/callback")
|
||||
def callback():
|
||||
code = request.args.get("code")
|
||||
auth_code_container["code"] = code
|
||||
return "Authorization successful. You may close this window."
|
||||
|
||||
# Start local server in background
|
||||
def run_server():
|
||||
app.run(port=port, debug=False, use_reloader=False)
|
||||
threading.Thread(target=run_server, daemon=True).start()
|
||||
|
||||
# Build auth URL
|
||||
params = {
|
||||
"response_type": "code",
|
||||
"client_id": client_id,
|
||||
"redirect_uri": redirect_uri
|
||||
def parse_event_symbol(symbol: str):
|
||||
symbol = symbol.lstrip('.')
|
||||
pattern = r"([A-Z]+)(\d{6})([CP])(\d+)"
|
||||
match = re.match(pattern, symbol)
|
||||
if not match:
|
||||
return None
|
||||
underlying, exp_str, opt_type, strike_str = match.groups()
|
||||
expiration = datetime.strptime(exp_str, "%y%m%d").date()
|
||||
strike = int(strike_str) / 10
|
||||
return {
|
||||
"underlying": underlying,
|
||||
"expiration": expiration.isoformat(),
|
||||
"option_type": opt_type,
|
||||
"strike": strike,
|
||||
}
|
||||
if scopes:
|
||||
params["scope"] = " ".join(scopes)
|
||||
def create_mqttc(config):
|
||||
mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
|
||||
mqttc.username_pw_set(username=config.mqtt.user,password=config.mqtt.password)
|
||||
mqttc.connect("proliant.lan",port=1883)
|
||||
logger.info("MQTT client instantiated")
|
||||
return mqttc
|
||||
|
||||
# Open browser
|
||||
webbrowser.open(f"{auth_url}?{requests.compat.urlencode(params)}")
|
||||
def parse_greek_event(greek_event):
|
||||
# parse symbol details
|
||||
parsed_symbol = parse_event_symbol(greek_event.event_symbol)
|
||||
|
||||
# Wait for code
|
||||
print("Waiting for authorization...")
|
||||
while "code" not in auth_code_container:
|
||||
pass
|
||||
|
||||
# Exchange code for token
|
||||
token_resp = requests.post(token_url, data={
|
||||
"grant_type": "authorization_code",
|
||||
"code": auth_code_container["code"],
|
||||
"redirect_uri": redirect_uri,
|
||||
"client_id": client_id,
|
||||
"client_secret": client_secret
|
||||
})
|
||||
token_resp.raise_for_status()
|
||||
|
||||
return token_resp.json()
|
||||
|
||||
# Example usage
|
||||
if __name__ == "__main__":
|
||||
client_id = "YOUR_CLIENT_ID"
|
||||
client_secret = "YOUR_CLIENT_SECRET"
|
||||
token_data = authenticate(client_id, client_secret, scopes=["accounts", "orders"])
|
||||
print(token_data)
|
||||
# combine everything into one dict
|
||||
event_dict = {
|
||||
**parsed_symbol,
|
||||
"event_time": greek_event.event_time,
|
||||
"event_flags": greek_event.event_flags,
|
||||
"index": greek_event.index,
|
||||
"time": greek_event.time,
|
||||
"sequence": greek_event.sequence,
|
||||
"price": float(greek_event.price),
|
||||
"volatility": float(greek_event.volatility),
|
||||
"delta": float(greek_event.delta),
|
||||
"gamma": float(greek_event.gamma),
|
||||
"theta": float(greek_event.theta),
|
||||
"rho": float(greek_event.rho),
|
||||
"vega": float(greek_event.vega),
|
||||
}
|
||||
|
||||
return event_dict
|
||||
|
||||
Reference in New Issue
Block a user