forex_analyzer / app.py
Yaroslav95's picture
ssr false
79c3a6c
import os
import sys
import requests
from openai import OpenAI
import pandas as pd
import pandas_ta as ta
import yfinance as yf
from dotenv import load_dotenv
import gradio as gr
# Load environment variables
load_dotenv()
class IntelligentForexAnalyzer:
def __init__(self):
print(f"Python version: {sys.version}")
print("IntelligentForexAnalyzer initialized.\n")
def get_forex_data(self, pair, period="1y", interval="1h"):
"""
Fetches Forex data from Yahoo Finance and calculates RSI, MACD, and Bollinger Bands.
"""
try:
print(f"Fetching data for {pair}...")
symbol = f"{pair.upper()}=X"
df = yf.download(symbol, period=period, interval=interval, progress=False)
if df.empty:
print(f"No data returned for {symbol}. Check the pair or interval.")
return None
print(df.head()) # Debug fetched data
# Calculate indicators
df["RSI"] = ta.rsi(df["Close"], length=14)
macd = ta.macd(df["Close"])
if macd is not None:
df["MACD"] = macd["MACD_12_26_9"]
df["MACD_signal"] = macd["MACDs_12_26_9"]
df["MACD_hist"] = macd["MACDh_12_26_9"]
else:
df["MACD"], df["MACD_signal"], df["MACD_hist"] = None, None, None
bb = ta.bbands(df["Close"], length=20, std=2)
if bb is not None:
df["BB_lower"], df["BB_mid"], df["BB_upper"] = (
bb["BBL_20_2.0"],
bb["BBM_20_2.0"],
bb["BBU_20_2.0"],
)
else:
df["BB_lower"], df["BB_mid"], df["BB_upper"] = None, None, None
return df
except Exception as e:
print(f"Error fetching data for {pair}: {e}")
return None
def analyze_pairs(self, pairs):
"""
Analyzes Forex pairs and summarizes indicators for trading decisions.
"""
results = {}
for pair in pairs:
df = self.get_forex_data(pair)
if df is None:
results[pair] = "No data available"
continue
close_price = df["Close"].iloc[-1]
rsi = df["RSI"].iloc[-1]
macd = df["MACD"].iloc[-1]
macd_signal = df["MACD_signal"].iloc[-1]
macd_hist = df["MACD_hist"].iloc[-1]
bb_lower = df["BB_lower"].iloc[-1]
bb_upper = df["BB_upper"].iloc[-1]
indicators = {
"Close Price": close_price,
"RSI": f"{rsi:.2f}" if not pd.isna(rsi) else "Not available",
"MACD": f"{macd:.2f}" if not pd.isna(macd) else "Not available",
"MACD Signal": (
f"{macd_signal:.2f}"
if not pd.isna(macd_signal)
else "Not available"
),
"MACD Hist": (
f"{macd_hist:.2f}" if not pd.isna(macd_hist) else "Not available"
),
"Bollinger Bands": (
f"{bb_lower:.2f} - {bb_upper:.2f}"
if not pd.isna(bb_lower) and not pd.isna(bb_upper)
else "Not available"
),
}
decision = self.make_trading_decision(indicators)
results[pair] = {"Indicators": indicators, "Decision": decision}
return results
def make_trading_decision(self, indicators):
"""
Makes a basic trading decision based on indicators.
"""
rsi = float(indicators["RSI"]) if indicators["RSI"] != "Not available" else None
macd = (
float(indicators["MACD"]) if indicators["MACD"] != "Not available" else None
)
macd_signal = (
float(indicators["MACD Signal"])
if indicators["MACD Signal"] != "Not available"
else None
)
close_price = indicators["Close Price"]
if rsi is not None:
if rsi < 30:
return f"LONG: RSI={rsi} indicates oversold conditions."
elif rsi > 70:
return f"SHORT: RSI={rsi} indicates overbought conditions."
if macd is not None and macd_signal is not None:
if macd > macd_signal:
return (
f"LONG: MACD={macd} is above Signal={macd_signal} (bullish trend)."
)
elif macd < macd_signal:
return (
f"SHORT: MACD={macd} is below Signal={macd_signal} (bearish trend)."
)
return f"HOLD: Price={close_price} within Bollinger range."
def analyze_with_llm(self, analysis_results):
"""
Uses OpenAI GPT for deeper insights using the updated ChatCompletion API.
"""
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
messages = [
{
"role": "system",
"content": "You are a Forex trading assistant. Analyze the following data:",
}
]
for pair, data in analysis_results.items():
if isinstance(data, str):
messages.append(
{"role": "user", "content": f"PAIR: {pair}\nError: {data}"}
)
else:
messages.append(
{
"role": "user",
"content": f"PAIR: {pair}\nIndicators: {data['Indicators']}\nDecision: {data['Decision']}",
}
)
try:
response = client.chat.completions.create(
model="gpt-3.5-turbo", messages=messages, temperature=0.5
)
return response.choices[0].message.content.strip()
except Exception as e:
return f"Error during LLM analysis: {e}"
def analyze_forex(forex_pairs):
pairs = forex_pairs.split(",")
analyzer = IntelligentForexAnalyzer()
analysis = analyzer.analyze_pairs([pair.strip() for pair in pairs])
llm_result = analyzer.analyze_with_llm(analysis)
result = "\n\n".join([f"{pair}: {data}" for pair, data in analysis.items()])
return result, llm_result
interface = gr.Interface(
fn=analyze_forex,
inputs=gr.Textbox(
label="Enter Forex Pairs (comma-separated)",
placeholder="e.g., EURUSD, GBPUSD, USDJPY",
),
outputs=[gr.Textbox(label="Analysis Results"), gr.Textbox(label="LLM analysis")],
title="Intelligent Forex Analyzer",
description="Enter Forex pairs to analyze their RSI, MACD, and Bollinger Bands and get trading recommendations.",
)
def auth_function(username, password):
valid_users = {"admin": "demo4nicolas"}
return username in valid_users and valid_users[username] == password
if __name__ == "__main__":
interface.launch(auth=auth_function, share=True, ssr_mode=False)
# if __name__ == "__main__":
# analyzer = IntelligentForexAnalyzer()
# forex_pairs = ["EURUSD", "GBPUSD", "USDJPY"]
# analysis = analyzer.analyze_pairs(forex_pairs)
# print("\n=== Forex Analysis ===")
# for pair, data in analysis.items():
# print(f"{pair}: {data}")
# llm_output = analyzer.analyze_with_llm(analysis)
# print("\n=== LLM Analysis ===")
# print(llm_output)