feat: Implement HTS (Higher Timeframe Trend System) strategy
- Add HTS strategy engine with crossover and alignment-based entries - Implement Auto HTS feature (computes on TF/4 from 1m data) - Add 1H Red Zone filter to validate long signals - Add channel-based stop loss with RTL functionality - Enhanced visualization with 30% opacity channel lines - Fixed data alignment in simulation (uses htsData instead of mismatched indices) - Fixed syntax errors in hts-engine.js (malformed template literals) - Fixed duplicate code in simulation.js - Added showSimulationMarkers to window object for global access - Enhanced logging for trade signals and simulation results - Fix missing prevFastHigh/currFastHigh in hts-visualizer.js - Disable trend zone overlays to prevent chart clutter - Implement client-side visualization for trade markers using line series - MA strategy indicator configuration fixed (was empty during engine run) - Made entry conditions more permissive for shorter timeframes - Added comprehensive error handling and console logging
This commit is contained in:
@ -2,38 +2,81 @@ import { MA } from './ma.js';
|
||||
import { BaseIndicator } from './base.js';
|
||||
|
||||
export class HTSIndicator extends BaseIndicator {
|
||||
calculate(candles) {
|
||||
calculate(candles, oneMinCandles = null, targetTF = null) {
|
||||
const shortPeriod = this.params.short || 33;
|
||||
const longPeriod = this.params.long || 144;
|
||||
const maType = this.params.maType || 'RMA';
|
||||
|
||||
const shortHigh = MA.get(maType, candles, shortPeriod, 'high');
|
||||
const shortLow = MA.get(maType, candles, shortPeriod, 'low');
|
||||
const longHigh = MA.get(maType, candles, longPeriod, 'high');
|
||||
const longLow = MA.get(maType, candles, longPeriod, 'low');
|
||||
|
||||
return candles.map((_, i) => ({
|
||||
const useAutoHTS = this.params.useAutoHTS || false;
|
||||
|
||||
let workingCandles = candles;
|
||||
|
||||
if (useAutoHTS && oneMinCandles && targetTF) {
|
||||
const tfMultipliers = {
|
||||
'5m': 5,
|
||||
'15m': 15,
|
||||
'30m': 30,
|
||||
'37m': 37,
|
||||
'1h': 60,
|
||||
'4h': 240
|
||||
};
|
||||
|
||||
const tfGroup = tfMultipliers[targetTF] || 5;
|
||||
|
||||
const grouped = [];
|
||||
let currentGroup = [];
|
||||
for (let i = 0; i < oneMinCandles.length; i++) {
|
||||
currentGroup.push(oneMinCandles[i]);
|
||||
if (currentGroup.length >= tfGroup) {
|
||||
grouped.push({
|
||||
time: currentGroup[tfGroup - 1].time,
|
||||
open: currentGroup[tfGroup - 1].open,
|
||||
high: currentGroup[tfGroup - 1].high,
|
||||
low: currentGroup[tfGroup - 1].low,
|
||||
close: currentGroup[tfGroup - 1].close,
|
||||
volume: currentGroup[tfGroup - 1].volume
|
||||
});
|
||||
currentGroup = [];
|
||||
}
|
||||
}
|
||||
|
||||
workingCandles = grouped;
|
||||
}
|
||||
|
||||
const shortHigh = MA.get(maType, workingCandles, shortPeriod, 'high');
|
||||
const shortLow = MA.get(maType, workingCandles, shortPeriod, 'low');
|
||||
const longHigh = MA.get(maType, workingCandles, longPeriod, 'high');
|
||||
const longLow = MA.get(maType, workingCandles, longPeriod, 'low');
|
||||
|
||||
return workingCandles.map((_, i) => ({
|
||||
fastHigh: shortHigh[i],
|
||||
fastLow: shortLow[i],
|
||||
slowHigh: longHigh[i],
|
||||
slowLow: longLow[i]
|
||||
slowLow: longLow[i],
|
||||
fastMidpoint: ((shortHigh[i] || 0) + (shortLow[i] || 0)) / 2,
|
||||
slowMidpoint: ((longHigh[i] || 0) + (longLow[i] || 0)) / 2
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
getMetadata() {
|
||||
const useAutoHTS = this.params?.useAutoHTS || false;
|
||||
|
||||
const fastLineWidth = useAutoHTS ? 1 : 1;
|
||||
const slowLineWidth = useAutoHTS ? 2 : 2;
|
||||
|
||||
return {
|
||||
name: 'HTS Trend System',
|
||||
description: 'High/Low Trend System with Fast and Slow MAs',
|
||||
inputs: [
|
||||
{ name: 'short', label: 'Fast Period', type: 'number', default: 33, min: 1, max: 500 },
|
||||
{ name: 'long', label: 'Slow Period', type: 'number', default: 144, min: 1, max: 500 },
|
||||
{ name: 'maType', label: 'MA Type', type: 'select', options: ['SMA', 'EMA', 'RMA', 'WMA', 'VWMA'], default: 'RMA' }
|
||||
{ name: 'maType', label: 'MA Type', type: 'select', options: ['SMA', 'EMA', 'RMA', 'WMA', 'VWMA'], default: 'RMA' },
|
||||
{ name: 'useAutoHTS', label: 'Auto HTS (TF/4)', type: 'boolean', default: false }
|
||||
],
|
||||
plots: [
|
||||
{ id: 'fastHigh', color: '#00bcd4', title: 'Fast High', width: 1 },
|
||||
{ id: 'fastLow', color: '#00bcd4', title: 'Fast Low', width: 1 },
|
||||
{ id: 'slowHigh', color: '#f44336', title: 'Slow High', width: 2 },
|
||||
{ id: 'slowLow', color: '#f44336', title: 'Slow Low', width: 2 }
|
||||
{ id: 'fastHigh', color: '#00bcd4', title: 'Fast High', width: fastLineWidth },
|
||||
{ id: 'fastLow', color: '#00bcd4', title: 'Fast Low', width: fastLineWidth },
|
||||
{ id: 'slowHigh', color: '#f44336', title: 'Slow High', width: slowLineWidth },
|
||||
{ id: 'slowLow', color: '#f44336', title: 'Slow Low', width: slowLineWidth }
|
||||
],
|
||||
displayMode: 'overlay'
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user