feat: new cockpit
This commit is contained in:
@@ -19,7 +19,7 @@ def _fetch_text(url: str, timeout: int = 15) -> str:
|
||||
import urllib.request
|
||||
import html
|
||||
req = urllib.request.Request(url, headers={
|
||||
"User-Agent": "Mozilla/5.0 (compatible; GeoOptions-Research/1.0)"
|
||||
"User-Agent": "Mozilla/5.0 (compatible; OpenFin-Research/1.0)"
|
||||
})
|
||||
with urllib.request.urlopen(req, timeout=timeout) as resp:
|
||||
raw = resp.read().decode("utf-8", errors="replace")
|
||||
|
||||
@@ -34,7 +34,7 @@ MONETARY_KEYWORDS = [
|
||||
HAWKISH_WORDS = ["hike", "hawkish", "raised", "tightening", "tighter"]
|
||||
DOVISH_WORDS = ["cut", "dovish", "easing", "lowered", "accommodative"]
|
||||
|
||||
_HEADERS = {"User-Agent": "Mozilla/5.0 (compatible; GeoOptions/1.0)"}
|
||||
_HEADERS = {"User-Agent": "Mozilla/5.0 (compatible; OpenFin/1.0)"}
|
||||
_LOOKBACK_DAYS = 14
|
||||
_MAX_KEY_POINTS = 8
|
||||
|
||||
|
||||
@@ -102,6 +102,14 @@ def init_db():
|
||||
added_at TEXT DEFAULT (datetime('now'))
|
||||
)""",
|
||||
"ALTER TABLE market_watchlist ADD COLUMN asset_class TEXT DEFAULT 'custom'",
|
||||
# Dashboard — instruments watchlist ("radar"), independent from market_watchlist
|
||||
"""CREATE TABLE IF NOT EXISTS instruments_watchlist (
|
||||
ticker TEXT PRIMARY KEY,
|
||||
name TEXT,
|
||||
asset_class TEXT DEFAULT 'unknown',
|
||||
sort_order INTEGER DEFAULT 0,
|
||||
added_at TEXT DEFAULT (datetime('now'))
|
||||
)""",
|
||||
]:
|
||||
try:
|
||||
c.execute(_sql)
|
||||
@@ -3002,6 +3010,52 @@ def remove_market_custom_ticker(ticker: str) -> bool:
|
||||
return changed
|
||||
|
||||
|
||||
# ── Instruments Watchlist (Dashboard "radar" card — independent from market_watchlist) ──
|
||||
|
||||
def get_instruments_watchlist() -> List[Dict]:
|
||||
conn = get_conn()
|
||||
rows = conn.execute(
|
||||
"SELECT ticker, name, asset_class, sort_order, added_at "
|
||||
"FROM instruments_watchlist ORDER BY sort_order ASC, added_at ASC"
|
||||
).fetchall()
|
||||
conn.close()
|
||||
return [dict(r) for r in rows]
|
||||
|
||||
|
||||
def add_instrument_watchlist(ticker: str, name: str = "", asset_class: str = "unknown") -> bool:
|
||||
conn = get_conn()
|
||||
try:
|
||||
max_order = conn.execute("SELECT COALESCE(MAX(sort_order), -1) FROM instruments_watchlist").fetchone()[0]
|
||||
conn.execute(
|
||||
"INSERT OR IGNORE INTO instruments_watchlist (ticker, name, asset_class, sort_order) VALUES (?, ?, ?, ?)",
|
||||
(ticker.upper(), name, asset_class, max_order + 1),
|
||||
)
|
||||
inserted = conn.total_changes > 0
|
||||
conn.commit()
|
||||
except Exception:
|
||||
inserted = False
|
||||
finally:
|
||||
conn.close()
|
||||
return inserted
|
||||
|
||||
|
||||
def remove_instrument_watchlist(ticker: str) -> bool:
|
||||
conn = get_conn()
|
||||
conn.execute("DELETE FROM instruments_watchlist WHERE ticker=?", (ticker.upper(),))
|
||||
changed = conn.total_changes > 0
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return changed
|
||||
|
||||
|
||||
def reorder_instruments_watchlist(tickers: List[str]) -> None:
|
||||
conn = get_conn()
|
||||
for i, t in enumerate(tickers):
|
||||
conn.execute("UPDATE instruments_watchlist SET sort_order=? WHERE ticker=?", (i, t.upper()))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
|
||||
# ── System Logs ───────────────────────────────────────────────────────────────
|
||||
|
||||
def log_system_event(
|
||||
|
||||
@@ -22,7 +22,7 @@ NAAIM_URLS = [
|
||||
|
||||
AAII_URL = "https://www.aaii.com/sentimentsurvey/sent_results.js"
|
||||
|
||||
_HEADERS = {"User-Agent": "Mozilla/5.0 (compatible; GeoOptions/1.0)"}
|
||||
_HEADERS = {"User-Agent": "Mozilla/5.0 (compatible; OpenFin/1.0)"}
|
||||
_TIMEOUT = 15
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user