|
import requests |
|
import time |
|
import pytz |
|
import json |
|
from datetime import datetime, timedelta |
|
from timeframe import fetch_financial_data |
|
|
|
def get_times(): |
|
"""Get current time in different financial centers""" |
|
|
|
greenwich_tz = pytz.timezone('GMT') |
|
london_tz = pytz.timezone('Europe/London') |
|
newyork_tz = pytz.timezone('America/New_York') |
|
tokyo_tz = pytz.timezone('Asia/Tokyo') |
|
sydney_tz = pytz.timezone('Australia/Sydney') |
|
|
|
|
|
utc_now = datetime.now(pytz.utc) |
|
|
|
|
|
greenwich_time = utc_now.astimezone(greenwich_tz) |
|
london_time = utc_now.astimezone(london_tz) |
|
newyork_time = utc_now.astimezone(newyork_tz) |
|
tokyo_time = utc_now.astimezone(tokyo_tz) |
|
sydney_time = utc_now.astimezone(sydney_tz) |
|
|
|
|
|
time_format = "%Y-%m-%d %H:%M:%S %Z%z" |
|
|
|
times = { |
|
"Greenwich": greenwich_time.strftime(time_format), |
|
"London": london_time.strftime(time_format), |
|
"New York": newyork_time.strftime(time_format), |
|
"Tokyo": tokyo_time.strftime(time_format), |
|
"Sydney": sydney_time.strftime(time_format) |
|
} |
|
|
|
return times |
|
|
|
def chat_with_ai(chat_history, temperature=0.4): |
|
"""Send chat history to AI and get response""" |
|
url = "https://corvo-ai-xx-ry.hf.space/chat" |
|
|
|
headers = { |
|
"Content-Type": "application/json", |
|
} |
|
|
|
payload = { |
|
"chat_history": chat_history, |
|
"temperature": temperature, |
|
} |
|
|
|
max_retries = 3 |
|
retry_delay = 5 |
|
|
|
for attempt in range(max_retries): |
|
try: |
|
response = requests.post(url, headers=headers, json=payload, timeout=120) |
|
response.raise_for_status() |
|
result = response.json() |
|
return result.get("assistant_response", "No response received.") |
|
except Exception as e: |
|
if attempt < max_retries - 1: |
|
time.sleep(retry_delay) |
|
print(f"Retry {attempt+1}: Communication error - {str(e)}") |
|
else: |
|
print(f"Final attempt failed: {str(e)}") |
|
|
|
return "عذراً، واجهت مشكلة في الاتصال. يرجى المحاولة مرة أخرى لاحقاً. 🙁" |
|
|
|
def fetch_pair_data(pair): |
|
""" |
|
Fetch data for a pair in multiple timeframes with appropriate time ranges: |
|
- 15m: 3 days of data |
|
- 5min: 1 day of data |
|
|
|
Returns data for both timeframes or only what's available |
|
""" |
|
now = datetime.now() |
|
|
|
|
|
special_symbols = ["DX-Y.NYB", "GC=F", "^SPX", "WTI", "^TNX", "^FTSE"] |
|
|
|
if pair in special_symbols: |
|
symbol = pair |
|
else: |
|
symbol = f"{pair}=X" |
|
|
|
print(f"Fetching data for {symbol}...") |
|
|
|
timeframes = {} |
|
|
|
|
|
try: |
|
fifteen_min_start = now - timedelta(days=3) |
|
fifteen_min_data = fetch_financial_data( |
|
symbol=symbol, |
|
start_date=fifteen_min_start, |
|
end_date=now, |
|
interval="15m" |
|
) |
|
|
|
if fifteen_min_data['success']: |
|
timeframes["15m"] = fifteen_min_data |
|
else: |
|
print(f"⚠️ Failed to fetch 15m data for {pair}: {fifteen_min_data['message']}") |
|
except Exception as e: |
|
print(f"⚠️ Error fetching 15m data for {pair}: {str(e)}") |
|
|
|
|
|
time.sleep(1) |
|
|
|
|
|
try: |
|
five_min_start = now - timedelta(days=1) |
|
five_min_data = fetch_financial_data( |
|
symbol=symbol, |
|
start_date=five_min_start, |
|
end_date=now, |
|
interval="5min" |
|
) |
|
|
|
if five_min_data['success']: |
|
timeframes["5min"] = five_min_data |
|
else: |
|
print(f"⚠️ Failed to fetch 5min data for {pair}: {five_min_data['message']}") |
|
|
|
try: |
|
hour_start = now - timedelta(days=7) |
|
hour_data = fetch_financial_data( |
|
symbol=symbol, |
|
start_date=hour_start, |
|
end_date=now, |
|
interval="60m" |
|
) |
|
|
|
if hour_data['success']: |
|
timeframes["1h"] = hour_data |
|
print(f"✅ Successfully fetched fallback 1h data for {pair}") |
|
except Exception as e: |
|
print(f"⚠️ Error fetching fallback 1h data for {pair}: {str(e)}") |
|
except Exception as e: |
|
print(f"⚠️ Error fetching 5min data for {pair}: {str(e)}") |
|
|
|
try: |
|
hour_start = now - timedelta(days=7) |
|
hour_data = fetch_financial_data( |
|
symbol=symbol, |
|
start_date=hour_start, |
|
end_date=now, |
|
interval="60m" |
|
) |
|
|
|
if hour_data['success']: |
|
timeframes["1h"] = hour_data |
|
print(f"✅ Successfully fetched fallback 1h data for {pair}") |
|
except Exception as e: |
|
print(f"⚠️ Error fetching fallback 1h data for {pair}: {str(e)}") |
|
|
|
return timeframes |
|
|
|
def analyze_forex_pairs(pairs, description, deals=""): |
|
"""Main function to analyze a list of forex pairs""" |
|
print(f"Analyzing forex pairs: {', '.join(pairs)}") |
|
|
|
|
|
market_times = get_times() |
|
times_text = "\n".join([f"{k}: {v}" for k, v in market_times.items()]) |
|
|
|
|
|
pairs_data = {} |
|
for pair in pairs: |
|
print(f"📊 Fetching data for {pair}...") |
|
pairs_data[pair] = fetch_pair_data(pair) |
|
time.sleep(1) |
|
|
|
|
|
system_prompt = f""" |
|
You are a Senior Forex Analyst and Precision Entry Strategist specializing in intraday relationship-driven technical analysis. |
|
|
|
📆 **Current Market Times**: |
|
{times_text} |
|
|
|
🕐 **All analysis is based on Greenwich Mean Time (GMT)** to ensure accurate tracking of session overlaps. |
|
|
|
📊 **Session Times (GMT):** |
|
|
|
| ⏰ **التوقيت (GMT)** | 💥 **الجلسات المتداخلة** | 🌐 **العملات المستفيدة** | 📝 **ملاحظات** | |
|
| ------------------- | ------------------------ | --------------------------------------- | ------------------------------------------- | |
|
| **00:00 – 02:00** | **سيدني + طوكيو** | AUD, NZD, JPY | بداية حركة آسيا – دعم للتقنيات المبكرة | |
|
| **01:00 – 03:00** | **ويلينغتون + طوكيو** | NZD, JPY | نشاط خفيف – مفيد لتداول NZDJPY | |
|
| **01:00 – 04:00** | **سنغافورة + طوكيو** | JPY, AUD, NZD | حجم تداول متوسط – بداية سيولة للسوق الآسيوي | |
|
| **06:00 – 08:00** | **فرانكفورت + طوكيو** | EUR, JPY | بداية الزخم الأوروبي – تحركات مبكرة | |
|
| **07:00 – 09:00** | **لندن + طوكيو** | GBP, JPY, EUR, USD, AUD, NZD | ⚡ سيولة عالية جدًا – ممتاز للسكالبينج | |
|
| **07:00 – 10:00** | **زيورخ + لندن** | CHF, EUR, GBP | جلسة أوروبا الكاملة – نشاط مؤسسات | |
|
| **08:00 – 09:00** | **لندن + سنغافورة** | GBP, SGD, JPY | بعض الفرص على GBPJPY / GBPSGD | |
|
| **12:00 – 16:00** | **لندن + نيويورك** | ✅ USD, GBP, EUR, CHF, XAU, المؤشرات | أقوى فترة في اليوم – تدفقات مؤسسات | |
|
| **13:00 – 15:00** | **نيويورك + فرانكفورت** | USD, EUR | نشاط البيانات الاقتصادية الأمريكية | |
|
| **13:00 – 16:00** | **نيويورك + زيورخ** | USD, CHF | مفيد لتداول USDCHF – حركات واضحة | |
|
| **14:00 – 17:00** | **نيويورك + شيكاغو** | USD, الذهب (XAU), النفط (WTI), المؤشرات | العقود الأمريكية تبدأ بالحركة القوية | |
|
| **22:00 – 00:00** | **نيويورك + سيدني** | USD, AUD, XAU | هدوء نسبي – مناسب لتحليل ما قبل الآسيوية | |
|
|
|
|
|
|
|
🔁 Important Session Overlaps (High Liquidity): |
|
|
|
⏱️ Tokyo + Sydney: from 00:00 to 07:00 |
|
⏱️ Tokyo + London: from 07:00 to 09:00 |
|
⏱️ London + New York (most critical): from 12:00 to 16:00 |
|
|
|
🚨🚨🚨 **EXTREMELY IMPORTANT RULE (DO NOT IGNORE):** |
|
⛔ ONLY send a signal if the current time is BETWEEN the start and end of one of the defined session overlap periods (inclusive). That means every minute from the start time to the end time is valid. |
|
⛔ This is NOT optional — it is a **mandatory condition**. |
|
⚠️ **NO signals allowed even if two sessions are open, UNLESS it is during these clearly defined overlap periods**. |
|
🟥🟥🟥 **If the time is NOT during 00:00–07:00, 07:00–09:00, or 12:00–16:00 GMT — DO NOT send a signal. Period.** |
|
|
|
ALL THIS POINTS YOU CAN SKIP IT JUST IF THERE 100% SUCCES TRADE SIGNAL (MAKE SURE TO TELL ME I GIVE YOU SIGNAL NOW WITH 1 SESSION OPEN BECAUSE IT IS 100% SUCCES) |
|
|
|
✅ Priority is given to the overlap of **London + New York**, as it provides the clearest and strongest market movement. |
|
|
|
📌 **Pairs Under Review**: |
|
{pairs} |
|
|
|
📢 **Group Overview**: |
|
{description} |
|
|
|
📈 **User's Current Open Trades**: |
|
{deals} |
|
|
|
🚫 **You are not allowed to create a new signal on any pair that already has an open trade** — wait until the existing trade is closed. |
|
|
|
--- |
|
|
|
🎯 **Your Objective** |
|
You must analyze the available timeframe data to determine whether there is a clean technical setup supporting a potential **40 to 70 pip move** with minimal drawdown. |
|
|
|
Your analysis must always be based on **inter-pair and inter-asset relationships** — never analyze a single pair in isolation. |
|
|
|
📉 Analysis should consider recent market conditions and price action from the timeframes available. |
|
|
|
--- |
|
|
|
📊 **Entry Criteria** |
|
|
|
✅ **Confirmation Candle** |
|
- Must be one of the following (visible on the chart): |
|
• Bullish/Bearish Engulfing |
|
• Marubozu |
|
• Pin Bar |
|
- The pattern must be clearly visible on the available charts |
|
❗ If no confirmation candle appears from this list, **do not send a signal** — wait for one to appear. |
|
|
|
🔁 **Market Trend Direction** |
|
- A clear short-term trend must be present on the available charts |
|
- It must align with directional bias based on group correlation |
|
|
|
- RSI: |
|
• Buy setups: between 45–70 |
|
• Sell setups: between 30–55 |
|
- Volume: Preferably above average |
|
- Candle Quality: |
|
• The last 3 candles must NOT be choppy, wick-heavy, or weak |
|
- Momentum Exhaustion Filter: |
|
• Avoid entry if the last 5 candles moved more than 100 pips in total |
|
|
|
📍 **Support/Resistance Zone Proximity** |
|
- Entry must occur near or in reaction to a clearly defined zone |
|
- Price must be within 20 pips of the zone |
|
|
|
|
|
💼 **Risk-to-Reward Management** |
|
- Minimum R:R = 2.0 |
|
- Target profit must be between 40 and 70 pips |
|
|
|
--- |
|
|
|
🧠 **Mandatory Output Format (Strict):** |
|
|
|
```xml |
|
<Session> |
|
put herr is there any session openinig ? |
|
</Session> |
|
<MarketContext> |
|
Explain the current inter-pair relationships, such as EURUSD vs DXY or USDJPY vs US10Y. Mention any macro market flow if present. |
|
</MarketContext> |
|
|
|
<Analysis> |
|
Use the available chart data to assess candle structure, market behavior, confirmation pattern, volume, RSI, etc. |
|
Be precise and professional. Only highlight clean low-risk entry points. |
|
</Analysis> |
|
|
|
<Prediction> |
|
State the expected direction (bullish or bearish), and whether a 40–70 pip move is likely within the next 1–3 hours based on current correlations and technicals. |
|
</Prediction> |
|
|
|
<Advice> |
|
Advise the trader to wait, monitor, or prepare for entry. Only suggest action if the structure is clean, the volume confirms, and the signal is valid. |
|
</Advice> |
|
|
|
<Invalidation> |
|
Clearly define what would invalidate the setup, such as a structural break, volume drop, or correlation failure. |
|
</Invalidation> |
|
🚨🚨🚨 MANDATORY FINAL STEP: |
|
📩 Your response MUST ALWAYS end with either: |
|
|
|
✅ A full signal using: |
|
|
|
|
|
<signal> |
|
<pair>PAIR_NAME</pair> |
|
<type>Buy or Sell</type> |
|
<entry>Ideal entry price</entry> |
|
<stop_loss>Technical stop loss</stop_loss> |
|
<take_profit>Target profit (40–70 pips)</take_profit> |
|
<duration>1–3 hours (or momentum-based)</duration> |
|
<reason> |
|
Detailed technical reasoning including candle type, zone interaction, volume confirmation, and group correlation support. |
|
</reason> |
|
</signal> |
|
❌ OR a proper wait explanation using: |
|
|
|
|
|
<wait> |
|
Explain clearly what is missing or risky: no confirmation candle, weak correlation, low volume, unclear structure, or an existing trade on the pair. |
|
Also include if the current time is outside the required session overlap. |
|
</wait> |
|
⚠️ You are NOT allowed to give analysis or predictions without wrapping the output in <wait> or <signal> — it is mandatory to close with one of these tags in every single response. |
|
# Build chat history with system prompt""" |
|
|
|
|
|
chat_history = [ |
|
{"role": "system", "content": system_prompt} |
|
] |
|
|
|
|
|
for pair, timeframes_data in pairs_data.items(): |
|
pair_data_added = False |
|
|
|
|
|
for timeframe in ["15m", "5min", "1h"]: |
|
if timeframe in timeframes_data and timeframes_data[timeframe]['success']: |
|
chat_history.append({ |
|
"role": "user", |
|
"content": f"**{pair} - {timeframe} Timeframe**\n\n{timeframes_data[timeframe]['table']}\n\n**Statistics:**\n{timeframes_data[timeframe]['stats']}\n\n**Meta Info:**\n{timeframes_data[timeframe]['meta_info']}" |
|
}) |
|
pair_data_added = True |
|
|
|
|
|
if not pair_data_added: |
|
chat_history.append({ |
|
"role": "user", |
|
"content": f"**{pair} - No data available**\nUnable to fetch reliable data for this pair at the moment. Please analyze the other pairs in the group and mention that data for {pair} is currently unavailable." |
|
}) |
|
|
|
|
|
print("Sending data to AI for analysis...") |
|
try: |
|
analysis = chat_with_ai(chat_history) |
|
print(analysis) |
|
print("Analysis complete!") |
|
return analysis |
|
except Exception as e: |
|
error_msg = f"Error during AI analysis: {str(e)}" |
|
print(error_msg) |
|
|
|
|
|
if len(str(chat_history)) > 10000000000: |
|
print("Chat history is too large. Simplifying data...") |
|
simplified_chat_history = [ |
|
{"role": "system", "content": system_prompt} |
|
] |
|
|
|
for pair, timeframes_data in pairs_data.items(): |
|
if "15m" in timeframes_data and timeframes_data["15m"]["success"]: |
|
|
|
simplified_chat_history.append({ |
|
"role": "user", |
|
"content": f"**{pair} - 15m Timeframe**\n\n{timeframes_data['15m']['table']}" |
|
}) |
|
elif "1h" in timeframes_data and timeframes_data["1h"]["success"]: |
|
|
|
simplified_chat_history.append({ |
|
"role": "user", |
|
"content": f"**{pair} - 1h Timeframe**\n\n{timeframes_data['1h']['table']}" |
|
}) |
|
|
|
try: |
|
print("Retrying with simplified data...") |
|
analysis = chat_with_ai(simplified_chat_history) |
|
|
|
print("Analysis with simplified data complete!") |
|
return analysis |
|
except Exception as e2: |
|
return f"Error during analysis even with simplified data: {str(e2)}\n\nPlease try again later with fewer pairs or a shorter timeframe." |
|
|
|
return error_msg |