wip
This commit is contained in:
@@ -1962,6 +1962,16 @@ class CleanTradingDashboard:
|
||||
def update_price_chart(n, pivots_value, relayout_data):
|
||||
"""Update price chart every second, persisting user zoom/pan"""
|
||||
try:
|
||||
# Log transformer status on first update
|
||||
if n == 1:
|
||||
if self.orchestrator and hasattr(self.orchestrator, 'primary_transformer'):
|
||||
if self.orchestrator.primary_transformer:
|
||||
logger.info("TRANSFORMER MODEL LOADED - Ghost candles should be visible")
|
||||
else:
|
||||
logger.warning("TRANSFORMER MODEL IS NONE - Enable training to load model")
|
||||
else:
|
||||
logger.warning("NO TRANSFORMER AVAILABLE - Enable training first")
|
||||
|
||||
# Validate and train on predictions every update (once per second)
|
||||
# This checks if any predictions can be validated against real candles
|
||||
self._validate_and_train_on_predictions('ETH/USDT')
|
||||
@@ -3365,6 +3375,7 @@ class CleanTradingDashboard:
|
||||
self._add_dqn_predictions_to_chart(fig, symbol, df_main, row)
|
||||
self._add_cnn_predictions_to_chart(fig, symbol, df_main, row)
|
||||
self._add_transformer_predictions_to_chart(fig, symbol, df_main, row)
|
||||
self._add_ghost_candles_to_chart(fig, symbol, df_main, row) # Add predicted future candles
|
||||
self._add_cob_rl_predictions_to_chart(fig, symbol, df_main, row)
|
||||
self._add_prediction_accuracy_feedback(fig, symbol, df_main, row)
|
||||
self._add_williams_pivots_to_chart(fig, symbol, df_main, row)
|
||||
@@ -3683,6 +3694,112 @@ class CleanTradingDashboard:
|
||||
except Exception as e:
|
||||
logger.debug(f"Error adding CNN predictions to chart: {e}")
|
||||
|
||||
def _add_ghost_candles_to_chart(self, fig: go.Figure, symbol: str, df_main: pd.DataFrame, row: int = 1):
|
||||
"""Add predicted future candles (ghost candles) to the chart"""
|
||||
try:
|
||||
# Get latest live prediction with next_candles
|
||||
prediction = self._get_live_transformer_prediction_with_next_candles(symbol)
|
||||
|
||||
if not prediction:
|
||||
logger.debug("No transformer prediction available - is training enabled?")
|
||||
return
|
||||
|
||||
if 'next_candles' not in prediction:
|
||||
logger.debug("Prediction exists but has no next_candles data")
|
||||
return
|
||||
|
||||
next_candles = prediction['next_candles']
|
||||
if not next_candles:
|
||||
return
|
||||
|
||||
# Get the chart timeframe from the dataframe (assume 1s or 1m based on df_main)
|
||||
if df_main.empty:
|
||||
return
|
||||
|
||||
# Detect timeframe from dataframe index
|
||||
if len(df_main) >= 2:
|
||||
time_diff = (df_main.index[-1] - df_main.index[-2]).total_seconds()
|
||||
if time_diff <= 1.5:
|
||||
chart_timeframe = '1s'
|
||||
elif time_diff <= 65:
|
||||
chart_timeframe = '1m'
|
||||
elif time_diff <= 3900:
|
||||
chart_timeframe = '1h'
|
||||
else:
|
||||
chart_timeframe = '1d'
|
||||
else:
|
||||
chart_timeframe = '1m' # Default
|
||||
|
||||
# Get prediction for this timeframe
|
||||
if chart_timeframe not in next_candles:
|
||||
logger.debug(f"No prediction for {chart_timeframe} timeframe")
|
||||
return
|
||||
|
||||
predicted_ohlcv = next_candles[chart_timeframe]
|
||||
if not predicted_ohlcv or len(predicted_ohlcv) < 5:
|
||||
return
|
||||
|
||||
# Calculate timestamp for predicted candle
|
||||
last_timestamp = df_main.index[-1]
|
||||
timeframe_seconds = {'1s': 1, '1m': 60, '1h': 3600, '1d': 86400}
|
||||
delta_seconds = timeframe_seconds.get(chart_timeframe, 60)
|
||||
predicted_timestamp = last_timestamp + timedelta(seconds=delta_seconds)
|
||||
|
||||
# Extract OHLCV values
|
||||
pred_open, pred_high, pred_low, pred_close, pred_volume = predicted_ohlcv
|
||||
|
||||
# Determine color based on direction
|
||||
is_bullish = pred_close >= pred_open
|
||||
|
||||
# Add ghost candle as semi-transparent candlestick
|
||||
fig.add_trace(
|
||||
go.Candlestick(
|
||||
x=[predicted_timestamp],
|
||||
open=[pred_open],
|
||||
high=[pred_high],
|
||||
low=[pred_low],
|
||||
close=[pred_close],
|
||||
name='Predicted Candle',
|
||||
increasing=dict(
|
||||
line=dict(color='rgba(0, 255, 0, 0.4)', width=1),
|
||||
fillcolor='rgba(0, 255, 0, 0.2)'
|
||||
),
|
||||
decreasing=dict(
|
||||
line=dict(color='rgba(255, 0, 0, 0.4)', width=1),
|
||||
fillcolor='rgba(255, 0, 0, 0.2)'
|
||||
),
|
||||
showlegend=True,
|
||||
legendgroup='predictions',
|
||||
opacity=0.5
|
||||
),
|
||||
row=row, col=1
|
||||
)
|
||||
|
||||
# Add a marker at the predicted close price
|
||||
fig.add_trace(
|
||||
go.Scatter(
|
||||
x=[predicted_timestamp],
|
||||
y=[pred_close],
|
||||
mode='markers',
|
||||
marker=dict(
|
||||
size=8,
|
||||
color='rgba(255, 215, 0, 0.8)', # Gold color
|
||||
symbol='star',
|
||||
line=dict(color='white', width=1)
|
||||
),
|
||||
name='Prediction Target',
|
||||
showlegend=True,
|
||||
legendgroup='predictions',
|
||||
hovertemplate=f'Predicted Close: ${pred_close:.2f}<br>Time: {predicted_timestamp.strftime("%H:%M:%S")}<extra></extra>'
|
||||
),
|
||||
row=row, col=1
|
||||
)
|
||||
|
||||
logger.info(f"Added ghost candle for {chart_timeframe}: O={pred_open:.2f}, H={pred_high:.2f}, L={pred_low:.2f}, C={pred_close:.2f}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error adding ghost candles to chart: {e}", exc_info=True)
|
||||
|
||||
def _add_transformer_predictions_to_chart(self, fig: go.Figure, symbol: str, df_main: pd.DataFrame, row: int = 1):
|
||||
"""Add Transformer price predictions as trend lines with confidence bands"""
|
||||
try:
|
||||
@@ -4071,9 +4188,20 @@ class CleanTradingDashboard:
|
||||
This makes a real-time prediction with the transformer model
|
||||
"""
|
||||
try:
|
||||
if not self.orchestrator or not hasattr(self.orchestrator, 'primary_transformer') or not self.orchestrator.primary_transformer:
|
||||
if not self.orchestrator:
|
||||
logger.debug("No orchestrator available for predictions")
|
||||
return None
|
||||
|
||||
if not hasattr(self.orchestrator, 'primary_transformer'):
|
||||
logger.debug("Orchestrator has no primary_transformer attribute")
|
||||
return None
|
||||
|
||||
if not self.orchestrator.primary_transformer:
|
||||
logger.debug("primary_transformer is None - model not loaded")
|
||||
return None
|
||||
|
||||
logger.debug(f"Making live transformer prediction for {symbol}...")
|
||||
|
||||
transformer = self.orchestrator.primary_transformer
|
||||
transformer.eval()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user