new data flow (trading works)

This commit is contained in:
Dobromir Popov
2025-05-29 15:10:44 +03:00
parent 3f4e9b9774
commit 3e697acf08
3 changed files with 605 additions and 68 deletions

View File

@ -349,15 +349,15 @@ class DataProvider:
df = df[['timestamp', 'open', 'high', 'low', 'close', 'volume']]
df = df.sort_values('timestamp').reset_index(drop=True)
logger.info(f"MEXC: Fetched {len(df)} candles for {symbol} {timeframe}")
logger.info(f"MEXC: Fetched {len(df)} candles for {symbol} {timeframe}")
return df
except Exception as e:
logger.error(f"MEXC: Error fetching data: {e}")
logger.error(f"MEXC: Error fetching data: {e}")
return None
def _fetch_from_binance(self, symbol: str, timeframe: str, limit: int) -> Optional[pd.DataFrame]:
"""Fetch data from Binance API (primary data source)"""
"""Fetch data from Binance API (primary data source) with HTTP 451 error handling"""
try:
# Convert symbol format
binance_symbol = symbol.replace('/', '').upper()
@ -369,7 +369,7 @@ class DataProvider:
}
binance_timeframe = timeframe_map.get(timeframe, '1h')
# API request
# API request with timeout and better headers
url = "https://api.binance.com/api/v3/klines"
params = {
'symbol': binance_symbol,
@ -377,7 +377,19 @@ class DataProvider:
'limit': limit
}
response = requests.get(url, params=params)
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Accept': 'application/json',
'Connection': 'keep-alive'
}
response = requests.get(url, params=params, headers=headers, timeout=10)
# Handle HTTP 451 (Unavailable For Legal Reasons) specifically
if response.status_code == 451:
logger.warning(f"Binance API returned 451 (blocked) for {symbol} {timeframe} - using fallback")
return self._get_fallback_data(symbol, timeframe, limit)
response.raise_for_status()
data = response.json()
@ -402,9 +414,40 @@ class DataProvider:
return df
except Exception as e:
logger.error(f"Error fetching from Binance API: {e}")
if "451" in str(e) or "Client Error" in str(e):
logger.warning(f"Binance API access blocked (451) for {symbol} {timeframe} - using fallback")
return self._get_fallback_data(symbol, timeframe, limit)
else:
logger.error(f"Error fetching from Binance API: {e}")
return self._get_fallback_data(symbol, timeframe, limit)
def _get_fallback_data(self, symbol: str, timeframe: str, limit: int) -> Optional[pd.DataFrame]:
"""Get fallback data when Binance API is unavailable - REAL DATA ONLY"""
try:
logger.info(f"FALLBACK: Attempting to get real cached data for {symbol} {timeframe}")
# ONLY try cached data
cached_data = self._load_from_cache(symbol, timeframe)
if cached_data is not None and not cached_data.empty:
# Limit to requested amount
limited_data = cached_data.tail(limit) if len(cached_data) > limit else cached_data
logger.info(f"FALLBACK: Using cached real data for {symbol} {timeframe}: {len(limited_data)} bars")
return limited_data
# Try MEXC as secondary real data source
mexc_data = self._fetch_from_mexc(symbol, timeframe, limit)
if mexc_data is not None and not mexc_data.empty:
logger.info(f"FALLBACK: Using MEXC real data for {symbol} {timeframe}: {len(mexc_data)} bars")
return mexc_data
# NO SYNTHETIC DATA - Return None if no real data available
logger.warning(f"FALLBACK: No real data available for {symbol} {timeframe} - waiting for real data")
return None
except Exception as e:
logger.error(f"Error getting fallback data: {e}")
return None
def _add_technical_indicators(self, df: pd.DataFrame) -> pd.DataFrame:
"""Add comprehensive technical indicators for multi-timeframe analysis"""
try: