diff --git a/app_streamlit.py b/app_streamlit.py index dcbc48e..8caa226 100644 --- a/app_streamlit.py +++ b/app_streamlit.py @@ -294,15 +294,13 @@ def compute_signals(df, interval="5m"): (df["close"] < df["MA7"]) & (df["MA7"] < df["MA25"]) ) df["bull_ma"] = ( - (df["close"] > df["MA7"]) & (df["MA7"] > df["MA25"]) & - (df["MA25"] > df["MA99"]) + (df["close"] > df["MA7"]) & (df["MA7"] > df["MA25"]) ) df["bear_ma"] = ( - (df["close"] < df["MA7"]) & (df["MA7"] < df["MA25"]) & - (df["MA25"] < df["MA99"]) + (df["close"] < df["MA7"]) & (df["MA7"] < df["MA25"]) ) - df["long_signal"] = df["bull_ma_2"] & (df["RSI"] < 60) & (df["MACD_hist"] > df["MACD_hist"].shift(1)) & (df["close"] > df["BB_mid"]) - df["short_signal"] = df["bear_ma_2"] & (df["RSI"] > 35) & (df["MACD_hist"] < df["MACD_hist"].shift(1)) & (df["close"] < df["BB_mid"]) + df["long_signal"] = df["bull_ma_2"] & (df["RSI"] < 60) & (df["MACD_hist"] > df["MACD_hist"].shift(1)) & (df["close"] > df["BB_mid"]) & (df["close"] < df["BB_upper"]) + df["short_signal"] = df["bear_ma_2"] & (df["RSI"] > 35) & (df["MACD_hist"] < df["MACD_hist"].shift(1)) & (df["close"] < df["BB_mid"]) & (df["close"] > df["BB_lower"]) df["long_signal"] = df["long_signal"] & (df["long_signal"].rolling(5, min_periods=1).sum().shift(1).fillna(0) == 0) df["short_signal"] = df["short_signal"] & (df["short_signal"].rolling(5, min_periods=1).sum().shift(1).fillna(0) == 0) @@ -314,6 +312,9 @@ def compute_signals(df, interval="5m"): df["oi_down"] = oi_series < oi_series.shift(1) df["oi_up_2"] = df["oi_up"] & df["oi_up"].shift(1).fillna(False) df["oi_down_2"] = df["oi_down"] & df["oi_down"].shift(1).fillna(False) + # OI 활성도: 방향 무관, 의미 있는 변동만 통과 (0.1% 이상). 신규 진입과 + # 청산 모두 캡처하기 위함. vol_short / vol_long 신호의 OI 필터로 사용. + df["oi_active"] = oi_series.pct_change().abs() > 0.001 df["taker_buy_dom"] = df["taker_buy_vol"] > df["taker_sell_vol"] df["taker_sell_dom"] = df["taker_sell_vol"] > df["taker_buy_vol"] @@ -323,8 +324,8 @@ def compute_signals(df, interval="5m"): df["fr_long_favor"] = df["taker_buy_vol"].rolling(3).mean() > df["taker_sell_vol"].rolling(3).mean() df["fr_short_favor"] = df["taker_sell_vol"].rolling(3).mean() > df["taker_buy_vol"].rolling(3).mean() - df["strong_long_signal"] = df["bull_ma"] & (df["RSI"] < 65) & (df["MACD_hist"] > df["MACD_hist"].shift(1)) & df["oi_up_2"] & df["taker_buy_2"] & df["fr_long_favor"] - df["strong_short_signal"] = df["bear_ma"] & (df["RSI"] > 35) & (df["MACD_hist"] < df["MACD_hist"].shift(1)) & df["oi_down_2"] & df["taker_sell_2"] & df["fr_short_favor"] + df["strong_long_signal"] = df["bull_ma_2"] & (df["RSI"] < 65) & (df["MACD_hist"] > df["MACD_hist"].shift(1)) & df["oi_up_2"] & df["taker_buy_2"] & df["fr_long_favor"] + df["strong_short_signal"] = df["bear_ma_2"] & (df["RSI"] > 35) & (df["MACD_hist"] < df["MACD_hist"].shift(1)) & df["oi_down_2"] & df["taker_sell_2"] & df["fr_short_favor"] df["strong_long_signal"] = df["strong_long_signal"] & (df["strong_long_signal"].rolling(10, min_periods=1).sum().shift(1).fillna(0) == 0) df["strong_short_signal"] = df["strong_short_signal"] & (df["strong_short_signal"].rolling(10, min_periods=1).sum().shift(1).fillna(0) == 0) @@ -344,7 +345,7 @@ def compute_signals(df, interval="5m"): (df["sell_net"] > sell_net_avg * 2) & (df["sell_net"] > 0) & (df["taker_sell_vol"] > _vol_min) & - df["oi_up"] + df["oi_active"] ) cooldown_vol_short = sell_spike_strong.rolling(10, min_periods=1).sum().shift(1).fillna(0) == 0 df["vol_short_signal"] = sell_spike_strong & cooldown_vol_short @@ -355,7 +356,7 @@ def compute_signals(df, interval="5m"): (df["buy_net"] > buy_net_avg * 2) & (df["buy_net"] > 0) & (df["taker_buy_vol"] > _vol_min) & - df["oi_up"] + df["oi_active"] ) cooldown_vol_long = buy_spike_strong.rolling(10, min_periods=1).sum().shift(1).fillna(0) == 0 df["vol_long_signal"] = buy_spike_strong & cooldown_vol_long