import os import sys import io import requests import gradio as gr import pandas as pd import yfinance as yf from bs4 import BeautifulSoup from pypdf import PdfReader from llama_cpp import Llama import faiss import numpy as np from sentence_transformers import SentenceTransformer from huggingface_hub import hf_hub_download MODEL_PATH = hf_hub_download( repo_id="bartowski/gemma-2-2b-it-GGUF", # example repo filename="gemma-2-2b-it-Q4_K_M.gguf" # exact file name ) # ===================================================== # 1. MODEL & STORAGE CONFIGURATION # ===================================================== # MODEL_PATH = "gemma-4-E2B-it-Q8_0.gguf" # if not os.path.exists(MODEL_PATH): # MODEL_PATH = "model.gguf" # if not os.path.exists(MODEL_PATH): # raise FileNotFoundError("āš ļø GGUF Model binary not found. Place file at root as 'model.gguf'") print("šŸš€ Mounting local LLM layers...") llm = Llama(model_path=MODEL_PATH, n_ctx=8192, n_threads=4) print("šŸ“¦ Embedding system initializing...") embed_model = SentenceTransformer("all-MiniLM-L6-v2") faiss_index = faiss.IndexFlatL2(384) strategy_database = {} current_id = 0 VALID_INDICATORS = ["RSI", "SMA", "EMA", "MACD", "BOLLINGER", "STOCHASTIC", "ADX", "VOLUME"] def add_to_faiss(text): global current_id emb = embed_model.encode([text]).astype("float32") faiss_index.add(emb) strategy_database[current_id] = text current_id += 1 # Seed some cool strategies add_to_faiss("SMA Crossover Strategy: Buy long when the 50 SMA crosses above the 200 SMA trendlines. Close positions when the fast 50 SMA moves below the 200 SMA.") add_to_faiss("RSI Oscillator Reversion Strategy: Initiate entry buys when the 14-period RSI indicator drops lower than 30. Trigger an exit when RSI moves above 70.") # ===================================================== # 2. RUNTIME BACKTEST SANDBOX # ===================================================== def run_backtest_sandbox(code_str, ticker): if "class AIStrategy(bt.Strategy)" not in code_str: return "āŒ Backtest Engine Aborted: Output lacks 'class AIStrategy(bt.Strategy)' definition layout." if "```python" in code_str: code_str = code_str.split("```python")[1].split("```")[0] old_stdout = sys.stdout buf = io.StringIO() sys.stdout = buf try: import backtrader as bt import pandas as pd env = {"bt": bt, "pd": pd} exec(code_str, env) Strat = env.get("AIStrategy") cerebro = bt.Cerebro() cerebro.addstrategy(Strat) df = yf.download(ticker, period="1y", interval="1d", progress=False) if isinstance(df.columns, pd.MultiIndex): df.columns = df.columns.get_level_values(0) if df.empty: sys.stdout = old_stdout return f"āŒ Data Feed Error: Empty dataset found for symbol: {ticker}" data = bt.feeds.PandasData(dataname=df) print(df.head()) cerebro.adddata(data) cerebro.broker.setcash(10000) print(f"\n⚔ BACKTEST ENGINE ACTIVE: {ticker} ⚔") print("🟢 STARTING EQUITY BASE : $", cerebro.broker.getvalue()) cerebro.run() print("šŸ”“ FINAL PORTFOLIO VALUE: $", cerebro.broker.getvalue()) # fig = cerebro.plot(style='candlestick')[0][0] sys.stdout = old_stdout return buf.getvalue() except Exception as e: sys.stdout = old_stdout return f"āŒ Sandbox Runtime Crash:\n{str(e)}" # ===================================================== # 3. FAISS SEARCH + CODE GENERATION PIPELINE # ===================================================== def code_gen_pipeline(query, ticker): if faiss_index.ntotal == 0: return "āš ļø Index records are empty.", "", "" q = np.array(embed_model.encode([query])).astype("float32") D, I = faiss_index.search(q, 1) # 1 means only give one best matching idx = I[0][0] if idx not in strategy_database: return "āŒ No closely matching strategy setup discovered in FAISS vectors.", "", "" strategy = strategy_database[idx] prompt = f""" Write Backtrader strategy class AIStrategy(bt.Strategy). Strategy: {strategy} """ res = llm.create_chat_completion( messages=[ {"role": "system", "content": "Generate ONLY python backtrader code"}, {"role": "user", "content": prompt} ], temperature=0 ) code = res["choices"][0]["message"]["content"] logs = run_backtest_sandbox(code, ticker) return f"FAISS HIT {idx}", code, logs # ===================================================== # 4. CHAT LOGIC WITH AUTOMATED 1-YEAR PLOT RENDERING # ===================================================== import re TICKER_MAP = { "apple": "AAPL", "aapl": "AAPL", "tesla": "TSLA", "tsla": "TSLA", "microsoft": "MSFT", "msft": "MSFT", "google": "GOOG", "alphabet": "GOOG", "goog": "GOOG", "amazon": "AMZN", "amzn": "AMZN", "nvidia": "NVDA", "nvda": "NVDA", "bitcoin": "BTC-USD", "btc": "BTC-USD", "btc-usd": "BTC-USD", "ethereum": "ETH-USD", "eth": "ETH-USD", "eth-usd": "ETH-USD", } def resolve_ticker(text): text = text.lower() # check company names first for keyword, ticker in TICKER_MAP.items(): if re.search(rf"\b{re.escape(keyword)}\b", text): return ticker return None import yfinance as yf def interactive_chat_pipeline(message, history): history = history or [] ticker = resolve_ticker(message) market_context = "" if ticker: try: df = yf.download( ticker, period="3mo", interval="1d", auto_adjust=True, progress=False ) market_context = ( df.tail(20) .reset_index() .to_json(orient="records") ) except Exception as e: market_context = f"Market data error: {e}" system_prompt = f""" You are a professional quantitative trading assistant. Analyze the supplied market data. Tasks: - Identify trend - Identify support and resistance - Analyze volume - Analyze momentum - Analyze price action - Analyze volatility Output format: Recommendation: BUY / SELL / HOLD Confidence: 0-100% Reasoning: - Trend - Momentum - Risk If data is weak, return HOLD. Market Data: {market_context} """ messages = [ { "role": "system", "content": system_prompt } ] messages.extend(history) messages.append( { "role": "user", "content": message } ) try: res = llm.create_chat_completion( messages=messages, temperature=0.2, max_tokens=500 ) reply = res["choices"][0]["message"]["content"] except Exception as e: reply = f"LLM Error: {e}" history.append( { "role": "user", "content": message } ) history.append( { "role": "assistant", "content": reply } ) return history # ===================================================== # 5. STRATEGY Encoding and Retrieval LAYER # ===================================================== def extract_and_save_strategy(url, file_obj, text): content = "" if url and url.strip(): try: r = requests.get(url, headers={'User-Agent': 'Mozilla'}, timeout=5) content = "\n".join([p.get_text() for p in BeautifulSoup(r.text, "html.parser").find_all(['p', 'li'])]) except Exception as e: return f"āŒ Web Scraper Fault Exception: {str(e)}" elif file_obj: try: if file_obj.name.endswith(".pdf"): content = "\n".join([p.extract_text() for p in PdfReader(file_obj.name).pages]) else: content = open(file_obj.name, "r", encoding="utf-8").read() except Exception as e: return f"āŒ Local I/O Extraction Error: {str(e)}" else: content = text if not content or not content.strip(): return "āš ļø Validation Halted: Targeted input field contains empty string payloads." # Ingestion check gate implementation upper_payload = content.upper() triggered_indicators = [ind for ind in VALID_INDICATORS if ind in upper_payload] if not triggered_indicators: return ( "### šŸ›‘ INGESTION PIPELINE BLOCKED!\n\n" "**Reason:** No verified quantitative indicator markers were located in the document material. " "Fluff files are filtered out to guarantee database consistency." ) extracted = llm.create_chat_completion( messages=[ {"role": "system", "content": "Extract only the clean operational trading parameters, indicator constraints, and signals from this document raw string layout."}, {"role": "user", "content": content[:3000]} ], temperature=0.0, max_tokens=500 )["choices"][0]["message"]["content"] assigned_index_row = int(current_id) add_to_faiss(extracted) return ( f"### šŸŽ‰ FAISS Insertion Success! Verified Index Key: [{assigned_index_row}]\n" f"**Indicators Triggered:** `{', '.join(triggered_indicators)}` \n\n" f"--- \n\n" f"**Stored Database Entry Matrix Structure:**\n{extracted}" ) def show_db(): if not strategy_database: return "FAISS Vectors Storage registers empty." return "\n\n".join([f"šŸ“Š **[Index Entry ID: {k}]**\n> {v}\n---" for k, v in strategy_database.items()]) # ===================================================== # 6. NEON THEMED GRADIO WORKSPACE ASSEMBLY # ===================================================== # Applying a colorful custom theme hue palette configuration landscape layout theme = gr.themes.Default( primary_hue="emerald", secondary_hue="blue", neutral_hue="slate" ).set( # --- LIGHT MODE OVERRIDES --- body_background_fill_dark="*neutral_50", # Forces light background even if system is dark body_background_fill="*neutral_50", # Clean, crisp terminal backdrop block_background_fill="*white", # Stark white component cards # --- NEON LIGHTNING ACCENTS --- block_border_width="2px", # Defined component frames block_border_color="*primary_400", # Electric emerald outline bounding boxes block_label_text_color="*primary_600", # High-visibility indicator labels button_primary_background_fill="*primary_500", # High-contrast action buttons button_primary_text_color="*white" ) with gr.Blocks(theme=theme) as demo: gr.Markdown("# LIVE Recommendation Trading Agent and Store strategy") gr.Markdown("⚔ Fully analytical assistant deploying localized LLM generation loops, FAISS memory pools, and live streaming data layers.") with gr.Tabs(): # TAB 1: CODE GENERATION ENGINE with gr.Tab("šŸ’» Code Engine Studio"): gr.Markdown("### šŸ¤– Retrieval-Augmented Strategy Synthesis") with gr.Row(): with gr.Column(scale=1): q_input = gr.Textbox(label="Strategy Formula Query", value="SMA crossover strategy") t_input = gr.Dropdown(["AAPL", "MSFT", "TSLA", "NVDA"], value="AAPL", label="Asset Testing Vector Target") run_btn = gr.Button("⚔ Query Database & Backtest", variant="primary") gr.Markdown("---") meta_out = gr.Textbox(label="FAISS Routing Matrix Status Logs", interactive=False) with gr.Column(scale=2): code_out = gr.Code(label="AI Synthesized Code Structure (Backtrader Framework)", language="python") logs_out = gr.Textbox(label="Virtual Machine Terminal Execution Trace Logs", lines=12, interactive=False) run_btn.click(code_gen_pipeline, [q_input, t_input], [meta_out, code_out, logs_out]) # TAB 2: LIVE MARKET CHAT WITH INTERACTIVE 1-YEAR TREND CHARTS with gr.Tab("šŸ’¬ Live Recommendation "): gr.Markdown("### šŸ“ˆ Real-Time Indicator Analytical Interface") gr.Markdown("Mention asset terms such as **Apple**, **Tesla**, or **Bitcoin** in your prompt message to spin up live pricing indexes and interactive analytical chart plots.") with gr.Row(): with gr.Column(scale=2): chatbot = gr.Chatbot(label="Interactive AI Terminal History Log Window", height=450) chat_input = gr.Textbox(placeholder="Inquire here... e.g., 'What is the price of Apple right now? Is it increasing?'", label="Command Center Text Stream Input") submit_btn = gr.Button("šŸ”„ Send Command", variant="primary") # Link operational interactive event loops triggers submit_btn.click( interactive_chat_pipeline, inputs=[chat_input, chatbot], outputs=[chatbot] ) chat_input.submit( interactive_chat_pipeline, inputs=[chat_input, chatbot], outputs=[chatbot] ) # TAB 3: FILTER-GUARDED DOCUMENT INGESTION PIPELINE with gr.Tab("šŸ“„ Strategy Encoding and Retrieval"): gr.Markdown("### šŸ—„ļø Using FAISS to encode and retrieve strategy based on indicators only") with gr.Row(): with gr.Column(scale=1): with gr.Accordion("Option A: Live Site HTML Address String Ingest", open=False): url_input = gr.Textbox(label="Target URL Link Path", placeholder="https://") with gr.Accordion("Option B: Structured Document Object Loader", open=False): file_input = gr.File(label="Upload File Source (.pdf, .txt, .md)", file_types=[".pdf", ".txt", ".md"]) with gr.Accordion("Option C: Raw Clipboard Text Editor", open=True): txt_input = gr.Textbox(label="Manual Formula Configuration Entry Field", lines=6, value="Paste trading manuals here...") save_btn = gr.Button("šŸ”’ Evaluate & Archive Data Parameters", variant="secondary") with gr.Column(scale=1): ingest_out = gr.Markdown(value="*System Status monitor: Standby mode active... Ready for next validation sequence.*") save_btn.click(extract_and_save_strategy, [url_input, file_input, txt_input], ingest_out) # TAB 4: DATABASE CONTROL SCREEN with gr.Tab("šŸ—ƒļø Strategy Database"): gr.Markdown("### šŸ” List of strategy") refresh_btn = gr.Button("šŸ”„ Synchronize Storage Index Table Rows", variant="panel") db_display = gr.Markdown(value=show_db()) refresh_btn.click(show_db, [], db_display) if __name__ == "__main__": demo.launch()