UNPKG

@gabriel3615/ta_analysis

Version:

stock ta analysis

62 lines (61 loc) 2.71 kB
import { backtestStrategiesConfig } from '../strategyConfig.js'; import { analyzeMarketStructure } from '../../analyzer/structure/structureDetector.js'; export function StructureBreakoutStrategy(symbol, timeframe, params = {}) { const { preferEvent = backtestStrategiesConfig.structureBreakout.preferEvent, confirmTrend = backtestStrategiesConfig.structureBreakout.confirmTrend, minLookback = backtestStrategiesConfig.structureBreakout.minLookback, coolDownBars = backtestStrategiesConfig.structureBreakout.coolDownBars, } = params; let lastSignalIndex = -1; let lastDirection = undefined; return { name: 'StructureBreakout', generateSignal(history, i) { if (i < minLookback) return null; if (i - lastSignalIndex < coolDownBars) return null; const window = history.slice(Math.max(0, i - 300), i + 1); const res = analyzeMarketStructure(window, timeframe); const evt = res.lastEvent; if (!evt) return null; // 事件过滤 if (preferEvent !== 'any' && evt.type !== preferEvent) return null; // 趋势一致性过滤 if (confirmTrend) { if (evt.direction === 'bullish' && res.trend !== 'up') return null; if (evt.direction === 'bearish' && res.trend !== 'down') return null; } let signal = null; if (evt.direction === 'bullish') { signal = { timestamp: history[i].timestamp, direction: 'long', strength: evt.type === 'BOS' ? 85 : 70, reason: `${timeframe} 结构事件: ${evt.type} 向上 (${res.summary})`, }; } else if (evt.direction === 'bearish') { signal = { timestamp: history[i].timestamp, direction: 'short', strength: evt.type === 'BOS' ? 85 : 70, reason: `${timeframe} 结构事件: ${evt.type} 向下 (${res.summary})`, }; } // 避免短时间内方向反转噪声 if (signal && lastDirection && signal.direction !== lastDirection && i - lastSignalIndex < coolDownBars * 2 && (signal.strength ?? 0) < 80) { return null; } if (signal) { lastSignalIndex = i; lastDirection = signal.direction; } return signal; }, }; }