일목균형표 복합지표 추가
This commit is contained in:
@@ -91,6 +91,10 @@ import {
|
||||
type StableStrategyFilterLevel,
|
||||
type StableStrategyId,
|
||||
} from '../utils/stableStrategyPairs';
|
||||
import {
|
||||
buildIchimokuSituationTree,
|
||||
isIchimokuSituationPaletteValue,
|
||||
} from '../utils/ichimokuSituationStrategy';
|
||||
import {
|
||||
buildStochOverboughtPairTree,
|
||||
findStochPairRootInForest,
|
||||
@@ -1367,7 +1371,8 @@ export default function StrategyEditorPage({
|
||||
const inflection33 = isInflection33PaletteValue(item.value);
|
||||
const ichimokuBb = isIchimokuBbPaletteValue(item.value);
|
||||
const stableStrategy = isStableStrategyPaletteValue(item.value);
|
||||
const composite = item.kind === 'composite' && !stochPair && !priceExtremeBreakout && !inflection33 && !ichimokuBb && !stableStrategy;
|
||||
const ichimokuSituation = isIchimokuSituationPaletteValue(item.value);
|
||||
const composite = item.kind === 'composite' && !stochPair && !priceExtremeBreakout && !inflection33 && !ichimokuBb && !stableStrategy && !ichimokuSituation;
|
||||
const newNode = stochPair
|
||||
? buildStochOverboughtPairTree(item.secondaryIndicator ?? 'CCI', DEF)
|
||||
: priceExtremeBreakout
|
||||
@@ -1378,6 +1383,8 @@ export default function StrategyEditorPage({
|
||||
? buildIchimokuBbTree(item.value, DEF)
|
||||
: stableStrategy
|
||||
? buildStableStrategyTree(item.value, DEF)
|
||||
: ichimokuSituation
|
||||
? buildIchimokuSituationTree(item.value, DEF)
|
||||
: makeNode('indicator', item.value, signalTab, DEF, composite ? { composite: true } : undefined);
|
||||
if (!newNode) return;
|
||||
handleEditorStateChange(prev => {
|
||||
|
||||
@@ -31,6 +31,11 @@ import {
|
||||
inferStableStrategyFilterLevel,
|
||||
type StableStrategyId,
|
||||
} from '../../utils/stableStrategyPairs';
|
||||
import {
|
||||
isIchimokuSituationPairRoot,
|
||||
ichimokuSituationDisplayName,
|
||||
type IchimokuSituationId,
|
||||
} from '../../utils/ichimokuSituationStrategy';
|
||||
import StableStrategyPairNodeSettings from './StableStrategyPairNodeSettings';
|
||||
import {
|
||||
isStochOverboughtPairRoot,
|
||||
@@ -241,12 +246,13 @@ export const LogicGateNode = memo(function LogicGateNode({ id, data, selected }:
|
||||
const isInflection33Pair = isInflection33PairRoot(node);
|
||||
const isIchimokuBbPair = isIchimokuBbPairRoot(node);
|
||||
const isStableStrategyPair = isStableStrategyPairRoot(node);
|
||||
const isIchimokuSituationPair = isIchimokuSituationPairRoot(node);
|
||||
const { onDragEnter, onDragOver, onDragLeave, onDrop } = usePaletteDropHandlers(id, d);
|
||||
const [settingsOpen, setSettingsOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`se-flow-node se-flow-node--logic${isStochPair ? ' se-flow-node--stoch-pair' : ''}${isPriceExtremePair ? ' se-flow-node--price-extreme-pair' : ''}${isInflection33Pair ? ' se-flow-node--inflection33-pair' : ''}${isIchimokuBbPair ? ' se-flow-node--ichimoku-bb-pair' : ''}${isStableStrategyPair ? ' se-flow-node--stable-strategy-pair' : ''}${isSell ? ' se-flow-node--sell-mode' : ''}${d.isOrphan ? ' se-flow-node--orphan' : ''} ${selected ? 'se-flow-node--selected' : ''} ${d.dragOver ? ' se-flow-node--drop' : ''}${settingsOpen ? ' se-flow-node--settings-open' : ''}`}
|
||||
className={`se-flow-node se-flow-node--logic${isStochPair ? ' se-flow-node--stoch-pair' : ''}${isPriceExtremePair ? ' se-flow-node--price-extreme-pair' : ''}${isInflection33Pair ? ' se-flow-node--inflection33-pair' : ''}${isIchimokuBbPair ? ' se-flow-node--ichimoku-bb-pair' : ''}${isStableStrategyPair ? ' se-flow-node--stable-strategy-pair' : ''}${isIchimokuSituationPair ? ' se-flow-node--ichimoku-situation-pair' : ''}${isSell ? ' se-flow-node--sell-mode' : ''}${d.isOrphan ? ' se-flow-node--orphan' : ''} ${selected ? 'se-flow-node--selected' : ''} ${d.dragOver ? ' se-flow-node--drop' : ''}${settingsOpen ? ' se-flow-node--settings-open' : ''}`}
|
||||
style={{ '--se-gate-color': color } as React.CSSProperties}
|
||||
onDragEnter={onDragEnter}
|
||||
onDragOver={onDragOver}
|
||||
@@ -297,6 +303,16 @@ export const LogicGateNode = memo(function LogicGateNode({ id, data, selected }:
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
{isIchimokuSituationPair && node.ichimokuSituationPair && (
|
||||
<div className="se-flow-gate-stoch-pair">
|
||||
<span className="se-flow-gate-stoch-pair-title">
|
||||
{ichimokuSituationDisplayName(
|
||||
node.ichimokuSituationPair.situationId as IchimokuSituationId,
|
||||
node.ichimokuSituationPair.mode,
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
{isInflection33Pair && node.inflection33Pair && (
|
||||
<div className="se-flow-gate-stoch-pair">
|
||||
<span className="se-flow-gate-stoch-pair-title">
|
||||
|
||||
@@ -8,6 +8,7 @@ import { isPriceExtremeBreakoutPairPaletteValue } from '../../utils/priceExtreme
|
||||
import { isInflection33PaletteValue } from '../../utils/inflection33Strategy';
|
||||
import { isIchimokuBbPaletteValue } from '../../utils/ichimokuBbStrategy';
|
||||
import { isStableStrategyPaletteValue, STABLE_STRATEGY_PALETTE_ITEMS } from '../../utils/stableStrategyPairs';
|
||||
import { isIchimokuSituationPaletteValue } from '../../utils/ichimokuSituationStrategy';
|
||||
import { getDefaultIndicatorPeriod } from '../../utils/conditionPeriods';
|
||||
import { getStrategyIndicatorDisplayName } from '../../utils/strategyPaletteStorage';
|
||||
import { getIndicatorPeriodLabel } from '../../utils/strategyFlowLayout';
|
||||
@@ -39,6 +40,9 @@ function periodLabel(item: PaletteItem, def: DefType): string {
|
||||
const meta = STABLE_STRATEGY_PALETTE_ITEMS.find(i => i.value === item.value);
|
||||
return meta?.periodHint ?? '';
|
||||
}
|
||||
if (item.kind === 'composite' && isIchimokuSituationPaletteValue(item.value)) {
|
||||
return '9 / 26 / 52';
|
||||
}
|
||||
if (item.kind === 'composite') {
|
||||
const d = getCompositeDefaultPeriods(item.value, def);
|
||||
return `${d.short} / ${d.long}`;
|
||||
@@ -194,12 +198,14 @@ export default function IndicatorPaletteTab({
|
||||
&& !isPriceExtremeBreakoutPairPaletteValue(item.value)
|
||||
&& !isInflection33PaletteValue(item.value)
|
||||
&& !isIchimokuBbPaletteValue(item.value)
|
||||
&& !isStableStrategyPaletteValue(item.value)}
|
||||
&& !isStableStrategyPaletteValue(item.value)
|
||||
&& !isIchimokuSituationPaletteValue(item.value)}
|
||||
stochPair={isStochOverboughtPairPaletteValue(item.value)}
|
||||
priceExtremeBreakout={isPriceExtremeBreakoutPairPaletteValue(item.value)}
|
||||
inflection33={isInflection33PaletteValue(item.value)}
|
||||
ichimokuBb={isIchimokuBbPaletteValue(item.value)}
|
||||
stableStrategy={isStableStrategyPaletteValue(item.value)}
|
||||
ichimokuSituation={isIchimokuSituationPaletteValue(item.value)}
|
||||
secondaryIndicator={item.secondaryIndicator}
|
||||
period={periodLabel(item, def)}
|
||||
periodValue={item.period}
|
||||
|
||||
@@ -29,6 +29,7 @@ interface Props {
|
||||
inflection33?: boolean;
|
||||
ichimokuBb?: boolean;
|
||||
stableStrategy?: boolean;
|
||||
ichimokuSituation?: boolean;
|
||||
secondaryIndicator?: string;
|
||||
selected?: boolean;
|
||||
onSelect?: () => void;
|
||||
@@ -37,7 +38,7 @@ interface Props {
|
||||
|
||||
export default function PaletteChip({
|
||||
type, value, label, desc, color, period, periodValue, shortPeriod, longPeriod,
|
||||
composite = false, stochPair = false, priceExtremeBreakout = false, inflection33 = false, ichimokuBb = false, stableStrategy = false, secondaryIndicator, selected = false, onSelect, onAdd,
|
||||
composite = false, stochPair = false, priceExtremeBreakout = false, inflection33 = false, ichimokuBb = false, stableStrategy = false, ichimokuSituation = false, secondaryIndicator, selected = false, onSelect, onAdd,
|
||||
}: Props) {
|
||||
const buildPayload = (): PaletteDragPayload => ({
|
||||
type, value, label,
|
||||
@@ -47,6 +48,7 @@ export default function PaletteChip({
|
||||
inflection33: inflection33 || undefined,
|
||||
ichimokuBb: ichimokuBb || undefined,
|
||||
stableStrategy: stableStrategy || undefined,
|
||||
ichimokuSituation: ichimokuSituation || undefined,
|
||||
secondaryIndicator,
|
||||
period: periodValue,
|
||||
shortPeriod,
|
||||
|
||||
@@ -794,6 +794,9 @@ function StrategyEditorCanvasInner({
|
||||
: n.stableStrategyPair?.mode === 'sell'
|
||||
? (gateType === 'OR' ? n.stableStrategyPair : undefined)
|
||||
: undefined,
|
||||
ichimokuSituationPair: n.ichimokuSituationPair
|
||||
? n.ichimokuSituationPair
|
||||
: undefined,
|
||||
}
|
||||
: n
|
||||
);
|
||||
|
||||
@@ -51,6 +51,10 @@ import {
|
||||
buildStableStrategyTree,
|
||||
isStableStrategyPaletteValue,
|
||||
} from '../utils/stableStrategyPairs';
|
||||
import {
|
||||
buildIchimokuSituationTree,
|
||||
isIchimokuSituationPaletteValue,
|
||||
} from '../utils/ichimokuSituationStrategy';
|
||||
import {
|
||||
buildSidewaysFilterNode,
|
||||
loadSidewaysPaletteItems,
|
||||
@@ -453,7 +457,8 @@ export function useStrategyEvaluationEditor({
|
||||
const inflection33 = isInflection33PaletteValue(item.value);
|
||||
const ichimokuBb = isIchimokuBbPaletteValue(item.value);
|
||||
const stableStrategy = isStableStrategyPaletteValue(item.value);
|
||||
const composite = item.kind === 'composite' && !stochPair && !priceExtremeBreakout && !inflection33 && !ichimokuBb && !stableStrategy;
|
||||
const ichimokuSituation = isIchimokuSituationPaletteValue(item.value);
|
||||
const composite = item.kind === 'composite' && !stochPair && !priceExtremeBreakout && !inflection33 && !ichimokuBb && !stableStrategy && !ichimokuSituation;
|
||||
const newNode = stochPair
|
||||
? buildStochOverboughtPairTree(item.secondaryIndicator ?? 'CCI', def)
|
||||
: priceExtremeBreakout
|
||||
@@ -464,6 +469,8 @@ export function useStrategyEvaluationEditor({
|
||||
? buildIchimokuBbTree(item.value, def)
|
||||
: stableStrategy
|
||||
? buildStableStrategyTree(item.value, def)
|
||||
: ichimokuSituation
|
||||
? buildIchimokuSituationTree(item.value, def)
|
||||
: makeNode('indicator', item.value, signalTab, def, composite ? { composite: true } : undefined);
|
||||
if (!newNode) return;
|
||||
handleEditorStateChange(prev => {
|
||||
|
||||
@@ -0,0 +1,358 @@
|
||||
/**
|
||||
* 일목균형표 상황별·엘리어트 파동 복합 전략
|
||||
* @see 일목균형표 전략.md
|
||||
*/
|
||||
import type { ConditionDSL, LogicNode } from './strategyTypes';
|
||||
import { initConditionPeriodsInherit, type IndicatorPeriodDef } from './conditionPeriods';
|
||||
import { genId } from './strategyNodeIds';
|
||||
|
||||
export type IchimokuSituationCategory = 'basic' | 'alignment' | 'elliott';
|
||||
|
||||
export type IchimokuSituationId =
|
||||
| 'GOLDEN_CROSS'
|
||||
| 'BASE_BREAKUP'
|
||||
| 'CLOUD_BREAKUP'
|
||||
| 'LAGGING_BULL'
|
||||
| 'CLOUD_SUPPORT'
|
||||
| 'DEAD_CROSS'
|
||||
| 'BASE_BREAKDOWN'
|
||||
| 'CLOUD_BREAKDOWN'
|
||||
| 'LAGGING_BEAR'
|
||||
| 'CLOUD_RESISTANCE'
|
||||
| 'SANYAKU_REVERSE'
|
||||
| 'HOJEON'
|
||||
| 'GYEOKJEON'
|
||||
| 'EW1'
|
||||
| 'EW2'
|
||||
| 'EW3'
|
||||
| 'EW4'
|
||||
| 'EW5'
|
||||
| 'EW_A'
|
||||
| 'EW_B'
|
||||
| 'EW_C';
|
||||
|
||||
const SITUATION_PREFIX = 'ICHIMOKU_SIT_';
|
||||
|
||||
export function ichimokuSituationPaletteValue(id: IchimokuSituationId, mode: 'buy' | 'sell'): string {
|
||||
return `${SITUATION_PREFIX}${id}_${mode.toUpperCase()}`;
|
||||
}
|
||||
|
||||
export interface IchimokuSituationPaletteMeta {
|
||||
value: string;
|
||||
label: string;
|
||||
desc: string;
|
||||
situationId: IchimokuSituationId;
|
||||
mode: 'buy' | 'sell';
|
||||
category: IchimokuSituationCategory;
|
||||
}
|
||||
|
||||
export const ICHIMOKU_SITUATION_PALETTE_ITEMS: IchimokuSituationPaletteMeta[] = [
|
||||
// §2.1 기본 매수
|
||||
{ value: ichimokuSituationPaletteValue('GOLDEN_CROSS', 'buy'), label: '일목 골든크로스 매수', situationId: 'GOLDEN_CROSS', mode: 'buy', category: 'basic',
|
||||
desc: 'L1 — 전환선이 기준선 상향 돌파 (호전 1차)' },
|
||||
{ value: ichimokuSituationPaletteValue('BASE_BREAKUP', 'buy'), label: '일목 기준선 돌파 매수', situationId: 'BASE_BREAKUP', mode: 'buy', category: 'basic',
|
||||
desc: 'L2 — 종가가 기준선 상향 돌파 (중기 추세 전환)' },
|
||||
{ value: ichimokuSituationPaletteValue('CLOUD_BREAKUP', 'buy'), label: '일목 구름 돌파 매수', situationId: 'CLOUD_BREAKUP', mode: 'buy', category: 'basic',
|
||||
desc: 'L3 — 구름대 상향 돌파 (매물·심리 저항 돌파)' },
|
||||
{ value: ichimokuSituationPaletteValue('LAGGING_BULL', 'buy'), label: '일목 후행 호전 매수', situationId: 'LAGGING_BULL', mode: 'buy', category: 'basic',
|
||||
desc: 'L4 — 후행스팬 > 26봉 전 종가 (추세 확정)' },
|
||||
{ value: ichimokuSituationPaletteValue('CLOUD_SUPPORT', 'buy'), label: '일목 구름 지지 매수', situationId: 'CLOUD_SUPPORT', mode: 'buy', category: 'basic',
|
||||
desc: 'L5 — 종가 > 선행1·기준선 (양운·기준선 지지 반등)' },
|
||||
// §1.3 호전
|
||||
{ value: ichimokuSituationPaletteValue('HOJEON', 'buy'), label: '일목 호전(정배열) 매수', situationId: 'HOJEON', mode: 'buy', category: 'alignment',
|
||||
desc: '괘·구름 위·양운·후행 — 완벽한 상승 추세 4조건' },
|
||||
// §2.2 기본 매도
|
||||
{ value: ichimokuSituationPaletteValue('DEAD_CROSS', 'sell'), label: '일목 데드크로스 매도', situationId: 'DEAD_CROSS', mode: 'sell', category: 'basic',
|
||||
desc: 'S1 — 전환선이 기준선 하향 이탈' },
|
||||
{ value: ichimokuSituationPaletteValue('BASE_BREAKDOWN', 'sell'), label: '일목 기준선 이탈 매도', situationId: 'BASE_BREAKDOWN', mode: 'sell', category: 'basic',
|
||||
desc: 'S2 — 종가가 기준선 하향 이탈' },
|
||||
{ value: ichimokuSituationPaletteValue('CLOUD_BREAKDOWN', 'sell'), label: '일목 구름 이탈 매도', situationId: 'CLOUD_BREAKDOWN', mode: 'sell', category: 'basic',
|
||||
desc: 'S3 — 구름대 하향 이탈 (지지 붕괴)' },
|
||||
{ value: ichimokuSituationPaletteValue('LAGGING_BEAR', 'sell'), label: '일목 후행 역전 매도', situationId: 'LAGGING_BEAR', mode: 'sell', category: 'basic',
|
||||
desc: 'S4 — 후행스팬 < 26봉 전 종가' },
|
||||
{ value: ichimokuSituationPaletteValue('CLOUD_RESISTANCE', 'sell'), label: '일목 구름 저항 매도', situationId: 'CLOUD_RESISTANCE', mode: 'sell', category: 'basic',
|
||||
desc: 'S5 — 종가 < 선행1·기준선 (음운·기준선 저항)' },
|
||||
{ value: ichimokuSituationPaletteValue('SANYAKU_REVERSE', 'sell'), label: '일목 삼역역전 매도', situationId: 'SANYAKU_REVERSE', mode: 'sell', category: 'alignment',
|
||||
desc: 'S6 — 데드 + 구름 아래 + 후행 역전 (강력 청산)' },
|
||||
{ value: ichimokuSituationPaletteValue('GYEOKJEON', 'sell'), label: '일목 역전(역배열) 매도', situationId: 'GYEOKJEON', mode: 'sell', category: 'alignment',
|
||||
desc: '괘·구름 아래·음운·후행 — 완벽한 하락 추세 4조건' },
|
||||
// §4 엘리어트 파동
|
||||
{ value: ichimokuSituationPaletteValue('EW1', 'buy'), label: '일목 1파 매수', situationId: 'EW1', mode: 'buy', category: 'elliott',
|
||||
desc: '추세 전환 시동 — 기준선 돌파 + 전환>기준 (소액·분할)' },
|
||||
{ value: ichimokuSituationPaletteValue('EW2', 'buy'), label: '일목 2파 매수', situationId: 'EW2', mode: 'buy', category: 'elliott',
|
||||
desc: '눌림목 — 기준선·구름하단(선행2) 지지 + 전환>기준' },
|
||||
{ value: ichimokuSituationPaletteValue('EW2', 'sell'), label: '일목 2파 손절', situationId: 'EW2', mode: 'sell', category: 'elliott',
|
||||
desc: '2파 지지 이탈 — 기준선 이탈 OR 구름 하향 돌파' },
|
||||
{ value: ichimokuSituationPaletteValue('EW3', 'buy'), label: '일목 3파 매수', situationId: 'EW3', mode: 'buy', category: 'elliott',
|
||||
desc: '본격 상승 — 삼역호전(괘·구름·후행·양운) 불타기' },
|
||||
{ value: ichimokuSituationPaletteValue('EW4', 'buy'), label: '일목 4파 재매수', situationId: 'EW4', mode: 'buy', category: 'elliott',
|
||||
desc: '횡보 조정 — 구름 상단(선행1)·기준선 지지 반등' },
|
||||
{ value: ichimokuSituationPaletteValue('EW4', 'sell'), label: '일목 4파 익절', situationId: 'EW4', mode: 'sell', category: 'elliott',
|
||||
desc: '4파 조정 — 기준선 이탈 OR 구름 하향 이탈' },
|
||||
{ value: ichimokuSituationPaletteValue('EW5', 'sell'), label: '일목 5파 분할매도', situationId: 'EW5', mode: 'sell', category: 'elliott',
|
||||
desc: '과열 — 전환선·데드·구름 이탈 (분할 청산)' },
|
||||
{ value: ichimokuSituationPaletteValue('EW_A', 'sell'), label: '일목 A파 매도', situationId: 'EW_A', mode: 'sell', category: 'elliott',
|
||||
desc: '하락 개시 — 기준선·데드크로스' },
|
||||
{ value: ichimokuSituationPaletteValue('EW_B', 'sell'), label: '일목 B파 매도', situationId: 'EW_B', mode: 'sell', category: 'elliott',
|
||||
desc: '기술적 반등 실패 — 기준선·음운 저항 (전량 대피)' },
|
||||
{ value: ichimokuSituationPaletteValue('EW_C', 'sell'), label: '일목 C파 매도', situationId: 'EW_C', mode: 'sell', category: 'elliott',
|
||||
desc: '본 하락 — 삼역역전 + 구름 이탈 (물타기 금지)' },
|
||||
];
|
||||
|
||||
const VALUE_TO_META: Record<string, { situationId: IchimokuSituationId; mode: 'buy' | 'sell' }> =
|
||||
Object.fromEntries(ICHIMOKU_SITUATION_PALETTE_ITEMS.map(i => [i.value, { situationId: i.situationId, mode: i.mode }]));
|
||||
|
||||
export function isIchimokuSituationPaletteValue(value: string): boolean {
|
||||
return value.startsWith(SITUATION_PREFIX) && value in VALUE_TO_META;
|
||||
}
|
||||
|
||||
export function isIchimokuSituationPairRoot(node: LogicNode): boolean {
|
||||
return !!node.ichimokuSituationPair?.situationId
|
||||
&& (node.type === 'AND' || node.type === 'OR');
|
||||
}
|
||||
|
||||
function makeIch(
|
||||
def: IndicatorPeriodDef,
|
||||
conditionType: string,
|
||||
leftField: string,
|
||||
rightField: string,
|
||||
extra?: Partial<ConditionDSL>,
|
||||
): LogicNode {
|
||||
const base: ConditionDSL = {
|
||||
indicatorType: 'ICHIMOKU',
|
||||
conditionType,
|
||||
leftField,
|
||||
rightField,
|
||||
candleRange: 1,
|
||||
valuePeriodOverride: false,
|
||||
thresholdOverride: false,
|
||||
rightPeriodOverride: false,
|
||||
...extra,
|
||||
};
|
||||
return {
|
||||
id: genId(),
|
||||
type: 'CONDITION',
|
||||
condition: initConditionPeriodsInherit('ICHIMOKU', base, def),
|
||||
};
|
||||
}
|
||||
|
||||
function pairMeta(
|
||||
situationId: IchimokuSituationId,
|
||||
mode: 'buy' | 'sell',
|
||||
): LogicNode['ichimokuSituationPair'] {
|
||||
return { situationId, mode };
|
||||
}
|
||||
|
||||
function wrapAnd(children: LogicNode[], meta: LogicNode['ichimokuSituationPair']): LogicNode {
|
||||
return { id: genId(), type: 'AND', ichimokuSituationPair: meta, children };
|
||||
}
|
||||
|
||||
function wrapOr(children: LogicNode[], meta: LogicNode['ichimokuSituationPair']): LogicNode {
|
||||
return { id: genId(), type: 'OR', ichimokuSituationPair: meta, children };
|
||||
}
|
||||
|
||||
type Builder = (def: IndicatorPeriodDef) => LogicNode;
|
||||
|
||||
const BUILDERS: Record<IchimokuSituationId, Partial<Record<'buy' | 'sell', Builder>>> = {
|
||||
GOLDEN_CROSS: {
|
||||
buy: def => wrapAnd([
|
||||
makeIch(def, 'CROSS_UP', 'CONVERSION_LINE', 'BASE_LINE'),
|
||||
], pairMeta('GOLDEN_CROSS', 'buy')),
|
||||
},
|
||||
BASE_BREAKUP: {
|
||||
buy: def => wrapAnd([
|
||||
makeIch(def, 'CROSS_UP', 'CLOSE_PRICE', 'BASE_LINE'),
|
||||
], pairMeta('BASE_BREAKUP', 'buy')),
|
||||
},
|
||||
CLOUD_BREAKUP: {
|
||||
buy: def => wrapAnd([
|
||||
makeIch(def, 'CLOUD_BREAK_UP', 'CLOSE_PRICE', 'NONE'),
|
||||
], pairMeta('CLOUD_BREAKUP', 'buy')),
|
||||
},
|
||||
LAGGING_BULL: {
|
||||
buy: def => wrapAnd([
|
||||
makeIch(def, 'LAGGING_GT_PRICE', 'LAGGING_SPAN', 'CLOSE_PRICE'),
|
||||
], pairMeta('LAGGING_BULL', 'buy')),
|
||||
},
|
||||
CLOUD_SUPPORT: {
|
||||
buy: def => wrapAnd([
|
||||
makeIch(def, 'GT', 'CLOSE_PRICE', 'LEADING_SPAN1'),
|
||||
makeIch(def, 'GT', 'CLOSE_PRICE', 'BASE_LINE'),
|
||||
], pairMeta('CLOUD_SUPPORT', 'buy')),
|
||||
},
|
||||
HOJEON: {
|
||||
buy: def => wrapAnd([
|
||||
makeIch(def, 'GT', 'CONVERSION_LINE', 'BASE_LINE'),
|
||||
makeIch(def, 'ABOVE_CLOUD', 'CLOSE_PRICE', 'NONE'),
|
||||
makeIch(def, 'SPAN1_GT_SPAN2', 'LEADING_SPAN1', 'LEADING_SPAN2'),
|
||||
makeIch(def, 'LAGGING_GT_PRICE', 'LAGGING_SPAN', 'CLOSE_PRICE'),
|
||||
], pairMeta('HOJEON', 'buy')),
|
||||
},
|
||||
DEAD_CROSS: {
|
||||
sell: def => wrapOr([
|
||||
makeIch(def, 'CROSS_DOWN', 'CONVERSION_LINE', 'BASE_LINE'),
|
||||
], pairMeta('DEAD_CROSS', 'sell')),
|
||||
},
|
||||
BASE_BREAKDOWN: {
|
||||
sell: def => wrapOr([
|
||||
makeIch(def, 'CROSS_DOWN', 'CLOSE_PRICE', 'BASE_LINE'),
|
||||
], pairMeta('BASE_BREAKDOWN', 'sell')),
|
||||
},
|
||||
CLOUD_BREAKDOWN: {
|
||||
sell: def => wrapOr([
|
||||
makeIch(def, 'CLOUD_BREAK_DOWN', 'CLOSE_PRICE', 'NONE'),
|
||||
], pairMeta('CLOUD_BREAKDOWN', 'sell')),
|
||||
},
|
||||
LAGGING_BEAR: {
|
||||
sell: def => wrapOr([
|
||||
makeIch(def, 'LAGGING_LT_PRICE', 'LAGGING_SPAN', 'CLOSE_PRICE'),
|
||||
], pairMeta('LAGGING_BEAR', 'sell')),
|
||||
},
|
||||
CLOUD_RESISTANCE: {
|
||||
sell: def => wrapAnd([
|
||||
makeIch(def, 'LT', 'CLOSE_PRICE', 'LEADING_SPAN1'),
|
||||
makeIch(def, 'LT', 'CLOSE_PRICE', 'BASE_LINE'),
|
||||
], pairMeta('CLOUD_RESISTANCE', 'sell')),
|
||||
},
|
||||
SANYAKU_REVERSE: {
|
||||
sell: def => wrapAnd([
|
||||
makeIch(def, 'LT', 'CONVERSION_LINE', 'BASE_LINE'),
|
||||
makeIch(def, 'BELOW_CLOUD', 'CLOSE_PRICE', 'NONE'),
|
||||
makeIch(def, 'LAGGING_LT_PRICE', 'LAGGING_SPAN', 'CLOSE_PRICE'),
|
||||
], pairMeta('SANYAKU_REVERSE', 'sell')),
|
||||
},
|
||||
GYEOKJEON: {
|
||||
sell: def => wrapAnd([
|
||||
makeIch(def, 'LT', 'CONVERSION_LINE', 'BASE_LINE'),
|
||||
makeIch(def, 'BELOW_CLOUD', 'CLOSE_PRICE', 'NONE'),
|
||||
makeIch(def, 'SPAN1_LT_SPAN2', 'LEADING_SPAN1', 'LEADING_SPAN2'),
|
||||
makeIch(def, 'LAGGING_LT_PRICE', 'LAGGING_SPAN', 'CLOSE_PRICE'),
|
||||
], pairMeta('GYEOKJEON', 'sell')),
|
||||
},
|
||||
EW1: {
|
||||
buy: def => wrapAnd([
|
||||
makeIch(def, 'CROSS_UP', 'CLOSE_PRICE', 'BASE_LINE'),
|
||||
makeIch(def, 'GT', 'CONVERSION_LINE', 'BASE_LINE'),
|
||||
], pairMeta('EW1', 'buy')),
|
||||
},
|
||||
EW2: {
|
||||
buy: def => wrapAnd([
|
||||
makeIch(def, 'GT', 'CLOSE_PRICE', 'BASE_LINE'),
|
||||
makeIch(def, 'GT', 'CLOSE_PRICE', 'LEADING_SPAN2'),
|
||||
makeIch(def, 'GT', 'CONVERSION_LINE', 'BASE_LINE'),
|
||||
], pairMeta('EW2', 'buy')),
|
||||
sell: def => wrapOr([
|
||||
makeIch(def, 'CROSS_DOWN', 'CLOSE_PRICE', 'BASE_LINE'),
|
||||
makeIch(def, 'CLOUD_BREAK_DOWN', 'CLOSE_PRICE', 'NONE'),
|
||||
], pairMeta('EW2', 'sell')),
|
||||
},
|
||||
EW3: {
|
||||
buy: def => wrapAnd([
|
||||
makeIch(def, 'GT', 'CONVERSION_LINE', 'BASE_LINE'),
|
||||
makeIch(def, 'ABOVE_CLOUD', 'CLOSE_PRICE', 'NONE'),
|
||||
makeIch(def, 'LAGGING_GT_PRICE', 'LAGGING_SPAN', 'CLOSE_PRICE'),
|
||||
makeIch(def, 'SPAN1_GT_SPAN2', 'LEADING_SPAN1', 'LEADING_SPAN2'),
|
||||
], pairMeta('EW3', 'buy')),
|
||||
},
|
||||
EW4: {
|
||||
buy: def => wrapAnd([
|
||||
makeIch(def, 'GT', 'CLOSE_PRICE', 'LEADING_SPAN1'),
|
||||
makeIch(def, 'GT', 'CONVERSION_LINE', 'BASE_LINE'),
|
||||
], pairMeta('EW4', 'buy')),
|
||||
sell: def => wrapOr([
|
||||
makeIch(def, 'CROSS_DOWN', 'CLOSE_PRICE', 'BASE_LINE'),
|
||||
makeIch(def, 'CLOUD_BREAK_DOWN', 'CLOSE_PRICE', 'NONE'),
|
||||
], pairMeta('EW4', 'sell')),
|
||||
},
|
||||
EW5: {
|
||||
sell: def => wrapOr([
|
||||
makeIch(def, 'CROSS_DOWN', 'CLOSE_PRICE', 'CONVERSION_LINE'),
|
||||
makeIch(def, 'CROSS_DOWN', 'CONVERSION_LINE', 'BASE_LINE'),
|
||||
makeIch(def, 'CLOUD_BREAK_DOWN', 'CLOSE_PRICE', 'NONE'),
|
||||
], pairMeta('EW5', 'sell')),
|
||||
},
|
||||
EW_A: {
|
||||
sell: def => wrapOr([
|
||||
makeIch(def, 'CROSS_DOWN', 'CLOSE_PRICE', 'BASE_LINE'),
|
||||
makeIch(def, 'CROSS_DOWN', 'CONVERSION_LINE', 'BASE_LINE'),
|
||||
], pairMeta('EW_A', 'sell')),
|
||||
},
|
||||
EW_B: {
|
||||
sell: def => wrapAnd([
|
||||
makeIch(def, 'LT', 'CLOSE_PRICE', 'BASE_LINE'),
|
||||
makeIch(def, 'BELOW_CLOUD', 'CLOSE_PRICE', 'NONE'),
|
||||
makeIch(def, 'LT', 'CONVERSION_LINE', 'BASE_LINE'),
|
||||
], pairMeta('EW_B', 'sell')),
|
||||
},
|
||||
EW_C: {
|
||||
sell: def => wrapAnd([
|
||||
makeIch(def, 'CLOUD_BREAK_DOWN', 'CLOSE_PRICE', 'NONE'),
|
||||
makeIch(def, 'BELOW_CLOUD', 'CLOSE_PRICE', 'NONE'),
|
||||
makeIch(def, 'LT', 'CONVERSION_LINE', 'BASE_LINE'),
|
||||
makeIch(def, 'LAGGING_LT_PRICE', 'LAGGING_SPAN', 'CLOSE_PRICE'),
|
||||
], pairMeta('EW_C', 'sell')),
|
||||
},
|
||||
};
|
||||
|
||||
export function ichimokuSituationMetaFromValue(value: string): { situationId: IchimokuSituationId; mode: 'buy' | 'sell' } | null {
|
||||
return VALUE_TO_META[value] ?? null;
|
||||
}
|
||||
|
||||
export function buildIchimokuSituationTree(value: string, def: IndicatorPeriodDef): LogicNode | null {
|
||||
const meta = ichimokuSituationMetaFromValue(value);
|
||||
if (!meta) return null;
|
||||
const builder = BUILDERS[meta.situationId][meta.mode];
|
||||
return builder ? builder(def) : null;
|
||||
}
|
||||
|
||||
export function ichimokuSituationDisplayName(situationId: IchimokuSituationId, mode: 'buy' | 'sell'): string {
|
||||
const item = ICHIMOKU_SITUATION_PALETTE_ITEMS.find(
|
||||
i => i.situationId === situationId && i.mode === mode,
|
||||
);
|
||||
return item?.label ?? `${situationId} ${mode === 'buy' ? '매수' : '매도'}`;
|
||||
}
|
||||
|
||||
export function ichimokuSituationPaletteDesc(value: string): string {
|
||||
return ICHIMOKU_SITUATION_PALETTE_ITEMS.find(i => i.value === value)?.desc ?? '';
|
||||
}
|
||||
|
||||
const COND_LABEL: Record<string, string> = {
|
||||
CROSS_UP: '상향돌파', CROSS_DOWN: '하향돌파',
|
||||
GT: '>', LT: '<',
|
||||
ABOVE_CLOUD: '구름 위', BELOW_CLOUD: '구름 아래',
|
||||
CLOUD_BREAK_UP: '구름 상향돌파', CLOUD_BREAK_DOWN: '구름 하향이탈',
|
||||
SPAN1_GT_SPAN2: '양운', SPAN1_LT_SPAN2: '음운',
|
||||
LAGGING_GT_PRICE: '후행>26봉전 종가', LAGGING_LT_PRICE: '후행<26봉전 종가',
|
||||
};
|
||||
|
||||
function fmtNode(n: LogicNode): string {
|
||||
if (n.type === 'CONDITION' && n.condition) {
|
||||
const c = n.condition;
|
||||
const op = COND_LABEL[c.conditionType] ?? c.conditionType;
|
||||
return `${c.leftField} ${op} ${c.rightField ?? ''}`.trim();
|
||||
}
|
||||
if (n.type === 'AND' || n.type === 'OR') {
|
||||
return (n.children ?? []).map(fmtNode).join(` ${n.type} `);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
export function ichimokuSituationSummaryText(
|
||||
situationId: IchimokuSituationId,
|
||||
mode: 'buy' | 'sell',
|
||||
def: IndicatorPeriodDef = {
|
||||
rsiPeriod: 14, cciPeriod: 20, adxPeriod: 14, williamsR: 14,
|
||||
trixPeriod: 12, vrPeriod: 26, psyPeriod: 12, newPsy: 12, investPsy: 12,
|
||||
},
|
||||
): string {
|
||||
const tree = BUILDERS[situationId][mode]?.(def);
|
||||
return tree ? fmtNode(tree) : '';
|
||||
}
|
||||
|
||||
export function ichimokuSituationCategoryLabel(cat: IchimokuSituationCategory): string {
|
||||
switch (cat) {
|
||||
case 'basic': return '기본';
|
||||
case 'alignment': return '호전·역전';
|
||||
case 'elliott': return '엘리어트';
|
||||
}
|
||||
}
|
||||
@@ -63,6 +63,14 @@ import {
|
||||
stableStrategyFilterLevelLabel,
|
||||
type StableStrategyId,
|
||||
} from '../utils/stableStrategyPairs';
|
||||
import {
|
||||
buildIchimokuSituationTree,
|
||||
isIchimokuSituationPairRoot,
|
||||
isIchimokuSituationPaletteValue,
|
||||
ichimokuSituationDisplayName,
|
||||
ichimokuSituationSummaryText,
|
||||
type IchimokuSituationId,
|
||||
} from '../utils/ichimokuSituationStrategy';
|
||||
import {
|
||||
buildPriceExtremeBreakoutTree,
|
||||
isPriceExtremeBreakoutPairPaletteValue,
|
||||
@@ -1015,6 +1023,10 @@ export const nodeToText = (node: LogicNode, DEF: DefType = DEF_DEFAULTS): string
|
||||
const cfg = inferIchimokuBbConfig(node);
|
||||
return `${ichimokuBbDisplayName(cfg.mode, cfg.chikouDisplacement)}\n${ichimokuBbSummaryText(cfg)}`;
|
||||
}
|
||||
if (isIchimokuSituationPairRoot(node) && node.ichimokuSituationPair) {
|
||||
const { situationId, mode } = node.ichimokuSituationPair;
|
||||
return `${ichimokuSituationDisplayName(situationId as IchimokuSituationId, mode)}\n${ichimokuSituationSummaryText(situationId as IchimokuSituationId, mode, DEF)}`;
|
||||
}
|
||||
if (isPriceExtremeBreakoutPairRoot(node) && node.priceExtremePair) {
|
||||
const { mode, shortPeriod, longPeriod } = node.priceExtremePair;
|
||||
const level = inferPriceExtremeFilterLevel(node);
|
||||
@@ -1038,6 +1050,10 @@ export const nodeToText = (node: LogicNode, DEF: DefType = DEF_DEFAULTS): string
|
||||
const cfg = inferIchimokuBbConfig(node);
|
||||
return `${ichimokuBbDisplayName(cfg.mode, cfg.chikouDisplacement)}\n${ichimokuBbSummaryText(cfg)}`;
|
||||
}
|
||||
if (isIchimokuSituationPairRoot(node) && node.ichimokuSituationPair) {
|
||||
const { situationId, mode } = node.ichimokuSituationPair;
|
||||
return `${ichimokuSituationDisplayName(situationId as IchimokuSituationId, mode)}\n${ichimokuSituationSummaryText(situationId as IchimokuSituationId, mode, DEF)}`;
|
||||
}
|
||||
if (isStochOverboughtPairRoot(node)) {
|
||||
const sec = node.stochPair!.secondaryIndicatorType;
|
||||
return `${stochPairDisplayName(sec)}\n${stochPairSummaryText(sec)}`;
|
||||
@@ -1565,6 +1581,8 @@ export type MakeNodeOptions = {
|
||||
ichimokuBb?: boolean;
|
||||
/** 추천 안정형 전략 복합 */
|
||||
stableStrategy?: boolean;
|
||||
/** 일목균형표 상황별·엘리어트 복합 */
|
||||
ichimokuSituation?: boolean;
|
||||
};
|
||||
|
||||
/** 팔레트 드래그 payload → makeNode 옵션 */
|
||||
@@ -1575,6 +1593,7 @@ export function makeNodeOptionsFromPalette(data: {
|
||||
inflection33?: boolean;
|
||||
ichimokuBb?: boolean;
|
||||
stableStrategy?: boolean;
|
||||
ichimokuSituation?: boolean;
|
||||
secondaryIndicator?: string;
|
||||
period?: number;
|
||||
shortPeriod?: number;
|
||||
@@ -1601,6 +1620,9 @@ export function makeNodeOptionsFromPalette(data: {
|
||||
if (data.stableStrategy || (data.value && isStableStrategyPaletteValue(data.value))) {
|
||||
return { stableStrategy: true };
|
||||
}
|
||||
if (data.ichimokuSituation || (data.value && isIchimokuSituationPaletteValue(data.value))) {
|
||||
return { ichimokuSituation: true };
|
||||
}
|
||||
if (data.composite) {
|
||||
return {
|
||||
composite: true,
|
||||
@@ -1638,6 +1660,10 @@ export const makeNode = (
|
||||
const tree = buildStableStrategyTree(value, DEF);
|
||||
if (tree) return tree;
|
||||
}
|
||||
if (options?.ichimokuSituation || isIchimokuSituationPaletteValue(value)) {
|
||||
const tree = buildIchimokuSituationTree(value, DEF);
|
||||
if (tree) return tree;
|
||||
}
|
||||
if (options?.composite) {
|
||||
let condition = makeCompositeCondition(value, signalType, DEF);
|
||||
condition = {
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
isNewLow920SellPaletteValue,
|
||||
} from './priceExtremeBreakoutPair';
|
||||
import { STABLE_STRATEGY_PALETTE_ITEMS } from './stableStrategyPairs';
|
||||
import { ichimokuSituationMetaFromValue } from './ichimokuSituationStrategy';
|
||||
|
||||
export type TemplatePaletteSource =
|
||||
| 'user'
|
||||
@@ -50,6 +51,8 @@ export function inferCompositePaletteSignal(item: PaletteItem): 'buy' | 'sell' {
|
||||
}
|
||||
const stable = STABLE_STRATEGY_PALETTE_ITEMS.find(s => s.value === item.value);
|
||||
if (stable) return stable.mode;
|
||||
const ichimokuSit = ichimokuSituationMetaFromValue(item.value);
|
||||
if (ichimokuSit) return ichimokuSit.mode;
|
||||
if (item.value.endsWith('_BUY')) return 'buy';
|
||||
if (item.value.endsWith('_SELL')) return 'sell';
|
||||
return 'buy';
|
||||
|
||||
@@ -26,6 +26,10 @@ import {
|
||||
buildStableStrategyTree,
|
||||
isStableStrategyPaletteValue,
|
||||
} from './stableStrategyPairs';
|
||||
import {
|
||||
buildIchimokuSituationTree,
|
||||
isIchimokuSituationPaletteValue,
|
||||
} from './ichimokuSituationStrategy';
|
||||
import {
|
||||
buildSidewaysFilterNode,
|
||||
loadSidewaysPaletteItems,
|
||||
@@ -71,18 +75,21 @@ function buildLogicNodeFromPaletteItem(
|
||||
const inflection33 = isInflection33PaletteValue(item.value);
|
||||
const ichimokuBb = isIchimokuBbPaletteValue(item.value);
|
||||
const stableStrategy = isStableStrategyPaletteValue(item.value);
|
||||
const ichimokuSituation = isIchimokuSituationPaletteValue(item.value);
|
||||
const composite = item.kind === 'composite'
|
||||
&& !stochPair
|
||||
&& !priceExtremeBreakout
|
||||
&& !inflection33
|
||||
&& !ichimokuBb
|
||||
&& !stableStrategy;
|
||||
&& !stableStrategy
|
||||
&& !ichimokuSituation;
|
||||
|
||||
if (stochPair) return buildStochOverboughtPairTree(item.secondaryIndicator ?? 'CCI', def);
|
||||
if (priceExtremeBreakout) return buildPriceExtremeBreakoutTree(item.value, def);
|
||||
if (inflection33) return buildInflection33Tree(item.value, def);
|
||||
if (ichimokuBb) return buildIchimokuBbTree(item.value, def);
|
||||
if (stableStrategy) return buildStableStrategyTree(item.value, def);
|
||||
if (ichimokuSituation) return buildIchimokuSituationTree(item.value, def);
|
||||
return makeNode('indicator', item.value, signalTab, def, composite ? { composite: true } : undefined);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,9 @@ import {
|
||||
import {
|
||||
STABLE_STRATEGY_PALETTE_ITEMS,
|
||||
} from './stableStrategyPairs';
|
||||
import {
|
||||
ICHIMOKU_SITUATION_PALETTE_ITEMS,
|
||||
} from './ichimokuSituationStrategy';
|
||||
import {
|
||||
NEW_HIGH_9_20_BUY_VALUE,
|
||||
NEW_LOW_9_20_SELL_VALUE,
|
||||
@@ -125,6 +128,12 @@ export const DEFAULT_COMPOSITE_ITEMS: Omit<PaletteItem, 'id' | 'kind'>[] = [
|
||||
builtIn: true,
|
||||
period: 26,
|
||||
},
|
||||
...ICHIMOKU_SITUATION_PALETTE_ITEMS.map(i => ({
|
||||
value: i.value,
|
||||
label: i.label,
|
||||
desc: `[${i.category === 'basic' ? '기본' : i.category === 'alignment' ? '호전·역전' : '엘리어트'}] ${i.desc}`,
|
||||
builtIn: true,
|
||||
})),
|
||||
...STABLE_STRATEGY_PALETTE_ITEMS.map(i => ({
|
||||
value: i.value,
|
||||
label: i.label,
|
||||
|
||||
@@ -80,6 +80,11 @@ export interface LogicNode {
|
||||
bbBand: 'UPPER_BAND' | 'MIDDLE_BAND' | 'LOWER_BAND';
|
||||
conditionType: 'CROSS_UP' | 'CROSS_DOWN' | 'GT' | 'LT';
|
||||
};
|
||||
/** 일목균형표 상황별·엘리어트 파동 복합 — @see 일목균형표 전략.md */
|
||||
ichimokuSituationPair?: {
|
||||
situationId: string;
|
||||
mode: 'buy' | 'sell';
|
||||
};
|
||||
}
|
||||
|
||||
export interface StrategyDSLDto {
|
||||
|
||||
Generated
+2680
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,56 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
export default {
|
||||
content: ['./index.html', './src/**/*.{js,jsx}'],
|
||||
darkMode: 'class',
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
trust: {
|
||||
DEFAULT: '#0047AB',
|
||||
50: '#E8F0FA',
|
||||
100: '#C5D9F2',
|
||||
600: '#0047AB',
|
||||
700: '#003A8C',
|
||||
800: '#002D6D',
|
||||
},
|
||||
safety: {
|
||||
DEFAULT: '#28A745',
|
||||
50: '#E8F5EC',
|
||||
600: '#28A745',
|
||||
700: '#1E7E34',
|
||||
},
|
||||
emergency: {
|
||||
red: '#DC3545',
|
||||
orange: '#FD7E14',
|
||||
},
|
||||
},
|
||||
fontFamily: {
|
||||
sans: ['Pretendard', '-apple-system', 'BlinkMacSystemFont', 'system-ui', 'sans-serif'],
|
||||
},
|
||||
boxShadow: {
|
||||
card: '0 2px 12px rgba(0, 71, 171, 0.08)',
|
||||
'card-dark': '0 2px 16px rgba(0, 0, 0, 0.35)',
|
||||
},
|
||||
animation: {
|
||||
'fade-in': 'fadeIn 0.35s ease-out',
|
||||
'slide-up': 'slideUp 0.35s ease-out',
|
||||
wave: 'wave 1.2s ease-in-out infinite',
|
||||
},
|
||||
keyframes: {
|
||||
fadeIn: {
|
||||
'0%': { opacity: '0' },
|
||||
'100%': { opacity: '1' },
|
||||
},
|
||||
slideUp: {
|
||||
'0%': { opacity: '0', transform: 'translateY(12px)' },
|
||||
'100%': { opacity: '1', transform: 'translateY(0)' },
|
||||
},
|
||||
wave: {
|
||||
'0%, 100%': { transform: 'scaleY(0.4)' },
|
||||
'50%': { transform: 'scaleY(1)' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
};
|
||||
+397
@@ -0,0 +1,397 @@
|
||||
# 일목균형표(Ichimoku Kinko Hyo) 전략 — 구성 요소·매매 로직·엘리어트 파동 연계
|
||||
|
||||
goldenChart **투자전략 DSL**의 `ICHIMOKU` 지표 조건과 연동하여, 일목균형표의 시간·가격 균형 관계와 엘리어트 파동(Elliott Wave) 단계별 전략 조건을 정리한 문서입니다.
|
||||
|
||||
> **관련 문서:** [매매전략조건.md](./매매전략조건.md) · [전략편집기 로직 및 동작흐름.md](./전략편집기%20로직%20및%20동작흐름.md)
|
||||
> **내장 템플릿:** `ICHIMOKU_TREND` · `ICHIMOKU_SANYAKU`(삼역호전) · `ICHIMOKU_PERFECT`(5원소)
|
||||
|
||||
---
|
||||
|
||||
## 1. 일목균형표란
|
||||
|
||||
일목균형표는 **과거·현재·미래**의 가격 균형을 한 차트(일목)에 담은 추세·지지·저항 통합 지표입니다.
|
||||
단순 이동평균 교차가 아니라, **선행(구름)·후행(26봉 지연)** 개념으로 시장의 “시간적 균형”을 읽습니다.
|
||||
|
||||
### 1.1 핵심 구성 요소
|
||||
|
||||
| 구성 요소 | DSL 필드 | 계산 (표준 9·26·52) | 시장에서의 역할 |
|
||||
|-----------|----------|---------------------|-----------------|
|
||||
| **전환선** (Conversion Line) | `CONVERSION_LINE` | (9봉 최고+최저) ÷ 2 | 단기 균형점. 주가의 **단기 방향·속도** |
|
||||
| **기준선** (Base Line) | `BASE_LINE` | (26봉 최고+최저) ÷ 2 | 중기 균형점. **추세 그 자체**, 강한 지지·저항 |
|
||||
| **선행스팬 1** (Leading Span 1) | `LEADING_SPAN1` | (전환선+기준선) ÷ 2, **26봉 선행** | 단·중기 평균을 미래로 투영 → **구름 상·하단** |
|
||||
| **선행스팬 2** (Leading Span 2) | `LEADING_SPAN2` | (52봉 최고+최저) ÷ 2, **26봉 선행** | 장기 균형점 → **구름 두께**·매물대 강도 |
|
||||
| **구름대** (Kumo / Cloud) | `LEADING_SPAN1` ↔ `LEADING_SPAN2` | 선행1·2 사이 영역 | 지지(양운) / 저항(음운) **매물·심리 경계** |
|
||||
| **후행스팬** (Lagging Span) | `LAGGING_SPAN` | 현재 종가를 **26봉 후행** 표시 | 현재 vs 26봉 전 종가 비교 → **추세 확정** |
|
||||
|
||||
### 1.2 구성 요소 간 관계 (개념도)
|
||||
|
||||
```text
|
||||
[미래] ← 선행스팬1·2 (26봉 앞)
|
||||
╱╲ 구름대 (Kumo)
|
||||
╱ ╲
|
||||
전환선 ────●────●────●──── (9봉, 가장 민감)
|
||||
기준선 ────────●────●──── (26봉, 추세의 중심)
|
||||
종가 ──────────●──────── (현재)
|
||||
후행 ────────────────●── (종가를 26봉 뒤에 표시)
|
||||
[과거]
|
||||
```
|
||||
|
||||
| 관계 | 의미 | 해석 |
|
||||
|------|------|------|
|
||||
| 전환선 ↔ 기준선 | 단기 vs 중기 균형 | 교차 = **추세 전환 1차 신호** |
|
||||
| 선행1 vs 선행2 | 구름 색·두께 | 선행1>선행2 → **양운**(상승 구름), 반대 → **음운** |
|
||||
| 종가 vs 구름 | 현재가 위치 | 구름 위 = 강세, 아래 = 약세, 내부 = **전환·횡보** |
|
||||
| 후행 vs 26봉 전 종가 | 시간 지연 확인 | 후행이 과거 종가 위 = **상승 추세 확정** |
|
||||
|
||||
### 1.3 호전(정배열) vs 역전(역배열)
|
||||
|
||||
#### 🟩 호전 — 완벽한 상승 추세
|
||||
|
||||
```text
|
||||
종가 > 전환선 > 기준선 > 구름(양운)
|
||||
후행스팬 > 26봉 전 종가
|
||||
(선택) 후행스팬 > 26봉 전 구름
|
||||
```
|
||||
|
||||
| 확인 항목 | DSL 조건 예시 |
|
||||
|-----------|---------------|
|
||||
| 괘(가격선) | `CONVERSION_LINE GT BASE_LINE` |
|
||||
| 주가·구름 | `CLOSE_PRICE ABOVE_CLOUD` |
|
||||
| 구름 성격 | `SPAN1_GT_SPAN2` (양운) |
|
||||
| 후행 확정 | `LAGGING_GT_PRICE` |
|
||||
|
||||
#### 🟥 역전 — 완벽한 하락 추세
|
||||
|
||||
```text
|
||||
종가 < 전환선 < 기준선 < 구름(음운)
|
||||
후행스팬 < 26봉 전 종가
|
||||
```
|
||||
|
||||
| 확인 항목 | DSL 조건 예시 |
|
||||
|-----------|---------------|
|
||||
| 괘 | `CONVERSION_LINE LT BASE_LINE` |
|
||||
| 주가·구름 | `CLOSE_PRICE BELOW_CLOUD` |
|
||||
| 구름 성격 | `SPAN1_LT_SPAN2` (음운) |
|
||||
| 후행 확정 | `LAGGING_LT_PRICE` |
|
||||
|
||||
---
|
||||
|
||||
## 2. 상황별 기본 매수·매도 판단 로직
|
||||
|
||||
### 2.1 매수(Long) 타이밍
|
||||
|
||||
| # | 상황 | 판단 근거 | DSL 조건 (예) | 강도 |
|
||||
|---|------|-----------|---------------|------|
|
||||
| L1 | **골든크로스(호전)** | 전환선이 기준선 상향 돌파 | `CONVERSION_LINE CROSS_UP BASE_LINE` | ★★★ |
|
||||
| L2 | **기준선 돌파** | 중기 추세 전환 | `CLOSE_PRICE CROSS_UP BASE_LINE` | ★★★ |
|
||||
| L3 | **구름 돌파** | 매물대·심리 저항 돌파 | `CLOUD_BREAK_UP` | ★★★★ |
|
||||
| L4 | **후행 호전** | 26봉 전 대비 추세 확정 | `LAGGING_GT_PRICE` (또는 `CROSS_UP`) | ★★★★ |
|
||||
| L5 | **구름 지지** | 양운 상단·기준선에서 반등 | `CLOSE_PRICE GT LEADING_SPAN1` + `GT BASE_LINE` | ★★ |
|
||||
| L6 | **삼역호전** | ①괘 ②구름 ③후행 동시 | 아래 §3.3 참조 | ★★★★★ |
|
||||
|
||||
**매수 시 주의**
|
||||
|
||||
- 구름 **내부**(`IN_CLOUD`)에서는 신호 빈도↑·신뢰도↓ → 필터(거래량·ADX) 권장.
|
||||
- `CROSS_*` 조건은 **해당 봉 1회**만 true → 연속 보유는 `GT`/`ABOVE_CLOUD` 등 **상태 조건** 병행.
|
||||
|
||||
### 2.2 매도(Short / 청산) 타이밍
|
||||
|
||||
| # | 상황 | 판단 근거 | DSL 조건 (예) | 강도 |
|
||||
|---|------|-----------|---------------|------|
|
||||
| S1 | **데드크로스(역전)** | 전환선 기준선 하향 이탈 | `CONVERSION_LINE CROSS_DOWN BASE_LINE` | ★★★ |
|
||||
| S2 | **기준선 이탈** | 중기 추세 붕괴 | `CLOSE_PRICE CROSS_DOWN BASE_LINE` | ★★★ |
|
||||
| S3 | **구름 이탈** | 지지 붕괴 | `CLOUD_BREAK_DOWN` | ★★★★ |
|
||||
| S4 | **후행 역전** | 하락 추세 확정 | `LAGGING_LT_PRICE` | ★★★★ |
|
||||
| S5 | **구름 저항** | 음운 하단·기준선에서 반락 | `CLOSE_PRICE LT LEADING_SPAN1` + `LT BASE_LINE` | ★★ |
|
||||
| S6 | **삼역역전** | ①데드 ②구름하 ③후행하 | §3.3 역방향 | ★★★★★ |
|
||||
|
||||
**매도(청산) 설계 팁**
|
||||
|
||||
- 추세 추종: `OR(데드크로스, 종가<전환선, 구름하향돌파)` — **연속 매도 방지**.
|
||||
- 익절: 5파·과열 구간에서는 전환선 이탈만으로도 1차 청산 신호로 사용.
|
||||
|
||||
### 2.3 구름·선행스팬 해석 요약
|
||||
|
||||
| 구름 상태 | 선행1 vs 선행2 | 종가 위치 | 일반적 해석 |
|
||||
|-----------|----------------|-----------|-------------|
|
||||
| **양운** | 선행1 > 선행2 | 종가 > 구름 | 상승 추세, 구름 = **지지** |
|
||||
| **음운** | 선행1 < 선행2 | 종가 < 구름 | 하락 추세, 구름 = **저항** |
|
||||
| **얇은 구름** | 두 선행 간격 좁음 | 돌파 직후 | 변곡·추세 전환 **임박** |
|
||||
| **두꺼운 구름** | 두 선행 간격 넓음 | 구름 안·근처 | **강한 매물대**, 돌파 난이도↑ |
|
||||
|
||||
---
|
||||
|
||||
## 3. 삼역호전 / 삼역역전 — 핵심 복합 신호
|
||||
|
||||
### 3.1 삼역호전 (三役好轉) — 강력 매수
|
||||
|
||||
| 역(役) | 일목 요소 | 조건 |
|
||||
|--------|-----------|------|
|
||||
| **괘** | 전환·기준 | 전환선 > 기준선 (또는 골든크로스) |
|
||||
| **주가** | 종가·구름 | 종가 > 구름 (`ABOVE_CLOUD` / `CLOUD_BREAK_UP`) |
|
||||
| **후행** | 후행·과거 종가 | 후행 > 26봉 전 종가 (`LAGGING_GT_PRICE`) |
|
||||
|
||||
**goldenChart 템플릿:** `ICHIMOKU_SANYAKU` — 구름 돌파(현재 봉) + 단계별 필터(N봉 EXISTS_IN).
|
||||
|
||||
### 3.2 삼역역전 — 강력 매도·대피
|
||||
|
||||
| 역 | 조건 |
|
||||
|----|------|
|
||||
| 괘 | 전환선 < 기준선 (데드크로스) |
|
||||
| 주가 | 종가 < 구름 (`BELOW_CLOUD` / `CLOUD_BREAK_DOWN`) |
|
||||
| 후행 | 후행 < 26봉 전 종가 (`LAGGING_LT_PRICE`) |
|
||||
|
||||
### 3.3 5원소 입체 매매 (Perfect Ichimoku)
|
||||
|
||||
괘 · 주가 · 구름(양/음운) · 후행 **4중 AND** — ta4j `PerfectIchimokuStrategy` 동형.
|
||||
|
||||
**goldenChart 템플릿:** `ICHIMOKU_PERFECT` (필터 강도에 따라 2~4조건).
|
||||
|
||||
---
|
||||
|
||||
## 4. 엘리어트 파동 × 일목균형표 — 단계별 전략 조건
|
||||
|
||||
엘리어트 파동의 **추세 전개**와 일목의 **선행·후행 시간 구조**를 결합하면, 파동 단계별 진입·청산 근거를 명확히 할 수 있습니다.
|
||||
|
||||
> **전제:** 아래 “파동”은 **추정**이며, 실전에서는 상위·하위 시간대 일목을 함께 봅니다.
|
||||
> 조건은 goldenChart DSL로 표현 가능한 형태로 기술합니다.
|
||||
|
||||
---
|
||||
|
||||
### 4.1 1파 — 상승 시동 (추세 전환 시작)
|
||||
|
||||
| 항목 | 내용 |
|
||||
|------|------|
|
||||
| **파동 특징** | 장기 하락 종료 후 첫 반등. 바닥 예측 난이도 **최고** |
|
||||
| **일목 상태** | 하락하던 전환·기준선을 **순차 돌파** 시작. 위에는 **두터운 음운**이 여전히 존재 |
|
||||
| **관계** | 종가 ≈ 전환선 근처, 기준선 **미돌파 또는 돌파 직후**, 구름 **아래·내부** |
|
||||
|
||||
**전략 조건**
|
||||
|
||||
| 구분 | 조건 | DSL 예시 |
|
||||
|------|------|----------|
|
||||
| 공격적 매수 | 기준선 상향 돌파 | `CLOSE_PRICE CROSS_UP BASE_LINE` |
|
||||
| 보조 확인 | 전환 > 기준 | `CONVERSION_LINE GT BASE_LINE` |
|
||||
| 필터(권장) | 아직 구름 아래면 **소액·분할** | `NOT ABOVE_CLOUD` → 포지션 축소 |
|
||||
| 매도/관망 | 음운 하단 저항 | `CLOSE_PRICE LT LEADING_SPAN2` 유지 시 추가 매수 자제 |
|
||||
|
||||
**판단:** 삼역호전 **미충족** → `ICHIMOKU_TREND`(골든크로스) 수준만 허용, `SANYAKU`/`PERFECT`는 **대기**.
|
||||
|
||||
---
|
||||
|
||||
### 4.2 2파 — 첫 번째 조정 (눌림목)
|
||||
|
||||
| 항목 | 내용 |
|
||||
|------|------|
|
||||
| **파동 특징** | 1파 되돌림(종종 50~61.8%). **마지막 저가 테스트** |
|
||||
| **일목 상태** | 주가 재하락하나 **선행2(구름 하단)·과거 바닥** 미이탈. 전환·기준 **수평 방어** |
|
||||
| **관계** | 종가 > 기준선 또는 구름 하단(선행2) **지지** |
|
||||
|
||||
**전략 조건**
|
||||
|
||||
| 구분 | 조건 | DSL 예시 |
|
||||
|------|------|----------|
|
||||
| **1차 적극 매수** | 기준선·구름 하단 지지 후 반등 | `CLOSE_PRICE GT BASE_LINE` AND `CLOSE_PRICE GT LEADING_SPAN2` |
|
||||
| 확인 | 전환 > 기준 유지 | `CONVERSION_LINE GT BASE_LINE` |
|
||||
| 손절 | 기준선·선행2 동시 이탈 | `CLOSE_PRICE CROSS_DOWN BASE_LINE` OR `CLOUD_BREAK_DOWN` |
|
||||
| 금지 | 후행 아직 미호전 | `LAGGING_LT_PRICE` 지속 시 **풀매수 금지** |
|
||||
|
||||
**판단:** **2파 끝 = 기준선/양운 상단 지지** → 3파 전 **핵심 분할 매수 구간**.
|
||||
|
||||
---
|
||||
|
||||
### 4.3 3파 — 본격 상승 (핵심 수익 구간)
|
||||
|
||||
| 항목 | 내용 |
|
||||
|------|------|
|
||||
| **파동 특징** | 거래량·길이 **최대**. 추세 추종 수익 **극대화** 구간 |
|
||||
| **일목 상태** | **삼역호전 완성**. 얇은 구름 돌파 → 앞선 **두터운 양운** |
|
||||
| **관계** | 종가 > 전환 > 기준 > 구름, 후행 > 26봉 전 종가·구름 |
|
||||
|
||||
**전략 조건 (삼역호전 = 3파 확인)**
|
||||
|
||||
```text
|
||||
AND(
|
||||
CONVERSION_LINE GT BASE_LINE, /* 괘 */
|
||||
CLOSE_PRICE ABOVE_CLOUD, /* 주가 — 또는 CLOUD_BREAK_UP */
|
||||
LAGGING_GT_PRICE, /* 후행 */
|
||||
SPAN1_GT_SPAN2 /* 양운 (선택) */
|
||||
)
|
||||
```
|
||||
|
||||
| 구분 | 전략 |
|
||||
|------|------|
|
||||
| **매수** | 삼역호전 충족 시 **추가 매수·불타기** (`ICHIMOKU_SANYAKU` / `PERFECT`) |
|
||||
| **보유** | 종가 > **전환선** 유지 → **매도 금지** (추세 타기) |
|
||||
| **청산 경고** | 전환선 이탈 **전**까지 보유 극대화 |
|
||||
| **손절** | `CLOUD_BREAK_DOWN` 또는 `CONVERSION_LINE CROSS_DOWN BASE_LINE` |
|
||||
|
||||
**판단:** �lliott **3파 ≈ 일목 삼역호전** — 시스템상 **가장 신뢰도 높은 롱 구간**.
|
||||
|
||||
---
|
||||
|
||||
### 4.4 4파 — 조정 (복잡한 횡보)
|
||||
|
||||
| 항목 | 내용 |
|
||||
|------|------|
|
||||
| **파동 특징** | 삼각형·횡보. 변동성↑, 방향성 혼란 |
|
||||
| **일목 상태** | 급등 후 **기준선 지지 테스트**. 일시 **구름 내부** 진입 가능 |
|
||||
| **관계** | 종가 ≈ 기준선 · 선행1(구름 상단). 전환·기준 **수렴** |
|
||||
|
||||
**전략 조건**
|
||||
|
||||
| 구분 | 조건 | DSL 예시 |
|
||||
|------|------|----------|
|
||||
| 일부 익절 | 기준선 이탈 | `CLOSE_PRICE CROSS_DOWN BASE_LINE` |
|
||||
| 재매수 | 구름 **상단(선행1)** 지지 | `CLOSE_PRICE GT LEADING_SPAN1` AND `IN_CLOUD` 또는 `ABOVE_CLOUD` 회복 |
|
||||
| 관망 | 구름 내부 장기 체류 | `IN_CLOUD` + `HOLD_N_DAYS` → 방향 재확인 전 **신규 진입 자제** |
|
||||
| 손절 | 구름 하단 이탈 | `CLOUD_BREAK_DOWN` |
|
||||
|
||||
**판단:** **단기 매매** 구간. 추세 추종은 포지션 **축소**, 스윙만 선행1·기준선 지지에서 재진입.
|
||||
|
||||
---
|
||||
|
||||
### 4.5 5파 — 마지막 상승 (과열·분산 매도)
|
||||
|
||||
| 항목 | 내용 |
|
||||
|------|------|
|
||||
| **파동 특징** | 신고가 갱신 but **모멘텀 둔화**. 대중 **후행 참여** |
|
||||
| **일목 상태** | 종가·전환·기준 **이격 과대**. 후행은 위에 있으나 **꺾임** 조짐. 구름 **얇아짐** |
|
||||
| **관계** | `DIFF_GT(종가, 전환선)` 과열 · `SPAN1`/`SPAN2` 간격 축소 |
|
||||
|
||||
**전략 조건**
|
||||
|
||||
| 구분 | 조건 | 전략 |
|
||||
|------|------|------|
|
||||
| 분할 매도 | 신고가 + 전환선과 이격 확대 | `CLOSE_PRICE GT CONVERSION_LINE` + `DIFF_GT` (임계값) |
|
||||
| 1차 청산 | **전환선 이탈** | `CLOSE_PRICE CROSS_DOWN CONVERSION_LINE` |
|
||||
| 2차 청산 | 데드크로스 | `CONVERSION_LINE CROSS_DOWN BASE_LINE` |
|
||||
| 전량 익절 | 구름 재진입·하향 | `CLOUD_BREAK_DOWN` 또는 `BELOW_CLOUD` |
|
||||
|
||||
**판단:** **매수 금지** · 보유분 **점진적 분할 매도**. 3파와 달리 **전환선 = 생명선**.
|
||||
|
||||
---
|
||||
|
||||
### 4.6 A-B-C 조정파 — 하락 전환
|
||||
|
||||
#### A파 (하락 개시)
|
||||
|
||||
| 일목 | 조건 |
|
||||
|------|------|
|
||||
| 기준선 **강한 이탈** | `CLOSE_PRICE CROSS_DOWN BASE_LINE` |
|
||||
| 데드크로스 | `CONVERSION_LINE CROSS_DOWN BASE_LINE` |
|
||||
| 전략 | **신규 매수 중단**, 5파 잔량 **청산 가속** |
|
||||
|
||||
#### B파 (기술적 반등)
|
||||
|
||||
| 일목 | 조건 |
|
||||
|------|------|
|
||||
| 반등하나 **기준선·음운 하단** 저항 | `CLOSE_PRICE CROSS_UP BASE_LINE` 후 `LT BASE_LINE` 재이탈 |
|
||||
| 구름 | `BELOW_CLOUD` 유지, `CLOUD_BREAK_UP` **실패** |
|
||||
| 전략 | 기준선 터치 후 **전량 매도·대피** (가짜 반등) |
|
||||
|
||||
**DSL 예시 (B파 저항 확인):**
|
||||
|
||||
```text
|
||||
AND(
|
||||
CLOSE_PRICE LT BASE_LINE,
|
||||
BELOW_CLOUD,
|
||||
CONVERSION_LINE LT BASE_LINE
|
||||
)
|
||||
```
|
||||
|
||||
#### C파 (본 하락)
|
||||
|
||||
| 일목 | 조건 |
|
||||
|------|------|
|
||||
| 구름 완전 이탈 | `CLOUD_BREAK_DOWN` + `BELOW_CLOUD` |
|
||||
| 삼역역전 | 데드 + 구름 아래 + `LAGGING_LT_PRICE` |
|
||||
| 전략 | **물타기 금지**, 현금·인버스. `ICHIMOKU_SANYAKU` 매도 OR 조건 활용 |
|
||||
|
||||
---
|
||||
|
||||
## 5. 파동 × 일목 — 한눈에 보는 매매 매트릭스
|
||||
|
||||
| 파동 | 일목 핵심 상태 | 매수 | 매도/청산 | goldenChart 템플릿 참고 |
|
||||
|------|----------------|------|-----------|-------------------------|
|
||||
| **1파** | 기준선 돌파 시도, 음운 위 | 소액·분할 | 관망 | `ICHIMOKU_TREND` (relaxed) |
|
||||
| **2파** | 기준선·선행2 지지 | **적극 1차 매수** | 지지 이탈 시 손절 | `TREND` + 구름 하단 `GT` |
|
||||
| **3파** | **삼역호전** | **추가·불타기** | 전환선 이탈 전 보유 | `ICHIMOKU_SANYAKU` / `PERFECT` |
|
||||
| **4파** | 기준선·구름 상단 횡보 | 지지 확인 시만 | 기준선 이탈 익절 | `IN_CLOUD` 필터 |
|
||||
| **5파** | 이격 과열, 얇은 구름 | **금지** | 전환선·데드 **분할 매도** | `CROSS_DOWN` 전환선 |
|
||||
| **A파** | 기준선 붕괴 | 금지 | 잔량 청산 | `TREND` sell |
|
||||
| **B파** | 기준선·음운 저항 | 금지 | **전량 매도** | `BELOW_CLOUD` + `LT BASE` |
|
||||
| **C파** | 삼역역전 | 금지 | 대피·숏 | `ICHIMOKU_SIT_EW_C_SELL` |
|
||||
|
||||
> **복합지표 팔레트:** `ICHIMOKU_SIT_*` — 기본(L1~S6)·호전·역전·엘리어트(1~5·A~C) 파동별 매수/매도 조건 세트 (전략편집기 복합지표 탭)
|
||||
|
||||
---
|
||||
|
||||
## 6. goldenChart 전략편집기 적용 가이드
|
||||
|
||||
### 6.1 내장 템플릿 매핑
|
||||
|
||||
| 템플릿 | 적합 파동 | 핵심 조건 |
|
||||
|--------|-----------|-----------|
|
||||
| `ICHIMOKU_TREND` | 1파·2파·A파 | 전환↔기준 골든/데드 + (선택) 구름 |
|
||||
| `ICHIMOKU_SANYAKU` | **3파** | 구름 돌파 + 후행·전환 필터 |
|
||||
| `ICHIMOKU_PERFECT` | 3파 (strict) | 4중 AND — 신호↓ 품질↑ |
|
||||
| `ICHIMOKU_BB` | 4파·5파 | 후행 vs 볼린저 — 변동성·과열 |
|
||||
|
||||
### 6.2 필터 강도 권장 (파동별)
|
||||
|
||||
| 파동 | `relaxed` | `balanced` | `strict` |
|
||||
|------|-----------|------------|----------|
|
||||
| 1~2파 | ○ 진입 탐색 | △ | ✕ (과도) |
|
||||
| **3파** | △ | **○** | ○ (확신 시) |
|
||||
| 4~5파 | — (매수 X) | 청산 보조 | 익절 강화 |
|
||||
| A~C파 | — | 매도 | **삼역역전** |
|
||||
|
||||
### 6.3 조건 설계 시 유의사항
|
||||
|
||||
1. **`CROSS_*` vs `GT/LT`:** 돌파 **트리거**는 CROSS, **보유**는 GT/ABOVE_CLOUD.
|
||||
2. **EXISTS_IN 윈도우:** 삼역호전 보조 필터에만 사용 — 트리거에 쓰면 시그널 과다.
|
||||
3. **멀티 타임프레임:** 3파 확인 = 상위 TF `ABOVE_CLOUD` + 하위 TF `CROSS_UP` 조합 권장.
|
||||
4. **엘리어트 병행:** 파동 카운트는 주관적 → 일목 **상태 조건**으로 객관화.
|
||||
|
||||
---
|
||||
|
||||
## 7. 요약 — 판단 흐름도
|
||||
|
||||
```text
|
||||
[하락/바닥] 1파: 기준선 돌파? ──No──→ 관망
|
||||
│
|
||||
Yes (소액)
|
||||
↓
|
||||
2파: 기준선·선행2 지지? ──No──→ 손절
|
||||
│
|
||||
Yes (1차 매수)
|
||||
↓
|
||||
3파: 삼역호전? ──No──→ 대기/추가 관망
|
||||
│
|
||||
Yes (적극 매수·보유)
|
||||
↓
|
||||
4파: 기준선·구름상단 지지? → 재매수 or 일부익절
|
||||
↓
|
||||
5파: 전환선 이탈? → 분할 매도
|
||||
↓
|
||||
A-B-C: 기준선 저항·삼역역전? → 전량 청산·대피
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. 참고 — 표준 기간 (9 · 26 · 52)
|
||||
|
||||
| 요소 | 기간 | 시간축 의미 |
|
||||
|------|------|-------------|
|
||||
| 전환선 | 9 | 단기 (약 1.5주, 일봉 기준) |
|
||||
| 기준선 | 26 | 중기 (약 1달) |
|
||||
| 선행스팬 | 26 선행 | **1달 앞** 매물·심리 |
|
||||
| 선행2 | 52 | 장기 (약 2.5달) |
|
||||
| 후행 | 26 후행 | **1달 전**과 현재 비교 |
|
||||
|
||||
분봉(3m·15m) 사용 시 동일 비율을 유지하되, `ICHIMOKU_SANYAKU` 템플릿의 EXISTS_IN 윈도우(N봉)를 **타임프레임에 맞게** 조절합니다.
|
||||
|
||||
---
|
||||
|
||||
*문서 버전: 2026-03 · goldenChart 전략 DSL `ICHIMOKU` 조건셋 기준*
|
||||
Reference in New Issue
Block a user