Files

55 lines
1.9 KiB
Python

"""Orchestrierung von Paper-/Simulations- und Live-Trading über den Broker.
- Paper-Modus: Simulationslauf über die Engine (Käufe/Verkäufe werden lokal
gegen den Kurs-Feed gebucht, kein echtes Geld).
- Live-Modus: platziert echte Markerorders über die Exchange-API.
"""
from __future__ import annotations
import logging
from .config import Config
from .engine import Engine, Result
from .exchange import Broker
from .strategy import Strategy
log = logging.getLogger("trademind.trader")
class Trader:
def __init__(self, cfg: Config, broker: Broker, strategy: Strategy):
self.cfg = cfg
self.t = cfg.trading
self.broker = broker
self.strategy = strategy
self.engine = Engine(self.t, strategy)
def symbol(self) -> str:
base = self.t.base_currency.upper()
quote = self.t.quote_currency.upper()
if self.broker.name == "coinbase":
return f"{base}-{quote}"
return f"{base}/{quote}"
def fetch_candles(self):
return self.broker.fetch_ohlcv(self.symbol(), self.t.timeframe, self.t.candles)
def simulate(self) -> Result:
"""Simulationslauf (Paper-Trading) über die verfügbaren Candles."""
candles = self.fetch_candles()
return self.engine.run(candles)
def live_cycle(self):
"""Ein Live-Zyklus: Signal bewerten und ggf. echte Order platzieren."""
candles = self.fetch_candles()
prep = self.strategy.prepare(candles)
sig = self.strategy.last_signal(prep)
if sig.action == 1:
size = (self.t.initial_balance * self.t.position_size_pct) / max(sig.price, 1e-9)
return self.broker.create_market_order(self.symbol(), "buy", size)
if sig.action in (-1, 2):
size = (self.t.initial_balance * self.t.position_size_pct) / max(sig.price, 1e-9)
return self.broker.create_market_order(self.symbol(), "sell", size)
return None