akashraut commited on
Commit
d951a81
·
verified ·
1 Parent(s): 77430b2

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +113 -0
app.py ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app.py
2
+ import yfinance as yf
3
+ import pandas as pd
4
+ import numpy as np
5
+ from datetime import datetime, timedelta
6
+ import gradio as gr
7
+ import matplotlib.pyplot as plt
8
+ from io import BytesIO
9
+ from statsmodels.tsa.arima.model import ARIMA
10
+ from mcp import Client
11
+ from langchain.prompts import PromptTemplate
12
+ from langchain.chains import LLMChain
13
+ from langchain.llms import OpenAI # Replace with local MCP-compatible LLM if needed
14
+ import re
15
+
16
+ # ---------------- MCP Setup ----------------
17
+ client = Client(api_key="YOUR_GROQ_API_KEY") # optional if MCP uses Groq API
18
+
19
+ # ---------------- Helper Functions ----------------
20
+ def fetch_metal_data(ticker="GC=F", period="1mo", interval="1d"):
21
+ """Fetch historical data for a metal."""
22
+ df = yf.download(ticker, period=period, interval=interval)
23
+ df = df.reset_index()
24
+ df = df[['Date', 'Close']]
25
+ df.rename(columns={'Close': 'Price'}, inplace=True)
26
+ return df
27
+
28
+ def predict_next_days(df, days=5):
29
+ """Predict next 'days' prices using ARIMA."""
30
+ try:
31
+ model = ARIMA(df['Price'], order=(2,1,2))
32
+ model_fit = model.fit()
33
+ forecast = model_fit.forecast(steps=days)
34
+ forecast_dates = [df['Date'].iloc[-1] + timedelta(days=i+1) for i in range(days)]
35
+ return pd.DataFrame({"Date": forecast_dates, "Predicted_Price": forecast})
36
+ except Exception as e:
37
+ return pd.DataFrame({"Date": [], "Predicted_Price": []})
38
+
39
+ def plot_forecast(df, forecast_df, metal):
40
+ plt.figure(figsize=(10,5))
41
+ plt.plot(df['Date'], df['Price'], label="Historical")
42
+ plt.plot(forecast_df['Date'], forecast_df['Predicted_Price'], label="Forecast", linestyle="--")
43
+ plt.title(f"{metal.capitalize()} Price Forecast")
44
+ plt.xlabel("Date")
45
+ plt.ylabel("Price")
46
+ plt.legend()
47
+ buf = BytesIO()
48
+ plt.savefig(buf, format='png')
49
+ buf.seek(0)
50
+ plt.close()
51
+ return buf
52
+
53
+ # ---------------- LangChain Prompt ----------------
54
+ prompt_template = """
55
+ Extract the metal and number of forecast days from user query.
56
+ User Query: "{query}"
57
+ Return as JSON with keys: "metal" ("gold" or "silver") and "days" (integer).
58
+ """
59
+
60
+ prompt = PromptTemplate(
61
+ input_variables=["query"],
62
+ template=prompt_template
63
+ )
64
+ llm = OpenAI(temperature=0) # Replace with MCP-compatible LLM if needed
65
+ chain = LLMChain(llm=llm, prompt=prompt)
66
+
67
+ def parse_query(query):
68
+ # Use LangChain to parse
69
+ try:
70
+ response = chain.run(query)
71
+ # Extract values from JSON-like string
72
+ metal = re.search(r'"metal"\s*:\s*"(\w+)"', response).group(1).lower()
73
+ days = int(re.search(r'"days"\s*:\s*(\d+)', response).group(1))
74
+ days = min(max(days, 1), 7) # limit 1-7 days
75
+ return metal, days
76
+ except:
77
+ # fallback
78
+ return "gold", 3
79
+
80
+ # ---------------- MCP Wrapped Function ----------------
81
+ @client.wrap
82
+ def metal_forecast_agent(query: str):
83
+ metal, days = parse_query(query)
84
+ ticker_map = {"gold": "GC=F", "silver": "SI=F"}
85
+ ticker = ticker_map.get(metal, "GC=F")
86
+ df = fetch_metal_data(ticker=ticker)
87
+ forecast_df = predict_next_days(df, days=days)
88
+ latest_price = float(df['Price'].iloc[-1])
89
+ plot_buf = plot_forecast(df, forecast_df, metal)
90
+ return {
91
+ "metal": metal,
92
+ "latest_price": latest_price,
93
+ "forecast": forecast_df.to_dict(orient="records"),
94
+ "plot_buf": plot_buf
95
+ }
96
+
97
+ # ---------------- Gradio Interface ----------------
98
+ def gr_metal_agent(query):
99
+ result = metal_forecast_agent(query)
100
+ latest_text = f"Latest {result['metal'].capitalize()} Price: {result['latest_price']:.2f}"
101
+ forecast_df = pd.DataFrame(result['forecast'])
102
+ return latest_text, forecast_df, result['plot_buf']
103
+
104
+ iface = gr.Interface(
105
+ fn=gr_metal_agent,
106
+ inputs=gr.Textbox(label="Ask about metal prices, e.g., 'gold next 5 days'"),
107
+ outputs=[gr.Textbox(label="Latest Price"), gr.Dataframe(label="Forecast"), gr.Image(label="Forecast Plot")],
108
+ title="Metal Price Predictor (MCP + LangChain)",
109
+ description="Ask naturally for gold/silver forecast and get live + predicted prices."
110
+ )
111
+
112
+ if __name__ == "__main__":
113
+ iface.launch()