153 lines
4.9 KiB
Python
153 lines
4.9 KiB
Python
# app/src/trading/auto/service.py
|
|
|
|
from __future__ import annotations
|
|
|
|
import asyncio
|
|
|
|
from src.core.types import JsonDict
|
|
from src.trading.auto.auto_lifecycle import AutoLifecycleMixin
|
|
from src.trading.auto.state import AutoTradeState
|
|
|
|
|
|
class AutoTradeService(AutoLifecycleMixin):
|
|
|
|
# GLOBAL SERVICE STATE
|
|
# единый runtime state автоторговли
|
|
# хранит:
|
|
# - сигналы
|
|
# - market context
|
|
# - execution context
|
|
# - PnL открытой позиции и реализованный PnL
|
|
# - lifecycle
|
|
# - protection state
|
|
_state = AutoTradeState()
|
|
|
|
# background asyncio loop task
|
|
# нужен для continuous auto-trading worker
|
|
# None -> loop не запущен
|
|
_loop_task: asyncio.Task | None = None
|
|
|
|
# интервал между auto-trading циклами
|
|
# run_cycle() вызывается каждые N секунд
|
|
_loop_interval_seconds: int = 5
|
|
|
|
# SIGNAL CONFIRMATION ENGINE
|
|
# минимальное количество одинаковых BUY/SELL подряд
|
|
# чтобы сигнал считался подтвержденным
|
|
_confirm_repeats: int = 2
|
|
|
|
# минимальное время удержания сигнала
|
|
# перед execution
|
|
_confirm_min_duration_seconds: int = 10
|
|
|
|
# EXECUTION CONFIDENCE RULES
|
|
# минимальный confidence для READY state
|
|
# ниже -> сигнал не считается готовым
|
|
_ready_confidence = 0.45
|
|
|
|
# минимальный execution confidence
|
|
# для реального допуска execution engine
|
|
_execution_confidence_required_score = 0.65
|
|
|
|
# RUNTIME TTL
|
|
# время жизни signal runtime
|
|
# после ttl сигнал считается устаревшим
|
|
_signal_ttl_seconds: int = 90
|
|
|
|
# время жизни market analysis runtime
|
|
# после ttl market context считается stale
|
|
_market_analysis_ttl_seconds: int = 180
|
|
|
|
# последний logged runtime expiration key
|
|
# нужен чтобы не спамить одинаковыми логами
|
|
_last_logged_runtime_expired_key: str | None = None
|
|
|
|
# SIGNAL MEMORY
|
|
# уникальный ключ последнего сигнала
|
|
# используется для deduplication
|
|
_last_signal_key: str | None = None
|
|
|
|
# последнее signal значение:
|
|
# BUY / SELL / HOLD
|
|
_last_signal_value: str | None = None
|
|
|
|
# последнее объяснение сигнала
|
|
_last_signal_reason: str = ""
|
|
|
|
# confidence последнего сигнала
|
|
_last_signal_confidence: float = 0.0
|
|
|
|
# полный payload последнего signal анализа
|
|
# содержит market metrics / indicators / runtime info
|
|
_last_signal_payload: JsonDict | None = None
|
|
|
|
# monotonic timestamp начала сигнала
|
|
# нужен для confirmation timing
|
|
_last_signal_started_at: float | None = None
|
|
|
|
# количество одинаковых сигналов подряд
|
|
# используется confirmation engine
|
|
_same_signal_count: int = 0
|
|
|
|
# EXECUTION SNAPSHOT VALIDATION
|
|
# максимальный допустимый возраст execution snapshot
|
|
# старше -> snapshot stale
|
|
_max_snapshot_age_seconds: float = 5.0
|
|
|
|
# warning threshold snapshot age
|
|
# выше -> degraded execution quality
|
|
_warning_snapshot_age_seconds: float = 2.0
|
|
|
|
# SPREAD RISK THRESHOLDS
|
|
# asset-specific spread thresholds
|
|
#
|
|
# warning_enter:
|
|
# warning при входе
|
|
#
|
|
# warning_exit:
|
|
# warning при выходе
|
|
#
|
|
# block_enter:
|
|
# полный блок входа
|
|
#
|
|
# block_exit:
|
|
# полный блок выхода
|
|
_spread_thresholds_by_asset: dict[str, dict[str, float]] = {
|
|
"BTC": {
|
|
"warning_enter": 0.08,
|
|
"warning_exit": 0.06,
|
|
"block_enter": 0.15,
|
|
"block_exit": 0.12,
|
|
},
|
|
"ETH": {
|
|
"warning_enter": 0.10,
|
|
"warning_exit": 0.08,
|
|
"block_enter": 0.18,
|
|
"block_exit": 0.15,
|
|
},
|
|
"LTC": {
|
|
"warning_enter": 0.18,
|
|
"warning_exit": 0.14,
|
|
"block_enter": 0.35,
|
|
"block_exit": 0.28,
|
|
},
|
|
"XRP": {
|
|
"warning_enter": 0.20,
|
|
"warning_exit": 0.16,
|
|
"block_enter": 0.40,
|
|
"block_exit": 0.32,
|
|
},
|
|
}
|
|
|
|
# default spread thresholds
|
|
# используются если asset не найден
|
|
_default_spread_thresholds: dict[str, float] = {
|
|
"warning_enter": 0.12,
|
|
"warning_exit": 0.09,
|
|
"block_enter": 0.25,
|
|
"block_exit": 0.20,
|
|
}
|
|
|
|
# последний logged execution quality key
|
|
# нужен чтобы не спамить одинаковыми warning/block logs
|
|
_last_logged_execution_quality_key: str | None = None |