From 1c2b223911e53d5916b68232357d7c729a888a28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=B8=D0=BA=D1=82=D0=BE=D1=80?= <78488229+viktor138irk@users.noreply.github.com> Date: Fri, 8 May 2026 03:46:14 +0900 Subject: [PATCH] Add AI bot controls and live toggle to dashboard --- app/static/index.html | 98 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 94 insertions(+), 4 deletions(-) diff --git a/app/static/index.html b/app/static/index.html index 7ee50c6..d63157f 100644 --- a/app/static/index.html +++ b/app/static/index.html @@ -8,17 +8,20 @@ @@ -26,6 +29,9 @@ Trade Autopilot + + + подключение... source: — @@ -44,6 +50,23 @@
Equity
+
+
Бот
+
+ + + +
+
+ + +
+
+
+
+
AI результат
+
+
Последнее событие
@@ -94,14 +117,20 @@ function updateLiveCandle(price, tsMs) { } async function loadMarket() { - const market = document.getElementById('market').value.trim().toUpperCase() || 'BTCUSDT'; + const market = getMarket(); document.getElementById('status').textContent = 'загрузка истории...'; const res = await fetch(`/api/v1/market/kline?market=${market}&period=1min&limit=200`); const json = await res.json(); candleSeries.setData(normalizeKline(json)); chart.timeScale().fitContent(); + await loadMarkers(market); connectWs(market); loadAccount(); + loadBotSettings(); +} + +function getMarket() { + return document.getElementById('market').value.trim().toUpperCase() || 'BTCUSDT'; } async function loadAccount() { @@ -111,6 +140,64 @@ async function loadAccount() { document.getElementById('equity').textContent = `${Number(acc.equity).toFixed(2)} ${acc.quote_asset}`; } +async function loadBotSettings() { + const res = await fetch('/api/v1/bot/settings'); + const json = await res.json(); + document.getElementById('botSettings').textContent = JSON.stringify(json, null, 2); +} + +async function analyze() { + const res = await fetch(`/api/v1/bot/analyze?market=${getMarket()}`); + const json = await res.json(); + document.getElementById('aiResult').textContent = JSON.stringify(json, null, 2); +} + +async function decide() { + const res = await fetch(`/api/v1/bot/decide?market=${getMarket()}`, { method: 'POST' }); + const json = await res.json(); + document.getElementById('aiResult').textContent = JSON.stringify(json, null, 2); +} + +async function autoDemoTrade() { + const res = await fetch(`/api/v1/bot/auto-demo-trade?market=${getMarket()}`, { method: 'POST' }); + const json = await res.json(); + document.getElementById('aiResult').textContent = JSON.stringify(json, null, 2); + await loadAccount(); + await loadMarkers(getMarket()); +} + +async function setBotEnabled(enabled) { + await fetch(`/api/v1/bot/settings?enabled=${enabled}`, { method: 'POST' }); + await loadBotSettings(); +} + +async function enableLive() { + const ack = encodeURIComponent(document.getElementById('ack').value.trim()); + const res = await fetch(`/api/v1/bot/live/enable?ack=${ack}`, { method: 'POST' }); + const json = await res.json(); + document.getElementById('aiResult').textContent = JSON.stringify(json, null, 2); + await loadBotSettings(); +} + +async function disableLive() { + const res = await fetch('/api/v1/bot/live/disable', { method: 'POST' }); + const json = await res.json(); + document.getElementById('aiResult').textContent = JSON.stringify(json, null, 2); + await loadBotSettings(); +} + +async function loadMarkers(market) { + const res = await fetch(`/api/v1/dashboard/markers?market=${market}&limit=100`); + const json = await res.json(); + const markers = (json.items || []).map(item => ({ + time: item.time, + position: item.side === 'buy' ? 'belowBar' : 'aboveBar', + shape: item.side === 'buy' ? 'arrowUp' : 'arrowDown', + text: item.text, + })); + candleSeries.setMarkers(markers); +} + function connectWs(market) { if (socket) socket.close(); const proto = location.protocol === 'https:' ? 'wss' : 'ws'; @@ -137,6 +224,9 @@ function connectWs(market) { document.getElementById('balance').textContent = `${Number(acc.balance).toFixed(2)} ${acc.quote_asset}`; document.getElementById('equity').textContent = `${Number(acc.equity).toFixed(2)} ${acc.quote_asset}`; } + if (msg.bot_state) { + document.getElementById('botSettings').textContent = JSON.stringify(msg.bot_state, null, 2); + } }; socket.onclose = () => {