esachdev12/CLINOVA
0
1"""2FinomIQ — Autonomous Financial Strategy Intelligence Platform.3Advanced Decision Intelligence Terminal with Strategy Sandbox.4"""5 6import json7import os8import subprocess9import yaml10import pandas as pd11from pathlib import Path12import gradio as gr13from app_theme import FinomIQTheme14from utils.chart_builder import (15 build_candlestick_chart, build_pnl_chart, 16 build_allocation_pie, build_risk_gauge, build_correlation_matrix,17 build_drawdown_chart, build_risk_return_scatter, build_sector_heatmap18)19from utils.knowledge_graph import build_financial_knowledge_graph, build_equity_curve20from utils.summary_engine import generate_rule_based_summary, generate_llm_summary21from utils.experiment_panels import (22 build_xai_thinking_advanced, 23 build_advanced_rl_stats, build_strategy_lab_status,24 build_rl_step_monitor25)26from utils.explainability import explain_decision_advanced27 28# ── Constants ─────────────────────────────────────────────────────────────────29 30RESULTS_PATH = "results/finomiq_intelligence_run.json"31CONFIG_PATH = "config.yaml"32LOG_PATH = "logs/finomiq.log"33 34# ── Helpers ───────────────────────────────────────────────────────────────────35 36def load_results():37 try:38 with open(RESULTS_PATH, "r") as f:39 return json.load(f)40 except:41 return None42 43def load_config():44 with open(CONFIG_PATH, "r") as f:45 return yaml.safe_load(f)46 47def run_intelligence_simulation(m_type, a_type, rules_text, hybrid):48 cfg = load_config()49 cfg["scenario"]["market_type"] = m_type50 cfg["agent"]["type"] = a_type51 cfg["strategy_sandbox"]["default_rules"] = rules_text52 cfg["strategy_sandbox"]["hybrid_mode"] = hybrid53 cfg["visualization"]["persistence_path"] = RESULTS_PATH54 55 with open(CONFIG_PATH, "w") as f:56 yaml.dump(cfg, f)57 58 cmd = ["python3", "runner.py", "--config", CONFIG_PATH]59 subprocess.run(cmd, capture_output=True)60 return load_results()61 62# ── Strategy Library ─────────────────────────────────────────────────────────63 64STRATEGY_TEMPLATES = {65 "Defensive Alpha": "IF sentiment < 0.4 AND vix > 25:\n HEDGE 20% GOLD\nIF drawdown > 0.05:\n SELL 50% BTC",66 "Momentum Chaser": "IF trend > 0.02 AND sentiment > 0.6:\n BUY 15% TSLA\nIF trend < -0.01:\n SELL 80% TSLA",67 "Conservative Growth": "IF vix < 15 AND sentiment > 0.5:\n BUY 5% AAPL\nIF vix > 30:\n HEDGE 30% GOLD",68 "Crypto Speculator": "IF sentiment > 0.8:\n BUY 20% BTC\nIF drawdown > 0.10:\n SELL 100% BTC"69}70 71# ── UI Data Mapping ───────────────────────────────────────────────────────────72 73def get_intelligence_data(summary_type="Rule-based"):74 data = load_results()75 if not data:76 return [None] * 1877 78 latest_ep = data["episodes"][-1]79 history = latest_ep.get("action_history", [])80 obs = latest_ep.get("observation", {})81 results_all = data.get("episodes", [])82 83 # 1. Advanced Charts84 asset = list(obs["asset_prices"].keys())[0]85 fig_candle = build_candlestick_chart(asset, history)86 fig_pnl = build_pnl_chart(history)87 fig_pie = build_allocation_pie(obs["current_positions"], obs["asset_prices"])88 fig_risk = build_risk_gauge(obs["risk_exposure_score"])89 fig_fkg = build_financial_knowledge_graph(obs)90 fig_equity = build_equity_curve(latest_ep.get("history", {}))91 fig_dd = build_drawdown_chart(history)92 fig_scatter = build_risk_return_scatter(results_all)93 fig_sector = build_sector_heatmap()94 95 # 2. Intel Panels96 rl_step_html = build_rl_step_monitor(history)97 rl_stats_html = build_advanced_rl_stats(obs)98 99 xai_data = explain_decision_advanced(asset, obs, history[-1]["action"] if history else 2)100 xai_html = build_xai_thinking_advanced(xai_data)101 102 cfg = load_config()103 from env.strategy_engine import StrategyDSLEngine104 engine = StrategyDSLEngine()105 rules = engine.parse_rules(cfg["strategy_sandbox"].get("default_rules", ""))106 lab_html = build_strategy_lab_status(rules, cfg["strategy_sandbox"].get("hybrid_mode", True))107 108 # Summary Generation109 if summary_type == "LLM-powered":110 summary_text = generate_llm_summary(data)111 else:112 summary_text = generate_rule_based_summary(data)113 114 # 3. Trade History115 trade_df = pd.DataFrame(obs.get("trade_history_summary", []))116 117 return (118 obs["portfolio_value"], obs["unrealized_pnl"], obs["volatility_index"],119 rl_step_html, xai_html, rl_stats_html, lab_html,120 fig_candle, fig_pnl, fig_pie, fig_risk, fig_fkg, fig_equity, fig_dd, fig_scatter, fig_sector,121 trade_df, summary_text122 )123# ── Main UI ───────────────────────────────────────────────────────────────────124 125with gr.Blocks(title="FinomIQ Terminal") as demo:126 gr.Markdown("# FinomIQ - Autonomous Financial Strategy Intelligence Platform")127 128 with gr.Row():129 # --- LEFT: Strategy Lab ---130 with gr.Column(scale=1):131 gr.Markdown("### Strategy Intelligence Lab")132 133 with gr.Tabs():134 with gr.Tab("Visual Builder"):135 gr.Markdown("<small>Construct strategic rules via interface</small>")136 with gr.Row():137 v_indicator = gr.Dropdown(label="Indicator", choices=["sentiment", "vix", "trend", "drawdown", "liquidity"], value="sentiment")138 v_operator = gr.Dropdown(label="Operator", choices=[">", "<", "=="], value=">")139 v_value = gr.Number(label="Value", value=0.7)140 with gr.Row():141 v_action = gr.Dropdown(label="Action", choices=["BUY", "SELL", "HEDGE"], value="BUY")142 v_amount = gr.Number(label="Amount %", value=10)143 v_asset = gr.Dropdown(label="Asset", choices=["AAPL", "TSLA", "BTC", "GOLD", "ETH"], value="AAPL")144 add_rule_btn = gr.Button("Add Rule to Strategy", size="sm")145 146 with gr.Tab("Strategy Library"):147 template_sel = gr.Dropdown(label="Templates", choices=list(STRATEGY_TEMPLATES.keys()))148 apply_template_btn = gr.Button("Load Template", size="sm")149 150 gr.Markdown("#### Active Strategy Rules (DSL)")151 rules_editor = gr.Code(152 label="Strategy Engine DSL",153 value="IF sentiment > 0.7 AND trend > 0.01:\n BUY 10% AAPL\nIF drawdown > 0.05:\n SELL 50% BTC",154 language="python",155 lines=10156 )157 clear_rules_btn = gr.Button("Clear All Rules", size="sm", variant="secondary")158 159 gr.Markdown("#### Simulation Scenario")160 m_type = gr.Dropdown(label="Market Regime", choices=["bull", "bear", "volatile", "crash"], value="bull")161 a_type = gr.Dropdown(label="AI Decision Core", choices=["ppo", "dqn", "hybrid"], value="ppo")162 hybrid_toggle = gr.Checkbox(label="Enable Hybrid Intelligence", value=True)163 164 run_btn = gr.Button("EXECUTE STRATEGY SIMULATION", variant="primary")165 166 gr.Markdown("---")167 summary_mode = gr.Radio(label="Summary Intelligence", choices=["Rule-based", "LLM-powered"], value="Rule-based")168 summary_display = gr.Markdown(label="Strategy Summary")169 170 gr.Markdown("---")171 lab_status_panel = gr.HTML()172 rl_stats_panel = gr.HTML()173 174 # --- RIGHT: Intelligence Terminal ---175 with gr.Column(scale=3):176 # Top Ribbon177 with gr.Row():178 equity_metric = gr.Number(label="Total Equity (USD)", precision=0)179 pnl_metric = gr.Number(label="Strategy PnL (USD)", precision=2)180 vix_metric = gr.Number(label="Market Volatility (VIX)", precision=1)181 182 rl_monitor_panel = gr.HTML()183 184 with gr.Tabs():185 with gr.Tab("Strategy Analytics"):186 with gr.Row():187 fig_equity = gr.Plot(label="Portfolio Equity Curve")188 fig_pnl = gr.Plot(label="PnL Trajectory")189 with gr.Row():190 fig_dd = gr.Plot(label="Drawdown Analysis")191 fig_scatter = gr.Plot(label="Risk-Return Efficiency")192 193 with gr.Tab("Market Depth"):194 with gr.Row():195 with gr.Column(scale=2):196 fig_candle = gr.Plot(label="Asset Price Action")197 with gr.Column(scale=1):198 fig_risk = gr.Plot(label="VaR Risk Gauge")199 with gr.Row():200 fig_sector = gr.Plot(label="Sector Heatmap")201 fig_pie = gr.Plot(label="Current Allocation")202 203 with gr.Tab("Neural Reasoning (XAI)"):204 with gr.Row():205 with gr.Column(scale=1):206 xai_panel = gr.HTML()207 with gr.Column(scale=1):208 fig_fkg = gr.Plot(label="Financial Knowledge Graph")209 gr.Markdown("### What-If Analysis Engine")210 gr.Info("Adjust parameters below to evaluate strategy performance under alternative market conditions.")211 with gr.Row():212 gr.Slider(label="Simulated Sentiment Shift", minimum=-0.5, maximum=0.5, value=0)213 gr.Slider(label="Simulated Volatility Spike", minimum=0, maximum=50, value=0)214 215 with gr.Tab("Execution Log"):216 trade_table = gr.DataFrame(label="Institutional Trade History")217 log_viewer = gr.Code(label="Engine Console Output", lines=15)218 219 def get_logs():220 if os.path.exists(LOG_PATH):221 with open(LOG_PATH, "r") as f:222 return f.read()[-5000:]223 return "No logs found."224 225 def add_visual_rule(rules, indicator, op, val, action, amount, asset):226 new_rule = f"IF {indicator} {op} {val}:\n {action} {amount}% {asset}"227 if rules.strip():228 return f"{rules}\n{new_rule}"229 return new_rule230 231 def load_template(template_name):232 return STRATEGY_TEMPLATES.get(template_name, "")233 234 def clear_rules():235 return ""236 237 def update_terminal(m, a, r, h, s_mode):238 data = run_intelligence_simulation(m, a, r, h)239 results = get_intelligence_data(s_mode)240 241 # results contains 18 values, but run_btn.click outputs expects 19 (including log_viewer)242 # We need to add log_viewer output value243 logs = get_logs()244 return (*results, logs)245 246 run_btn.click(247 fn=update_terminal,248 inputs=[m_type, a_type, rules_editor, hybrid_toggle, summary_mode],249 outputs=[250 equity_metric, pnl_metric, vix_metric, 251 rl_monitor_panel, xai_panel, rl_stats_panel, lab_status_panel,252 fig_candle, fig_pnl, fig_pie, fig_risk, fig_fkg, fig_equity, fig_dd, fig_scatter, fig_sector,253 trade_table, summary_display, log_viewer254 ]255 )256 257 add_rule_btn.click(258 fn=add_visual_rule,259 inputs=[rules_editor, v_indicator, v_operator, v_value, v_action, v_amount, v_asset],260 outputs=rules_editor261 )262 263 apply_template_btn.click(264 fn=load_template,265 inputs=template_sel,266 outputs=rules_editor267 )268 269 clear_rules_btn.click(270 fn=clear_rules,271 outputs=rules_editor272 )273 274if __name__ == "__main__":275 import argparse276 parser = argparse.ArgumentParser()277 parser.add_argument("--server_port", type=int, default=7860)278 args = parser.parse_known_args()[0]279 demo.launch(server_port=args.server_port, theme=FinomIQTheme())280 