Files
dzentra_bot/app/src/trading/strategies/trend.py

91 lines
3.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# app/src/trading/strategies/trend.py
from __future__ import annotations
from src.integrations.exchange.service import ExchangeService
from src.trading.strategies.base import StrategyContext
from src.trading.strategies.signals import SignalResult, SignalType
class TrendStrategy:
name = "TREND"
_last_prices: dict[str, float] = {}
_threshold_percent = 0.02
# анализ простого тренда по изменению цены
def analyze(self, context: StrategyContext) -> SignalResult:
try:
ticker = ExchangeService().get_price(context.symbol)
except Exception as exc:
return SignalResult(
signal=SignalType.HOLD,
reason="Не удалось получить рыночную цену. Безопасный HOLD.",
confidence=0.0,
payload={
"strategy": self.name,
"symbol": context.symbol,
"error": str(exc),
},
)
symbol = ticker.symbol
current_price = ticker.price
previous_price = self._last_prices.get(symbol)
self._last_prices[symbol] = current_price
if previous_price is None or previous_price <= 0:
return SignalResult(
signal=SignalType.HOLD,
reason="Недостаточно данных для определения тренда.",
confidence=0.0,
payload={
"strategy": self.name,
"symbol": symbol,
"price": current_price,
},
)
change_percent = ((current_price - previous_price) / previous_price) * 100
if change_percent >= self._threshold_percent:
return SignalResult(
signal=SignalType.BUY,
reason="Цена растёт выше порога тренда.",
confidence=min(1.0, abs(change_percent) / self._threshold_percent),
payload={
"strategy": self.name,
"symbol": symbol,
"previous_price": previous_price,
"current_price": current_price,
"change_percent": round(change_percent, 5),
},
)
if change_percent <= -self._threshold_percent:
return SignalResult(
signal=SignalType.SELL,
reason="Цена падает ниже порога тренда.",
confidence=min(1.0, abs(change_percent) / self._threshold_percent),
payload={
"strategy": self.name,
"symbol": symbol,
"previous_price": previous_price,
"current_price": current_price,
"change_percent": round(change_percent, 5),
},
)
return SignalResult(
signal=SignalType.HOLD,
reason="Изменение цены ниже порога тренда.",
confidence=0.0,
payload={
"strategy": self.name,
"symbol": symbol,
"previous_price": previous_price,
"current_price": current_price,
"change_percent": round(change_percent, 5),
},
)