build 050: switch MarketAnalysisService to canonical candles
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from enum import StrEnum
|
||||
from math import isfinite
|
||||
|
||||
from src.core.numbers import safe_float
|
||||
from src.integrations.exchange.service import ExchangeService
|
||||
@@ -240,7 +241,7 @@ class MarketAnalysisService:
|
||||
limit: int = 200,
|
||||
) -> MarketAnalysisResult:
|
||||
try:
|
||||
batch = ExchangeService().get_klines(
|
||||
candles = ExchangeService().get_candles(
|
||||
symbol=symbol,
|
||||
interval=interval,
|
||||
limit=limit,
|
||||
@@ -253,18 +254,38 @@ class MarketAnalysisService:
|
||||
htf_interval=self._htf_interval,
|
||||
)
|
||||
|
||||
candles = batch.candles
|
||||
closes = [item.close_price for item in candles]
|
||||
analysis_symbol = candles[0].symbol if candles else symbol
|
||||
|
||||
if len(candles) < self._min_candles:
|
||||
return build_unknown_market_analysis_result(
|
||||
symbol=batch.symbol,
|
||||
symbol=analysis_symbol,
|
||||
interval=interval,
|
||||
reason="Недостаточно свечей для анализа рынка.",
|
||||
candles_count=len(candles),
|
||||
htf_interval=self._htf_interval,
|
||||
)
|
||||
|
||||
closes: list[float] = []
|
||||
|
||||
for candle in candles:
|
||||
close_price_value = safe_float(candle.close_price)
|
||||
|
||||
if (
|
||||
close_price_value is None
|
||||
or not isfinite(close_price_value)
|
||||
):
|
||||
return build_unknown_market_analysis_result(
|
||||
symbol=analysis_symbol,
|
||||
interval=interval,
|
||||
reason=(
|
||||
"Получены некорректные цены закрытия свечей."
|
||||
),
|
||||
candles_count=len(candles),
|
||||
htf_interval=self._htf_interval,
|
||||
)
|
||||
|
||||
closes.append(close_price_value)
|
||||
|
||||
close_price = closes[-1] if closes else None
|
||||
ema_fast = ema(closes, self._fast_ema_period)
|
||||
ema_slow = ema(closes, self._slow_ema_period)
|
||||
@@ -279,7 +300,7 @@ class MarketAnalysisService:
|
||||
or atr_value is None
|
||||
):
|
||||
return build_unknown_market_analysis_result(
|
||||
symbol=batch.symbol,
|
||||
symbol=analysis_symbol,
|
||||
interval=interval,
|
||||
reason="Недостаточно данных для расчёта EMA / ATR.",
|
||||
candles_count=len(candles),
|
||||
@@ -303,7 +324,7 @@ class MarketAnalysisService:
|
||||
|
||||
htf_context = build_htf_volatility_context(
|
||||
self,
|
||||
symbol=batch.symbol,
|
||||
symbol=analysis_symbol,
|
||||
base_interval=interval,
|
||||
)
|
||||
|
||||
@@ -483,7 +504,7 @@ class MarketAnalysisService:
|
||||
phase_window=self._phase_window,
|
||||
)
|
||||
|
||||
# Текущая свеча — последняя свеча из batch.
|
||||
# Текущая свеча — последняя свеча из canonical candles.
|
||||
# Обычно это ещё формирующаяся свеча текущего 5m-интервала.
|
||||
current_interval_change_percent = self._candle_change_percent(
|
||||
candles,
|
||||
@@ -563,7 +584,7 @@ class MarketAnalysisService:
|
||||
|
||||
htf_trend_context = build_htf_trend_context(
|
||||
self,
|
||||
symbol=batch.symbol,
|
||||
symbol=analysis_symbol,
|
||||
base_interval=interval,
|
||||
local_state=state,
|
||||
local_trend=trend,
|
||||
@@ -681,7 +702,7 @@ class MarketAnalysisService:
|
||||
)
|
||||
|
||||
payload = build_market_analysis_payload(
|
||||
symbol=batch.symbol,
|
||||
symbol=analysis_symbol,
|
||||
interval=interval,
|
||||
state=state,
|
||||
trend=trend,
|
||||
@@ -744,7 +765,7 @@ class MarketAnalysisService:
|
||||
)
|
||||
|
||||
return build_market_analysis_result(
|
||||
symbol=batch.symbol,
|
||||
symbol=analysis_symbol,
|
||||
interval=interval,
|
||||
state=state,
|
||||
trend=trend,
|
||||
|
||||
Reference in New Issue
Block a user