remove emojis from console
This commit is contained in:
@@ -277,7 +277,7 @@ class DataProvider:
|
||||
if DUCKDB_STORAGE_AVAILABLE:
|
||||
try:
|
||||
self.duckdb_storage = DuckDBStorage()
|
||||
logger.info("✅ DuckDB storage initialized (unified Parquet + SQL)")
|
||||
logger.info(" DuckDB storage initialized (unified Parquet + SQL)")
|
||||
except Exception as e:
|
||||
logger.warning(f"Could not initialize DuckDB storage: {e}")
|
||||
|
||||
@@ -396,7 +396,7 @@ class DataProvider:
|
||||
|
||||
if success:
|
||||
self._unified_storage_enabled = True
|
||||
logger.info("✅ Unified storage system enabled successfully")
|
||||
logger.info(" Unified storage system enabled successfully")
|
||||
return True
|
||||
else:
|
||||
logger.error("Failed to enable unified storage system")
|
||||
@@ -550,7 +550,7 @@ class DataProvider:
|
||||
else:
|
||||
logger.info("Skipping initial data load (using DuckDB cache)")
|
||||
|
||||
logger.info("✅ Initial data load completed - stopping maintenance worker")
|
||||
logger.info(" Initial data load completed - stopping maintenance worker")
|
||||
logger.info("📊 Data will be updated on-demand only (no continuous fetching)")
|
||||
|
||||
# Stop the maintenance worker after initial load
|
||||
@@ -602,7 +602,7 @@ class DataProvider:
|
||||
# Cap at 1500 candles maximum
|
||||
fetch_limit = min(estimated_missing + 10, 1500)
|
||||
|
||||
logger.info(f"🔄 Fetching {fetch_limit} recent candles for {symbol} {timeframe} (since {last_timestamp})")
|
||||
logger.info(f" Fetching {fetch_limit} recent candles for {symbol} {timeframe} (since {last_timestamp})")
|
||||
new_df = self._fetch_from_binance(symbol, timeframe, fetch_limit)
|
||||
|
||||
if new_df is None or new_df.empty:
|
||||
@@ -622,9 +622,9 @@ class DataProvider:
|
||||
combined_df = combined_df.sort_index()
|
||||
self.cached_data[symbol][timeframe] = combined_df.tail(1500)
|
||||
|
||||
logger.info(f"✅ {symbol} {timeframe}: +{len(new_df)} new (total: {len(self.cached_data[symbol][timeframe])})")
|
||||
logger.info(f" {symbol} {timeframe}: +{len(new_df)} new (total: {len(self.cached_data[symbol][timeframe])})")
|
||||
else:
|
||||
logger.info(f"✅ {symbol} {timeframe}: Up to date ({len(existing_df)} candles)")
|
||||
logger.info(f" {symbol} {timeframe}: Up to date ({len(existing_df)} candles)")
|
||||
else:
|
||||
# No existing data - fetch initial 1500 candles
|
||||
logger.info(f"🆕 No existing data, fetching 1500 candles for {symbol} {timeframe}")
|
||||
@@ -643,7 +643,7 @@ class DataProvider:
|
||||
with self.data_lock:
|
||||
self.cached_data[symbol][timeframe] = df
|
||||
|
||||
logger.info(f"✅ Loaded {len(df)} candles for {symbol} {timeframe}")
|
||||
logger.info(f" Loaded {len(df)} candles for {symbol} {timeframe}")
|
||||
|
||||
# Small delay to avoid rate limits
|
||||
time.sleep(0.1)
|
||||
@@ -651,7 +651,7 @@ class DataProvider:
|
||||
except Exception as e:
|
||||
logger.error(f"Error loading data for {symbol} {timeframe}: {e}")
|
||||
|
||||
logger.info("✅ Smart incremental data load completed")
|
||||
logger.info(" Smart incremental data load completed")
|
||||
|
||||
def _start_background_catch_up(self):
|
||||
"""
|
||||
@@ -737,9 +737,9 @@ class DataProvider:
|
||||
|
||||
final_count = len(self.cached_data[symbol][timeframe])
|
||||
|
||||
logger.info(f"✅ {symbol} {timeframe}: Caught up! Now have {final_count} candles")
|
||||
logger.info(f" {symbol} {timeframe}: Caught up! Now have {final_count} candles")
|
||||
else:
|
||||
logger.warning(f"❌ {symbol} {timeframe}: Could not fetch historical data from any exchange")
|
||||
logger.warning(f" {symbol} {timeframe}: Could not fetch historical data from any exchange")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error catching up candles for {symbol} {timeframe}: {e}")
|
||||
@@ -775,7 +775,7 @@ class DataProvider:
|
||||
# Cap at 1500 candles maximum
|
||||
fetch_limit = min(estimated_missing + 5, 1500)
|
||||
|
||||
logger.info(f"🔄 Fetching {fetch_limit} recent candles for {symbol} {timeframe} (since {last_timestamp})")
|
||||
logger.info(f" Fetching {fetch_limit} recent candles for {symbol} {timeframe} (since {last_timestamp})")
|
||||
|
||||
# Fetch missing candles
|
||||
df = self._fetch_from_binance(symbol, timeframe, fetch_limit)
|
||||
@@ -811,7 +811,7 @@ class DataProvider:
|
||||
|
||||
candle_count = len(self.cached_data[symbol][timeframe])
|
||||
|
||||
logger.info(f"✅ Updated {symbol} {timeframe}: +{len(df)} new (total: {candle_count})")
|
||||
logger.info(f" Updated {symbol} {timeframe}: +{len(df)} new (total: {candle_count})")
|
||||
else:
|
||||
logger.warning(f"Could not fetch new data for {symbol} {timeframe}")
|
||||
else:
|
||||
@@ -827,17 +827,17 @@ class DataProvider:
|
||||
try:
|
||||
if symbol and timeframe:
|
||||
# Refresh specific symbol/timeframe
|
||||
logger.info(f"🔄 Manual refresh requested for {symbol} {timeframe}")
|
||||
logger.info(f" Manual refresh requested for {symbol} {timeframe}")
|
||||
self._update_cached_data(symbol, timeframe)
|
||||
else:
|
||||
# Refresh all symbols/timeframes
|
||||
logger.info("🔄 Manual refresh requested for all symbols/timeframes")
|
||||
logger.info(" Manual refresh requested for all symbols/timeframes")
|
||||
for sym in self.symbols:
|
||||
for tf in self.timeframes:
|
||||
self._update_cached_data(sym, tf)
|
||||
time.sleep(0.1) # Small delay to avoid rate limits
|
||||
|
||||
logger.info("✅ Manual refresh completed for all symbols/timeframes")
|
||||
logger.info(" Manual refresh completed for all symbols/timeframes")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error in manual refresh: {e}")
|
||||
@@ -3107,7 +3107,7 @@ class DataProvider:
|
||||
def _load_from_duckdb_sync(self):
|
||||
"""Load all data from DuckDB synchronously for instant startup"""
|
||||
if not self.duckdb_storage:
|
||||
logger.warning("⚠️ DuckDB storage not available - cannot load cached data")
|
||||
logger.warning(" DuckDB storage not available - cannot load cached data")
|
||||
return
|
||||
|
||||
logger.info("📦 Loading cached data from DuckDB...")
|
||||
@@ -3125,18 +3125,18 @@ class DataProvider:
|
||||
if df is not None and not df.empty:
|
||||
with self.data_lock:
|
||||
self.cached_data[symbol][timeframe] = df.tail(1500)
|
||||
logger.info(f"✅ {symbol} {timeframe}: {len(df)} candles from DuckDB")
|
||||
logger.info(f" {symbol} {timeframe}: {len(df)} candles from DuckDB")
|
||||
loaded_count += len(df)
|
||||
else:
|
||||
logger.debug(f"No data in DuckDB for {symbol} {timeframe} - will fetch from API")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"❌ Error loading {symbol} {timeframe}: {e}")
|
||||
logger.error(f" Error loading {symbol} {timeframe}: {e}")
|
||||
|
||||
if loaded_count > 0:
|
||||
logger.info(f"✅ Loaded {loaded_count:,} candles total")
|
||||
logger.info(f" Loaded {loaded_count:,} candles total")
|
||||
else:
|
||||
logger.warning("⚠️ No cached data found - will fetch from API")
|
||||
logger.warning(" No cached data found - will fetch from API")
|
||||
|
||||
def _load_from_duckdb(self, symbol: str, timeframe: str, limit: int = 1500) -> Optional[pd.DataFrame]:
|
||||
"""Load data from DuckDB storage
|
||||
@@ -3338,7 +3338,7 @@ class DataProvider:
|
||||
async def _start_fallback_websocket_streaming(self):
|
||||
"""Fallback to old WebSocket method if Enhanced COB WebSocket fails"""
|
||||
try:
|
||||
logger.warning("⚠️ Starting fallback WebSocket streaming")
|
||||
logger.warning(" Starting fallback WebSocket streaming")
|
||||
|
||||
# Start old WebSocket for each symbol
|
||||
for symbol in self.symbols:
|
||||
@@ -3346,7 +3346,7 @@ class DataProvider:
|
||||
self.websocket_tasks[symbol] = task
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"❌ Error starting fallback WebSocket: {e}")
|
||||
logger.error(f" Error starting fallback WebSocket: {e}")
|
||||
|
||||
def get_cob_websocket_status(self) -> Dict[str, Any]:
|
||||
"""Get COB WebSocket status for dashboard"""
|
||||
|
||||
@@ -364,7 +364,7 @@ class EnhancedCOBWebSocket:
|
||||
try:
|
||||
await callback(symbol, cob_data)
|
||||
except Exception as e:
|
||||
logger.error(f"❌ Error in COB callback: {e}")
|
||||
logger.error(f" Error in COB callback: {e}")
|
||||
|
||||
logger.debug(f"Initial snapshot for {symbol}: ${mid_price:.2f}, spread: {spread_bps:.1f} bps")
|
||||
else:
|
||||
|
||||
@@ -324,10 +324,10 @@ class BybitRestClient:
|
||||
"""
|
||||
try:
|
||||
result = self.get_server_time()
|
||||
logger.info("✅ Bybit REST API connectivity test successful")
|
||||
logger.info(" Bybit REST API connectivity test successful")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"❌ Bybit REST API connectivity test failed: {e}")
|
||||
logger.error(f" Bybit REST API connectivity test failed: {e}")
|
||||
return False
|
||||
|
||||
def test_authentication(self) -> bool:
|
||||
@@ -338,8 +338,8 @@ class BybitRestClient:
|
||||
"""
|
||||
try:
|
||||
result = self.get_account_info()
|
||||
logger.info("✅ Bybit REST API authentication test successful")
|
||||
logger.info(" Bybit REST API authentication test successful")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"❌ Bybit REST API authentication test failed: {e}")
|
||||
logger.error(f" Bybit REST API authentication test failed: {e}")
|
||||
return False
|
||||
@@ -256,7 +256,7 @@ Each exchange was scored (1-5) across four weighted categories:
|
||||
| Criteria | Deribit | Binance | Bybit | OKX |
|
||||
|-------------------|---------------|---------------|---------------|---------------|
|
||||
| **Max Leverage** | 10× | 75× | 100× | 10× |
|
||||
| **Market Orders** | ✅ | ✅ | ✅ | ✅ |
|
||||
| **Market Orders** | | | | |
|
||||
| **Base Fee** | 0% maker | 0.02% maker | -0.01% maker | 0.02% maker |
|
||||
| **Python SDK** | Official | Robust | Low-latency | Full-featured |
|
||||
| **HFT Suitability**| ★★★★☆ | ★★★★★ | ★★★★☆ | ★★★☆☆ |
|
||||
|
||||
@@ -27,7 +27,7 @@ def test_final_mexc_order():
|
||||
api_secret = os.getenv('MEXC_SECRET_KEY', '')
|
||||
|
||||
if not api_key or not api_secret:
|
||||
print("❌ No MEXC API credentials found")
|
||||
print(" No MEXC API credentials found")
|
||||
return
|
||||
|
||||
# Parameters
|
||||
@@ -68,9 +68,9 @@ def test_final_mexc_order():
|
||||
print(f"Response: {response.text}")
|
||||
|
||||
if response.status_code == 200:
|
||||
print("✅ SUCCESS!")
|
||||
print(" SUCCESS!")
|
||||
else:
|
||||
print("❌ FAILED")
|
||||
print(" FAILED")
|
||||
# Try alternative method - sending as query params
|
||||
print("\n--- Trying alternative method ---")
|
||||
test_alternative_method(api_key, api_secret)
|
||||
|
||||
@@ -59,7 +59,7 @@ def test_mexc_order_placement():
|
||||
api_secret = os.getenv('MEXC_SECRET_KEY', '')
|
||||
|
||||
if not api_key or not api_secret:
|
||||
print("❌ No MEXC API credentials found")
|
||||
print(" No MEXC API credentials found")
|
||||
return
|
||||
|
||||
# Test parameters - very small order
|
||||
@@ -105,7 +105,7 @@ def test_mexc_order_placement():
|
||||
|
||||
if response.status_code == 200:
|
||||
result = response.json()
|
||||
print("✅ Order placed successfully!")
|
||||
print(" Order placed successfully!")
|
||||
print(f"Order result: {result}")
|
||||
|
||||
# Try to cancel it immediately if we got an order ID
|
||||
@@ -131,11 +131,11 @@ def test_mexc_order_placement():
|
||||
print(f"Cancel response: {cancel_response.status_code} - {cancel_response.text}")
|
||||
|
||||
else:
|
||||
print("❌ Order placement failed")
|
||||
print(" Order placement failed")
|
||||
print(f"Response: {response.text}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Request error: {e}")
|
||||
print(f" Request error: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_mexc_order_placement()
|
||||
@@ -59,7 +59,7 @@ def test_mexc_order_v2():
|
||||
api_secret = os.getenv('MEXC_SECRET_KEY', '')
|
||||
|
||||
if not api_key or not api_secret:
|
||||
print("❌ No MEXC API credentials found")
|
||||
print(" No MEXC API credentials found")
|
||||
return
|
||||
|
||||
# Order parameters matching MEXC examples
|
||||
@@ -99,19 +99,19 @@ def test_mexc_order_v2():
|
||||
|
||||
if response.status_code == 200:
|
||||
result = response.json()
|
||||
print("✅ Order placed successfully!")
|
||||
print(" Order placed successfully!")
|
||||
print(f"Order result: {result}")
|
||||
|
||||
# Cancel immediately if successful
|
||||
if 'orderId' in result:
|
||||
print(f"\n🔄 Canceling order {result['orderId']}...")
|
||||
print(f"\n Canceling order {result['orderId']}...")
|
||||
cancel_order(api_key, api_secret, 'ETHUSDC', result['orderId'])
|
||||
|
||||
else:
|
||||
print("❌ Order placement failed")
|
||||
print(" Order placement failed")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Request error: {e}")
|
||||
print(f" Request error: {e}")
|
||||
|
||||
def cancel_order(api_key: str, secret_key: str, symbol: str, order_id: str):
|
||||
"""Cancel a MEXC order"""
|
||||
|
||||
@@ -42,7 +42,7 @@ def test_mexc_order_v3():
|
||||
api_secret = os.getenv('MEXC_SECRET_KEY', '')
|
||||
|
||||
if not api_key or not api_secret:
|
||||
print("❌ No MEXC API credentials found")
|
||||
print(" No MEXC API credentials found")
|
||||
return
|
||||
|
||||
# Order parameters exactly like the examples
|
||||
@@ -92,19 +92,19 @@ def test_mexc_order_v3():
|
||||
|
||||
if response.status_code == 200:
|
||||
result = response.json()
|
||||
print("✅ Order placed successfully!")
|
||||
print(" Order placed successfully!")
|
||||
print(f"Order result: {result}")
|
||||
|
||||
# Cancel immediately if successful
|
||||
if 'orderId' in result:
|
||||
print(f"\n🔄 Canceling order {result['orderId']}...")
|
||||
print(f"\n Canceling order {result['orderId']}...")
|
||||
cancel_order_v3(api_key, api_secret, 'ETHUSDC', result['orderId'])
|
||||
|
||||
else:
|
||||
print("❌ Order placement failed")
|
||||
print(" Order placement failed")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Request error: {e}")
|
||||
print(f" Request error: {e}")
|
||||
|
||||
def cancel_order_v3(api_key: str, secret_key: str, symbol: str, order_id: str):
|
||||
"""Cancel a MEXC order using V3 method"""
|
||||
|
||||
@@ -26,7 +26,7 @@ def debug_interface():
|
||||
api_secret = os.getenv('MEXC_SECRET_KEY', '')
|
||||
|
||||
if not api_key or not api_secret:
|
||||
print("❌ No MEXC API credentials found")
|
||||
print(" No MEXC API credentials found")
|
||||
return False
|
||||
|
||||
from NN.exchanges.mexc_interface import MEXCInterface
|
||||
@@ -98,17 +98,17 @@ def debug_interface():
|
||||
|
||||
# Compare parameters
|
||||
print(f"\n📊 COMPARISON:")
|
||||
print(f"symbol: Interface='{interface_params['symbol']}', Manual='{manual_params['symbol']}' {'✅' if interface_params['symbol'] == manual_params['symbol'] else '❌'}")
|
||||
print(f"side: Interface='{interface_params['side']}', Manual='{manual_params['side']}' {'✅' if interface_params['side'] == manual_params['side'] else '❌'}")
|
||||
print(f"type: Interface='{interface_params['type']}', Manual='{manual_params['type']}' {'✅' if interface_params['type'] == manual_params['type'] else '❌'}")
|
||||
print(f"quantity: Interface='{interface_params['quantity']}', Manual='{manual_params['quantity']}' {'✅' if interface_params['quantity'] == manual_params['quantity'] else '❌'}")
|
||||
print(f"price: Interface='{interface_params['price']}', Manual='{manual_params['price']}' {'✅' if interface_params['price'] == manual_params['price'] else '❌'}")
|
||||
print(f"timestamp: Interface='{interface_params['timestamp']}', Manual='{manual_params['timestamp']}' {'✅' if interface_params['timestamp'] == manual_params['timestamp'] else '❌'}")
|
||||
print(f"recvWindow: Interface='{interface_params['recvWindow']}', Manual='{manual_params['recvWindow']}' {'✅' if interface_params['recvWindow'] == manual_params['recvWindow'] else '❌'}")
|
||||
print(f"symbol: Interface='{interface_params['symbol']}', Manual='{manual_params['symbol']}' {'' if interface_params['symbol'] == manual_params['symbol'] else ''}")
|
||||
print(f"side: Interface='{interface_params['side']}', Manual='{manual_params['side']}' {'' if interface_params['side'] == manual_params['side'] else ''}")
|
||||
print(f"type: Interface='{interface_params['type']}', Manual='{manual_params['type']}' {'' if interface_params['type'] == manual_params['type'] else ''}")
|
||||
print(f"quantity: Interface='{interface_params['quantity']}', Manual='{manual_params['quantity']}' {'' if interface_params['quantity'] == manual_params['quantity'] else ''}")
|
||||
print(f"price: Interface='{interface_params['price']}', Manual='{manual_params['price']}' {'' if interface_params['price'] == manual_params['price'] else ''}")
|
||||
print(f"timestamp: Interface='{interface_params['timestamp']}', Manual='{manual_params['timestamp']}' {'' if interface_params['timestamp'] == manual_params['timestamp'] else ''}")
|
||||
print(f"recvWindow: Interface='{interface_params['recvWindow']}', Manual='{manual_params['recvWindow']}' {'' if interface_params['recvWindow'] == manual_params['recvWindow'] else ''}")
|
||||
|
||||
# Check for timeInForce difference
|
||||
if 'timeInForce' in interface_params:
|
||||
print(f"timeInForce: Interface='{interface_params['timeInForce']}', Manual=None ❌ (EXTRA PARAMETER)")
|
||||
print(f"timeInForce: Interface='{interface_params['timeInForce']}', Manual=None (EXTRA PARAMETER)")
|
||||
|
||||
# Test without timeInForce
|
||||
print(f"\n🔧 TESTING WITHOUT timeInForce:")
|
||||
@@ -119,10 +119,10 @@ def debug_interface():
|
||||
print(f"Interface signature (no timeInForce): {interface_signature_minimal}")
|
||||
|
||||
if interface_signature_minimal == manual_signature:
|
||||
print("✅ Signatures match when timeInForce is removed!")
|
||||
print(" Signatures match when timeInForce is removed!")
|
||||
return True
|
||||
else:
|
||||
print("❌ Still don't match")
|
||||
print(" Still don't match")
|
||||
|
||||
return False
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ def test_order_signature():
|
||||
api_secret = os.getenv('MEXC_SECRET_KEY', '')
|
||||
|
||||
if not api_key or not api_secret:
|
||||
print("❌ No MEXC API credentials found")
|
||||
print(" No MEXC API credentials found")
|
||||
return False
|
||||
|
||||
# Test order parameters
|
||||
@@ -79,9 +79,9 @@ def test_order_signature():
|
||||
|
||||
# Compare
|
||||
if signature_manual == signature_interface:
|
||||
print("✅ Signatures match!")
|
||||
print(" Signatures match!")
|
||||
else:
|
||||
print("❌ Signatures don't match")
|
||||
print(" Signatures don't match")
|
||||
print("This indicates a problem with the signature generation method")
|
||||
return False
|
||||
|
||||
@@ -106,10 +106,10 @@ def test_order_signature():
|
||||
print(f"Response: {response.text}")
|
||||
|
||||
if response.status_code == 200:
|
||||
print("✅ Manual order method works!")
|
||||
print(" Manual order method works!")
|
||||
return True
|
||||
else:
|
||||
print("❌ Manual order method failed")
|
||||
print(" Manual order method failed")
|
||||
|
||||
# Test 4: Try test order endpoint
|
||||
print("\n4. Testing with test order endpoint:")
|
||||
@@ -119,7 +119,7 @@ def test_order_signature():
|
||||
print(f"Test order response: {response2.status_code} - {response2.text}")
|
||||
|
||||
if response2.status_code == 200:
|
||||
print("✅ Test order works - real order parameters might have issues")
|
||||
print(" Test order works - real order parameters might have issues")
|
||||
|
||||
# Test 5: Try different parameter variations
|
||||
print("\n5. Testing different parameter sets:")
|
||||
|
||||
@@ -28,7 +28,7 @@ def test_different_approaches():
|
||||
api_secret = os.getenv('MEXC_SECRET_KEY', '')
|
||||
|
||||
if not api_key or not api_secret:
|
||||
print("❌ No MEXC API credentials found")
|
||||
print(" No MEXC API credentials found")
|
||||
return False
|
||||
|
||||
# Test order parameters
|
||||
@@ -109,13 +109,13 @@ def test_different_approaches():
|
||||
print(f"Response: {response.status_code} - {response.text}")
|
||||
|
||||
if response.status_code == 200:
|
||||
print(f"✅ {method} WORKS!")
|
||||
print(f" {method} WORKS!")
|
||||
return True
|
||||
else:
|
||||
print(f"❌ {method} failed")
|
||||
print(f" {method} failed")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ {method} error: {e}")
|
||||
print(f" {method} error: {e}")
|
||||
|
||||
# Try one more approach - use minimal parameters
|
||||
print("\n" + "=" * 60)
|
||||
@@ -149,11 +149,11 @@ def test_different_approaches():
|
||||
print(f"Minimal response: {response.status_code} - {response.text}")
|
||||
|
||||
if response.status_code == 200:
|
||||
print("✅ Minimal parameters work!")
|
||||
print(" Minimal parameters work!")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Minimal parameters error: {e}")
|
||||
print(f" Minimal parameters error: {e}")
|
||||
|
||||
return False
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ def test_signature_generation():
|
||||
api_secret = os.getenv('MEXC_SECRET_KEY', '')
|
||||
|
||||
if not api_key or not api_secret:
|
||||
print("❌ No MEXC API credentials found")
|
||||
print(" No MEXC API credentials found")
|
||||
return False
|
||||
|
||||
# Import the interface
|
||||
@@ -66,9 +66,9 @@ def test_signature_generation():
|
||||
|
||||
# Compare
|
||||
if signature_manual == signature_interface:
|
||||
print("✅ Signatures match!")
|
||||
print(" Signatures match!")
|
||||
else:
|
||||
print("❌ Signatures don't match")
|
||||
print(" Signatures don't match")
|
||||
print("This indicates a problem with the signature generation method")
|
||||
|
||||
# Test 3: Try account request with manual signature
|
||||
@@ -97,10 +97,10 @@ def test_signature_generation():
|
||||
print(f"Response: {response.text}")
|
||||
|
||||
if response.status_code == 200:
|
||||
print("✅ Manual method works!")
|
||||
print(" Manual method works!")
|
||||
return True
|
||||
else:
|
||||
print("❌ Manual method failed")
|
||||
print(" Manual method failed")
|
||||
|
||||
# Test 4: Try different parameter ordering
|
||||
print("\n4. Testing different parameter orderings:")
|
||||
|
||||
@@ -24,22 +24,22 @@ def test_small_order():
|
||||
api_secret = os.getenv('MEXC_SECRET_KEY', '')
|
||||
|
||||
if not api_key or not api_secret:
|
||||
print("❌ No MEXC API credentials found")
|
||||
print(" No MEXC API credentials found")
|
||||
return
|
||||
|
||||
# Create MEXC interface
|
||||
mexc = MEXCInterface(api_key=api_key, api_secret=api_secret, test_mode=False)
|
||||
|
||||
if not mexc.connect():
|
||||
print("❌ Failed to connect to MEXC API")
|
||||
print(" Failed to connect to MEXC API")
|
||||
return
|
||||
|
||||
print("✅ Connected to MEXC API")
|
||||
print(" Connected to MEXC API")
|
||||
|
||||
# Get current price
|
||||
ticker = mexc.get_ticker("ETH/USDT") # Will be converted to ETHUSDC
|
||||
if not ticker:
|
||||
print("❌ Failed to get ticker")
|
||||
print(" Failed to get ticker")
|
||||
return
|
||||
|
||||
current_price = ticker['last']
|
||||
@@ -63,7 +63,7 @@ def test_small_order():
|
||||
)
|
||||
|
||||
if result:
|
||||
print("✅ Order placed successfully!")
|
||||
print(" Order placed successfully!")
|
||||
print(f"Order result: {result}")
|
||||
|
||||
# Try to cancel it immediately
|
||||
@@ -72,10 +72,10 @@ def test_small_order():
|
||||
cancel_result = mexc.cancel_order("ETH/USDT", result['orderId'])
|
||||
print(f"Cancel result: {cancel_result}")
|
||||
else:
|
||||
print("❌ Order placement failed")
|
||||
print(" Order placement failed")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Order error: {e}")
|
||||
print(f" Order error: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_small_order()
|
||||
@@ -106,9 +106,9 @@ async def test_live_trading():
|
||||
if user_input.upper() == 'YES':
|
||||
cancelled = executor._cancel_open_orders("ETH/USDT")
|
||||
if cancelled:
|
||||
logger.info("✅ Open orders cancelled successfully")
|
||||
logger.info(" Open orders cancelled successfully")
|
||||
else:
|
||||
logger.warning("⚠️ Some orders may not have been cancelled")
|
||||
logger.warning(" Some orders may not have been cancelled")
|
||||
else:
|
||||
logger.info("No open orders found")
|
||||
except Exception as e:
|
||||
@@ -146,7 +146,7 @@ async def test_live_trading():
|
||||
)
|
||||
|
||||
if success:
|
||||
logger.info("✅ Test BUY order executed successfully!")
|
||||
logger.info(" Test BUY order executed successfully!")
|
||||
|
||||
# Check order status
|
||||
await asyncio.sleep(1)
|
||||
@@ -168,14 +168,14 @@ async def test_live_trading():
|
||||
)
|
||||
|
||||
if success:
|
||||
logger.info("✅ Test SELL order executed successfully!")
|
||||
logger.info("✅ Full test trade cycle completed!")
|
||||
logger.info(" Test SELL order executed successfully!")
|
||||
logger.info(" Full test trade cycle completed!")
|
||||
else:
|
||||
logger.warning("❌ Test SELL order failed")
|
||||
logger.warning(" Test SELL order failed")
|
||||
else:
|
||||
logger.warning("❌ No position found after BUY order")
|
||||
logger.warning(" No position found after BUY order")
|
||||
else:
|
||||
logger.warning("❌ Test BUY order failed")
|
||||
logger.warning(" Test BUY order failed")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error executing test trade: {e}")
|
||||
@@ -205,7 +205,7 @@ async def test_live_trading():
|
||||
try:
|
||||
open_orders = executor.exchange.get_open_orders("ETH/USDT")
|
||||
if open_orders and len(open_orders) > 0:
|
||||
logger.warning(f"⚠️ {len(open_orders)} open orders still pending:")
|
||||
logger.warning(f" {len(open_orders)} open orders still pending:")
|
||||
for order in open_orders:
|
||||
order_id = order.get('orderId', 'N/A')
|
||||
side = order.get('side', 'N/A')
|
||||
@@ -214,7 +214,7 @@ async def test_live_trading():
|
||||
status = order.get('status', 'N/A')
|
||||
logger.info(f" Order {order_id}: {side} {qty} ETH at ${price} - Status: {status}")
|
||||
else:
|
||||
logger.info("✅ No pending orders")
|
||||
logger.info(" No pending orders")
|
||||
except Exception as e:
|
||||
logger.error(f"Error checking final open orders: {e}")
|
||||
|
||||
|
||||
@@ -423,13 +423,13 @@ class ExtremaTrainer:
|
||||
self.context_data[symbol].last_update = datetime.now()
|
||||
|
||||
results[symbol] = True
|
||||
logger.info(f"✅ Loaded {len(context_data)} 1m candles for {symbol} context")
|
||||
logger.info(f" Loaded {len(context_data)} 1m candles for {symbol} context")
|
||||
else:
|
||||
results[symbol] = False
|
||||
logger.warning(f"❌ No 1m context data available for {symbol}")
|
||||
logger.warning(f" No 1m context data available for {symbol}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"❌ Error loading context data for {symbol}: {e}")
|
||||
logger.error(f" Error loading context data for {symbol}: {e}")
|
||||
results[symbol] = False
|
||||
|
||||
except Exception as e:
|
||||
|
||||
@@ -110,11 +110,11 @@ class OvernightTrainingCoordinator:
|
||||
logger.info("🌙 OVERNIGHT TRAINING SESSION STARTED")
|
||||
logger.info("=" * 60)
|
||||
logger.info("Features enabled:")
|
||||
logger.info("✅ CNN training on signal changes")
|
||||
logger.info("✅ COB RL training on market microstructure")
|
||||
logger.info("✅ Trade execution and recording")
|
||||
logger.info("✅ Performance tracking and statistics")
|
||||
logger.info("✅ Model checkpointing")
|
||||
logger.info(" CNN training on signal changes")
|
||||
logger.info(" COB RL training on market microstructure")
|
||||
logger.info(" Trade execution and recording")
|
||||
logger.info(" Performance tracking and statistics")
|
||||
logger.info(" Model checkpointing")
|
||||
logger.info("=" * 60)
|
||||
|
||||
def stop_overnight_training(self):
|
||||
@@ -253,7 +253,7 @@ class OvernightTrainingCoordinator:
|
||||
status = "EXECUTED" if signal_record.executed else "SIGNAL_ONLY"
|
||||
logger.info(f"[{status}] {symbol} {decision.action} "
|
||||
f"(conf: {decision.confidence:.3f}, "
|
||||
f"training: {'✅' if signal_record.training_triggered else '❌'}, "
|
||||
f"training: {'' if signal_record.training_triggered else ''}, "
|
||||
f"pnl: {signal_record.trade_pnl:.2f if signal_record.trade_pnl else 'N/A'})")
|
||||
|
||||
except Exception as e:
|
||||
|
||||
@@ -49,7 +49,7 @@ class RealtimePredictionLoop:
|
||||
async def start(self):
|
||||
"""Start the continuous prediction loop"""
|
||||
self.running = True
|
||||
logger.info("🔄 Starting Real-Time Prediction Loop")
|
||||
logger.info(" Starting Real-Time Prediction Loop")
|
||||
|
||||
# Start prediction tasks for each symbol
|
||||
symbols = self.orchestrator.config.get('symbols', ['ETH/USDT', 'BTC/USDT'])
|
||||
@@ -67,7 +67,7 @@ class RealtimePredictionLoop:
|
||||
|
||||
async def _prediction_loop_for_symbol(self, symbol: str):
|
||||
"""Run prediction loop for a specific symbol"""
|
||||
logger.info(f"🔄 Prediction loop started for {symbol}")
|
||||
logger.info(f" Prediction loop started for {symbol}")
|
||||
|
||||
while self.running:
|
||||
try:
|
||||
@@ -194,10 +194,10 @@ class RealtimePredictionLoop:
|
||||
if cnn_input and cnn_input.data_quality_score > 0.5:
|
||||
cnn_data = self.unified_data_interface.get_model_specific_input(cnn_input, 'cnn')
|
||||
if cnn_data is not None:
|
||||
# ✅ THIS IS WHERE model.predict() GETS CALLED WITH CORRECT DATA!
|
||||
# THIS IS WHERE model.predict() GETS CALLED WITH CORRECT DATA!
|
||||
cnn_prediction = self.orchestrator.cnn_model.predict(cnn_data)
|
||||
predictions['cnn'] = cnn_prediction
|
||||
logger.info(f"✅ CNN prediction for {symbol}: {cnn_prediction} (quality: {cnn_input.data_quality_score:.2f})")
|
||||
logger.info(f" CNN prediction for {symbol}: {cnn_prediction} (quality: {cnn_input.data_quality_score:.2f})")
|
||||
except Exception as e:
|
||||
logger.error(f"CNN prediction error for {symbol}: {e}")
|
||||
|
||||
@@ -215,7 +215,7 @@ class RealtimePredictionLoop:
|
||||
'action': action,
|
||||
'action_name': ['SELL', 'HOLD', 'BUY'][action]
|
||||
}
|
||||
logger.info(f"✅ DQN prediction for {symbol}: {predictions['dqn']['action_name']} (quality: {dqn_input.data_quality_score:.2f})")
|
||||
logger.info(f" DQN prediction for {symbol}: {predictions['dqn']['action_name']} (quality: {dqn_input.data_quality_score:.2f})")
|
||||
except Exception as e:
|
||||
logger.error(f"DQN prediction error for {symbol}: {e}")
|
||||
|
||||
@@ -229,7 +229,7 @@ class RealtimePredictionLoop:
|
||||
if cob_data is not None and hasattr(self.orchestrator.cob_rl_model, 'predict'):
|
||||
cob_prediction = self.orchestrator.cob_rl_model.predict(cob_data)
|
||||
predictions['cob_rl'] = cob_prediction
|
||||
logger.info(f"✅ COB RL prediction for {symbol}: {cob_prediction} (quality: {cob_input.data_quality_score:.2f})")
|
||||
logger.info(f" COB RL prediction for {symbol}: {cob_prediction} (quality: {cob_input.data_quality_score:.2f})")
|
||||
except Exception as e:
|
||||
logger.error(f"COB RL prediction error for {symbol}: {e}")
|
||||
|
||||
@@ -243,7 +243,7 @@ class RealtimePredictionLoop:
|
||||
if transformer_data is not None and hasattr(self.orchestrator.transformer_model, 'predict'):
|
||||
transformer_prediction = self.orchestrator.transformer_model.predict(transformer_data)
|
||||
predictions['transformer'] = transformer_prediction
|
||||
logger.info(f"✅ Transformer prediction for {symbol}: {transformer_prediction} (quality: {transformer_input.data_quality_score:.2f})")
|
||||
logger.info(f" Transformer prediction for {symbol}: {transformer_prediction} (quality: {transformer_input.data_quality_score:.2f})")
|
||||
except Exception as e:
|
||||
logger.error(f"Transformer prediction error for {symbol}: {e}")
|
||||
|
||||
|
||||
@@ -811,7 +811,7 @@ class TradingExecutor:
|
||||
self.min_profitability_multiplier,
|
||||
self.profitability_reward_multiplier - self.profitability_adjustment_step
|
||||
)
|
||||
logger.info(f"⚠️ SUCCESS RATE LOW ({success_rate:.1%}) - Decreased profitability multiplier: {old_multiplier:.1f} → {self.profitability_reward_multiplier:.1f}")
|
||||
logger.info(f" SUCCESS RATE LOW ({success_rate:.1%}) - Decreased profitability multiplier: {old_multiplier:.1f} → {self.profitability_reward_multiplier:.1f}")
|
||||
|
||||
else:
|
||||
logger.debug(f"Success rate {success_rate:.1%} in acceptable range - keeping multiplier at {self.profitability_reward_multiplier:.1f}")
|
||||
|
||||
@@ -96,7 +96,7 @@ class UnifiedDataProviderExtension:
|
||||
logger.info("✓ Ingestion pipeline started")
|
||||
|
||||
self._initialized = True
|
||||
logger.info("✅ Unified storage system initialized successfully")
|
||||
logger.info(" Unified storage system initialized successfully")
|
||||
|
||||
return True
|
||||
|
||||
@@ -119,7 +119,7 @@ class UnifiedDataProviderExtension:
|
||||
logger.info("✓ Database connection closed")
|
||||
|
||||
self._initialized = False
|
||||
logger.info("✅ Unified storage system shutdown complete")
|
||||
logger.info(" Unified storage system shutdown complete")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error shutting down unified storage: {e}")
|
||||
|
||||
@@ -60,7 +60,7 @@ class UnifiedQueryableStorage:
|
||||
self.backend = get_timescale_storage(timescale_connection_string)
|
||||
if self.backend:
|
||||
self.backend_type = "timescale"
|
||||
logger.info("✅ Using TimescaleDB for queryable storage")
|
||||
logger.info(" Using TimescaleDB for queryable storage")
|
||||
except Exception as e:
|
||||
logger.warning(f"TimescaleDB not available: {e}")
|
||||
|
||||
@@ -69,7 +69,7 @@ class UnifiedQueryableStorage:
|
||||
try:
|
||||
self.backend = SQLiteQueryableStorage(sqlite_path)
|
||||
self.backend_type = "sqlite"
|
||||
logger.info("✅ Using SQLite for queryable storage (TimescaleDB fallback)")
|
||||
logger.info(" Using SQLite for queryable storage (TimescaleDB fallback)")
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to initialize SQLite storage: {e}")
|
||||
raise Exception("No queryable storage backend available")
|
||||
|
||||
Reference in New Issue
Block a user