diff --git a/src/api/dashboard/static/index.html b/src/api/dashboard/static/index.html
index 4b66b4a..c2b31aa 100644
--- a/src/api/dashboard/static/index.html
+++ b/src/api/dashboard/static/index.html
@@ -1254,15 +1254,28 @@
}
onVisibleRangeChange() {
- if (!this.hasInitialLoad || this.isLoading) return;
+ if (!this.hasInitialLoad || this.isLoading) {
+ console.log('Skipping range change:', { hasInitialLoad: this.hasInitialLoad, isLoading: this.isLoading });
+ return;
+ }
const visibleRange = this.chart.timeScale().getVisibleLogicalRange();
- if (!visibleRange) return;
+ if (!visibleRange) {
+ console.log('No visible range');
+ return;
+ }
+
+ console.log('Visible range:', visibleRange);
const data = this.candleSeries.data();
- if (!data || data.length === 0) return;
+ if (!data || data.length === 0) {
+ console.log('No data available');
+ return;
+ }
- if (visibleRange.from < 10) {
+ // Load when user scrolls close to the left edge (earlier time)
+ if (visibleRange.from < 20) {
+ console.log('Near left edge, loading historical data...');
const oldestCandle = data[0];
if (oldestCandle) {
this.loadHistoricalData(oldestCandle.time);
@@ -1275,11 +1288,12 @@
this.isLoading = true;
try {
- const endTime = new Date(beforeTime * 1000);
- const startTime = new Date(endTime.getTime() - 24 * 60 * 60 * 1000);
+ // Fetch candles before the oldest visible candle
+ // Use end parameter to get candles up to (but not including) the oldest candle
+ const endTime = new Date((beforeTime - 1) * 1000); // 1 second before oldest
const response = await fetch(
- `/api/v1/candles?symbol=BTC&interval=${this.currentInterval}&start=${startTime.toISOString()}&end=${endTime.toISOString()}&limit=500`
+ `/api/v1/candles?symbol=BTC&interval=${this.currentInterval}&end=${endTime.toISOString()}&limit=500`
);
const data = await response.json();
@@ -1297,6 +1311,9 @@
this.allData.set(this.currentInterval, mergedData);
this.candleSeries.setData(mergedData);
+ console.log(`Loaded ${chartData.length} historical candles`);
+ } else {
+ console.log('No more historical data available');
}
} catch (error) {
console.error('Error loading historical data:', error);
@@ -1750,6 +1767,9 @@
});
}
+ // Track trade line series for cleanup
+ window.tradeLineSeries = [];
+
// Show simulation buy/sell markers on the chart
function showSimulationMarkers() {
if (!window.lastSimulationResults || !window.dashboard) return;
@@ -1757,36 +1777,59 @@
const trades = window.lastSimulationResults.trades;
const markers = [];
+ // Clear existing trade lines
+ window.tradeLineSeries.forEach(series => {
+ window.dashboard.chart.removeSeries(series);
+ });
+ window.tradeLineSeries = [];
+
trades.forEach(trade => {
const entryTime = Math.floor(new Date(trade.entryTime).getTime() / 1000);
const exitTime = Math.floor(new Date(trade.exitTime).getTime() / 1000);
const pnlSymbol = trade.pnl > 0 ? '+' : '';
- // Entry Marker - Buy signal
+ // Entry Marker - Buy signal (blue arrow and text)
markers.push({
time: entryTime,
position: 'belowBar',
- color: '#26a69a',
+ color: '#2196f3',
shape: 'arrowUp',
- text: '🟢 BUY',
- size: 2
+ text: 'BUY',
+ size: 1
});
- // Exit Marker - Sell signal with P&L info
+ // Exit Marker - Sell signal (green for profit, red for loss)
markers.push({
time: exitTime,
position: 'aboveBar',
- color: trade.pnl > 0 ? '#26a69a' : '#ef5350',
+ color: trade.pnl > 0 ? '#4caf50' : '#f44336',
shape: 'arrowDown',
- text: (trade.pnl > 0 ? '🟢' : '🔴') + ' SELL ' + pnlSymbol + trade.pnlPct.toFixed(1) + '%',
- size: 2
+ text: 'SELL ' + pnlSymbol + trade.pnlPct.toFixed(1) + '%',
+ size: 1
});
+
+ // Create separate line series for this trade (entry to exit)
+ const tradeLine = window.dashboard.chart.addLineSeries({
+ color: '#2196f3',
+ lineWidth: 1,
+ lastValueVisible: false,
+ title: '',
+ priceLineVisible: false,
+ crosshairMarkerVisible: false
+ });
+
+ tradeLine.setData([
+ { time: entryTime, value: trade.entryPrice },
+ { time: exitTime, value: trade.exitPrice }
+ ]);
+
+ window.tradeLineSeries.push(tradeLine);
});
// Sort markers by time
markers.sort((a, b) => a.time - b.time);
- // Apply to chart
+ // Apply markers to chart
window.dashboard.candleSeries.setMarkers(markers);
// Log to console instead of alert
@@ -1800,6 +1843,12 @@
function clearSimulationMarkers() {
if (window.dashboard) {
window.dashboard.candleSeries.setMarkers([]);
+
+ // Remove trade line series
+ window.tradeLineSeries.forEach(series => {
+ window.dashboard.chart.removeSeries(series);
+ });
+ window.tradeLineSeries = [];
}
}