전략편집기 수정
This commit is contained in:
@@ -1,6 +1,15 @@
|
||||
/** 조건 노드별 지표 기간·임계값 — 차트 DEF 기본값 대비 노드 단위 오버라이드 */
|
||||
import type { ConditionDSL } from './strategyTypes';
|
||||
import { getCompositeDefaultPeriods, parsePeriodFromCompositeField, syncCompositeFields, type CompositePeriodDef } from './compositeIndicators';
|
||||
import {
|
||||
compositeFieldLabel,
|
||||
compositeValueField,
|
||||
getCompositeDefaultPeriods,
|
||||
isThresholdField,
|
||||
parsePeriodFromCompositeField,
|
||||
syncCompositeFields,
|
||||
type CompositePeriodDef,
|
||||
} from './compositeIndicators';
|
||||
import { DEFAULT_START_CANDLE, normalizeStartCandleType } from './strategyStartNodes';
|
||||
|
||||
export interface IndicatorPeriodDef {
|
||||
rsiPeriod: number;
|
||||
@@ -41,7 +50,7 @@ export function getDefaultIndicatorPeriod(indicatorType: string, def: IndicatorP
|
||||
}
|
||||
|
||||
function parseFieldPeriod(field?: string): number | null {
|
||||
if (!field) return null;
|
||||
if (!field || isThresholdField(field)) return null;
|
||||
const m = field.match(/_(\d+)$/);
|
||||
if (!m) return null;
|
||||
const n = parseInt(m[1], 10);
|
||||
@@ -72,6 +81,24 @@ export function getConditionRightPeriod(cond: ConditionDSL, def: IndicatorPeriod
|
||||
return getDefaultIndicatorPeriod(cond.indicatorType, def);
|
||||
}
|
||||
|
||||
/** 조건대상 직접입력 — 기간(일) 또는 임계값 */
|
||||
export function resolveFieldCustomKind(
|
||||
indicatorType: string,
|
||||
field: string | undefined,
|
||||
): 'period' | 'threshold' | 'none' {
|
||||
if (!field) return 'none';
|
||||
if (isThresholdField(field)) return 'threshold';
|
||||
const prefix = VALUE_FIELD_PREFIX[indicatorType];
|
||||
if (prefix && (field === prefix || field.startsWith(`${prefix}_`))) return 'period';
|
||||
return 'none';
|
||||
}
|
||||
|
||||
export function isValuePeriodFieldStored(indicatorType: string, field?: string): boolean {
|
||||
const prefix = VALUE_FIELD_PREFIX[indicatorType];
|
||||
if (!prefix || !field) return false;
|
||||
return field.startsWith(`${prefix}_`) && field.length > prefix.length + 1;
|
||||
}
|
||||
|
||||
export function usesValuePeriodField(cond: ConditionDSL): boolean {
|
||||
if (cond.composite) return true;
|
||||
const prefix = VALUE_FIELD_PREFIX[cond.indicatorType];
|
||||
@@ -178,6 +205,49 @@ export function getCompositePeriodPresetOptions(
|
||||
return [...new Set([base, short, long, ...COMMON_PERIODS])].sort((a, b) => a - b);
|
||||
}
|
||||
|
||||
/** 복합지표 조건대상1/2 드롭다운 — CCI 1 라인(9일) 형식 */
|
||||
export function getCompositeLeftCandleType(cond: ConditionDSL): string {
|
||||
return normalizeStartCandleType(cond.leftCandleType ?? DEFAULT_START_CANDLE);
|
||||
}
|
||||
|
||||
export function getCompositeRightCandleType(cond: ConditionDSL): string {
|
||||
return normalizeStartCandleType(cond.rightCandleType ?? DEFAULT_START_CANDLE);
|
||||
}
|
||||
|
||||
export function setCompositeLeftCandleType(cond: ConditionDSL, candleType: string): ConditionDSL {
|
||||
return syncCompositeFields({
|
||||
...cond,
|
||||
composite: true,
|
||||
leftCandleType: normalizeStartCandleType(candleType),
|
||||
});
|
||||
}
|
||||
|
||||
export function setCompositeRightCandleType(cond: ConditionDSL, candleType: string): ConditionDSL {
|
||||
return syncCompositeFields({
|
||||
...cond,
|
||||
composite: true,
|
||||
rightCandleType: normalizeStartCandleType(candleType),
|
||||
});
|
||||
}
|
||||
|
||||
export function getCompositeFieldOpts(
|
||||
indicatorType: string,
|
||||
slot: 1 | 2,
|
||||
def: IndicatorPeriodDef,
|
||||
cond: ConditionDSL,
|
||||
): { value: string; label: string }[] {
|
||||
const side = slot === 1 ? 'left' : 'right';
|
||||
const current = slot === 1
|
||||
? getConditionValuePeriod(cond, def)
|
||||
: getConditionRightPeriod(cond, def);
|
||||
const presets = getCompositePeriodPresetOptions(indicatorType, def, side);
|
||||
const periods = [...new Set([...presets, current])].sort((a, b) => a - b);
|
||||
return periods.map(p => ({
|
||||
value: compositeValueField(indicatorType, p),
|
||||
label: compositeFieldLabel(indicatorType, slot, p),
|
||||
}));
|
||||
}
|
||||
|
||||
export function getThresholdPresetOptions(indicatorType: string): number[] {
|
||||
switch (indicatorType) {
|
||||
case 'RSI':
|
||||
|
||||
Reference in New Issue
Block a user