Phase 3 LLM-Enhanced Model Integration
This Python program connects NinjaTrader 8 to your trained Stable-Baselines3 Phase 3 model with LLM-enhanced features for automated trading on E-mini Nasdaq-100 (NQ).
[NinjaTrader 8] <--TCP:8888--> [Python Bridge] <---> [Phase 3 Model + Adapter]
AIBridgeV2.cs ai_trading_bridge.py NQ_ts-0040960...zip
Data Flow (Phase 3):
- NinjaTrader sends real-time bar data (OHLCV + indicators)
- Python builds 261D observation:
- 220D market features (20 bars Γ 11 indicators)
- 8D position state (includes validity flags)
- 33D LLM features (extended market context)
- VecNormalize applies normalization (trained on 40,960 timesteps)
- Adapter layer reduces 261D β 228D
- Policy network predicts action (0-5)
- Python sends action to NinjaTrader
- NinjaTrader executes the action
models/
βββ ai_trading_bridge.py # Main program
βββ config.py # Configuration settings (Phase 3)
βββ tcp_client.py # TCP communication
βββ observation_builder.py # Observation construction (261D)
βββ model_manager.py # Model loading & inference (with adapter)
βββ llm_features.py # LLM feature builder (33D features)
βββ trade_logger.py # Performance tracking
βββ requirements.txt # Dependencies
βββ README.md # This file
β
βββ model/ # Phase 3 model directory
β βββ NQ_ts-0040960_evt-best_val-+216.697_sharpe-+0.48_seed-42.zip # β
Trained model
β βββ NQ_ts-0040960_evt-best_val-+216.697_sharpe-+0.48_seed-42_vecnormalize.pkl # β
VecNormalize
β βββ NQ_ts-0040960_evt-best_val-+216.697_sharpe-+0.48_seed-42_metadata.json # Metadata
β
βββ logs/ # Auto-created
βββ trading_log.txt # Session logs
βββ actions.csv # All actions taken
βββ performance.txt # Statistics
cd "/mnt/c/Users/javlo/Documents/NinjaTrader 8/bin/Custom/models"
pip install -r requirements.txtDependencies:
stable-baselines3>=2.0.0- RL frameworksb3-contrib>=2.0.0- Advanced algorithms (MaskablePPO)numpy>=1.21.0- Numerical computinggym>=0.21.0- Environment interface
- File:
model/NQ_ts-0040960_evt-best_val-+216.697_sharpe-+0.48_seed-42.zip - Size: 2.5 MB
- Type: MaskablePPO with adapter layer (261D β 228D)
- Trained: 40,960 timesteps
- Performance: +$216.697 validation, Sharpe 0.48
- File:
model/NQ_ts-0040960_evt-best_val-+216.697_sharpe-+0.48_seed-42_vecnormalize.pkl - Size: 28.6 KB
- Shape: (261,) - Includes LLM features
- Trained: 40,960 timesteps (Phase 3)
These files are CRITICAL for model operation and are already present!
Test that everything is configured correctly:
python config.pyExpected output (Phase 3):
======================================================================
AI Trading Bridge - Configuration Validation
======================================================================
β
Configuration valid!
π Model path: .../model/NQ_ts-0040960_evt-best_val-+216.697_sharpe-+0.48_seed-42.zip
π VecNormalize path: .../model/NQ_ts-0040960..._vecnormalize.pkl
π Log directory: .../logs
π’ Observation shape: (261,)
- Market features: 220 (20 bars Γ 11 features)
- Position features: 8
- LLM features: 33
- Base (Phase 2): 228, Extended (Phase 3): 261
π TCP: localhost:8888
π Model type: MaskablePPO
======================================================================
If you see errors:
- Missing model file β Ensure Phase 3 model exists in model/ subdirectory
- Missing VecNormalize file β This is CRITICAL (must match model)
Test TCP connection to NinjaTrader:
python tcp_client.pyBefore running:
- Start NinjaTrader 8
- Load NQ 1-minute chart
- Add AIBridgeV2 strategy to chart
- Enable strategy (green arrow)
Expected output:
π Connecting to NinjaTrader @ localhost:8888...
β
Connected to NinjaTrader successfully!
Waiting for messages (Ctrl+C to stop)...
π¨ Received: bar
Close: 21450.25
ATR: 45.5
π€ Sending test action: HOLD (0)
If connection fails:
- Check NinjaTrader Output Window for "TCP Server started"
- Ensure AIBridgeV2 strategy is enabled
- Check no firewall blocking port 8888
Test observation construction:
python observation_builder.pyExpected output (Phase 3):
1. Adding first bar...
Window size: 1/20
β οΈ LLM feature calculation failed (using base obs only): single positional indexer is out-of-bounds
β
Observation shape: (261,)
First 11 features (bar 1): [21450.25 1234. 21448. ...]
Position features (8): [0. 1. 0. 0. 0. 1. 0. 0.]
LLM features (33): shape=(33,), sample=[0. 0. 0. 0. 0.]
2. Adding 19 more bars...
Window size: 20/20
β
Full observation shape: (261,)
Market features (220): min=0.00, max=21470.00
Position features (8): [0. 1. 0. 0. 0. 1. 0. 0.]
LLM features (33): min=0.00, max=0.00
Note: LLM feature warnings are normal during warmup (needs 60+ bars for multi-timeframe calculations).
Test model loading and predictions:
python model_manager.pyExpected output (Phase 3):
======================================================================
Loading Phase 3 AI Model
======================================================================
π Loading model: .../model/NQ_ts-0040960...zip
β οΈ MaskablePPO detected - trying standard loader first
β οΈ Standard loading failed (expected for Phase 3)
Trying custom loader (handles adapter architecture)...
π§ Using custom loader for pickle compatibility...
Detecting network architecture from weights...
Architecture: pi=[512, 256, 128], vf=[512, 256, 128]
π Adapter detected: torch.Size([228, 261])
π Phase 3 model - extracting adapter (261D β 228D)
β
Policy weights loaded (228D input)
β
Adapter extracted: torch.Size([228, 261])
β
Adapter layer created in ModelManager
β
Model loaded with custom loader: MaskablePPO
π Loading VecNormalize: .../model/NQ_ts-0040960..._vecnormalize.pkl
β
VecNormalize loaded
Running mean shape: (261,)
Running var shape: (261,)
β
Model ready for predictions!
2. Testing prediction with dummy observation...
Dummy observation shape: (261,)
β
Prediction successful!
Action: 4 (ENABLE_TRAIL)
If model loading fails:
- Check Phase 3 model file exists in model/ subdirectory
- Check VecNormalize file matches model (261D)
- Adapter architecture is required for Phase 3 (automatic)
Test logging functionality:
python trade_logger.pyExpected output:
1. Logging sample bars and actions...
[2025-11-07T10:30:00.000Z] π Bar #1 | Close=21450.00 | Vol=1200 | ATR=45.00
[2025-11-07T10:30:00.000Z] π― Action 1: BUY
... (more bars) ...
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Performance Summary (Live)
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Runtime: 0s
Bars Processed: 15
Actions Sent: 15
Action Distribution:
β
HOLD (0): 12 ( 80.0%) [Expected: 86.5%]
β
BUY (1): 1 ( 6.7%) [Expected: 5.0%]
...
Before running live trading:
- β Python dependencies installed
- β
NQ_o1.zipmodel file present - β
phase2_position_mgmt_final_vecnorm.pklfile present β - β All tests passed (tcp, observation, model, logger)
- β NinjaTrader 8 running
- β NQ 1-minute chart loaded
- β AIBridgeV2 strategy compiled (F5)
- β AIBridgeV2 strategy enabled on chart
- β Using Sim101 account (NOT live account!)
- Open NinjaTrader 8
- Connect to data feed
- Load chart:
Instruments β NQ 09-25 β 1 Minute - Add strategy:
Strategies β AIBridgeV2 - Enable strategy (green arrow at top)
- Verify in Output Window:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ AIBridgeV2 Starting... (Phase 2 Model Support) Integer Actions: 0-5 | ATR-based SL/TP | Trailing Stops βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β TCP Server started - Waiting for Python client connection...
Open a terminal and run:
cd "/mnt/c/Users/javlo/Documents/NinjaTrader 8/bin/Custom/models"
python ai_trading_bridge.pyExpected startup sequence:
======================================================================
AI Trading Bridge - Phase 2 Model
Initializing...
======================================================================
1. Validating configuration...
β
Configuration valid
2. Initializing components...
β
Observation builder ready
β
Model manager ready
β
Logger ready
β
TCP client ready
3. Loading AI model...
======================================================================
Loading Phase 2 AI Model
======================================================================
β
Model loaded: MaskablePPO
β
VecNormalize loaded
4. Connecting to NinjaTrader...
π Connecting to NinjaTrader @ localhost:8888...
β
Connected to NinjaTrader successfully!
======================================================================
β
All systems ready!
======================================================================
======================================================================
AI Trading Bridge - RUNNING
Press Ctrl+C to stop
======================================================================
π NinjaTrader Configuration:
Symbol: NQ 09-25
Tick Size: 0.25
Max Position: 10
NinjaTrader Output:
[2025-11-07 10:30:00] π Bar data sent: Close=$21450.25, ...
β
Action sent to NinjaTrader
[2025-11-07 10:30:00] π¨ Received Phase 2 action: 0
[2025-11-07 10:30:00] Action 0: HOLD - No action taken
Python Console Output:
[2025-11-07T10:30:00.000Z] π Bar #1 | Close=21450.25 | Vol=1234 | ATR=45.5
[2025-11-07T10:30:00.000Z] π― Action 0: HOLD
π€ Sending: HOLD (action=0)
[2025-11-07T10:31:00.000Z] π Bar #2 | Close=21452.75 | Vol=1456 | ATR=45.2
β³ Building window: 2/20 bars
[2025-11-07T10:49:00.000Z] π Bar #20 | Close=21478.50 | Vol=1889 | ATR=46.1
[2025-11-07T10:49:00.000Z] π― Action 1: BUY
π€ Sending: BUY (action=1)
When a trade executes:
[2025-11-07T10:49:00.000Z] π― Action 1: BUY
β
Order filled: AI_LONG @ 21478.50 x 1
π Position: LONG @ 21478.50
[2025-11-07T10:52:00.000Z] π― Action 3: MOVE_TO_BE
β
MOVE_TO_BE executed | New SL: 21478.75 | PnL: $600.00 | Count: 1
[2025-11-07T10:55:00.000Z] π― Action 4: ENABLE_TRAIL
β
ENABLE_TRAIL activated | SL: 21533.00 | Profit: $1,390.00 (1.05R)
[2025-11-07T10:56:00.000Z] π Bar #27 | Close=21548.25
β Trail SL updated: 21548.25 | Profit: $1,695.00
Every 10 bars, statistics are printed:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Performance Summary (Live)
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Runtime: 23m 45s
Bars Processed: 142
Actions Sent: 142
Action Distribution:
β
HOLD (0): 122 ( 85.9%) [Expected: 86.5%]
β
BUY (1): 7 ( 4.9%) [Expected: 5.0%]
β
SELL (2): 6 ( 4.2%) [Expected: 5.0%]
β
MOVE_TO_BE (3): 4 ( 2.8%) [Expected: 2.0%]
β
ENABLE_TRAIL (4): 2 ( 1.4%) [Expected: 1.0%]
β
DISABLE_TRAIL (5): 1 ( 0.7%) [Expected: 0.5%]
Position Management Usage: 4.9% [Target: ~13.5%]
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Indicators:
- β Green checkmark: Distribution within 5% of expected
β οΈ Yellow warning: Distribution 5-10% off expected- β Red X: Distribution >10% off expected
Graceful Shutdown:
- Press
Ctrl+Cin Python terminal - Python will:
- Print final statistics
- Disconnect from NinjaTrader cleanly
- Close log files
- Exit
Final Output:
β οΈ Shutdown signal received...
======================================================================
Final Session Statistics
======================================================================
Session Duration: 1h 23m 45s
Total Bars: 142
Total Actions: 142
Action Distribution:
HOLD (0): 122 ( 85.9%)
BUY (1): 7 ( 4.9%)
SELL (2): 6 ( 4.2%)
MOVE_TO_BE (3): 4 ( 2.8%)
ENABLE_TRAIL (4): 2 ( 1.4%)
DISABLE_TRAIL (5): 1 ( 0.7%)
Position Management Usage: 4.9%
Expected PM Usage: 13.5%
β οΈ PM usage outside expected range
======================================================================
β
Shutdown complete
======================================================================
All logs are saved in models/logs/:
Complete session log with timestamps:
======================================================================
AI Trading Bridge Session Started
Time: 2025-11-07 10:30:00
======================================================================
2025-11-07T10:30:00 | Action 0: HOLD
2025-11-07T10:49:00 | Action 1: BUY
2025-11-07T10:52:00 | Action 3: MOVE_TO_BE
...
Structured action log (importable to Excel):
timestamp,bar_index,action,action_name,close_price,atr,position
2025-11-07T10:30:00,1,0,HOLD,21450.25,45.5,0
2025-11-07T10:49:00,20,1,BUY,21478.50,46.1,0
2025-11-07T10:52:00,23,3,MOVE_TO_BE,21485.00,45.8,1Session summaries and statistics
Solution: Ensure NQ_o1.zip exists in models/ directory
Solution: This is CRITICAL. You must:
- Re-run your training script
- VecNormalize stats already present:
phase2_position_mgmt_final_vecnorm.pkl - Copy file to
models/directory
Without this file, model predictions will be incorrect!
Solution:
- Ensure NinjaTrader is running
- Ensure AIBridgeV2 strategy is enabled on chart
- Check Output Window for "TCP Server started"
- Try reloading the strategy
Solution:
- Check that NinjaTrader sends all 8 indicators
- Verify timestamp format is ISO 8601
- Run
python observation_builder.pyto test
Possible causes:
- Model still warming up (wait for more data)
- Market conditions different from training
- Position state not updating correctly from NinjaTrader
Not necessarily an error - monitor over longer period
If you trained with a different algorithm:
Edit config.py:
MODEL_TYPE = "DQN" # Options: PPO, MaskablePPO, DQN, A2C, SACSupported Algorithms:
"PPO"- Proximal Policy Optimization (stable-baselines3)"MaskablePPO"- PPO with action masking (sb3-contrib) β Current model"DQN"- Deep Q-Network (stable-baselines3)"A2C"- Advantage Actor-Critic (stable-baselines3)"SAC"- Soft Actor-Critic (stable-baselines3)
Note: MaskablePPO requires sb3-contrib package
Edit config.py:
VERBOSE = True # Print detailed output
SHOW_BAR_DATA = True # Print every bar
SHOW_OBSERVATIONS = False # Print observation arrays (noisy)
SHOW_PREDICTIONS = True # Print model predictions
STATS_UPDATE_FREQUENCY = 10 # Print stats every N barsIf port 8888 is in use:
- Edit
config.py:
TCP_PORT = 9999 # Or any available port- Edit
AIBridgeV2.csin NinjaTrader:
ServerPort = 9999 // Match Python port- Recompile strategy (F5)
Based on Phase 2 model training:
| Metric | Expected Value |
|---|---|
| Sharpe Ratio | ~21.71 |
| Returns | +11% |
| PM Usage | ~13.5% of actions |
| HOLD Actions | ~86.5% |
| Entry Actions (BUY/SELL) | ~10% |
| PM Actions (3,4,5) | ~3.5% |
Note: Performance may vary based on:
- Market conditions
- Data feed quality
- Execution slippage
- Actual vs simulated commissions
- ALWAYS test in Sim101 account first - NEVER use live account initially
- Run for minimum 1 week in simulation before considering live
- Monitor action distribution - if significantly different from expected, investigate
- Check log files daily for errors or unusual behavior
- Set up alerts for disconnections or errors
- Have a manual override plan to close positions if needed
- PM usage consistently >20% or <5%
- Action distribution deviates >20% from expected
- Model predictions become erratic
- TCP connection becomes unstable
- Unexpected errors in logs
For issues:
- Check this README troubleshooting section
- Review log files in
models/logs/ - Test individual components (tcp_client.py, model_manager.py, etc.)
- Check NinjaTrader Output Window for errors
Model-specific questions:
- Refer to your model training documentation
- Check Phase 2 model evaluation results
- Verify VecNormalize stats are from correct training run
# Terminal 1: Start NinjaTrader, enable AIBridgeV2
# Terminal 2:
cd "/mnt/c/Users/javlo/Documents/NinjaTrader 8/bin/Custom/models"
python ai_trading_bridge.pyCtrl+C in Python terminal
tail -f logs/trading_log.txt # Real-time log
cat logs/actions.csv # Action historypython config.py # Validate configuration
python tcp_client.py # Test TCP connection
python observation_builder.py # Test observation builder
python model_manager.py # Test model loading
python trade_logger.py # Test logger- Python Bridge Version: 2.0 (Phase 3)
- Compatible with: NinjaTrader 8, AIBridgeV2 strategy
- Model: Phase 3 LLM-Enhanced (Stable-Baselines3 + Adapter)
- Observation Space: (261,) - 220 market + 8 position + 33 LLM features
- Action Space: Discrete(6) - Actions 0-5
- Model Architecture: MaskablePPO with 261D β 228D adapter layer
- Training: 40,960 timesteps, gymnasium framework
Created: November 7, 2025 Last Updated: November 26, 2025 (Phase 3 Migration)