feat(quant-engine): 10개 고전 기술전략 갭분석 후 7개 보조신호 채택
사용자 제시 10개 고전 기술전략(골든크로스/모멘텀/52주신고가/연속상승하락/이격도/돌파실패/ 강한종가/변동성확장/평균회귀/추세필터)을 기존 엔진과 대조한 갭분석 결과: - 이미 구현됨: 모멘텀(VELOCITY_V1/RS_MOMENTUM_V1), 이격도·평균회귀(MEAN_REVERSION_GATE_V1) - 신규 채택 7개: GOLDEN_CROSS_SIGNAL_V1, STRONG_CLOSE_SIGNAL_V1, VOLATILITY_EXPANSION_BREAKOUT_V1, FIFTY_TWO_WEEK_HIGH_TRIGGER_V1, CONSECUTIVE_STREAK_V1, BREAKOUT_FAILURE_STOP_V1, TREND_FILTER_GATE_V1 AGENTS.md 하드룰(추격매수 방지, anti-late-entry gate 필수통과)에 따라 BUY 방향 신호 전부를 STRATEGY_SCORING의 보조신호로만 편입 — BREAKOUT_QUALITY_GATE_V2/FOLLOW_THROUGH_DAY_CONFIRM_V1/ ANTI_LATE_ENTRY_GATE_V2 게이트 체인을 우회하는 독립 BUY 트리거로는 사용하지 않음. 검증: validate_specs/validate_golden_coverage_100(100%)/validate_calibration_registry_v1/ validate_schema_model_generation_v1/validate_agents_shrink_v1 전부 PASS. golden test 22/22 PASS. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
"""Auto-generated schema model descriptor."""
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
SCHEMA_TITLE = 'BREAKOUT_FAILURE_STOP_V1'
|
||||
SCHEMA_ID = 'schema://formula/BREAKOUT_FAILURE_STOP_V1'
|
||||
SCHEMA_PATH = 'schemas/generated/breakout_failure_stop_v1.schema.json'
|
||||
SCHEMA_PROPERTIES = ['formula_id', 'owner', 'status', 'inputs', 'outputs']
|
||||
SCHEMA_REQUIRED = ['formula_id', 'owner', 'status', 'inputs', 'outputs']
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class SchemaModel:
|
||||
title: str
|
||||
schema_id: str
|
||||
path: str
|
||||
properties: list[str]
|
||||
required: list[str]
|
||||
|
||||
def load_schema() -> dict[str, Any]:
|
||||
return json.loads(Path(__file__).with_suffix('.schema.json').read_text(encoding='utf-8'))
|
||||
|
||||
def describe() -> SchemaModel:
|
||||
return SchemaModel(
|
||||
title=SCHEMA_TITLE,
|
||||
schema_id=SCHEMA_ID,
|
||||
path=SCHEMA_PATH,
|
||||
properties=list(SCHEMA_PROPERTIES),
|
||||
required=list(SCHEMA_REQUIRED),
|
||||
)
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "schema://formula/BREAKOUT_FAILURE_STOP_V1",
|
||||
"title": "BREAKOUT_FAILURE_STOP_V1",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"formula_id": { "const": "BREAKOUT_FAILURE_STOP_V1" },
|
||||
"owner": { "type": "string" },
|
||||
"status": { "type": "string" },
|
||||
"inputs": { "type": "array", "items": { "type": "string" } },
|
||||
"outputs": { "type": "array", "items": { "type": "string" } }
|
||||
},
|
||||
"required": ["formula_id", "owner", "status", "inputs", "outputs"],
|
||||
"x_formula_inputs": ["prior_high", "close_price", "days_since_breakout"],
|
||||
"x_formula_outputs": ["breakout_failure"]
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
"""Auto-generated schema model descriptor."""
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
SCHEMA_TITLE = 'CONSECUTIVE_STREAK_V1'
|
||||
SCHEMA_ID = 'schema://formula/CONSECUTIVE_STREAK_V1'
|
||||
SCHEMA_PATH = 'schemas/generated/consecutive_streak_v1.schema.json'
|
||||
SCHEMA_PROPERTIES = ['formula_id', 'owner', 'status', 'inputs', 'outputs']
|
||||
SCHEMA_REQUIRED = ['formula_id', 'owner', 'status', 'inputs', 'outputs']
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class SchemaModel:
|
||||
title: str
|
||||
schema_id: str
|
||||
path: str
|
||||
properties: list[str]
|
||||
required: list[str]
|
||||
|
||||
def load_schema() -> dict[str, Any]:
|
||||
return json.loads(Path(__file__).with_suffix('.schema.json').read_text(encoding='utf-8'))
|
||||
|
||||
def describe() -> SchemaModel:
|
||||
return SchemaModel(
|
||||
title=SCHEMA_TITLE,
|
||||
schema_id=SCHEMA_ID,
|
||||
path=SCHEMA_PATH,
|
||||
properties=list(SCHEMA_PROPERTIES),
|
||||
required=list(SCHEMA_REQUIRED),
|
||||
)
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "schema://formula/CONSECUTIVE_STREAK_V1",
|
||||
"title": "CONSECUTIVE_STREAK_V1",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"formula_id": { "const": "CONSECUTIVE_STREAK_V1" },
|
||||
"owner": { "type": "string" },
|
||||
"status": { "type": "string" },
|
||||
"inputs": { "type": "array", "items": { "type": "string" } },
|
||||
"outputs": { "type": "array", "items": { "type": "string" } }
|
||||
},
|
||||
"required": ["formula_id", "owner", "status", "inputs", "outputs"],
|
||||
"x_formula_inputs": ["daily_close_changes"],
|
||||
"x_formula_outputs": ["up_streak", "down_streak"]
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
"""Auto-generated schema model descriptor."""
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
SCHEMA_TITLE = 'FIFTY_TWO_WEEK_HIGH_TRIGGER_V1'
|
||||
SCHEMA_ID = 'schema://formula/FIFTY_TWO_WEEK_HIGH_TRIGGER_V1'
|
||||
SCHEMA_PATH = 'schemas/generated/fifty_two_week_high_trigger_v1.schema.json'
|
||||
SCHEMA_PROPERTIES = ['formula_id', 'owner', 'status', 'inputs', 'outputs']
|
||||
SCHEMA_REQUIRED = ['formula_id', 'owner', 'status', 'inputs', 'outputs']
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class SchemaModel:
|
||||
title: str
|
||||
schema_id: str
|
||||
path: str
|
||||
properties: list[str]
|
||||
required: list[str]
|
||||
|
||||
def load_schema() -> dict[str, Any]:
|
||||
return json.loads(Path(__file__).with_suffix('.schema.json').read_text(encoding='utf-8'))
|
||||
|
||||
def describe() -> SchemaModel:
|
||||
return SchemaModel(
|
||||
title=SCHEMA_TITLE,
|
||||
schema_id=SCHEMA_ID,
|
||||
path=SCHEMA_PATH,
|
||||
properties=list(SCHEMA_PROPERTIES),
|
||||
required=list(SCHEMA_REQUIRED),
|
||||
)
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "schema://formula/FIFTY_TWO_WEEK_HIGH_TRIGGER_V1",
|
||||
"title": "FIFTY_TWO_WEEK_HIGH_TRIGGER_V1",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"formula_id": { "const": "FIFTY_TWO_WEEK_HIGH_TRIGGER_V1" },
|
||||
"owner": { "type": "string" },
|
||||
"status": { "type": "string" },
|
||||
"inputs": { "type": "array", "items": { "type": "string" } },
|
||||
"outputs": { "type": "array", "items": { "type": "string" } }
|
||||
},
|
||||
"required": ["formula_id", "owner", "status", "inputs", "outputs"],
|
||||
"x_formula_inputs": ["close_price", "high52w"],
|
||||
"x_formula_outputs": ["fifty_two_week_high_breakout"]
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
"""Auto-generated schema model descriptor."""
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
SCHEMA_TITLE = 'GOLDEN_CROSS_SIGNAL_V1'
|
||||
SCHEMA_ID = 'schema://formula/GOLDEN_CROSS_SIGNAL_V1'
|
||||
SCHEMA_PATH = 'schemas/generated/golden_cross_signal_v1.schema.json'
|
||||
SCHEMA_PROPERTIES = ['formula_id', 'owner', 'status', 'inputs', 'outputs']
|
||||
SCHEMA_REQUIRED = ['formula_id', 'owner', 'status', 'inputs', 'outputs']
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class SchemaModel:
|
||||
title: str
|
||||
schema_id: str
|
||||
path: str
|
||||
properties: list[str]
|
||||
required: list[str]
|
||||
|
||||
def load_schema() -> dict[str, Any]:
|
||||
return json.loads(Path(__file__).with_suffix('.schema.json').read_text(encoding='utf-8'))
|
||||
|
||||
def describe() -> SchemaModel:
|
||||
return SchemaModel(
|
||||
title=SCHEMA_TITLE,
|
||||
schema_id=SCHEMA_ID,
|
||||
path=SCHEMA_PATH,
|
||||
properties=list(SCHEMA_PROPERTIES),
|
||||
required=list(SCHEMA_REQUIRED),
|
||||
)
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "schema://formula/GOLDEN_CROSS_SIGNAL_V1",
|
||||
"title": "GOLDEN_CROSS_SIGNAL_V1",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"formula_id": { "const": "GOLDEN_CROSS_SIGNAL_V1" },
|
||||
"owner": { "type": "string" },
|
||||
"status": { "type": "string" },
|
||||
"inputs": { "type": "array", "items": { "type": "string" } },
|
||||
"outputs": { "type": "array", "items": { "type": "string" } }
|
||||
},
|
||||
"required": ["formula_id", "owner", "status", "inputs", "outputs"],
|
||||
"x_formula_inputs": ["ma20", "ma20_prev", "ma60", "ma60_prev"],
|
||||
"x_formula_outputs": ["golden_cross_today"]
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
"""Auto-generated schema model descriptor."""
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
SCHEMA_TITLE = 'STRONG_CLOSE_SIGNAL_V1'
|
||||
SCHEMA_ID = 'schema://formula/STRONG_CLOSE_SIGNAL_V1'
|
||||
SCHEMA_PATH = 'schemas/generated/strong_close_signal_v1.schema.json'
|
||||
SCHEMA_PROPERTIES = ['formula_id', 'owner', 'status', 'inputs', 'outputs']
|
||||
SCHEMA_REQUIRED = ['formula_id', 'owner', 'status', 'inputs', 'outputs']
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class SchemaModel:
|
||||
title: str
|
||||
schema_id: str
|
||||
path: str
|
||||
properties: list[str]
|
||||
required: list[str]
|
||||
|
||||
def load_schema() -> dict[str, Any]:
|
||||
return json.loads(Path(__file__).with_suffix('.schema.json').read_text(encoding='utf-8'))
|
||||
|
||||
def describe() -> SchemaModel:
|
||||
return SchemaModel(
|
||||
title=SCHEMA_TITLE,
|
||||
schema_id=SCHEMA_ID,
|
||||
path=SCHEMA_PATH,
|
||||
properties=list(SCHEMA_PROPERTIES),
|
||||
required=list(SCHEMA_REQUIRED),
|
||||
)
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "schema://formula/STRONG_CLOSE_SIGNAL_V1",
|
||||
"title": "STRONG_CLOSE_SIGNAL_V1",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"formula_id": { "const": "STRONG_CLOSE_SIGNAL_V1" },
|
||||
"owner": { "type": "string" },
|
||||
"status": { "type": "string" },
|
||||
"inputs": { "type": "array", "items": { "type": "string" } },
|
||||
"outputs": { "type": "array", "items": { "type": "string" } }
|
||||
},
|
||||
"required": ["formula_id", "owner", "status", "inputs", "outputs"],
|
||||
"x_formula_inputs": ["close_price", "high_price", "low_price"],
|
||||
"x_formula_outputs": ["strong_close", "close_position_pct"]
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
"""Auto-generated schema model descriptor."""
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
SCHEMA_TITLE = 'TREND_FILTER_GATE_V1'
|
||||
SCHEMA_ID = 'schema://formula/TREND_FILTER_GATE_V1'
|
||||
SCHEMA_PATH = 'schemas/generated/trend_filter_gate_v1.schema.json'
|
||||
SCHEMA_PROPERTIES = ['formula_id', 'owner', 'status', 'inputs', 'outputs']
|
||||
SCHEMA_REQUIRED = ['formula_id', 'owner', 'status', 'inputs', 'outputs']
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class SchemaModel:
|
||||
title: str
|
||||
schema_id: str
|
||||
path: str
|
||||
properties: list[str]
|
||||
required: list[str]
|
||||
|
||||
def load_schema() -> dict[str, Any]:
|
||||
return json.loads(Path(__file__).with_suffix('.schema.json').read_text(encoding='utf-8'))
|
||||
|
||||
def describe() -> SchemaModel:
|
||||
return SchemaModel(
|
||||
title=SCHEMA_TITLE,
|
||||
schema_id=SCHEMA_ID,
|
||||
path=SCHEMA_PATH,
|
||||
properties=list(SCHEMA_PROPERTIES),
|
||||
required=list(SCHEMA_REQUIRED),
|
||||
)
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "schema://formula/TREND_FILTER_GATE_V1",
|
||||
"title": "TREND_FILTER_GATE_V1",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"formula_id": { "const": "TREND_FILTER_GATE_V1" },
|
||||
"owner": { "type": "string" },
|
||||
"status": { "type": "string" },
|
||||
"inputs": { "type": "array", "items": { "type": "string" } },
|
||||
"outputs": { "type": "array", "items": { "type": "string" } }
|
||||
},
|
||||
"required": ["formula_id", "owner", "status", "inputs", "outputs"],
|
||||
"x_formula_inputs": ["close_price", "ma120", "ma120_prev"],
|
||||
"x_formula_outputs": ["trend_filter_pass"]
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
"""Auto-generated schema model descriptor."""
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
SCHEMA_TITLE = 'VOLATILITY_EXPANSION_BREAKOUT_V1'
|
||||
SCHEMA_ID = 'schema://formula/VOLATILITY_EXPANSION_BREAKOUT_V1'
|
||||
SCHEMA_PATH = 'schemas/generated/volatility_expansion_breakout_v1.schema.json'
|
||||
SCHEMA_PROPERTIES = ['formula_id', 'owner', 'status', 'inputs', 'outputs']
|
||||
SCHEMA_REQUIRED = ['formula_id', 'owner', 'status', 'inputs', 'outputs']
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class SchemaModel:
|
||||
title: str
|
||||
schema_id: str
|
||||
path: str
|
||||
properties: list[str]
|
||||
required: list[str]
|
||||
|
||||
def load_schema() -> dict[str, Any]:
|
||||
return json.loads(Path(__file__).with_suffix('.schema.json').read_text(encoding='utf-8'))
|
||||
|
||||
def describe() -> SchemaModel:
|
||||
return SchemaModel(
|
||||
title=SCHEMA_TITLE,
|
||||
schema_id=SCHEMA_ID,
|
||||
path=SCHEMA_PATH,
|
||||
properties=list(SCHEMA_PROPERTIES),
|
||||
required=list(SCHEMA_REQUIRED),
|
||||
)
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "schema://formula/VOLATILITY_EXPANSION_BREAKOUT_V1",
|
||||
"title": "VOLATILITY_EXPANSION_BREAKOUT_V1",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"formula_id": { "const": "VOLATILITY_EXPANSION_BREAKOUT_V1" },
|
||||
"owner": { "type": "string" },
|
||||
"status": { "type": "string" },
|
||||
"inputs": { "type": "array", "items": { "type": "string" } },
|
||||
"outputs": { "type": "array", "items": { "type": "string" } }
|
||||
},
|
||||
"required": ["formula_id", "owner", "status", "inputs", "outputs"],
|
||||
"x_formula_inputs": ["bb_width", "bb_width_20d_percentile", "ret_1d"],
|
||||
"x_formula_outputs": ["volatility_expansion_breakout"]
|
||||
}
|
||||
Reference in New Issue
Block a user