@gabriel3615/ta_analysis
Version:
stock ta analysis
56 lines (55 loc) • 2.33 kB
JavaScript
import { TradeDirection } from '../../../types.js';
function clamp(value, min = 0, max = 100) {
return Math.max(min, Math.min(max, value));
}
export function createBbsrPlugin() {
return {
id: 'bbsr',
category: 'main',
extract(input, _context) {
const daily = input.analyses.bbsr.dailyBBSRResult;
const weekly = input.analyses.bbsr.weeklyBBSRResult;
const cand = [daily, weekly].filter(Boolean);
if (cand.length === 0)
return {
direction: TradeDirection.Neutral,
confidence: 0,
source: 'bbsr',
};
const now = Date.now();
let best = { direction: TradeDirection.Neutral, score: 0 };
for (const s of cand) {
const pt = s.signal?.patternType;
const dir = pt === 'bullish'
? TradeDirection.Long
: pt === 'bearish'
? TradeDirection.Short
: TradeDirection.Neutral;
const proximityPct = (Math.abs(s.currentPrice - s.SRLevel) / Math.max(1e-8, s.SRLevel)) *
100;
const proximityScore = Math.max(0, 30 - proximityPct);
const days = Math.max(0, (now - new Date(s.signalDate).getTime()) / 86400000);
const recencyScore = Math.max(0, 20 - days * 2);
const score = clamp(0.6 * (s.strength ?? 0) + proximityScore + recencyScore);
if (score > best.score)
best = { direction: dir, score };
}
if (daily?.signal?.patternType &&
weekly?.signal?.patternType &&
daily.signal.patternType !== weekly.signal.patternType) {
best.score = Math.max(0, best.score - 10);
}
return {
direction: best.direction,
confidence: best.score,
source: 'bbsr',
};
},
summarize(input) {
const b = input.analyses.bbsr;
const daily = b.dailyBBSRResult?.strength;
const weekly = b.weeklyBBSRResult?.strength;
return `BBSR(日/周) 强度:${daily ?? '-'} / ${weekly ?? '-'}`;
},
};
}