From 7e8722aa57c21c89be45d63712e748a1f6bdaacb Mon Sep 17 00:00:00 2001 From: Dobromir Popov Date: Mon, 8 Dec 2025 19:35:58 +0200 Subject: [PATCH] no data rail guide --- ANNOTATE/core/real_training_adapter.py | 37 +++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/ANNOTATE/core/real_training_adapter.py b/ANNOTATE/core/real_training_adapter.py index e08bf59..a98a828 100644 --- a/ANNOTATE/core/real_training_adapter.py +++ b/ANNOTATE/core/real_training_adapter.py @@ -930,6 +930,17 @@ class RealTrainingAdapter: # Create market state snapshot at this candle hold_market_state = self._create_market_state_snapshot(market_state, idx) + # Validate that the snapshot has enough data + has_enough_data = True + for tf, tf_data in hold_market_state.get('timeframes', {}).items(): + if len(tf_data.get('close', [])) < 50: # Minimum required + has_enough_data = False + break + + if not has_enough_data: + logger.debug(f" Skipping HOLD sample at idx {idx} - insufficient data") + continue + # Calculate current unrealized PnL at this point entry_price = expected_outcome.get('entry_price', 0) current_price = timeframes['1m']['close'][idx] if idx < len(timeframes['1m']['close']) else entry_price @@ -1043,18 +1054,22 @@ class RealTrainingAdapter: logger.debug(f" Estimated exit index: {exit_index} ({candles_in_trade} candles)") # Create NO_TRADE samples: 5 before entry + 5 after exit + # CRITICAL: Only create samples that have enough historical data (600 candles) + required_candles = 600 negative_indices = [] - # 5 candles BEFORE entry + # 5 candles BEFORE entry (but only if we have enough history) for offset in range(1, samples_before + 1): idx = entry_index - offset - if 0 <= idx < len(timestamps): + # Check if we have enough candles before this index + if idx >= required_candles - 1 and idx < len(timestamps): negative_indices.append(('before_entry', idx)) - # 5 candles AFTER exit + # 5 candles AFTER exit (should have enough history since exit is after entry) for offset in range(1, samples_after + 1): idx = exit_index + offset - if 0 <= idx < len(timestamps): + # Check if we have enough candles before this index + if idx >= required_candles - 1 and idx < len(timestamps): negative_indices.append(('after_exit', idx)) # Create negative samples @@ -1062,6 +1077,17 @@ class RealTrainingAdapter: # Create a market state snapshot at this timestamp negative_market_state = self._create_market_state_snapshot(market_state, idx) + # Validate that the snapshot has enough data + has_enough_data = True + for tf, tf_data in negative_market_state.get('timeframes', {}).items(): + if len(tf_data.get('close', [])) < 50: # Minimum required + has_enough_data = False + break + + if not has_enough_data: + logger.debug(f" Skipping negative sample at idx {idx} - insufficient data") + continue + negative_sample = { 'market_state': negative_market_state, 'action': 'HOLD', # No action @@ -2492,6 +2518,9 @@ class RealTrainingAdapter: OPTIMIZATION: Batches are already on GPU and grouped for efficient processing. Each mini-batch contains 5 samples for better GPU utilization. + + IMPORTANT: Yields the same batch objects across epochs (no copying). + The train_step method should not modify batch contents in-place. """ for batch in grouped_batches: yield batch