33변곡 템플릿 추가

This commit is contained in:
Macbook
2026-05-24 13:03:39 +09:00
parent 03fab44cb3
commit 5685deb2c7
5 changed files with 173 additions and 43 deletions
+101
View File
@@ -0,0 +1,101 @@
import type { LogicNode } from './strategyTypes';
import { genId, type DefType } from './strategyEditorShared';
export type SimpleStrategyTemplate = {
kind: 'simple';
signal: 'buy' | 'sell';
label: string;
description?: string;
ind: string;
cond: string;
l: string;
r: string;
};
export type CompositeStrategyTemplate = {
kind: 'composite';
signal: 'buy' | 'sell';
label: string;
description: string;
build: () => LogicNode;
};
export type StrategyTemplateDef = SimpleStrategyTemplate | CompositeStrategyTemplate;
function condition(
indicatorType: string,
conditionType: string,
leftField: string,
rightField: string,
candleRange = 1,
): LogicNode {
return {
id: genId(),
type: 'CONDITION',
condition: { indicatorType, conditionType, leftField, rightField, candleRange },
};
}
function andTree(...children: LogicNode[]): LogicNode {
return { id: genId(), type: 'AND', children };
}
/** 33변곡 매수 — 바닥권 시간변곡(약 33거래일 주기) 전환 구간 */
export function build33InflectionBuyTree(): LogicNode {
return andTree(
condition('RSI', 'CROSS_UP', 'RSI_VALUE', 'OVERSOLD_30'),
condition('MA', 'CROSS_UP', 'MA5', 'MA20'),
condition('MA', 'CROSS_UP', 'CLOSE_PRICE', 'MA20'),
condition('MACD', 'CROSS_UP', 'MACD_LINE', 'SIGNAL_LINE'),
condition('DISPARITY', 'CROSS_UP', 'DISPARITY20', 'OVERSOLD_95'),
);
}
/** 33변곡 매도 — 상승 5파 끝(33·36·38일 변곡) 구간 이탈 */
export function build33InflectionSellTree(): LogicNode {
return andTree(
condition('RSI', 'GTE', 'RSI_VALUE', 'OVERBOUGHT_70'),
condition('MA', 'CROSS_DOWN', 'MA5', 'MA20'),
condition('MA', 'CROSS_DOWN', 'CLOSE_PRICE', 'MA20'),
condition('MACD', 'CROSS_DOWN', 'MACD_LINE', 'SIGNAL_LINE'),
condition('DISPARITY', 'GTE', 'DISPARITY20', 'OVERBOUGHT_105'),
);
}
export function getStrategyTemplates(def: DefType): StrategyTemplateDef[] {
const maShort = `MA${def.maLines[0]}`;
const maMid = `MA${def.maLines[1]}`;
return [
{ kind: 'simple', ind: 'MA', cond: 'CROSS_UP', l: maShort, r: maMid, signal: 'buy', label: 'MA 골든크로스 매수' },
{ kind: 'simple', ind: 'MA', cond: 'CROSS_DOWN', l: maShort, r: maMid, signal: 'sell', label: 'MA 데드크로스 매도' },
{ kind: 'simple', ind: 'RSI', cond: 'LTE', l: 'RSI_VALUE', r: 'OVERSOLD_30', signal: 'buy', label: 'RSI 과매도 매수' },
{ kind: 'simple', ind: 'RSI', cond: 'GTE', l: 'RSI_VALUE', r: 'OVERBOUGHT_70', signal: 'sell', label: 'RSI 과매수 매도' },
{ kind: 'simple', ind: 'MACD', cond: 'CROSS_UP', l: 'MACD_LINE', r: 'SIGNAL_LINE', signal: 'buy', label: 'MACD 상향 돌파' },
{ kind: 'simple', ind: 'MACD', cond: 'CROSS_DOWN', l: 'MACD_LINE', r: 'SIGNAL_LINE', signal: 'sell', label: 'MACD 하향 돌파' },
{ kind: 'simple', ind: 'BOLLINGER', cond: 'CROSS_UP', l: 'CLOSE_PRICE', r: 'LOWER_BAND', signal: 'buy', label: '볼린저 하단 돌파 매수' },
{ kind: 'simple', ind: 'BOLLINGER', cond: 'CROSS_UP', l: 'CLOSE_PRICE', r: 'UPPER_BAND', signal: 'sell', label: '볼린저 상단 돌파 매도' },
{ kind: 'simple', ind: 'CCI', cond: 'CROSS_UP', l: 'CCI_VALUE', r: 'OVERSOLD_NEG100', signal: 'buy', label: 'CCI 과매도 반등' },
{ kind: 'simple', ind: 'PSYCHOLOGICAL', cond: 'CROSS_UP', l: 'PSY_VALUE', r: 'OVERBOUGHT_75', signal: 'buy', label: '심리도 상향 돌파' },
{ kind: 'simple', ind: 'STOCHASTIC', cond: 'CROSS_UP', l: 'STOCH_K', r: 'STOCH_D', signal: 'buy', label: '스토캐스틱 골든크로스' },
{ kind: 'simple', ind: 'ADX', cond: 'CROSS_UP', l: 'ADX_VALUE', r: 'ADX_25', signal: 'buy', label: 'ADX 중앙선 상향 돌파' },
{
kind: 'composite',
signal: 'buy',
label: '33변곡 매수',
description: '바닥권 시간변곡 — RSI 과매도 탈출 + MA 골든크로스 + 20일선·이격도 돌파',
build: build33InflectionBuyTree,
},
{
kind: 'composite',
signal: 'sell',
label: '33변곡 매도',
description: '상승 5파 끝 변곡 — RSI 과매수 + MA 데드크로스 + 20일선·이격도 이탈',
build: build33InflectionSellTree,
},
];
}
export function simpleTemplateToNode(tmpl: SimpleStrategyTemplate): LogicNode {
return condition(tmpl.ind, tmpl.cond, tmpl.l, tmpl.r);
}