"""Settings for the Updraft Space (Quality-Trend 3 strategy). Secrets come from the Space's "Variables and secrets" settings (never from the repo): NASDAQ_DATA_LINK_API_KEY, ALPACA_API_KEY_ID, ALPACA_API_SECRET_KEY, REBALANCE_TOKEN.""" from __future__ import annotations import os NDL_KEY = os.getenv("NASDAQ_DATA_LINK_API_KEY", "") ALPACA_KEY = os.getenv("ALPACA_API_KEY_ID", "") ALPACA_SECRET = os.getenv("ALPACA_API_SECRET_KEY", "") # Paper unless BOTH ALPACA_PAPER=false and ALPACA_ALLOW_LIVE=yes are set. ALPACA_PAPER = os.getenv("ALPACA_PAPER", "true").strip().lower() != "false" or \ os.getenv("ALPACA_ALLOW_LIVE", "").strip().lower() != "yes" DATA_FEED = os.getenv("ALPACA_DATA_FEED", "iex") REBALANCE_TOKEN = os.getenv("REBALANCE_TOKEN", "") AUTO_REBALANCE = os.getenv("AUTO_REBALANCE", "1").strip() == "1" # the Space's own monthly scheduler # The backtested rule (Quant Model scripts/finalize_qt3_managed.py) N, KEEP = 3, 6 # hold 3; keep a holding while it ranks in the top 6 TOPN, MIN_PRICE, MIN_DV = 1000, 5.0, 5e6 POOL = 0.70 # quality pool = top 30% of the capital-discipline composite QCD = ["basic_diluted_gap", "quality_score", "equity_financing_neg", "fcf_yield", "roe", "buyback_yield", "net_share_reduction_yoy"] # Execution CASH_BUFFER = float(os.getenv("CASH_BUFFER", "0.01")) # keep 1% cash for fills / drift MIN_TRADE = float(os.getenv("MIN_TRADE", "25")) # skip adjustments smaller than this ($) … BAND = float(os.getenv("REBALANCE_BAND", "0.02")) # … or smaller than 2% of a position's target TAG = "qt3" # client_order_id prefix of this strategy's orders CACHE_DIR = os.getenv("QT3_CACHE", "/tmp/qt3") RANKING_MAX_AGE_H = float(os.getenv("RANKING_MAX_AGE_H", "20")) INCEPTION = os.getenv("QT3_INCEPTION", "") # YYYY-MM-DD for public stats; default = first order def status() -> dict: return {"data_key": bool(NDL_KEY), "alpaca_keys": bool(ALPACA_KEY and ALPACA_SECRET), "paper": ALPACA_PAPER, "rebalance_enabled": bool(REBALANCE_TOKEN), "auto_rebalance": AUTO_REBALANCE}