File strategy.py of Package fint-bot

from __future__ import annotations

from abc import ABC, abstractmethod
from dataclasses import dataclass
from typing import Optional

from tinkoff.invest import Candle, CandleInterval, OrderDirection, OrderState, OrderType, MarketDataResponse, Instrument

from robotlib.money import Money


@dataclass
class TradeStrategyParams:
    """Параметры для стратегии"""
    instrument_balance: int
    currency_balance: float
    pending_orders: list[OrderState]


@dataclass
class RobotTradeOrder:
    """Торговый ордер робота"""
    quantity: int
    direction: OrderDirection
    price: Optional[Money] = None
    order_type: OrderType = OrderType.ORDER_TYPE_MARKET


@dataclass
class StrategyDecision:
    """Решение стратегии"""
    robot_trade_order: Optional[RobotTradeOrder] = None
    cancel_orders: list[OrderState] = None

    def __post_init__(self):
        if self.cancel_orders is None:
            self.cancel_orders = []


class TradeStrategyBase(ABC):
    """Базовый класс торговой стратегии"""
    strategy_id: str = "base_strategy"
    candle_subscription_interval: Optional[CandleInterval] = None
    order_book_subscription_depth: Optional[int] = None
    trades_subscription: bool = False

    @abstractmethod
    def decide(self, market_data: MarketDataResponse, params: TradeStrategyParams) -> StrategyDecision:
        """Принять решение на основе рыночных данных"""
        raise NotImplementedError()

    def decide_by_candle(self, candle: Candle, params: TradeStrategyParams) -> StrategyDecision:
        """Принять решение на основе свечи (для бэктестирования)"""
        return StrategyDecision()

    def load_candles(self, candles: list[Candle]) -> None:
        """Загрузить исторические свечи"""
        pass

    def load_instrument_info(self, instrument_info: Instrument) -> None:
        """Загрузить информацию об инструменте"""
        pass
openSUSE Build Service is sponsored by