일목균형표 수정
This commit is contained in:
@@ -143,12 +143,12 @@ export const STABLE_STRATEGY_PALETTE_ITEMS: StableStrategyPaletteMeta[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: ICHIMOKU_SANYAKU_BUY, label: '일목 삼역호전 매수', strategyId: 'ICHIMOKU_SANYAKU', mode: 'buy',
|
value: ICHIMOKU_SANYAKU_BUY, label: '일목 삼역호전 매수', strategyId: 'ICHIMOKU_SANYAKU', mode: 'buy',
|
||||||
desc: '구름 돌파 + 삼역 필터 — 최근 N봉 내 존재로 전후 봉 분산 조건 허용 (보통 20봉)',
|
desc: '구름 돌파(현재봉) + 보조필터 N봉 내 존재 — 전후 봉 분산 허용, 트리거는 1회',
|
||||||
periodHint: '9 / 26 / 52',
|
periodHint: '9 / 26 / 52',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: ICHIMOKU_SANYAKU_SELL, label: '일목 삼역호전 매도', strategyId: 'ICHIMOKU_SANYAKU', mode: 'sell',
|
value: ICHIMOKU_SANYAKU_SELL, label: '일목 삼역호전 매도', strategyId: 'ICHIMOKU_SANYAKU', mode: 'sell',
|
||||||
desc: '전환·기준·구름 이탈 — N봉 내 돌파 존재 + 전환선 이탈 fallback',
|
desc: '전환·기준·구름 하향 돌파(현재봉 1회) — 유지 조건 없음',
|
||||||
periodHint: '9 / 26 / 52',
|
periodHint: '9 / 26 / 52',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -394,7 +394,7 @@ function buildIchimokuTrendSell(def: IndicatorPeriodDef, level: StableStrategyFi
|
|||||||
return wrapOrRoot(branches, pairMeta('ICHIMOKU_TREND', 'sell', level));
|
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 {
|
function ichimokuSanyakuWindow(level: StableStrategyFilterLevel): number {
|
||||||
switch (level) {
|
switch (level) {
|
||||||
case 'relaxed': return 12;
|
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 {
|
function ichimokuSanyakuBuyTrigger(def: IndicatorPeriodDef, level: StableStrategyFilterLevel): LogicNode {
|
||||||
const w = ichimokuSanyakuWindow(level);
|
|
||||||
if (level === 'strict') {
|
if (level === 'strict') {
|
||||||
return wrapOr([
|
return wrapOr([
|
||||||
makeExistsIn('ICHIMOKU', 'CLOUD_BREAK_UP', 'NONE', 'NONE', def, w),
|
makeCondition('ICHIMOKU', 'CLOUD_BREAK_UP', 'NONE', 'NONE', def),
|
||||||
makeExistsIn('ICHIMOKU', 'CHIKOU_CROSS_ABOVE_PRIOR_CLOUD', 'NONE', 'NONE', def, w),
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** 전환>기준·양운 — 돌파 봉 전후 시간차 허용 (N봉 내 존재) */
|
||||||
* 구름 돌파 직후에는 전환>기준·양운이 아직 false인 경우가 많음.
|
|
||||||
* N봉 내 존재로 전후 봉에 분산된 추세 확인 허용.
|
|
||||||
*/
|
|
||||||
function ichimokuSanyakuTrendConfirm(def: IndicatorPeriodDef, level: StableStrategyFilterLevel): LogicNode[] {
|
function ichimokuSanyakuTrendConfirm(def: IndicatorPeriodDef, level: StableStrategyFilterLevel): LogicNode[] {
|
||||||
if (level === 'relaxed') return [];
|
if (level === 'relaxed') return [];
|
||||||
const w = ichimokuSanyakuWindow(level);
|
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[] {
|
function ichimokuSanyakuCoreFilters(def: IndicatorPeriodDef, level: StableStrategyFilterLevel): LogicNode[] {
|
||||||
const w = ichimokuSanyakuWindow(level);
|
const w = ichimokuSanyakuWindow(level);
|
||||||
if (level === 'relaxed') {
|
if (level === 'relaxed') {
|
||||||
return [
|
return [makeCondition('ICHIMOKU', 'GT', 'CLOSE_PRICE', 'CONVERSION_LINE', def)];
|
||||||
makeExistsIn('ICHIMOKU', 'GT', 'CLOSE_PRICE', 'CONVERSION_LINE', def, w),
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
const nodes: LogicNode[] = [
|
const nodes: LogicNode[] = [
|
||||||
makeExistsIn('ICHIMOKU', 'GT', 'CLOSE_PRICE', 'CONVERSION_LINE', def, w),
|
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));
|
return wrapAnd(nodes, pairMeta('ICHIMOKU_SANYAKU', 'buy', level));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 일목 삼역호전 — 청산 (돌파·이탈 N봉 내 존재 + 전환선 이탈 fallback) */
|
/** 일목 삼역호전 — 청산 (1회성 하향 돌파만; 유지 조건 LT/구름아래 제거 → 연속 매도 방지) */
|
||||||
function buildIchimokuSanyakuSell(def: IndicatorPeriodDef, level: StableStrategyFilterLevel): LogicNode {
|
function buildIchimokuSanyakuSell(def: IndicatorPeriodDef, level: StableStrategyFilterLevel): LogicNode {
|
||||||
const w = ichimokuSanyakuWindow(level);
|
|
||||||
const branches: LogicNode[] = [
|
const branches: LogicNode[] = [
|
||||||
makeExistsIn('ICHIMOKU', 'CROSS_DOWN', 'CLOSE_PRICE', 'CONVERSION_LINE', def, w),
|
makeCondition('ICHIMOKU', 'CROSS_DOWN', 'CLOSE_PRICE', 'CONVERSION_LINE', def),
|
||||||
makeExistsIn('ICHIMOKU', 'CROSS_DOWN', 'CLOSE_PRICE', 'BASE_LINE', def, w),
|
makeCondition('ICHIMOKU', 'CROSS_DOWN', 'CLOSE_PRICE', 'BASE_LINE', def),
|
||||||
makeExistsIn('ICHIMOKU', 'CROSS_DOWN', 'CONVERSION_LINE', 'BASE_LINE', def, w),
|
makeCondition('ICHIMOKU', 'CROSS_DOWN', 'CONVERSION_LINE', 'BASE_LINE', def),
|
||||||
makeExistsIn('ICHIMOKU', 'CLOUD_BREAK_DOWN', 'CLOSE_PRICE', 'NONE', def, w),
|
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));
|
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_TREND' && level === 'relaxed') parts.push('구름필터 없음');
|
||||||
if (strategyId === 'ICHIMOKU_SANYAKU') {
|
if (strategyId === 'ICHIMOKU_SANYAKU') {
|
||||||
const w = ichimokuSanyakuWindow(level);
|
const w = ichimokuSanyakuWindow(level);
|
||||||
if (level === 'strict') parts.push(`N${w}봉·삼역·MA60·거래량`);
|
if (level === 'strict') parts.push(`돌파1회·필터N${w}·MA60·거래량`);
|
||||||
else if (level === 'balanced') parts.push(`N${w}봉·구름돌파·(전환>기준 OR 양운)`);
|
else if (level === 'balanced') parts.push(`돌파1회·필터N${w}·(전환>기준 OR 양운)`);
|
||||||
else parts.push(`N${w}봉·구름돌파·종가>전환`);
|
else parts.push('돌파1회·종가>전환');
|
||||||
}
|
}
|
||||||
if (strategyId === 'MACD_MOMENTUM' && level === 'relaxed') parts.push('EMA60·ADX 없음');
|
if (strategyId === 'MACD_MOMENTUM' && level === 'relaxed') parts.push('EMA60·ADX 없음');
|
||||||
if (strategyId === 'MA_TREND' && level === 'relaxed') parts.push('ADX 없음');
|
if (strategyId === 'MA_TREND' && level === 'relaxed') parts.push('ADX 없음');
|
||||||
|
|||||||
Reference in New Issue
Block a user