feat: paper trader su USDC (ETH_USDC-PERPETUAL), pronto per operatività reale
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -51,8 +51,8 @@ class CerberoClient:
|
||||
|
||||
# --- Account ---
|
||||
|
||||
def get_account_summary(self) -> dict:
|
||||
return self._post("/mcp-deribit/tools/get_account_summary")
|
||||
def get_account_summary(self, currency: str = "USDC") -> dict:
|
||||
return self._post("/mcp-deribit/tools/get_account_summary", {"currency": currency})
|
||||
|
||||
def get_positions(self, currency: str = "ETH") -> list[dict]:
|
||||
return self._post("/mcp-deribit/tools/get_positions", {"currency": currency})
|
||||
|
||||
@@ -12,7 +12,9 @@ from src.live.cerbero_client import CerberoClient
|
||||
from src.live.signal_engine import SignalEngine
|
||||
|
||||
LOG_DIR = Path(__file__).resolve().parents[2] / "data" / "paper_trades"
|
||||
INSTRUMENT = "ETH-PERPETUAL"
|
||||
INSTRUMENT = "ETH_USDC-PERPETUAL"
|
||||
TRAIN_INSTRUMENT = "ETH-PERPETUAL" # storico più lungo per training
|
||||
CURRENCY = "USDC"
|
||||
RESOLUTION = "15"
|
||||
LEVERAGE = 3
|
||||
POSITION_PCT = 0.15
|
||||
@@ -60,11 +62,11 @@ class PaperTrader:
|
||||
with open(self.status_path, "w") as f:
|
||||
json.dump(status, f, indent=2)
|
||||
|
||||
def fetch_candles(self, days: int = LOOKBACK_DAYS) -> pd.DataFrame:
|
||||
def fetch_candles(self, days: int = LOOKBACK_DAYS, instrument: str | None = None) -> pd.DataFrame:
|
||||
end = datetime.now(timezone.utc)
|
||||
start = end - timedelta(days=days)
|
||||
candles = self.client.get_historical(
|
||||
INSTRUMENT,
|
||||
instrument or TRAIN_INSTRUMENT,
|
||||
start.strftime("%Y-%m-%d"),
|
||||
end.strftime("%Y-%m-%d"),
|
||||
RESOLUTION,
|
||||
@@ -77,8 +79,8 @@ class PaperTrader:
|
||||
return df
|
||||
|
||||
def train_model(self):
|
||||
self.log("TRAINING", {"lookback_days": TRAIN_LOOKBACK_DAYS})
|
||||
df = self.fetch_candles(TRAIN_LOOKBACK_DAYS)
|
||||
self.log("TRAINING", {"lookback_days": TRAIN_LOOKBACK_DAYS, "instrument": TRAIN_INSTRUMENT})
|
||||
df = self.fetch_candles(TRAIN_LOOKBACK_DAYS, TRAIN_INSTRUMENT)
|
||||
if df.empty:
|
||||
self.log("TRAINING_FAILED", {"reason": "no data"})
|
||||
return False
|
||||
@@ -93,8 +95,8 @@ class PaperTrader:
|
||||
equity = account["equity"]
|
||||
|
||||
notional = equity * POSITION_PCT
|
||||
amount = round(notional / price, 1)
|
||||
amount = max(amount, 1.0)
|
||||
amount = round(notional / price, 3)
|
||||
amount = max(amount, 0.001)
|
||||
|
||||
side = "buy" if direction == "buy" else "sell"
|
||||
|
||||
@@ -180,7 +182,7 @@ class PaperTrader:
|
||||
|
||||
def run_once(self) -> str:
|
||||
"""Esegui un singolo ciclo. Ritorna lo stato."""
|
||||
df = self.fetch_candles(LOOKBACK_DAYS)
|
||||
df = self.fetch_candles(LOOKBACK_DAYS, TRAIN_INSTRUMENT)
|
||||
if df.empty:
|
||||
return "no_data"
|
||||
|
||||
@@ -204,7 +206,8 @@ class PaperTrader:
|
||||
def run(self, retrain_hours: int = 24):
|
||||
"""Loop principale."""
|
||||
print("=" * 60)
|
||||
print(f" PAPER TRADER — {INSTRUMENT} {RESOLUTION}m")
|
||||
print(f" PAPER TRADER — {INSTRUMENT} (margine {CURRENCY})")
|
||||
print(f" Segnali da: {TRAIN_INSTRUMENT} {RESOLUTION}m")
|
||||
print(f" Leva: {LEVERAGE}x, Position: {POSITION_PCT*100:.0f}%, Hold: {HOLD_BARS} barre")
|
||||
print(f" Poll: ogni {POLL_SECONDS}s")
|
||||
print(f" Log: {self.log_path}")
|
||||
|
||||
Reference in New Issue
Block a user