Spaces:
Sleeping
Sleeping
| """ | |
| Risk manager — lot sizing, hold time calculation, gap strategy. | |
| Central trade decision layer. | |
| """ | |
| import logging | |
| from config import TRADE_MODE, MIN_CONFIDENCE | |
| from agents.aggregator import get_lot_size, get_hold_time, determine_strategy | |
| from data.price_data import detect_gap | |
| logger = logging.getLogger("gap_system.execution.risk_manager") | |
| async def evaluate_trade( | |
| asset: str, | |
| direction: str, | |
| confidence: float, | |
| ) -> dict: | |
| """ | |
| Evaluate whether to trade and with what parameters. | |
| Returns trade parameters or skip signal. | |
| """ | |
| # Confidence threshold | |
| if confidence < MIN_CONFIDENCE: | |
| logger.info("Skipping %s: confidence %.1f%% below threshold %.1f%%", | |
| asset, confidence * 100, MIN_CONFIDENCE * 100) | |
| return {"action": "SKIP", "reason": "below_confidence_threshold"} | |
| # Lot size | |
| lot_size = get_lot_size(confidence) | |
| if lot_size is None: | |
| return {"action": "SKIP", "reason": "no_lot_for_confidence"} | |
| # Hold time | |
| hold_seconds = get_hold_time(confidence) | |
| if hold_seconds is None: | |
| return {"action": "SKIP", "reason": "no_hold_time_for_confidence"} | |
| # Detect gap | |
| gap_info = await detect_gap(asset) | |
| if gap_info is None: | |
| gap_direction = "NONE" | |
| else: | |
| gap_direction = gap_info.get("gap_direction", "NONE") | |
| # No gap = no trade | |
| if gap_direction == "NONE": | |
| logger.info("No gap detected for %s — skipping", asset) | |
| return {"action": "SKIP", "reason": "no_gap_detected"} | |
| # Strategy | |
| strategy = determine_strategy(gap_direction, direction, confidence) | |
| if strategy == "SKIP": | |
| logger.info("Strategy SKIP for %s (conflict, low confidence)", asset) | |
| return {"action": "SKIP", "reason": "conflicting_signals"} | |
| return { | |
| "action": "TRADE", | |
| "asset": asset, | |
| "direction": direction, | |
| "confidence": confidence, | |
| "lot_size": lot_size, | |
| "hold_seconds": hold_seconds, | |
| "strategy": strategy, | |
| "gap_direction": gap_direction, | |
| "gap_info": gap_info, | |
| } | |
| async def execute(trade_params: dict) -> dict: | |
| """Execute a trade using the configured mode.""" | |
| if trade_params.get("action") != "TRADE": | |
| return trade_params | |
| asset = trade_params["asset"] | |
| direction = trade_params["direction"] | |
| lot_size = trade_params["lot_size"] | |
| hold_seconds = trade_params["hold_seconds"] | |
| logger.info( | |
| "Executing: %s %s %.2f lots, hold %ds, strategy=%s", | |
| asset, direction, lot_size, hold_seconds, | |
| trade_params.get("strategy", "?"), | |
| ) | |
| if TRADE_MODE == "darwinex": | |
| from execution.darwinex_executor import execute_trade | |
| else: | |
| from execution.mt5_executor import execute_trade | |
| result = await execute_trade(asset, direction, lot_size, hold_seconds) | |
| result["strategy"] = trade_params.get("strategy", "") | |
| return result | |