position history with fees

This commit is contained in:
Dobromir Popov
2025-05-28 11:17:41 +03:00
parent f8681447e3
commit dd86d21854
11 changed files with 880 additions and 58 deletions

View File

@ -144,9 +144,14 @@ class DataProvider:
logger.info(f"Preloading 300s of data for {symbol} {timeframe}")
df = self._preload_300s_data(symbol, timeframe)
else:
# Fetch from API with requested limit
# Fetch from API with requested limit (Binance primary, MEXC fallback)
logger.info(f"Fetching historical data for {symbol} {timeframe}")
df = self._fetch_from_binance(symbol, timeframe, limit)
# Fallback to MEXC if Binance fails
if df is None or df.empty:
logger.info(f"Binance failed, trying MEXC fallback for {symbol}")
df = self._fetch_from_mexc(symbol, timeframe, limit)
if df is not None and not df.empty:
# Add technical indicators
@ -217,9 +222,14 @@ class DataProvider:
logger.info(f"Preloading {candles_needed} candles for {symbol} {timeframe} (300s worth)")
# Fetch the data
# Fetch the data (Binance primary, MEXC fallback)
df = self._fetch_from_binance(symbol, timeframe, candles_needed)
# Fallback to MEXC if Binance fails
if df is None or df.empty:
logger.info(f"Binance failed, trying MEXC fallback for preload {symbol}")
df = self._fetch_from_mexc(symbol, timeframe, candles_needed)
if df is not None and not df.empty:
logger.info(f"Successfully preloaded {len(df)} candles for {symbol} {timeframe}")
return df
@ -289,8 +299,65 @@ class DataProvider:
logger.error(f"Error in preload_all_symbols_data: {e}")
return {}
def _fetch_from_mexc(self, symbol: str, timeframe: str, limit: int) -> Optional[pd.DataFrame]:
"""Fetch data from MEXC API (fallback data source when Binance is unavailable)"""
try:
# MEXC doesn't support 1s intervals
if timeframe == '1s':
logger.warning(f"MEXC doesn't support 1s intervals, skipping {symbol}")
return None
# Convert symbol format
mexc_symbol = symbol.replace('/', '').upper()
# Convert timeframe for MEXC (excluding 1s)
timeframe_map = {
'1m': '1m', '5m': '5m', '15m': '15m', '30m': '30m',
'1h': '1h', '4h': '4h', '1d': '1d'
}
mexc_timeframe = timeframe_map.get(timeframe)
if mexc_timeframe is None:
logger.warning(f"MEXC doesn't support timeframe {timeframe}, skipping {symbol}")
return None
# MEXC API request
url = "https://api.mexc.com/api/v3/klines"
params = {
'symbol': mexc_symbol,
'interval': mexc_timeframe,
'limit': limit
}
response = requests.get(url, params=params)
response.raise_for_status()
data = response.json()
# Convert to DataFrame (MEXC uses 8 columns vs Binance's 12)
df = pd.DataFrame(data, columns=[
'timestamp', 'open', 'high', 'low', 'close', 'volume',
'close_time', 'quote_volume'
])
# Process columns
df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')
for col in ['open', 'high', 'low', 'close', 'volume']:
df[col] = df[col].astype(float)
# Keep only OHLCV columns
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}")
return df
except Exception as 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"""
"""Fetch data from Binance API (primary data source)"""
try:
# Convert symbol format
binance_symbol = symbol.replace('/', '').upper()
@ -331,7 +398,7 @@ class DataProvider:
df = df[['timestamp', 'open', 'high', 'low', 'close', 'volume']]
df = df.sort_values('timestamp').reset_index(drop=True)
logger.info(f"Fetched {len(df)} candles for {symbol} {timeframe}")
logger.info(f"Binance: Fetched {len(df)} candles for {symbol} {timeframe}")
return df
except Exception as e: