Spaces:
Running
Running
| import gradio as gr | |
| from services.llm_client import llm_service | |
| from core.analyzer import PortfolioAnalyzer | |
| from core.comparer import PortfolioComparer | |
| from core.chat import ChatAssistant | |
| from core.metrics import show_metrics_table | |
| from core.visualization import build_alpha_chart | |
| from core.crypto_dashboard import build_crypto_dashboard # 🆕 новая вкладка | |
| # === Model setup === | |
| MODEL_NAME = "meta-llama/Meta-Llama-3.1-8B-Instruct" | |
| analyzer = PortfolioAnalyzer(llm_service, MODEL_NAME) | |
| comparer = PortfolioComparer(llm_service, MODEL_NAME) | |
| chatbot = ChatAssistant(llm_service, MODEL_NAME) | |
| # === Theme === | |
| dark_theme = gr.themes.Base( | |
| primary_hue="violet", | |
| secondary_hue="gray", | |
| neutral_hue="zinc", | |
| ).set( | |
| body_background_fill="#0d1117", | |
| body_text_color="#e6edf3", | |
| block_background_fill="#161b22", | |
| block_border_color="#30363d", | |
| button_primary_background_fill="#4f46e5", | |
| button_primary_background_fill_hover="#6366f1", | |
| button_primary_text_color="#ffffff", | |
| input_background_fill="#0d1117", | |
| block_shadow="0 2px 6px rgba(0,0,0,0.3)", | |
| block_label_text_color="#9da5b4", | |
| block_label_text_size="sm", | |
| ) | |
| with gr.Blocks(theme=dark_theme, css=""" | |
| #root, [data-testid="block-container"] { | |
| max-width: 1050px !important; | |
| margin: auto !important; | |
| } | |
| .gradio-container { font-family: 'Inter', sans-serif; background-color:#0d1117!important;} | |
| #llm_comment_box textarea,#analysis_output textarea{ | |
| min-height:520px!important;background-color:#161b22!important;color:#f0f6fc!important; | |
| border:1px solid #30363d!important;border-radius:6px!important;font-family:'JetBrains Mono',monospace!important; | |
| } | |
| .gr-dataframe table{width:100%!important;color:#c9d1d9!important;background:#161b22!important;} | |
| .gr-dataframe th{background:#21262d!important;color:#f0f6fc!important;border-bottom:1px solid #30363d!important;} | |
| .gr-dataframe td{border-top:1px solid #30363d!important;padding:8px!important;} | |
| """) as demo: | |
| gr.Markdown("## Investment Portfolio Analyzer") | |
| gr.Markdown( | |
| "Professional AI-driven analytics for investment and crypto markets.", | |
| elem_classes="subtitle", | |
| ) | |
| with gr.Tabs(): | |
| # --- Analysis --- | |
| with gr.TabItem("Analysis"): | |
| portfolio_input = gr.Textbox(label="Portfolio ID or Link", | |
| placeholder="Enter portfolio ID (uuid)", | |
| value="b1ef37aa-5b9a-41b4-9394-8823f2de36bb") | |
| analyze_btn = gr.Button("Run Analysis", variant="primary") | |
| analyze_out = gr.Textbox(label="Analysis Result", lines=15, elem_id="analysis_output") | |
| analyze_btn.click(fn=analyzer.run, inputs=portfolio_input, outputs=analyze_out) | |
| # --- Comparison --- | |
| with gr.TabItem("Comparison Table"): | |
| from core.comparison_table import show_comparison_table | |
| pid_a = gr.Textbox(label="Portfolio A", value="3852a354-e66e-4bc5-97e9-55124e31e687") | |
| pid_b = gr.Textbox(label="Portfolio B", value="b1ef37aa-5b9a-41b4-9394-8823f2de36bb") | |
| compare_btn = gr.Button("Load Comparison", variant="primary") | |
| comp_table = gr.Dataframe(label="Comparative Metrics", wrap=True) | |
| comp_comment = gr.Textbox(label="AI Commentary", lines=14, elem_id="llm_comment_box") | |
| compare_btn.click(fn=show_comparison_table, | |
| inputs=[pid_a, pid_b], | |
| outputs=[comp_table, comp_comment]) | |
| # --- Assistant --- | |
| with gr.TabItem("Assistant"): | |
| chat_in = gr.Textbox(label="Ask about investments or analysis") | |
| chat_btn = gr.Button("Send Question", variant="primary") | |
| chat_out = gr.Textbox(label="AI Response", lines=8) | |
| chat_btn.click(fn=chatbot.run, inputs=chat_in, outputs=chat_out) | |
| # --- Metrics --- | |
| with gr.TabItem("Metrics Table"): | |
| metrics_in = gr.Textbox(label="Portfolio ID", value="b1ef37aa-5b9a-41b4-9394-8823f2de36bb") | |
| metrics_btn = gr.Button("Load Metrics", variant="primary") | |
| metrics_out = gr.Dataframe(label="Portfolio Metrics", wrap=True) | |
| metrics_btn.click(fn=show_metrics_table, inputs=metrics_in, outputs=metrics_out) | |
| # --- AlphaBTC Chart --- | |
| with gr.TabItem("AlphaBTC Chart"): | |
| chart_in = gr.Textbox(label="Portfolio ID", value="3852a354-e66e-4bc5-97e9-55124e31e687") | |
| chart_btn = gr.Button("Generate Chart", variant="primary") | |
| chart_out = gr.Plot(label="Alpha vs BTC") | |
| chart_btn.click(fn=build_alpha_chart, inputs=chart_in, outputs=chart_out) | |
| # --- Crypto Intelligence Dashboard (refactored) --- | |
| with gr.TabItem("Crypto Intelligence Dashboard"): | |
| gr.Markdown("### 📊 Unified Market Intelligence (Binance + TradingView)") | |
| with gr.Row(): | |
| assets_select = gr.CheckboxGroup( | |
| label="Select assets", | |
| choices=["BTCUSDT", "ETHUSDT", "BNBUSDT", "SOLUSDT", "DOGEUSDT"], | |
| value=["BTCUSDT", "ETHUSDT"] | |
| ) | |
| start_picker = gr.DatePicker(label="Start Date", value=(datetime.now() - timedelta(days=365*2))) | |
| end_picker = gr.DatePicker(label="End Date", value=datetime.now()) | |
| load_btn = gr.Button("Load Market Data", variant="primary") | |
| price_plot = gr.Plot(label="Recent Market (Binance)") | |
| hist_plot = gr.Plot(label="Historical Chart (TradingView)") | |
| ai_summary = gr.Textbox(label="AI Market Summary", lines=8, elem_id="llm_comment_box") | |
| from core.crypto_dashboard import build_crypto_dashboard | |
| load_btn.click( | |
| fn=build_crypto_dashboard, | |
| inputs=[assets_select, start_picker, end_picker], | |
| outputs=[price_plot, hist_plot, ai_summary], | |
| show_progress="minimal", | |
| ) | |
| gr.Markdown("---") | |
| gr.Markdown( | |
| "<center><small style='color:#6e7681;'>Developed with Featherless.ai • Powered by OpenAI-compatible API</small></center>", | |
| elem_classes="footer", | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch() | |