Fájl részletek

Ezen az oldalon egy konkrét fájl aktuális állapotát tudod megnézni.

Vissza a fájltérképhez Csak változott Stratégia-labor Monitor főoldal
Fájl útvonala
/opt/bots/saturnus/app/tools/edge_case_transitions_test.py
Létezik most?
IGEN
Aktuális státusz
UNCHANGED
Méret
11727
Módosítás ideje
1772375991.3796678
Korábbi baseline időpont
1772375991.3796678
SHA256 rövid

Előnézet (első 120 sor)

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
edge_case_transitions_test.py (CANONICAL TEST TOOL)

Read-only edge-case tests for:
  - BUY_LOCK transitions (SELL -> BUY -> LOCK)
  - Dominance validation (PANIC vs others) + boundary (==) checks
  - Extra transitions: SELL under lock, TTL expiry, clean lock lifecycle

NO state.json writes, NO Freqtrade calls.
"""

import sys
import time

APP_DIR = "/opt/bots/saturnus/app"
sys.path.insert(0, APP_DIR)

import tick_runner
import rule_engine


def ok(msg: str) -> None:
    print(f"OK  - {msg}")


def fail(msg: str) -> None:
    print(f"ERR - {msg}")
    raise SystemExit(2)


def assert_true(cond: bool, msg_ok: str, msg_fail: str) -> None:
    if cond:
        ok(msg_ok)
    else:
        fail(msg_fail)


def mk_levels(base: float, trough: float) -> dict:
    # use fixed pct values aligned with default tick_runner env defaults:
    # STD_SELL=3%, PROFITLESS_SELL=0.1%, PANIC_SELL=1%
    # STD_BUY=3%, PROFITLESS_BUY=-0.1%, PANIC_BUY=1%
    return {
        "std_sell": base * (1.0 - 0.03),
        "profitless_sell": base * (1.0 - 0.001),
        "panic_sell": base * (1.0 - 0.01),
        "std_buy": trough * (1.0 + 0.03),
        "profitless_buy": trough * (1.0 - 0.001),
        "panic_buy": trough * (1.0 + 0.01),
    }


def decide_ctx(*, in_position: bool, last: float, prev_last: float, base: float, peak: float | None, trough: float | None) -> dict:
    levels = mk_levels(base=base, trough=(trough if trough is not None else last))
    ctx = {
        "in_position": bool(in_position),
        "last": float(last),
        "prev_last": float(prev_last),
        "base": float(base),
        "peak": peak,
        "trough": trough,
        "levels": levels,
    }
    return rule_engine.decide(ctx)


def test_buy_lock_transitions() -> None:
    print("\n=== BUY_LOCK átmenetek (SELL → BUY → LOCK) ===")

    # Flat + BUY -> BUY allowed + lock created
    state = {"in_position": False, "market": {"pair": "SOL/USDC", "timeframe": "1m", "last": 100.0, "prev_last": 99.0}}
    d_buy = {"action": "BUY", "rule": "TEST_BUY", "reason": "BUY_SIGNAL", "level": "std_buy"}
    out1 = tick_runner.apply_buy_lock(state, d_buy)

    assert_true(out1.get("action") == "BUY",
                "Flat BUY -> decision BUY",
                "Flat BUY -> decision not BUY")

    locks = state.get("locks") if isinstance(state.get("locks"), dict) else {}
    assert_true(isinstance(locks.get("buy_pending"), dict),
                "Flat BUY -> buy_pending lock létrejött",
                "Flat BUY -> buy_pending lock missing")

    # Flat + BUY again -> HOLD with BUY_LOCK
    out2 = tick_runner.apply_buy_lock(state, d_buy)
    assert_true(out2.get("action") == "HOLD",
                "Lock mellett BUY -> HOLD",
                "Lock mellett BUY -> not HOLD")
    assert_true(out2.get("rule") == "BUY_LOCK",
                "Lock mellett BUY -> rule=BUY_LOCK",
                "Lock mellett BUY -> rule not BUY_LOCK")

    # Any non-BUY decision clears lock
    out3 = tick_runner.apply_buy_lock(state, {"action": "HOLD", "rule": "TEST_HOLD", "reason": "HOLD"})
    locks2 = state.get("locks") if isinstance(state.get("locks"), dict) else {}
    assert_true(locks2.get("buy_pending") is None,
                "HOLD mellett lock törlődik",
                "HOLD mellett lock nem törlődött")

    # In_position clears lock and does not lock decisions
    state2 = {"in_position": False, "market": {"pair": "SOL/USDC", "timeframe": "1m", "last": 100.0, "prev_last": 99.0}}
    tick_runner.apply_buy_lock(state2, d_buy)
    state2["in_position"] = True
    out4 = tick_runner.apply_buy_lock(state2, d_buy)
    locks3 = state2.get("locks") if isinstance(state2.get("locks"), dict) else {}
    assert_true(locks3.get("buy_pending") is None,
                "In_position -> lock törlődik",
                "In_position -> lock nem törlődött")
    assert_true(out4.get("action") == "BUY",
                "In_position esetén döntés nem lockkolódik",
                "In_position esetén döntés lockkolódott")


def test_dominance_validation() -> None:
    print("\n=== Dominancia validáció (RuleEngine) ===")

    base = 100.0
    peak = 110.0

Csak változott diff sorok

Teljes diff

[INFO] Nincs tartalmi eltérés a baseline és az aktuális fájl között.