from __future__ import annotations from abc import ABC, abstractmethod from enum import Enum from typing import Dict, Optional, cast import pandas as pd from pt_trading.results import BacktestResult from pt_trading.trading_pair import TradingPair NanoPerMin = 1e9 class PairsTradingFitMethod(ABC): TRADES_COLUMNS = [ "time", "symbol", "side", "action", "price", "disequilibrium", "scaled_disequilibrium", "signed_scaled_disequilibrium", "pair", ] @staticmethod def create(config: Dict) -> PairsTradingFitMethod: import importlib fit_method_class_name = config.get("fit_method_class", None) assert fit_method_class_name is not None module_name, class_name = fit_method_class_name.rsplit(".", 1) module = importlib.import_module(module_name) fit_method = getattr(module, class_name)() return cast(PairsTradingFitMethod, fit_method) @abstractmethod def run_pair( self, pair: TradingPair, bt_result: BacktestResult ) -> Optional[pd.DataFrame]: ... @abstractmethod def reset(self) -> None: ... @abstractmethod def create_trading_pair( self, config: Dict, market_data: pd.DataFrame, symbol_a: str, symbol_b: str, ) -> TradingPair: ...