better vyt/sell signal proecessing/display
This commit is contained in:
@@ -316,7 +316,14 @@ class RealTrainingAdapter:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def _create_pivot_training_batch(self, model_inputs: Dict, pivot_event, inference_ref) -> Optional[Dict]:
|
def _create_pivot_training_batch(self, model_inputs: Dict, pivot_event, inference_ref) -> Optional[Dict]:
|
||||||
"""Create training batch from inference inputs and pivot event"""
|
"""
|
||||||
|
Create training batch from inference inputs and pivot event
|
||||||
|
|
||||||
|
Strategy: Train to execute trades on L2 pivots that align with upper trend
|
||||||
|
- L2L (support) in UPTREND → BUY
|
||||||
|
- L2H (resistance) in DOWNTREND → SELL
|
||||||
|
- Misaligned pivots → HOLD (don't trade against trend)
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
import torch
|
import torch
|
||||||
|
|
||||||
@@ -327,15 +334,29 @@ class RealTrainingAdapter:
|
|||||||
# Get device
|
# Get device
|
||||||
device = next(iter(batch.values())).device if batch else torch.device('cpu')
|
device = next(iter(batch.values())).device if batch else torch.device('cpu')
|
||||||
|
|
||||||
# Determine action from pivot type
|
# Get trend direction from pivot event (if available)
|
||||||
# L2L, L3L, etc. -> BUY (support levels)
|
trend_direction = getattr(pivot_event, 'trend_direction', 'sideways')
|
||||||
# L2H, L3H, etc. -> SELL (resistance levels)
|
pivot_type = pivot_event.pivot_type
|
||||||
if pivot_event.pivot_type.endswith('L'):
|
|
||||||
action = 1 # BUY
|
# Determine action based on pivot type AND trend alignment
|
||||||
elif pivot_event.pivot_type.endswith('H'):
|
# Only trade when pivot aligns with trend
|
||||||
action = 2 # SELL
|
action = 0 # Default: HOLD
|
||||||
else:
|
|
||||||
action = 0 # HOLD
|
if pivot_type in ['L2L', 'L3L']: # Support levels (lows)
|
||||||
|
# BUY only if in UPTREND (buying at support in uptrend)
|
||||||
|
if trend_direction in ['up', 'uptrend', 'UPTREND']:
|
||||||
|
action = 1 # BUY
|
||||||
|
logger.info(f"Pivot training: BUY signal at {pivot_type} (aligned with {trend_direction})")
|
||||||
|
else:
|
||||||
|
logger.debug(f"Pivot training: HOLD at {pivot_type} (not aligned with {trend_direction})")
|
||||||
|
|
||||||
|
elif pivot_type in ['L2H', 'L3H']: # Resistance levels (highs)
|
||||||
|
# SELL only if in DOWNTREND (selling at resistance in downtrend)
|
||||||
|
if trend_direction in ['down', 'downtrend', 'DOWNTREND']:
|
||||||
|
action = 2 # SELL
|
||||||
|
logger.info(f"Pivot training: SELL signal at {pivot_type} (aligned with {trend_direction})")
|
||||||
|
else:
|
||||||
|
logger.debug(f"Pivot training: HOLD at {pivot_type} (not aligned with {trend_direction})")
|
||||||
|
|
||||||
batch['actions'] = torch.tensor([[action]], dtype=torch.long, device=device)
|
batch['actions'] = torch.tensor([[action]], dtype=torch.long, device=device)
|
||||||
|
|
||||||
@@ -4824,7 +4845,7 @@ class RealTrainingAdapter:
|
|||||||
Execute trade based on signal, respecting position management rules
|
Execute trade based on signal, respecting position management rules
|
||||||
|
|
||||||
Rules:
|
Rules:
|
||||||
1. Only execute if confidence >= 0.6
|
1. Only execute if confidence >= 0.5 (lowered for more learning opportunities)
|
||||||
2. Only open new position if no position is currently open
|
2. Only open new position if no position is currently open
|
||||||
3. Close position on opposite signal
|
3. Close position on opposite signal
|
||||||
4. Track all executed trades for visualization
|
4. Track all executed trades for visualization
|
||||||
@@ -4836,8 +4857,8 @@ class RealTrainingAdapter:
|
|||||||
confidence = signal['confidence']
|
confidence = signal['confidence']
|
||||||
timestamp = signal['timestamp']
|
timestamp = signal['timestamp']
|
||||||
|
|
||||||
# Rule 1: Confidence threshold
|
# Rule 1: Confidence threshold (lowered to 0.5 for more learning opportunities)
|
||||||
if confidence < 0.6:
|
if confidence < 0.5:
|
||||||
return None # Rejected: low confidence
|
return None # Rejected: low confidence
|
||||||
|
|
||||||
# Rule 2 & 3: Position management
|
# Rule 2 & 3: Position management
|
||||||
@@ -4962,8 +4983,8 @@ class RealTrainingAdapter:
|
|||||||
confidence = signal['confidence']
|
confidence = signal['confidence']
|
||||||
position = session.get('position')
|
position = session.get('position')
|
||||||
|
|
||||||
if confidence < 0.6:
|
if confidence < 0.5:
|
||||||
return f"Low confidence ({confidence:.2f} < 0.6)"
|
return f"Low confidence ({confidence:.2f} < 0.5)"
|
||||||
|
|
||||||
if action == 'HOLD':
|
if action == 'HOLD':
|
||||||
return "HOLD signal (no trade)"
|
return "HOLD signal (no trade)"
|
||||||
|
|||||||
@@ -3863,7 +3863,7 @@ class ChartManager {
|
|||||||
// Update confidence
|
// Update confidence
|
||||||
const confPct = (confidence * 100).toFixed(0);
|
const confPct = (confidence * 100).toFixed(0);
|
||||||
signalConf.textContent = `${confPct}%`;
|
signalConf.textContent = `${confPct}%`;
|
||||||
signalConf.style.color = confidence >= 0.6 ? '#10b981' : '#9ca3af';
|
signalConf.style.color = confidence >= 0.5 ? '#10b981' : '#9ca3af';
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Error updating signal banner for ${timeframe}:`, error);
|
console.error(`Error updating signal banner for ${timeframe}:`, error);
|
||||||
|
|||||||
@@ -1135,53 +1135,82 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function updatePnLTracking(action, currentPrice, timestamp) {
|
function updatePnLTracking(action, currentPrice, timestamp) {
|
||||||
// Simple trading simulation: BUY opens long, SELL opens short, HOLD closes positions
|
// Paper trading simulation with proper position management
|
||||||
if (action === 'BUY' && pnlTracker.positions.length === 0) {
|
// Rules:
|
||||||
// Open long position
|
// 1. BUY: Close SHORT if exists, then open LONG
|
||||||
pnlTracker.positions.push({
|
// 2. SELL: Close LONG if exists, then open SHORT
|
||||||
action: 'BUY',
|
// 3. HOLD: Do nothing (keep existing positions)
|
||||||
entryPrice: currentPrice,
|
|
||||||
entryTime: timestamp,
|
const currentPosition = pnlTracker.positions.length > 0 ? pnlTracker.positions[0] : null;
|
||||||
size: pnlTracker.positionSize
|
|
||||||
});
|
if (action === 'BUY') {
|
||||||
} else if (action === 'SELL' && pnlTracker.positions.length === 0) {
|
// Close SHORT position if exists
|
||||||
// Open short position
|
if (currentPosition && currentPosition.action === 'SELL') {
|
||||||
pnlTracker.positions.push({
|
const pnl = (currentPosition.entryPrice - currentPrice) / currentPosition.entryPrice * currentPosition.size;
|
||||||
action: 'SELL',
|
|
||||||
entryPrice: currentPrice,
|
|
||||||
entryTime: timestamp,
|
|
||||||
size: pnlTracker.positionSize
|
|
||||||
});
|
|
||||||
} else if (action === 'HOLD' && pnlTracker.positions.length > 0) {
|
|
||||||
// Close all positions
|
|
||||||
pnlTracker.positions.forEach(pos => {
|
|
||||||
let pnl = 0;
|
|
||||||
if (pos.action === 'BUY') {
|
|
||||||
// Long: profit if price went up
|
|
||||||
pnl = (currentPrice - pos.entryPrice) / pos.entryPrice * pos.size;
|
|
||||||
} else if (pos.action === 'SELL') {
|
|
||||||
// Short: profit if price went down
|
|
||||||
pnl = (pos.entryPrice - currentPrice) / pos.entryPrice * pos.size;
|
|
||||||
}
|
|
||||||
|
|
||||||
pnlTracker.closedTrades.push({
|
pnlTracker.closedTrades.push({
|
||||||
entryPrice: pos.entryPrice,
|
entryPrice: currentPosition.entryPrice,
|
||||||
exitPrice: currentPrice,
|
exitPrice: currentPrice,
|
||||||
pnl: pnl,
|
pnl: pnl,
|
||||||
entryTime: pos.entryTime,
|
entryTime: currentPosition.entryTime,
|
||||||
exitTime: timestamp
|
exitTime: timestamp,
|
||||||
|
type: 'SHORT'
|
||||||
});
|
});
|
||||||
|
|
||||||
pnlTracker.totalPnL += pnl;
|
pnlTracker.totalPnL += pnl;
|
||||||
});
|
pnlTracker.positions = [];
|
||||||
|
|
||||||
|
console.log(`[Paper Trading] Closed SHORT @ ${currentPrice.toFixed(2)}, PnL: ${pnl >= 0 ? '+' : ''}${pnl.toFixed(2)}`);
|
||||||
|
}
|
||||||
|
|
||||||
pnlTracker.positions = [];
|
// Open LONG position (if no position or just closed SHORT)
|
||||||
|
if (pnlTracker.positions.length === 0) {
|
||||||
|
pnlTracker.positions.push({
|
||||||
|
action: 'BUY',
|
||||||
|
entryPrice: currentPrice,
|
||||||
|
entryTime: timestamp,
|
||||||
|
size: pnlTracker.positionSize
|
||||||
|
});
|
||||||
|
console.log(`[Paper Trading] Opened LONG @ ${currentPrice.toFixed(2)}`);
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate win rate
|
} else if (action === 'SELL') {
|
||||||
|
// Close LONG position if exists
|
||||||
|
if (currentPosition && currentPosition.action === 'BUY') {
|
||||||
|
const pnl = (currentPrice - currentPosition.entryPrice) / currentPosition.entryPrice * currentPosition.size;
|
||||||
|
|
||||||
|
pnlTracker.closedTrades.push({
|
||||||
|
entryPrice: currentPosition.entryPrice,
|
||||||
|
exitPrice: currentPrice,
|
||||||
|
pnl: pnl,
|
||||||
|
entryTime: currentPosition.entryTime,
|
||||||
|
exitTime: timestamp,
|
||||||
|
type: 'LONG'
|
||||||
|
});
|
||||||
|
|
||||||
|
pnlTracker.totalPnL += pnl;
|
||||||
|
pnlTracker.positions = [];
|
||||||
|
|
||||||
|
console.log(`[Paper Trading] Closed LONG @ ${currentPrice.toFixed(2)}, PnL: ${pnl >= 0 ? '+' : ''}${pnl.toFixed(2)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open SHORT position (if no position or just closed LONG)
|
||||||
|
if (pnlTracker.positions.length === 0) {
|
||||||
|
pnlTracker.positions.push({
|
||||||
|
action: 'SELL',
|
||||||
|
entryPrice: currentPrice,
|
||||||
|
entryTime: timestamp,
|
||||||
|
size: pnlTracker.positionSize
|
||||||
|
});
|
||||||
|
console.log(`[Paper Trading] Opened SHORT @ ${currentPrice.toFixed(2)}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// HOLD: Do nothing, keep existing positions
|
||||||
|
|
||||||
|
// Calculate win rate
|
||||||
|
if (pnlTracker.closedTrades.length > 0) {
|
||||||
const wins = pnlTracker.closedTrades.filter(t => t.pnl > 0).length;
|
const wins = pnlTracker.closedTrades.filter(t => t.pnl > 0).length;
|
||||||
pnlTracker.winRate = pnlTracker.closedTrades.length > 0
|
pnlTracker.winRate = (wins / pnlTracker.closedTrades.length * 100);
|
||||||
? (wins / pnlTracker.closedTrades.length * 100)
|
|
||||||
: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update PnL display
|
// Update PnL display
|
||||||
@@ -1192,6 +1221,38 @@
|
|||||||
const pnlColor = pnlTracker.totalPnL >= 0 ? 'text-success' : 'text-danger';
|
const pnlColor = pnlTracker.totalPnL >= 0 ? 'text-success' : 'text-danger';
|
||||||
const pnlSign = pnlTracker.totalPnL >= 0 ? '+' : '';
|
const pnlSign = pnlTracker.totalPnL >= 0 ? '+' : '';
|
||||||
|
|
||||||
|
// Update position status in trading panel
|
||||||
|
const positionStatusEl = document.getElementById('position-status');
|
||||||
|
if (positionStatusEl) {
|
||||||
|
if (pnlTracker.positions.length > 0) {
|
||||||
|
const pos = pnlTracker.positions[0];
|
||||||
|
const posType = pos.action === 'BUY' ? 'LONG' : 'SHORT';
|
||||||
|
const posColor = pos.action === 'BUY' ? 'text-success' : 'text-danger';
|
||||||
|
positionStatusEl.textContent = posType;
|
||||||
|
positionStatusEl.className = `fw-bold ${posColor}`;
|
||||||
|
} else {
|
||||||
|
positionStatusEl.textContent = 'NO POSITION';
|
||||||
|
positionStatusEl.className = 'fw-bold text-info';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update session PnL
|
||||||
|
const sessionPnlEl = document.getElementById('session-pnl');
|
||||||
|
if (sessionPnlEl) {
|
||||||
|
sessionPnlEl.textContent = `${pnlSign}$${pnlTracker.totalPnL.toFixed(2)}`;
|
||||||
|
sessionPnlEl.className = `fw-bold ${pnlColor}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update win rate
|
||||||
|
const winRateEl = document.getElementById('win-rate');
|
||||||
|
if (winRateEl) {
|
||||||
|
const wins = pnlTracker.closedTrades.filter(t => t.pnl > 0).length;
|
||||||
|
const total = pnlTracker.closedTrades.length;
|
||||||
|
winRateEl.textContent = total > 0
|
||||||
|
? `${pnlTracker.winRate.toFixed(0)}% (${wins}/${total})`
|
||||||
|
: '0% (0/0)';
|
||||||
|
}
|
||||||
|
|
||||||
// Update PnL metric
|
// Update PnL metric
|
||||||
const pnlElement = document.getElementById('metric-pnl');
|
const pnlElement = document.getElementById('metric-pnl');
|
||||||
if (pnlElement) {
|
if (pnlElement) {
|
||||||
|
|||||||
Reference in New Issue
Block a user