Saxo connector
This commit is contained in:
@@ -44,6 +44,36 @@ def init_db():
|
||||
created_at TEXT DEFAULT (datetime('now'))
|
||||
)""")
|
||||
|
||||
c.execute("""CREATE TABLE IF NOT EXISTS saxo_auth (
|
||||
id INTEGER PRIMARY KEY CHECK (id = 1),
|
||||
access_token TEXT,
|
||||
refresh_token TEXT,
|
||||
expires_at TEXT,
|
||||
refresh_expires_at TEXT,
|
||||
environment TEXT DEFAULT 'sim',
|
||||
updated_at TEXT DEFAULT (datetime('now'))
|
||||
)""")
|
||||
|
||||
c.execute("""CREATE TABLE IF NOT EXISTS saxo_option_snapshots (
|
||||
id TEXT PRIMARY KEY,
|
||||
symbol TEXT NOT NULL,
|
||||
snapshot_date TEXT NOT NULL,
|
||||
spot REAL,
|
||||
expiry_date TEXT NOT NULL,
|
||||
strike REAL NOT NULL,
|
||||
option_type TEXT NOT NULL,
|
||||
bid REAL,
|
||||
ask REAL,
|
||||
mid REAL,
|
||||
volatility_pct REAL,
|
||||
delta REAL,
|
||||
gamma REAL,
|
||||
theta REAL,
|
||||
vega REAL,
|
||||
created_at TEXT DEFAULT (datetime('now'))
|
||||
)""")
|
||||
c.execute("CREATE INDEX IF NOT EXISTS idx_saxo_snap_symbol_date ON saxo_option_snapshots(symbol, snapshot_date)")
|
||||
|
||||
c.execute("""CREATE TABLE IF NOT EXISTS strategy_scenarios (
|
||||
id TEXT PRIMARY KEY,
|
||||
symbol TEXT NOT NULL,
|
||||
@@ -6017,3 +6047,72 @@ def delete_saved_strategy(strategy_id: str) -> bool:
|
||||
deleted = cur.rowcount > 0
|
||||
conn.close()
|
||||
return deleted
|
||||
|
||||
|
||||
# ── Saxo OpenAPI: OAuth tokens & option snapshots ─────────────────────────────
|
||||
|
||||
def save_saxo_tokens(access_token: str, refresh_token: str, expires_at: str, refresh_expires_at: str, environment: str = "sim"):
|
||||
conn = get_conn()
|
||||
conn.execute("""INSERT INTO saxo_auth (id, access_token, refresh_token, expires_at, refresh_expires_at, environment, updated_at)
|
||||
VALUES (1, ?, ?, ?, ?, ?, datetime('now'))
|
||||
ON CONFLICT(id) DO UPDATE SET
|
||||
access_token=excluded.access_token, refresh_token=excluded.refresh_token,
|
||||
expires_at=excluded.expires_at, refresh_expires_at=excluded.refresh_expires_at,
|
||||
environment=excluded.environment, updated_at=datetime('now')""",
|
||||
(access_token, refresh_token, expires_at, refresh_expires_at, environment))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
|
||||
def get_saxo_tokens() -> Optional[Dict[str, Any]]:
|
||||
conn = get_conn()
|
||||
row = conn.execute("SELECT * FROM saxo_auth WHERE id=1").fetchone()
|
||||
conn.close()
|
||||
return dict(row) if row else None
|
||||
|
||||
|
||||
def clear_saxo_tokens():
|
||||
conn = get_conn()
|
||||
conn.execute("DELETE FROM saxo_auth WHERE id=1")
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
|
||||
def save_saxo_snapshot_rows(rows: List[Dict[str, Any]]):
|
||||
if not rows:
|
||||
return
|
||||
import uuid
|
||||
conn = get_conn()
|
||||
conn.executemany("""INSERT INTO saxo_option_snapshots (
|
||||
id, symbol, snapshot_date, spot, expiry_date, strike, option_type,
|
||||
bid, ask, mid, volatility_pct, delta, gamma, theta, vega
|
||||
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""", [
|
||||
(
|
||||
f"SNAP-{uuid.uuid4().hex[:12]}",
|
||||
r["symbol"], r["snapshot_date"], r.get("spot"), r["expiry_date"], r["strike"], r["option_type"],
|
||||
r.get("bid"), r.get("ask"), r.get("mid"), r.get("volatility_pct"),
|
||||
r.get("delta"), r.get("gamma"), r.get("theta"), r.get("vega"),
|
||||
)
|
||||
for r in rows
|
||||
])
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
|
||||
def get_saxo_snapshots(symbol: Optional[str] = None, date_from: Optional[str] = None, date_to: Optional[str] = None) -> List[Dict[str, Any]]:
|
||||
conn = get_conn()
|
||||
query = "SELECT * FROM saxo_option_snapshots WHERE 1=1"
|
||||
params: List[Any] = []
|
||||
if symbol:
|
||||
query += " AND symbol=?"
|
||||
params.append(symbol)
|
||||
if date_from:
|
||||
query += " AND snapshot_date>=?"
|
||||
params.append(date_from)
|
||||
if date_to:
|
||||
query += " AND snapshot_date<=?"
|
||||
params.append(date_to)
|
||||
query += " ORDER BY snapshot_date DESC, expiry_date, strike LIMIT 5000"
|
||||
rows = conn.execute(query, params).fetchall()
|
||||
conn.close()
|
||||
return [dict(r) for r in rows]
|
||||
|
||||
Reference in New Issue
Block a user