claude/interesting-mcnulty #3
@@ -11,6 +11,7 @@ FEATURE_COLS = [
|
|||||||
# 시장 미시구조: OI 변화율(z-score), 펀딩비(z-score)
|
# 시장 미시구조: OI 변화율(z-score), 펀딩비(z-score)
|
||||||
# parquet에 oi_change/funding_rate 컬럼이 없으면 dataset_builder에서 0으로 채움
|
# parquet에 oi_change/funding_rate 컬럼이 없으면 dataset_builder에서 0으로 채움
|
||||||
"oi_change", "funding_rate",
|
"oi_change", "funding_rate",
|
||||||
|
"adx",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@@ -39,7 +40,7 @@ def build_features(
|
|||||||
) -> pd.Series:
|
) -> pd.Series:
|
||||||
"""
|
"""
|
||||||
기술 지표가 계산된 DataFrame의 마지막 행에서 ML 피처를 추출한다.
|
기술 지표가 계산된 DataFrame의 마지막 행에서 ML 피처를 추출한다.
|
||||||
btc_df, eth_df가 제공되면 23개 피처를, 없으면 15개 피처를 반환한다.
|
btc_df, eth_df가 제공되면 24개 피처를, 없으면 16개 피처를 반환한다.
|
||||||
signal: "LONG" | "SHORT"
|
signal: "LONG" | "SHORT"
|
||||||
oi_change, funding_rate: 실제 값이 제공되면 사용, 없으면 0.0으로 채운다.
|
oi_change, funding_rate: 실제 값이 제공되면 사용, 없으면 0.0으로 채운다.
|
||||||
"""
|
"""
|
||||||
@@ -133,5 +134,6 @@ def build_features(
|
|||||||
# 실시간에서 실제 값이 제공되면 사용, 없으면 0으로 채운다
|
# 실시간에서 실제 값이 제공되면 사용, 없으면 0으로 채운다
|
||||||
base["oi_change"] = float(oi_change) if oi_change is not None else 0.0
|
base["oi_change"] = float(oi_change) if oi_change is not None else 0.0
|
||||||
base["funding_rate"] = float(funding_rate) if funding_rate is not None else 0.0
|
base["funding_rate"] = float(funding_rate) if funding_rate is not None else 0.0
|
||||||
|
base["adx"] = float(last.get("adx", 0))
|
||||||
|
|
||||||
return pd.Series(base)
|
return pd.Series(base)
|
||||||
|
|||||||
@@ -17,20 +17,21 @@ def _make_df(n=10, base_price=1.0):
|
|||||||
"ema21": closes, "ema50": closes, "atr": [0.01] * n,
|
"ema21": closes, "ema50": closes, "atr": [0.01] * n,
|
||||||
"stoch_k": [50.0] * n, "stoch_d": [50.0] * n,
|
"stoch_k": [50.0] * n, "stoch_d": [50.0] * n,
|
||||||
"vol_ma20": [1000.0] * n,
|
"vol_ma20": [1000.0] * n,
|
||||||
|
"adx": [20.0] * n,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
def test_build_features_with_btc_eth_has_21_features():
|
def test_build_features_with_btc_eth_has_24_features():
|
||||||
xrp_df = _make_df(10, base_price=1.0)
|
xrp_df = _make_df(10, base_price=1.0)
|
||||||
btc_df = _make_df(10, base_price=50000.0)
|
btc_df = _make_df(10, base_price=50000.0)
|
||||||
eth_df = _make_df(10, base_price=3000.0)
|
eth_df = _make_df(10, base_price=3000.0)
|
||||||
features = build_features(xrp_df, "LONG", btc_df=btc_df, eth_df=eth_df)
|
features = build_features(xrp_df, "LONG", btc_df=btc_df, eth_df=eth_df)
|
||||||
assert len(features) == 23
|
assert len(features) == 24
|
||||||
|
|
||||||
def test_build_features_without_btc_eth_has_13_features():
|
def test_build_features_without_btc_eth_has_16_features():
|
||||||
xrp_df = _make_df(10, base_price=1.0)
|
xrp_df = _make_df(10, base_price=1.0)
|
||||||
features = build_features(xrp_df, "LONG")
|
features = build_features(xrp_df, "LONG")
|
||||||
assert len(features) == 15
|
assert len(features) == 16
|
||||||
|
|
||||||
def test_build_features_btc_ret_1_correct():
|
def test_build_features_btc_ret_1_correct():
|
||||||
xrp_df = _make_df(10, base_price=1.0)
|
xrp_df = _make_df(10, base_price=1.0)
|
||||||
@@ -49,9 +50,9 @@ def test_build_features_rs_zero_when_btc_ret_zero():
|
|||||||
features = build_features(xrp_df, "LONG", btc_df=btc_df, eth_df=eth_df)
|
features = build_features(xrp_df, "LONG", btc_df=btc_df, eth_df=eth_df)
|
||||||
assert features["xrp_btc_rs"] == 0.0
|
assert features["xrp_btc_rs"] == 0.0
|
||||||
|
|
||||||
def test_feature_cols_has_23_items():
|
def test_feature_cols_has_24_items():
|
||||||
from src.ml_features import FEATURE_COLS
|
from src.ml_features import FEATURE_COLS
|
||||||
assert len(FEATURE_COLS) == 23
|
assert len(FEATURE_COLS) == 24
|
||||||
|
|
||||||
|
|
||||||
def make_df(n=100):
|
def make_df(n=100):
|
||||||
|
|||||||
Reference in New Issue
Block a user