| 12345678910111213141516171819202122232425262728293031 |
- import math
- from okx_codex_trader.models import Candle
- from scripts.run_crash_follow_short_observer import frame_from_candles, latest_signal, load_pair_frame
- def test_latest_signal_detects_crash_follow_short() -> None:
- eth = []
- btc = []
- for index in range(800):
- eth_price = 100.0 + math.sin(index / 9.0)
- btc_price = 100.0
- if index >= 760:
- btc_price = 96.0
- if index == 799:
- eth_price = 95.0
- btc_price = 94.0
- ts = 1_700_000_000_000 + (index * 3_600_000)
- high = eth_price + (10.0 if index == 799 else 2.0)
- low = eth_price - (10.0 if index == 799 else 2.0)
- eth.append(Candle("ETH-USDT-SWAP", ts, eth_price, high, low, eth_price, 1_000.0))
- btc.append(Candle("BTC-USDT-SWAP", ts, btc_price, btc_price, btc_price, btc_price, 1_000.0))
- eth_frame = frame_from_candles(eth)
- btc_frame = frame_from_candles(btc)[["ts", "close"]].rename(columns={"close": "btc_close"})
- frame = eth_frame.merge(btc_frame, on="ts", how="inner").sort_values("ts").reset_index(drop=True)
- signal = latest_signal(frame)
- assert signal["signal"] == "entry_short"
- assert signal["target_side"] == "short"
- assert signal["indicators"]["btc_riskoff_gate"] is True
|