feat: enforce profit-only spot exits
This commit is contained in:
+28
-8
@@ -13,7 +13,11 @@ from crypto_spot_bot.learning import TradeLearner
|
||||
from crypto_spot_bot.market_data import MarketData
|
||||
from crypto_spot_bot.models import BotStatus, Signal, Ticker, utc_now
|
||||
from crypto_spot_bot.patterns import PatternAnalyzer
|
||||
from crypto_spot_bot.strategy import SpotStrategy, torch_model_readiness_reasons
|
||||
from crypto_spot_bot.strategy import (
|
||||
SpotStrategy,
|
||||
apply_profit_only_exit_policy,
|
||||
torch_model_readiness_reasons,
|
||||
)
|
||||
from crypto_spot_bot.storage import Storage
|
||||
from crypto_spot_bot.time_series import TimeSeriesForecaster, _barrier_outcome
|
||||
|
||||
@@ -165,6 +169,8 @@ class CryptoSpotBot:
|
||||
adaptive_rules["reduce_now"] = position.id is not None and position.id == reduction_candidate_id
|
||||
learning = {"adaptive_rules": adaptive_rules}
|
||||
signal = self.strategy.exit_signal(position, candles, ticker, learning, forecast)
|
||||
if ticker is not None:
|
||||
signal = apply_profit_only_exit_policy(self.settings, position, ticker, signal)
|
||||
self._record_signal(signal)
|
||||
if signal.action == "SELL" and ticker is not None:
|
||||
await asyncio.to_thread(self.broker.sell, position, ticker, signal.reason)
|
||||
@@ -371,14 +377,28 @@ class CryptoSpotBot:
|
||||
volume_24h=0.0,
|
||||
change_24h=0.0,
|
||||
)
|
||||
self.broker.sell(
|
||||
position,
|
||||
synthetic_ticker,
|
||||
f"{self.settings.strategy_mode}: закрыта старая paper-позиция вне списка разрешенных пар",
|
||||
)
|
||||
self.storage.event(
|
||||
f"{position.symbol}: старая paper-позиция закрыта при переходе на {self.settings.strategy_mode}"
|
||||
candidate = Signal(
|
||||
position.symbol,
|
||||
"SELL",
|
||||
0.5,
|
||||
f"{self.settings.strategy_mode}: старая paper-позиция вне списка разрешенных пар",
|
||||
{
|
||||
"emergency_exit": True,
|
||||
"emergency_exit_type": "symbol_removed_from_universe",
|
||||
},
|
||||
)
|
||||
decision = apply_profit_only_exit_policy(self.settings, position, synthetic_ticker, candidate)
|
||||
self._record_signal(decision)
|
||||
if decision.action == "SELL":
|
||||
self.broker.sell(position, synthetic_ticker, decision.reason)
|
||||
self.storage.event(
|
||||
f"{position.symbol}: старая paper-позиция закрыта при переходе на {self.settings.strategy_mode}"
|
||||
)
|
||||
else:
|
||||
self.storage.event(
|
||||
f"{position.symbol}: старая paper-позиция сохранена политикой profit-only",
|
||||
"WARN",
|
||||
)
|
||||
|
||||
def _reduction_candidate_id(self, prices: dict[str, float]) -> int | None:
|
||||
rules = self._with_exposure_context(self.learner.state.adaptive_rules or {})
|
||||
|
||||
Reference in New Issue
Block a user