Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -3,28 +3,50 @@ from bs4 import BeautifulSoup
|
|
| 3 |
import pandas as pd
|
| 4 |
from io import StringIO
|
| 5 |
from datetime import datetime, timedelta
|
| 6 |
-
from openai import OpenAI
|
| 7 |
-
import gradio as gr
|
| 8 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
OPENROUTER_API_KEY = "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"
|
| 10 |
|
| 11 |
HEADERS = {
|
| 12 |
-
'User-Agent':
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
'Accept-Language': 'en-US,en;q=0.9',
|
| 14 |
-
'Referer': 'https://www.google.com/'
|
|
|
|
|
|
|
|
|
|
| 15 |
}
|
| 16 |
|
| 17 |
-
|
|
|
|
|
|
|
| 18 |
url = f'https://www.marketwatch.com/investing/stock/{symbol}'
|
| 19 |
response = requests.get(url, headers=HEADERS)
|
| 20 |
if response.status_code == 200:
|
| 21 |
soup = BeautifulSoup(response.text, 'html.parser')
|
| 22 |
price_tag = soup.find('bg-quote', class_='value')
|
| 23 |
if price_tag:
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 28 |
end_date = datetime.now()
|
| 29 |
start_date = end_date - timedelta(days=days)
|
| 30 |
start_date_str = start_date.strftime('%m/%d/%Y 00:00:00')
|
|
@@ -39,12 +61,15 @@ def get_historical_data(symbol: str, days=30):
|
|
| 39 |
if response.status_code == 200:
|
| 40 |
try:
|
| 41 |
df = pd.read_csv(StringIO(response.text))
|
| 42 |
-
return df
|
| 43 |
-
except Exception:
|
| 44 |
-
return
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
|
|
|
|
|
|
|
|
|
| 48 |
return """
|
| 49 |
Technical Analysis: Core Concepts & Formulas
|
| 50 |
-------------------------------------------
|
|
@@ -119,72 +144,45 @@ Key Technical Indicators and Their Formulas:
|
|
| 119 |
- Hammer, Shooting Star, Engulfing, Doji, Morning/Evening Star, etc.
|
| 120 |
"""
|
| 121 |
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
---
|
| 138 |
-
|
| 139 |
-
**Technical Analysis Documentation:**
|
| 140 |
-
{get_technical_analysis_docs()}
|
| 141 |
-
|
| 142 |
-
**Instructions:**
|
| 143 |
-
You must perform the entire analysis in one go — do not ask for any further data or clarification.
|
| 144 |
-
Perform the full process:
|
| 145 |
-
1. Review the historical OHLCV data provided.
|
| 146 |
-
2. Perform a rigorous, step-by-step technical analysis using the full range of indicators.
|
| 147 |
-
3. Identify trends, chart patterns, volume analysis, risk management.
|
| 148 |
-
4. Predict the next day’s closing price.
|
| 149 |
-
5. Justify your prediction with detailed reasoning.
|
| 150 |
-
---
|
| 151 |
-
**Step-by-Step Analysis Plan:**
|
| 152 |
-
1. Data Review and Preparation
|
| 153 |
-
2. Chart and Trend Analysis
|
| 154 |
-
3. Apply Core Technical Indicators
|
| 155 |
-
4. Pattern Recognition
|
| 156 |
-
5. Advanced Analysis
|
| 157 |
-
6. Confirmation and Risk Management
|
| 158 |
-
7. Prediction and Justification
|
| 159 |
-
8. Review and Backtesting (Optional)
|
| 160 |
-
---
|
| 161 |
-
**Output Format:**
|
| 162 |
-
- Predicted Price for Next Day:
|
| 163 |
-
- Detailed Reasoning:
|
| 164 |
-
- Trend analysis and key levels
|
| 165 |
-
- Indicator values and interpretations
|
| 166 |
-
- Patterns identified
|
| 167 |
-
- Volume analysis
|
| 168 |
-
- Confidence level and uncertainty factors
|
| 169 |
-
- Additional insights or warnings
|
| 170 |
-
"""
|
| 171 |
-
client = OpenAI(
|
| 172 |
-
base_url="https://openrouter.ai/api/v1",
|
| 173 |
-
api_key=OPENROUTER_API_KEY,
|
| 174 |
)
|
| 175 |
-
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
|
| 179 |
-
|
| 180 |
-
|
| 181 |
-
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
|
| 185 |
-
|
| 186 |
-
|
|
|
|
| 187 |
)
|
| 188 |
|
| 189 |
if __name__ == "__main__":
|
| 190 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3 |
import pandas as pd
|
| 4 |
from io import StringIO
|
| 5 |
from datetime import datetime, timedelta
|
|
|
|
|
|
|
| 6 |
|
| 7 |
+
from langchain.tools import tool
|
| 8 |
+
from langchain.agents import initialize_agent, Tool
|
| 9 |
+
from langchain_openai import ChatOpenAI
|
| 10 |
+
|
| 11 |
+
# === Configuration ===
|
| 12 |
OPENROUTER_API_KEY = "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"
|
| 13 |
|
| 14 |
HEADERS = {
|
| 15 |
+
'User-Agent': (
|
| 16 |
+
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
|
| 17 |
+
'AppleWebKit/537.36 (KHTML, like Gecko) '
|
| 18 |
+
'Chrome/124.0.0.0 Safari/537.36'
|
| 19 |
+
),
|
| 20 |
+
'Accept': (
|
| 21 |
+
'text/html,application/xhtml+xml,application/xml;'
|
| 22 |
+
'q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8'
|
| 23 |
+
),
|
| 24 |
'Accept-Language': 'en-US,en;q=0.9',
|
| 25 |
+
'Referer': 'https://www.google.com/',
|
| 26 |
+
'Connection': 'keep-alive',
|
| 27 |
+
'Cache-Control': 'max-age=0',
|
| 28 |
+
'Upgrade-Insecure-Requests': '1'
|
| 29 |
}
|
| 30 |
|
| 31 |
+
@tool("GetCurrentPrice")
|
| 32 |
+
def get_current_price(symbol: str) -> str:
|
| 33 |
+
"""Get the current price for a stock symbol (e.g., 'AAPL')."""
|
| 34 |
url = f'https://www.marketwatch.com/investing/stock/{symbol}'
|
| 35 |
response = requests.get(url, headers=HEADERS)
|
| 36 |
if response.status_code == 200:
|
| 37 |
soup = BeautifulSoup(response.text, 'html.parser')
|
| 38 |
price_tag = soup.find('bg-quote', class_='value')
|
| 39 |
if price_tag:
|
| 40 |
+
price = price_tag.get_text(strip=True)
|
| 41 |
+
return f"{symbol.upper()} current price: ${price} (from MarketWatch)"
|
| 42 |
+
else:
|
| 43 |
+
return "Stock price not found."
|
| 44 |
+
else:
|
| 45 |
+
return f"Failed to retrieve stock page. Status code: {response.status_code}"
|
| 46 |
+
|
| 47 |
+
@tool("GetHistoricalData")
|
| 48 |
+
def get_historical_data(symbol: str, days: int = 5000) -> str:
|
| 49 |
+
"""Get the last N days of historical OHLCV data for a stock symbol as CSV."""
|
| 50 |
end_date = datetime.now()
|
| 51 |
start_date = end_date - timedelta(days=days)
|
| 52 |
start_date_str = start_date.strftime('%m/%d/%Y 00:00:00')
|
|
|
|
| 61 |
if response.status_code == 200:
|
| 62 |
try:
|
| 63 |
df = pd.read_csv(StringIO(response.text))
|
| 64 |
+
return f"Historical data for {symbol.upper()} (from MarketWatch):\n" + df.head(10).to_csv(index=False)
|
| 65 |
+
except Exception as e:
|
| 66 |
+
return f"Failed to parse CSV data: {e}"
|
| 67 |
+
else:
|
| 68 |
+
return f"Failed to download historical data. Status code: {response.status_code}"
|
| 69 |
+
|
| 70 |
+
@tool("GetTechnicalAnalysisDocs")
|
| 71 |
+
def get_technical_analysis_docs(_: str = "") -> str:
|
| 72 |
+
"""Get documentation for technical analysis indicators."""
|
| 73 |
return """
|
| 74 |
Technical Analysis: Core Concepts & Formulas
|
| 75 |
-------------------------------------------
|
|
|
|
| 144 |
- Hammer, Shooting Star, Engulfing, Doji, Morning/Evening Star, etc.
|
| 145 |
"""
|
| 146 |
|
| 147 |
+
tools = [
|
| 148 |
+
Tool.from_function(
|
| 149 |
+
get_current_price,
|
| 150 |
+
name="GetCurrentPrice",
|
| 151 |
+
description="Get the current price for a stock symbol (e.g., AAPL)"
|
| 152 |
+
),
|
| 153 |
+
Tool.from_function(
|
| 154 |
+
get_historical_data,
|
| 155 |
+
name="GetHistoricalData",
|
| 156 |
+
description="Get the last N days of historical OHLCV data for a stock symbol as CSV"
|
| 157 |
+
),
|
| 158 |
+
Tool.from_function(
|
| 159 |
+
get_technical_analysis_docs,
|
| 160 |
+
name="GetTechnicalAnalysisDocs",
|
| 161 |
+
description="Provide documentation for technical analysis indicators"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 162 |
)
|
| 163 |
+
]
|
| 164 |
+
|
| 165 |
+
llm = ChatOpenAI(
|
| 166 |
+
openai_api_key=OPENROUTER_API_KEY,
|
| 167 |
+
openai_api_base="https://openrouter.ai/api/v1",
|
| 168 |
+
model_name="google/gemma-3n-e4b-it:free"
|
| 169 |
+
)
|
| 170 |
+
|
| 171 |
+
agent = initialize_agent(
|
| 172 |
+
tools,
|
| 173 |
+
llm,
|
| 174 |
+
agent="zero-shot-react-description",
|
| 175 |
+
verbose=True # This will show all reasoning and tool usage!
|
| 176 |
)
|
| 177 |
|
| 178 |
if __name__ == "__main__":
|
| 179 |
+
print("Welcome to the Stock Analysis Agent!")
|
| 180 |
+
print("Ask anything about stocks, technical analysis, or predictions.")
|
| 181 |
+
print("Type 'exit' to quit.")
|
| 182 |
+
while True:
|
| 183 |
+
user_input = input("\nYour question: ")
|
| 184 |
+
if user_input.lower() in ["exit", "quit"]:
|
| 185 |
+
print("Goodbye!")
|
| 186 |
+
break
|
| 187 |
+
result = agent.run(user_input)
|
| 188 |
+
print("\nAgent's answer:\n", result)
|