Files
OpenFin/backend/routers/config.py
OpenSquared 39da3b8945 feat: Config tab "Options — Paramètres" with IV gate controls + exit params
- New tab replaces "Journal & Sortie" — consolidates all options-specific settings
- IV Gate section: toggle on/off + 3 sliders (IVR High/Extreme/Skew threshold)
  with live color-coded summary and interdependency guards (high < extreme)
- Exit params section: target, stop-loss, reversal mode + threshold (moved from removed journal tab)
- Backend: GET/PUT /api/config/options-gate endpoint reads/writes 4 config DB keys
- useApi.ts: useOptionsGate + useSaveOptionsGate hooks

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 10:23:31 +02:00

122 lines
3.8 KiB
Python

from fastapi import APIRouter
from pydantic import BaseModel
from typing import Dict, Any, Optional
import os
from services.database import get_all_config, set_config, get_config, get_sources, update_sources, get_analysis_config, save_analysis_config
router = APIRouter(prefix="/api/config", tags=["config"])
class ApiKeysRequest(BaseModel):
openai_api_key: Optional[str] = None
newsapi_key: Optional[str] = None
eia_api_key: Optional[str] = None
fred_api_key: Optional[str] = None
class SourcesRequest(BaseModel):
sources: Dict[str, Any]
class SettingsRequest(BaseModel):
ai_enabled: Optional[str] = None
ai_auto_rescore: Optional[str] = None
class AnalysisConfigRequest(BaseModel):
top_n: Optional[int] = None
category_filter: Optional[str] = None
template: Optional[str] = None
@router.get("/")
def get_config_all():
return get_all_config()
@router.get("/sources")
def list_sources():
return get_sources()
@router.put("/sources")
def update_sources_endpoint(req: SourcesRequest):
update_sources(req.sources)
return {"status": "ok", "updated": len(req.sources)}
@router.put("/api-keys")
def update_api_keys(req: ApiKeysRequest):
updated = []
if req.openai_api_key is not None:
set_config("openai_api_key", req.openai_api_key)
os.environ["OPENAI_API_KEY"] = req.openai_api_key
updated.append("openai")
if req.newsapi_key is not None:
set_config("newsapi_key", req.newsapi_key)
updated.append("newsapi")
if req.eia_api_key is not None:
set_config("eia_api_key", req.eia_api_key)
updated.append("eia")
if req.fred_api_key is not None:
set_config("fred_api_key", req.fred_api_key)
updated.append("fred")
return {"status": "ok", "updated": updated}
@router.put("/settings")
def update_settings(req: SettingsRequest):
if req.ai_enabled is not None:
set_config("ai_enabled", req.ai_enabled)
if req.ai_auto_rescore is not None:
set_config("ai_auto_rescore", req.ai_auto_rescore)
return {"status": "ok"}
@router.get("/analysis")
def get_analysis_config_endpoint():
return get_analysis_config()
@router.put("/analysis")
def save_analysis_config_endpoint(req: AnalysisConfigRequest):
current = get_analysis_config()
if req.top_n is not None:
current["top_n"] = req.top_n
if req.category_filter is not None:
current["category_filter"] = req.category_filter
if req.template is not None:
current["template"] = req.template
save_analysis_config(current)
return {"status": "ok", "config": current}
class OptionsGateRequest(BaseModel):
iv_gate_enabled: Optional[bool] = None
iv_gate_ivr_high: Optional[float] = None
iv_gate_ivr_extreme: Optional[float] = None
iv_gate_skew_threshold: Optional[float] = None
@router.get("/options-gate")
def get_options_gate():
return {
"iv_gate_enabled": (get_config("iv_gate_enabled") or "true").lower() == "true",
"iv_gate_ivr_high": float(get_config("iv_gate_ivr_high") or 60),
"iv_gate_ivr_extreme": float(get_config("iv_gate_ivr_extreme") or 80),
"iv_gate_skew_threshold": float(get_config("iv_gate_skew_threshold") or 8),
}
@router.put("/options-gate")
def save_options_gate(req: OptionsGateRequest):
if req.iv_gate_enabled is not None:
set_config("iv_gate_enabled", "true" if req.iv_gate_enabled else "false")
if req.iv_gate_ivr_high is not None:
set_config("iv_gate_ivr_high", str(req.iv_gate_ivr_high))
if req.iv_gate_ivr_extreme is not None:
set_config("iv_gate_ivr_extreme", str(req.iv_gate_ivr_extreme))
if req.iv_gate_skew_threshold is not None:
set_config("iv_gate_skew_threshold", str(req.iv_gate_skew_threshold))
return {"status": "ok"}