일목균형표 수정

This commit is contained in:
Macbook
2026-06-16 21:15:57 +09:00
parent 0047a20e08
commit c4123b51f8
+21 -31
View File
@@ -143,12 +143,12 @@ export const STABLE_STRATEGY_PALETTE_ITEMS: StableStrategyPaletteMeta[] = [
},
{
value: ICHIMOKU_SANYAKU_BUY, label: '일목 삼역호전 매수', strategyId: 'ICHIMOKU_SANYAKU', mode: 'buy',
desc: '구름 돌파 + 삼역 필터 — 최근 N봉 내 존재 전후 봉 분산 조건 허용 (보통 20봉)',
desc: '구름 돌파(현재봉) + 보조필터 N봉 내 존재 전후 봉 분산 허용, 트리거는 1회',
periodHint: '9 / 26 / 52',
},
{
value: ICHIMOKU_SANYAKU_SELL, label: '일목 삼역호전 매도', strategyId: 'ICHIMOKU_SANYAKU', mode: 'sell',
desc: '전환·기준·구름 이탈 — N봉 내 돌파 존재 + 전환선 이탈 fallback',
desc: '전환·기준·구름 하향 돌파(현재봉 1회) — 유지 조건 없음',
periodHint: '9 / 26 / 52',
},
{
@@ -394,7 +394,7 @@ function buildIchimokuTrendSell(def: IndicatorPeriodDef, level: StableStrategyFi
return wrapOrRoot(branches, pairMeta('ICHIMOKU_TREND', 'sell', level));
}
/** 일목 삼역호전 — N봉 내 존재 윈도우 (3m 기준: 12≈36분, 20≈1h, 26≈78분) */
/** 일목 삼역호전 — N봉 내 존재 윈도우 (3m: 12≈36분, 20≈1h, 26≈78분) — 추세 확인·상태 필터에만 사용 */
function ichimokuSanyakuWindow(level: StableStrategyFilterLevel): number {
switch (level) {
case 'relaxed': return 12;
@@ -403,22 +403,18 @@ function ichimokuSanyakuWindow(level: StableStrategyFilterLevel): number {
}
}
/** 일목 삼역호전 — 매수 트리거 (구름/후행 돌파, N봉 내 존재) */
/** 매수 트리거 — 1회성 돌파 (현재 봉만). EXISTS_IN 적용 시 N봉마다 재충족되어 시그널 폭증 */
function ichimokuSanyakuBuyTrigger(def: IndicatorPeriodDef, level: StableStrategyFilterLevel): LogicNode {
const w = ichimokuSanyakuWindow(level);
if (level === 'strict') {
return wrapOr([
makeExistsIn('ICHIMOKU', 'CLOUD_BREAK_UP', 'NONE', 'NONE', def, w),
makeExistsIn('ICHIMOKU', 'CHIKOU_CROSS_ABOVE_PRIOR_CLOUD', 'NONE', 'NONE', def, w),
makeCondition('ICHIMOKU', 'CLOUD_BREAK_UP', 'NONE', 'NONE', def),
makeCondition('ICHIMOKU', 'CHIKOU_CROSS_ABOVE_PRIOR_CLOUD', 'NONE', 'NONE', def),
]);
}
return makeExistsIn('ICHIMOKU', 'CLOUD_BREAK_UP', 'NONE', 'NONE', def, w);
return makeCondition('ICHIMOKU', 'CLOUD_BREAK_UP', 'NONE', 'NONE', def);
}
/**
* 구름 돌파 직후에는 전환>기준·양운이 아직 false인 경우가 많음.
* N봉 내 존재로 전후 봉에 분산된 추세 확인 허용.
*/
/** 전환>기준·양운 — 돌파 봉 전후 시간차 허용 (N봉 내 존재) */
function ichimokuSanyakuTrendConfirm(def: IndicatorPeriodDef, level: StableStrategyFilterLevel): LogicNode[] {
if (level === 'relaxed') return [];
const w = ichimokuSanyakuWindow(level);
@@ -430,13 +426,14 @@ function ichimokuSanyakuTrendConfirm(def: IndicatorPeriodDef, level: StableStrat
];
}
/** 일목 삼역호전 — 공통 추세·구름 필터 (N봉 내 존재) */
/**
* 돌파 트리거(현재 봉) + 보조 필터(N봉 내 존재).
* 트리거·돌파 이벤트에 EXISTS_IN을 쓰면 윈도우 동안 매 봉 AND 충족 → 시그널 과다.
*/
function ichimokuSanyakuCoreFilters(def: IndicatorPeriodDef, level: StableStrategyFilterLevel): LogicNode[] {
const w = ichimokuSanyakuWindow(level);
if (level === 'relaxed') {
return [
makeExistsIn('ICHIMOKU', 'GT', 'CLOSE_PRICE', 'CONVERSION_LINE', def, w),
];
return [makeCondition('ICHIMOKU', 'GT', 'CLOSE_PRICE', 'CONVERSION_LINE', def)];
}
const nodes: LogicNode[] = [
makeExistsIn('ICHIMOKU', 'GT', 'CLOSE_PRICE', 'CONVERSION_LINE', def, w),
@@ -464,21 +461,14 @@ function buildIchimokuSanyakuBuy(def: IndicatorPeriodDef, level: StableStrategyF
return wrapAnd(nodes, pairMeta('ICHIMOKU_SANYAKU', 'buy', level));
}
/** 일목 삼역호전 — 청산 (돌파·이탈 N봉 내 존재 + 전환선 이탈 fallback) */
/** 일목 삼역호전 — 청산 (1회성 하향 돌파만; 유지 조건 LT/구름아래 제거 → 연속 매도 방지) */
function buildIchimokuSanyakuSell(def: IndicatorPeriodDef, level: StableStrategyFilterLevel): LogicNode {
const w = ichimokuSanyakuWindow(level);
const branches: LogicNode[] = [
makeExistsIn('ICHIMOKU', 'CROSS_DOWN', 'CLOSE_PRICE', 'CONVERSION_LINE', def, w),
makeExistsIn('ICHIMOKU', 'CROSS_DOWN', 'CLOSE_PRICE', 'BASE_LINE', def, w),
makeExistsIn('ICHIMOKU', 'CROSS_DOWN', 'CONVERSION_LINE', 'BASE_LINE', def, w),
makeExistsIn('ICHIMOKU', 'CLOUD_BREAK_DOWN', 'CLOSE_PRICE', 'NONE', def, w),
makeCondition('ICHIMOKU', 'CROSS_DOWN', 'CLOSE_PRICE', 'CONVERSION_LINE', def),
makeCondition('ICHIMOKU', 'CROSS_DOWN', 'CLOSE_PRICE', 'BASE_LINE', def),
makeCondition('ICHIMOKU', 'CROSS_DOWN', 'CONVERSION_LINE', 'BASE_LINE', def),
makeCondition('ICHIMOKU', 'CLOUD_BREAK_DOWN', 'CLOSE_PRICE', 'NONE', def),
];
if (level !== 'strict') {
branches.push(makeCondition('ICHIMOKU', 'LT', 'CLOSE_PRICE', 'CONVERSION_LINE', def));
if (level === 'relaxed') {
branches.push(makeCondition('ICHIMOKU', 'BELOW_CLOUD', 'CLOSE_PRICE', 'NONE', def));
}
}
return wrapOrRoot(branches, pairMeta('ICHIMOKU_SANYAKU', 'sell', level));
}
@@ -601,9 +591,9 @@ export function stableStrategyFilterSummary(
if (strategyId === 'ICHIMOKU_TREND' && level === 'relaxed') parts.push('구름필터 없음');
if (strategyId === 'ICHIMOKU_SANYAKU') {
const w = ichimokuSanyakuWindow(level);
if (level === 'strict') parts.push(`N${w}봉·삼역·MA60·거래량`);
else if (level === 'balanced') parts.push(`N${w}봉·구름돌파·(전환>기준 OR 양운)`);
else parts.push(`N${w}봉·구름돌파·종가>전환`);
if (level === 'strict') parts.push(`돌파1회·필터N${w}·MA60·거래량`);
else if (level === 'balanced') parts.push(`돌파1회·필터N${w}·(전환>기준 OR 양운)`);
else parts.push('돌파1회·종가>전환');
}
if (strategyId === 'MACD_MOMENTUM' && level === 'relaxed') parts.push('EMA60·ADX 없음');
if (strategyId === 'MA_TREND' && level === 'relaxed') parts.push('ADX 없음');