vol_breakout 멀티종목 tick, vol_live HTML 모니터, 마감 봉만 저장하는 캔들 다운로드, 텔레그램 체결 알림, cron/watch 감시 스크립트 및 테스트를 포함한다. Co-authored-by: Cursor <cursoragent@cursor.com>
47 lines
1.4 KiB
Python
47 lines
1.4 KiB
Python
"""vol_breakout 현물 롱 단위 테스트."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pandas as pd
|
|
|
|
from bithumb.operations.multi_portfolio import count_empty_buy_slots, empty_multi_portfolio
|
|
from bithumb.simulation.vol_breakout import (
|
|
baseline_15m_signal_at,
|
|
spot_long_action,
|
|
)
|
|
|
|
|
|
def test_spot_long_action_buy_only_when_flat() -> None:
|
|
assert spot_long_action(1, False) == "buy"
|
|
assert spot_long_action(1, True) is None
|
|
|
|
|
|
def test_spot_long_action_sell_only_when_long() -> None:
|
|
assert spot_long_action(-1, True) == "sell"
|
|
assert spot_long_action(-1, False) is None
|
|
|
|
|
|
def test_baseline_signal_breakout() -> None:
|
|
n = 30
|
|
closes = [100.0] * n
|
|
closes[-1] = 120.0
|
|
df = pd.DataFrame({
|
|
"datetime": pd.date_range("2026-01-01", periods=n, freq="15min"),
|
|
"open": closes,
|
|
"high": [c + 1 for c in closes],
|
|
"low": [c - 1 for c in closes],
|
|
"close": closes,
|
|
"volume": [1.0] * n,
|
|
})
|
|
sig = baseline_15m_signal_at(df, n - 1, lookback=5, atr_mult=0.01)
|
|
assert sig == 1
|
|
|
|
|
|
def test_empty_buy_slots_dynamic_split() -> None:
|
|
pf = empty_multi_portfolio(["TRX", "NEAR", "WLD"], cash_krw=900_000)
|
|
assert count_empty_buy_slots(pf, ["TRX", "NEAR", "WLD"]) == 3
|
|
pf["positions"]["TRX"]["coin_qty"] = 100.0
|
|
assert count_empty_buy_slots(pf, ["TRX", "NEAR", "WLD"]) == 2
|
|
pf["positions"]["NEAR"]["coin_qty"] = 10.0
|
|
assert count_empty_buy_slots(pf, ["TRX", "NEAR", "WLD"]) == 1
|