local strategy

This commit is contained in:
BTC Bot
2026-02-17 10:39:39 +01:00
parent fcac738e64
commit eafba745b1
7 changed files with 218 additions and 203 deletions

View File

@ -1483,54 +1483,37 @@
return tfCandles[pointers[tf]].close;
};
// Debug logging for first evaluation
if (index === 1) {
console.log('First candle time:', candles[index].time, 'Date:', new Date(candles[index].time * 1000));
console.log('MA44 value:', getVal('ma44', primaryTF));
}
// Simple logic for MVP strategies
if (config.id === 'ma44_strategy') {
const ma44 = getVal('ma44', primaryTF);
// Simple logic for MA Trend strategy
if (config.id === 'ma_trend') {
const period = config.params?.period || 44;
// Debug logging for first evaluation
if (index === 1) {
console.log('First candle time:', candles[index].time, 'Date:', new Date(candles[index].time * 1000));
console.log(`MA${period} value:`, getVal(`ma${period}`, primaryTF));
}
const maValue = getVal(`ma${period}`, primaryTF);
const price = candles[index].close;
// Optional: Multi-TF trend filter
// Optional: Multi-TF trend filter (must align for both entry and exit)
const secondaryTF = config.timeframes?.secondary?.[0];
let trendOk = true;
let secondaryBullish = true;
let secondaryBearish = true;
if (secondaryTF) {
const secondaryPrice = getPrice(secondaryTF);
const secondaryMA = getVal(`ma44_${secondaryTF}`, secondaryTF);
trendOk = secondaryPrice > secondaryMA;
const secondaryMA = getVal(`ma${period}_${secondaryTF}`, secondaryTF);
if (secondaryPrice !== null && secondaryMA !== null) {
secondaryBullish = secondaryPrice > secondaryMA;
secondaryBearish = secondaryPrice < secondaryMA;
}
if (index === 1) {
console.log(`Trend check: ${secondaryTF} price=${secondaryPrice}, MA=${secondaryMA}, trendOk=${trendOk}`);
console.log(`Trend check: ${secondaryTF} price=${secondaryPrice}, MA=${secondaryMA}, bullish=${secondaryBullish}, bearish=${secondaryBearish}`);
}
}
if (ma44) {
if (price > ma44 && trendOk) return 'BUY';
if (price < ma44) return 'SELL';
}
}
if (config.id === 'ma125_strategy') {
const ma125 = getVal('ma125', primaryTF);
const price = candles[index].close;
// Optional: Multi-TF trend filter
const secondaryTF = config.timeframes?.secondary?.[0];
let trendOk = true;
if (secondaryTF) {
const secondaryPrice = getPrice(secondaryTF);
const secondaryMA = getVal(`ma125_${secondaryTF}`, secondaryTF);
trendOk = secondaryPrice > secondaryMA;
if (index === 1) {
console.log(`Trend check: ${secondaryTF} price=${secondaryPrice}, MA=${secondaryMA}, trendOk=${trendOk}`);
}
}
if (ma125) {
if (price > ma125 && trendOk) return 'BUY';
if (price < ma125) return 'SELL';
if (maValue) {
if (price > maValue && secondaryBullish) return 'BUY';
if (price < maValue && secondaryBearish) return 'SELL';
}
}
@ -2131,6 +2114,9 @@
this.loadInitialData();
this.loadTA();
// Clear simulation results when changing timeframe
clearSimulationResults();
// Update simulation panel timeframe display
updateTimeframeDisplay();
}
@ -2312,6 +2298,36 @@
window.tradeLineSeries = [];
}
}
function clearSimulationResults() {
// Clear markers from chart
clearSimulationMarkers();
// Clear simulation data
window.lastSimulationResults = null;
// Hide results section
const resultsSection = document.getElementById('resultsSection');
if (resultsSection) {
resultsSection.style.display = 'none';
}
// Reset results display
const simTrades = document.getElementById('simTrades');
const simWinRate = document.getElementById('simWinRate');
const simPnL = document.getElementById('simPnL');
const simProfitFactor = document.getElementById('simProfitFactor');
const equitySparkline = document.getElementById('equitySparkline');
if (simTrades) simTrades.textContent = '0';
if (simWinRate) simWinRate.textContent = '0%';
if (simPnL) {
simPnL.textContent = '$0.00';
simPnL.style.color = '';
}
if (simProfitFactor) simProfitFactor.textContent = '0';
if (equitySparkline) equitySparkline.innerHTML = '';
}
// Set default start date (7 days ago)
function setDefaultStartDate() {
@ -2398,11 +2414,8 @@
// Strategy parameter definitions
const StrategyParams = {
ma44_strategy: [
{ name: 'maPeriod', label: 'MA Period', type: 'number', default: 44, min: 5, max: 500 }
],
ma125_strategy: [
{ name: 'maPeriod', label: 'MA Period', type: 'number', default: 125, min: 5, max: 500 }
ma_trend: [
{ name: 'period', label: 'MA Period', type: 'number', default: 44, min: 5, max: 500 }
]
};
@ -2462,7 +2475,8 @@
value="${param.default}"
${param.min !== undefined ? `min="${param.min}"` : ''}
${param.max !== undefined ? `max="${param.max}"` : ''}
${param.step !== undefined ? `step="${param.step}"` : ''}>
${param.step !== undefined ? `step="${param.step}"` : ''}
>
</div>
`).join('');
}
@ -2571,6 +2585,7 @@
// Build strategy config
const engineConfig = {
id: strategyConfig.id,
params: strategyConfig.params,
timeframes: { primary: interval, secondary: secondaryTF ? [secondaryTF] : [] },
indicators: []
};
@ -2581,37 +2596,21 @@
console.log(' Available candles:', Object.keys(candlesMap));
// Add indicator based on strategy
if (strategyConfig.id === 'ma44_strategy') {
if (strategyConfig.id === 'ma_trend') {
const period = strategyConfig.params?.period || 44;
// Primary timeframe indicator
engineConfig.indicators.push({
name: 'ma44',
name: `ma${period}`,
type: 'sma',
params: { period: strategyConfig.params.maPeriod || 44 },
params: { period: period },
timeframe: interval
});
// Confirmation timeframe indicator (for trend filter)
if (secondaryTF) {
engineConfig.indicators.push({
name: `ma44_${secondaryTF}`,
name: `ma${period}_${secondaryTF}`,
type: 'sma',
params: { period: strategyConfig.params.maPeriod || 44 },
timeframe: secondaryTF
});
}
} else if (strategyConfig.id === 'ma125_strategy') {
// Primary timeframe indicator
engineConfig.indicators.push({
name: 'ma125',
type: 'sma',
params: { period: strategyConfig.params.maPeriod || 125 },
timeframe: interval
});
// Confirmation timeframe indicator (for trend filter)
if (secondaryTF) {
engineConfig.indicators.push({
name: `ma125_${secondaryTF}`,
type: 'sma',
params: { period: strategyConfig.params.maPeriod || 125 },
params: { period: period },
timeframe: secondaryTF
});
}
@ -2652,6 +2651,23 @@
// Show results section
document.getElementById('resultsSection').style.display = 'block';
// Update chart with full historical data from simulation
if (window.dashboard && candlesMap[interval]) {
const chartData = candlesMap[interval].map(c => ({
time: c.time,
open: c.open,
high: c.high,
low: c.low,
close: c.close
}));
window.dashboard.candleSeries.setData(chartData);
window.dashboard.allData.set(interval, chartData);
console.log(`Chart updated with ${chartData.length} candles from simulation range`);
}
// Show simulation markers on chart
showSimulationMarkers();
} catch (error) {
console.error('Simulation error:', error);
alert('Simulation error: ' + error.message);
@ -3112,7 +3128,7 @@
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 5000);
const response = await fetch('/api/v1/strategies', {
const response = await fetch('/api/v1/strategies?_=' + Date.now(), {
signal: controller.signal
});
clearTimeout(timeoutId);

View File

@ -10,7 +10,7 @@ from datetime import datetime, timedelta, timezone
from typing import Optional, List
from contextlib import asynccontextmanager
from fastapi import FastAPI, HTTPException, Query, BackgroundTasks
from fastapi import FastAPI, HTTPException, Query, BackgroundTasks, Response
from fastapi.staticfiles import StaticFiles
from fastapi.responses import StreamingResponse
from fastapi.middleware.cors import CORSMiddleware
@ -100,12 +100,16 @@ async def root():
@app.get("/api/v1/strategies")
async def list_strategies():
async def list_strategies(response: Response):
"""List all available trading strategies with metadata"""
# Prevent caching
response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
response.headers["Pragma"] = "no-cache"
response.headers["Expires"] = "0"
# Strategy registry from brain.py
strategy_registry = {
"ma44_strategy": "src.strategies.ma44_strategy.MA44Strategy",
"ma125_strategy": "src.strategies.ma125_strategy.MA125Strategy",
"ma_trend": "src.strategies.ma_strategy.MAStrategy",
}
strategies = []