From 9883d1bea90d10d86183bd69c403cbcfe4bb86a0 Mon Sep 17 00:00:00 2001 From: DiTus Date: Tue, 3 Mar 2026 23:07:03 +0100 Subject: [PATCH] feat: enhance strategy simulation with Inverse Perpetual support, effective leverage caps, and advanced charting --- .../dashboard/static/css/indicators-new.css | 27 ++ src/api/dashboard/static/js/ui/chart.js | 23 + .../dashboard/static/js/ui/strategy-panel.js | 459 +++++++++++++----- 3 files changed, 375 insertions(+), 134 deletions(-) diff --git a/src/api/dashboard/static/css/indicators-new.css b/src/api/dashboard/static/css/indicators-new.css index d2f00e7..a67d85d 100644 --- a/src/api/dashboard/static/css/indicators-new.css +++ b/src/api/dashboard/static/css/indicators-new.css @@ -696,4 +696,31 @@ display: flex; gap: 8px; margin-top: 12px; +} + +.chart-toggle-group { + display: flex; + background: var(--tv-hover); + border-radius: 4px; + padding: 2px; +} + +.chart-toggle-group .toggle-btn { + padding: 2px 8px; + font-size: 10px; + border: none; + background: transparent; + color: var(--tv-text-secondary); + cursor: pointer; + border-radius: 3px; + transition: all 0.2s ease; +} + +.chart-toggle-group .toggle-btn.active { + background: var(--tv-border); + color: var(--tv-text); +} + +.chart-toggle-group .toggle-btn:hover:not(.active) { + color: var(--tv-text); } \ No newline at end of file diff --git a/src/api/dashboard/static/js/ui/chart.js b/src/api/dashboard/static/js/ui/chart.js index e4b8cde..1050d85 100644 --- a/src/api/dashboard/static/js/ui/chart.js +++ b/src/api/dashboard/static/js/ui/chart.js @@ -22,6 +22,7 @@ constructor() { this.summarySignal = null; this.lastCandleTimestamp = null; this.simulationMarkers = []; + this.avgPriceSeries = null; this.init(); } @@ -35,6 +36,18 @@ constructor() { this.simulationMarkers = []; this.updateSignalMarkers(); } + + setAvgPriceData(data) { + if (this.avgPriceSeries) { + this.avgPriceSeries.setData(data || []); + } + } + + clearAvgPriceData() { + if (this.avgPriceSeries) { + this.avgPriceSeries.setData([]); + } + } init() { this.createTimeframeButtons(); @@ -128,6 +141,16 @@ constructor() { lastValueVisible: false, priceLineVisible: false, }, 0); + + this.avgPriceSeries = this.chart.addSeries(LightweightCharts.LineSeries, { + color: '#00bcd4', + lineWidth: 1, + lineStyle: LightweightCharts.LineStyle.Solid, + lastValueVisible: true, + priceLineVisible: false, + crosshairMarkerVisible: false, + title: '', + }); this.currentPriceLine = this.candleSeries.createPriceLine({ price: 0, diff --git a/src/api/dashboard/static/js/ui/strategy-panel.js b/src/api/dashboard/static/js/ui/strategy-panel.js index 35297b1..b6c9b9f 100644 --- a/src/api/dashboard/static/js/ui/strategy-panel.js +++ b/src/api/dashboard/static/js/ui/strategy-panel.js @@ -4,6 +4,43 @@ let activeIndicators = []; let simulationResults = null; let equitySeries = null; let equityChart = null; +let posSeries = null; +let posSizeChart = null; + +const STORAGE_KEY = 'ping_pong_settings'; + +function getSavedSettings() { + const saved = localStorage.getItem(STORAGE_KEY); + if (!saved) return null; + try { + return JSON.parse(saved); + } catch (e) { + return null; + } +} + +function saveSettings() { + const settings = { + startDate: document.getElementById('simStartDate').value, + contractType: document.getElementById('simContractType').value, + direction: document.getElementById('simDirection').value, + capital: document.getElementById('simCapital').value, + exchangeLeverage: document.getElementById('simExchangeLeverage').value, + maxEffectiveLeverage: document.getElementById('simMaxEffectiveLeverage').value, + posSize: document.getElementById('simPosSize').value, + tp: document.getElementById('simTP').value + }; + localStorage.setItem(STORAGE_KEY, JSON.stringify(settings)); + + const btn = document.getElementById('saveSimSettings'); + const originalText = btn.textContent; + btn.textContent = 'Saved!'; + btn.style.color = '#26a69a'; + setTimeout(() => { + btn.textContent = originalText; + btn.style.color = ''; + }, 2000); +} export function initStrategyPanel() { window.renderStrategyPanel = renderStrategyPanel; @@ -30,6 +67,7 @@ export function renderStrategyPanel() { if (!container) return; activeIndicators = window.getActiveIndicators?.() || []; + const saved = getSavedSettings(); container.innerHTML = `