@gabriel3615/ta_analysis
Version:
stock ta analysis
62 lines (61 loc) • 2.71 kB
JavaScript
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;
},
};
}