deribit
This commit is contained in:
@ -17,17 +17,17 @@ import time
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class ConfigSynchronizer:
|
||||
"""Handles automatic synchronization of config parameters with MEXC API"""
|
||||
"""Handles automatic synchronization of config parameters with exchange APIs"""
|
||||
|
||||
def __init__(self, config_path: str = "config.yaml", mexc_interface=None):
|
||||
"""Initialize the config synchronizer
|
||||
|
||||
Args:
|
||||
config_path: Path to the main config file
|
||||
mexc_interface: MEXCInterface instance for API calls
|
||||
mexc_interface: Exchange interface instance for API calls (maintains compatibility)
|
||||
"""
|
||||
self.config_path = config_path
|
||||
self.mexc_interface = mexc_interface
|
||||
self.exchange_interface = mexc_interface # Generic exchange interface
|
||||
self.last_sync_time = None
|
||||
self.sync_interval = 3600 # Sync every hour by default
|
||||
self.backup_enabled = True
|
||||
@ -130,15 +130,15 @@ class ConfigSynchronizer:
|
||||
logger.info(f"CONFIG SYNC: Skipping sync, last sync was recent")
|
||||
return sync_record
|
||||
|
||||
if not self.mexc_interface:
|
||||
if not self.exchange_interface:
|
||||
sync_record['status'] = 'error'
|
||||
sync_record['errors'].append('No MEXC interface available')
|
||||
logger.error("CONFIG SYNC: No MEXC interface available for fee sync")
|
||||
sync_record['errors'].append('No exchange interface available')
|
||||
logger.error("CONFIG SYNC: No exchange interface available for fee sync")
|
||||
return sync_record
|
||||
|
||||
# Get current fees from MEXC API
|
||||
logger.info("CONFIG SYNC: Fetching trading fees from MEXC API")
|
||||
api_fees = self.mexc_interface.get_trading_fees()
|
||||
logger.info("CONFIG SYNC: Fetching trading fees from exchange API")
|
||||
api_fees = self.exchange_interface.get_trading_fees()
|
||||
sync_record['api_response'] = api_fees
|
||||
|
||||
if api_fees.get('source') == 'fallback':
|
||||
@ -205,7 +205,7 @@ class ConfigSynchronizer:
|
||||
|
||||
config['trading']['fee_sync_metadata'] = {
|
||||
'last_sync': datetime.now().isoformat(),
|
||||
'api_source': 'mexc',
|
||||
'api_source': 'exchange', # Changed from 'mexc' to 'exchange'
|
||||
'sync_enabled': True,
|
||||
'api_commission_rates': {
|
||||
'maker': api_fees.get('maker_commission', 0),
|
||||
@ -288,7 +288,7 @@ class ConfigSynchronizer:
|
||||
'sync_interval_seconds': self.sync_interval,
|
||||
'latest_sync_result': latest_sync,
|
||||
'total_syncs': len(self.sync_history),
|
||||
'mexc_interface_available': self.mexc_interface is not None
|
||||
'mexc_interface_available': self.exchange_interface is not None # Changed from mexc_interface to exchange_interface
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
|
@ -22,7 +22,8 @@ import sys
|
||||
# Add NN directory to path for exchange interfaces
|
||||
sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'NN'))
|
||||
|
||||
from NN.exchanges import MEXCInterface
|
||||
from NN.exchanges.exchange_factory import ExchangeFactory
|
||||
from NN.exchanges.exchange_interface import ExchangeInterface
|
||||
from .config import get_config
|
||||
from .config_sync import ConfigSynchronizer
|
||||
|
||||
@ -63,53 +64,68 @@ class TradeRecord:
|
||||
hold_time_seconds: float = 0.0 # Hold time in seconds
|
||||
|
||||
class TradingExecutor:
|
||||
"""Handles trade execution through MEXC API with risk management"""
|
||||
"""Handles trade execution through multiple exchange APIs with risk management"""
|
||||
|
||||
def __init__(self, config_path: str = "config.yaml"):
|
||||
"""Initialize the trading executor"""
|
||||
self.config = get_config(config_path)
|
||||
self.mexc_config = self.config.get('mexc_trading', {})
|
||||
self.exchanges_config = self.config.get('exchanges', {})
|
||||
self.trading_config = self.config.get('trading', {})
|
||||
|
||||
# Initialize MEXC interface
|
||||
api_key = os.getenv('MEXC_API_KEY', self.mexc_config.get('api_key', ''))
|
||||
api_secret = os.getenv('MEXC_SECRET_KEY', self.mexc_config.get('api_secret', ''))
|
||||
# Initialize exchanges using factory
|
||||
self.primary_exchange = ExchangeFactory.get_primary_exchange(self.exchanges_config)
|
||||
self.all_exchanges = ExchangeFactory.create_multiple_exchanges(self.exchanges_config)
|
||||
|
||||
# Determine trading mode from unified config
|
||||
trading_mode = self.mexc_config.get('trading_mode', 'simulation')
|
||||
# Set primary exchange as main interface
|
||||
self.exchange = self.primary_exchange
|
||||
|
||||
# Map trading mode to exchange test_mode and execution mode
|
||||
if trading_mode == 'simulation':
|
||||
exchange_test_mode = True
|
||||
if not self.exchange:
|
||||
logger.error("Failed to initialize primary exchange")
|
||||
self.trading_enabled = False
|
||||
self.simulation_mode = True
|
||||
elif trading_mode == 'testnet':
|
||||
exchange_test_mode = True
|
||||
self.simulation_mode = False
|
||||
elif trading_mode == 'live':
|
||||
exchange_test_mode = False
|
||||
self.simulation_mode = False
|
||||
else:
|
||||
logger.warning(f"Unknown trading_mode '{trading_mode}', defaulting to simulation")
|
||||
exchange_test_mode = True
|
||||
self.simulation_mode = True
|
||||
primary_name = self.exchanges_config.get('primary', 'deribit')
|
||||
primary_config = self.exchanges_config.get(primary_name, {})
|
||||
|
||||
# Determine trading and simulation modes
|
||||
trading_mode = primary_config.get('trading_mode', 'simulation')
|
||||
self.trading_enabled = self.trading_config.get('enabled', True)
|
||||
self.simulation_mode = trading_mode == 'simulation'
|
||||
|
||||
logger.info(f"Trading Executor initialized with {primary_name} as primary exchange")
|
||||
logger.info(f"Trading mode: {trading_mode}, Simulation: {self.simulation_mode}")
|
||||
|
||||
self.exchange = MEXCInterface(
|
||||
api_key=api_key,
|
||||
api_secret=api_secret,
|
||||
test_mode=exchange_test_mode,
|
||||
# Initialize config synchronizer with the primary exchange
|
||||
self.config_sync = ConfigSynchronizer(
|
||||
config_path=config_path,
|
||||
mexc_interface=self.exchange if self.trading_enabled else None
|
||||
)
|
||||
|
||||
# Trading state
|
||||
self.positions: Dict[str, Position] = {}
|
||||
self.trade_history: List[TradeRecord] = []
|
||||
# Trading state management
|
||||
self.current_position = {} # symbol -> position data
|
||||
self.trade_history = []
|
||||
self.daily_trades = 0
|
||||
self.daily_pnl = 0.0
|
||||
self.daily_loss = 0.0
|
||||
self.last_trade_time = {}
|
||||
self.trading_enabled = self.mexc_config.get('enabled', False)
|
||||
self.trading_mode = trading_mode
|
||||
self.consecutive_losses = 0 # Track consecutive losing trades
|
||||
|
||||
logger.debug(f"TRADING EXECUTOR: Initial trading_enabled state from config: {self.trading_enabled}")
|
||||
|
||||
# Store trading mode for compatibility
|
||||
primary_name = self.exchanges_config.get('primary', 'deribit')
|
||||
primary_config = self.exchanges_config.get(primary_name, {})
|
||||
self.trading_mode = primary_config.get('trading_mode', 'simulation')
|
||||
|
||||
# Initialize session stats
|
||||
self.session_start_time = datetime.now()
|
||||
self.session_trades = 0
|
||||
self.session_pnl = 0.0
|
||||
|
||||
# Position tracking
|
||||
self.positions = {} # symbol -> Position object
|
||||
self.trade_records = [] # List of TradeRecord objects
|
||||
|
||||
logger.info(f"TradingExecutor initialized - Trading: {self.trading_enabled}, Mode: {self.trading_mode}")
|
||||
|
||||
# Legacy compatibility (deprecated)
|
||||
self.dry_run = self.simulation_mode
|
||||
|
||||
@ -155,24 +171,34 @@ class TradingExecutor:
|
||||
|
||||
logger.info(f"Trading Executor initialized - Mode: {self.trading_mode}, Enabled: {self.trading_enabled}")
|
||||
|
||||
def _connect_exchange(self) -> bool:
|
||||
"""Connect to the MEXC exchange"""
|
||||
def _safe_exchange_call(self, method_name: str, *args, **kwargs):
|
||||
"""Safely call exchange methods with null checking"""
|
||||
if not self.exchange:
|
||||
logger.warning(f"No exchange interface available for {method_name}")
|
||||
return None
|
||||
|
||||
try:
|
||||
logger.debug("TRADING EXECUTOR: Calling self.exchange.connect()...")
|
||||
connected = self.exchange.connect()
|
||||
logger.debug(f"TRADING EXECUTOR: self.exchange.connect() returned: {connected}")
|
||||
if connected:
|
||||
logger.info("Successfully connected to MEXC exchange")
|
||||
return True
|
||||
method = getattr(self.exchange, method_name, None)
|
||||
if method:
|
||||
return method(*args, **kwargs)
|
||||
else:
|
||||
logger.error("Failed to connect to MEXC exchange: Connection returned False.")
|
||||
if not self.dry_run:
|
||||
logger.info("TRADING EXECUTOR: Setting trading_enabled to False due to connection failure.")
|
||||
self.trading_enabled = False
|
||||
return False
|
||||
logger.error(f"Method {method_name} not available on exchange")
|
||||
return None
|
||||
except Exception as e:
|
||||
logger.error(f"Error connecting to MEXC exchange: {e}. Setting trading_enabled to False.")
|
||||
self.trading_enabled = False
|
||||
logger.error(f"Error calling {method_name}: {e}")
|
||||
return None
|
||||
|
||||
def _connect_exchange(self) -> bool:
|
||||
"""Connect to the primary exchange"""
|
||||
if not self.exchange:
|
||||
logger.warning("No exchange interface available")
|
||||
return False
|
||||
|
||||
if self.exchange.connect():
|
||||
logger.info("Successfully connected to exchange")
|
||||
return True
|
||||
else:
|
||||
logger.error("Failed to connect to exchange")
|
||||
return False
|
||||
|
||||
def execute_signal(self, symbol: str, action: str, confidence: float,
|
||||
|
Reference in New Issue
Block a user