| 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", |
| filename="gemma-2-2b-it-Q4_K_M.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 |
|
|
| |
| 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.") |
|
|
|
|
| |
| |
| |
| 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()) |
| |
|
|
| sys.stdout = old_stdout |
| return buf.getvalue() |
|
|
| except Exception as e: |
| sys.stdout = old_stdout |
| return f"β Sandbox Runtime Crash:\n{str(e)}" |
|
|
|
|
| |
| |
| |
| 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) |
| 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 |
|
|
|
|
| |
| |
| |
| 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() |
|
|
| |
| 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 |
|
|
|
|
|
|
| |
| |
| |
| 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." |
|
|
| |
| 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()]) |
|
|
|
|
| |
| |
| |
| |
| theme = gr.themes.Default( |
| primary_hue="emerald", |
| secondary_hue="blue", |
| neutral_hue="slate" |
| ).set( |
| |
| body_background_fill_dark="*neutral_50", |
| body_background_fill="*neutral_50", |
| block_background_fill="*white", |
| |
| |
| block_border_width="2px", |
| block_border_color="*primary_400", |
| block_label_text_color="*primary_600", |
| button_primary_background_fill="*primary_500", |
| 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(): |
| |
| |
| 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]) |
|
|
| |
| 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") |
|
|
| |
| submit_btn.click( |
| interactive_chat_pipeline, |
| inputs=[chat_input, chatbot], |
| outputs=[chatbot] |
| ) |
|
|
| chat_input.submit( |
| interactive_chat_pipeline, |
| inputs=[chat_input, chatbot], |
| outputs=[chatbot] |
| ) |
|
|
| |
| 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) |
|
|
| |
| 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() |