From 1a9101a123aa47888b1b704ea645127509cdd0b9 Mon Sep 17 00:00:00 2001 From: m5l14i11 Date: Thu, 19 Sep 2024 20:33:38 +0300 Subject: [PATCH] upd --- core/commands/broker.py | 2 +- core/events/position.py | 2 +- core/events/risk.py | 2 +- core/events/signal.py | 2 +- core/interfaces/abstract_exchange.py | 2 +- .../abstract_order_size_strategy.py | 2 +- core/interfaces/abstract_position_factory.py | 4 +- .../abstract_position_risk_strategy.py | 2 +- core/models/entity/_base.py | 17 ++-- core/models/{ => entity}/position.py | 44 +++------- core/models/{ => entity}/position_risk.py | 87 +++++++++---------- core/models/{ => entity}/profit_target.py | 31 +++---- core/models/{ => entity}/signal.py | 30 ++----- core/models/entity/signal_risk.py | 12 +++ core/models/signal_risk.py | 24 ----- core/models/strategy_ref.py | 2 +- core/queries/broker.py | 2 +- core/queries/copilot.py | 4 +- core/queries/portfolio.py | 2 +- core/queries/position.py | 2 +- executor/_paper_actor.py | 2 +- portfolio/_portfolio.py | 2 +- position/_position_factory.py | 12 +-- position/_state.py | 2 +- position/size/fixed.py | 2 +- position/size/kelly.py | 4 +- position/size/optimal_f.py | 2 +- risk/_actor.py | 8 +- 28 files changed, 131 insertions(+), 178 deletions(-) rename core/models/{ => entity}/position.py (89%) rename core/models/{ => entity}/position_risk.py (87%) rename core/models/{ => entity}/profit_target.py (80%) rename core/models/{ => entity}/signal.py (57%) create mode 100644 core/models/entity/signal_risk.py delete mode 100644 core/models/signal_risk.py diff --git a/core/commands/broker.py b/core/commands/broker.py index a4655f68..17dfd3f1 100644 --- a/core/commands/broker.py +++ b/core/commands/broker.py @@ -2,7 +2,7 @@ from core.events.base import EventMeta from core.models.broker import MarginMode, PositionMode -from core.models.position import Position +from core.models.entity.position import Position from core.models.symbol import Symbol from .base import Command, CommandGroup diff --git a/core/events/position.py b/core/events/position.py index d5372d77..bb919d42 100644 --- a/core/events/position.py +++ b/core/events/position.py @@ -1,6 +1,6 @@ from dataclasses import dataclass, field -from core.models.position import Position +from core.models.entity.position import Position from .base import Event, EventGroup, EventMeta diff --git a/core/events/risk.py b/core/events/risk.py index 6ca91c53..9f027403 100644 --- a/core/events/risk.py +++ b/core/events/risk.py @@ -1,6 +1,6 @@ from dataclasses import dataclass, field -from core.models.position import Position +from core.models.entity.position import Position from .base import Event, EventGroup, EventMeta diff --git a/core/events/signal.py b/core/events/signal.py index e9653ab4..2df1cd3c 100644 --- a/core/events/signal.py +++ b/core/events/signal.py @@ -1,6 +1,6 @@ from dataclasses import dataclass, field -from core.models.signal import Signal +from core.models.entity.signal import Signal from .base import Event, EventGroup, EventMeta diff --git a/core/interfaces/abstract_exchange.py b/core/interfaces/abstract_exchange.py index 93761033..d289f088 100644 --- a/core/interfaces/abstract_exchange.py +++ b/core/interfaces/abstract_exchange.py @@ -1,8 +1,8 @@ from abc import ABC, abstractmethod from core.models.broker import MarginMode, PositionMode +from core.models.entity.position import PositionSide from core.models.lookback import Lookback -from core.models.position import PositionSide from core.models.symbol import Symbol from core.models.timeframe import Timeframe diff --git a/core/interfaces/abstract_order_size_strategy.py b/core/interfaces/abstract_order_size_strategy.py index d87f29bf..326528eb 100644 --- a/core/interfaces/abstract_order_size_strategy.py +++ b/core/interfaces/abstract_order_size_strategy.py @@ -1,7 +1,7 @@ from abc import abstractmethod from core.interfaces.abstract_event_manager import AbstractEventManager -from core.models.signal import Signal +from core.models.entity.signal import Signal class AbstractOrderSizeStrategy(AbstractEventManager): diff --git a/core/interfaces/abstract_position_factory.py b/core/interfaces/abstract_position_factory.py index 96302a40..a1a8e5af 100644 --- a/core/interfaces/abstract_position_factory.py +++ b/core/interfaces/abstract_position_factory.py @@ -1,8 +1,8 @@ from abc import ABC, abstractmethod -from core.models.position import Position +from core.models.entity.position import Position +from core.models.entity.signal import Signal from core.models.risk_type import SignalRiskType -from core.models.signal import Signal from core.models.ta import TechAnalysis diff --git a/core/interfaces/abstract_position_risk_strategy.py b/core/interfaces/abstract_position_risk_strategy.py index 95cbf91c..876d1f73 100644 --- a/core/interfaces/abstract_position_risk_strategy.py +++ b/core/interfaces/abstract_position_risk_strategy.py @@ -2,7 +2,7 @@ from typing import List, Tuple from core.models.entity.ohlcv import OHLCV -from core.models.signal import SignalSide +from core.models.entity.signal import SignalSide class AbstractPositionRiskStrategy(ABC): diff --git a/core/models/entity/_base.py b/core/models/entity/_base.py index df604867..2fafdefc 100644 --- a/core/models/entity/_base.py +++ b/core/models/entity/_base.py @@ -54,11 +54,18 @@ def from_list(cls, values: List[Any]) -> "Entity": return cls.from_dict(data) def __str__(self) -> str: - field_dict = { - key: value - for key, value in self.to_dict().items() - if not key.startswith("_") - } + def filter_private_fields(data): + if isinstance(data, dict): + return { + key: filter_private_fields(value) + for key, value in data.items() + if not key.startswith("_") + } + elif isinstance(data, list): + return [filter_private_fields(item) for item in data] + return data + + field_dict = filter_private_fields(self.to_dict()) def format_value(value): if isinstance(value, dict): diff --git a/core/models/position.py b/core/models/entity/position.py similarity index 89% rename from core/models/position.py rename to core/models/entity/position.py index ba8bdeb4..a7b266a2 100644 --- a/core/models/position.py +++ b/core/models/entity/position.py @@ -1,21 +1,23 @@ import logging import uuid -from dataclasses import dataclass, field, replace +from dataclasses import field, replace from datetime import datetime from typing import List, Optional, Tuple import numpy as np -from .entity.ohlcv import OHLCV -from .entity.order import Order -from .order_type import OrderStatus +from core.models.order_type import OrderStatus +from core.models.risk_type import PositionRiskType, SessionRiskType, SignalRiskType +from core.models.side import PositionSide, SignalSide +from core.models.ta import TechAnalysis + +from ._base import Entity +from .ohlcv import OHLCV +from .order import Order from .position_risk import PositionRisk from .profit_target import ProfitTarget -from .risk_type import PositionRiskType, SessionRiskType, SignalRiskType -from .side import PositionSide, SignalSide from .signal import Signal from .signal_risk import SignalRisk -from .ta import TechAnalysis logger = logging.getLogger(__name__) @@ -23,7 +25,7 @@ LATENCY_GAP_THRESHOLD = 1.8 -@dataclass(frozen=True) +@Entity class Position: initial_size: float signal: Signal @@ -436,29 +438,3 @@ def _average_size(orders: List[Order]) -> float: def _average_price(orders: List[Order]) -> float: total_price = sum(order.price for order in orders) return total_price / len(orders) if orders else 0.0 - - def to_dict(self): - return { - "signal": self.signal.to_dict(), - "signal_risk": self.signal_risk.to_dict(), - "position_risk": self.position_risk.to_dict(), - "curr_target": self.curr_target, - "side": str(self.side), - "size": self.size, - "entry_price": self.entry_price, - "exit_price": self.exit_price, - "closed": self.closed, - "valid": self.is_valid, - "pnl": self.pnl, - "fee": self.fee, - "take_profit": self.take_profit, - "stop_loss": self.stop_loss, - "trade_time": self.trade_time, - "break_even": self.has_break_even, - } - - def __str__(self): - return f"signal={self.signal}, signal_risk={self.signal_risk.type}, position_risk={self.position_risk.type}, open_ohlcv={self.signal_bar}, close_ohlcv={self.risk_bar}, side={self.side}, size={self.size}, entry_price={self.entry_price}, exit_price={self.exit_price}, tp={self.take_profit}, sl={self.stop_loss}, pnl={self.pnl}, trade_time={self.trade_time}, closed={self.closed}, valid={self.is_valid}, break_even={self.has_break_even}" - - def __repr__(self): - return f"Position({self})" diff --git a/core/models/position_risk.py b/core/models/entity/position_risk.py similarity index 87% rename from core/models/position_risk.py rename to core/models/entity/position_risk.py index 0d0e1591..8c70b36a 100644 --- a/core/models/position_risk.py +++ b/core/models/entity/position_risk.py @@ -1,4 +1,4 @@ -from dataclasses import dataclass, field, replace +from dataclasses import field, replace from typing import List, Tuple import numpy as np @@ -13,10 +13,12 @@ ) from sklearn.preprocessing import MinMaxScaler, StandardScaler -from .entity.ohlcv import OHLCV -from .risk_type import PositionRiskType -from .side import PositionSide -from .ta import TechAnalysis +from core.models.risk_type import PositionRiskType +from core.models.side import PositionSide +from core.models.ta import TechAnalysis + +from ._base import Entity +from .ohlcv import OHLCV TIME_THRESHOLD = 10000 LOOKBACK = 6 @@ -126,23 +128,31 @@ def _ats(closes: List[float], atr: List[float]) -> List[float]: OHLCV_SIZE = 200 -@dataclass(frozen=True) +@Entity class PositionRisk(TaMixin): - model: SGDRegressor - scaler: StandardScaler - ohlcv: List[OHLCV] = field(default_factory=list) + _model: SGDRegressor + _scaler: StandardScaler + _ohlcv: List[OHLCV] = field(default_factory=list) type: PositionRiskType = PositionRiskType.NONE trail_factor: float = field(default_factory=lambda: np.random.uniform(1.1, 1.8)) @property def curr_bar(self): - return self.ohlcv[-1] + return self._ohlcv[-1] + + @property + def time_points(self): + return [o.timestamp for o in self._ohlcv] + + @property + def session(self): + return self._ohlcv def update_model(self): - if len(self.ohlcv) < 3: + if len(self._ohlcv) < 3: return - last_ohlcv = self.ohlcv[-3:] + last_ohlcv = self._ohlcv[-3:] close = [ohlcv.close for ohlcv in last_ohlcv] high = [ohlcv.high for ohlcv in last_ohlcv] @@ -184,23 +194,23 @@ def update_model(self): ) target = np.array([close[-1]]) - features_scaled = self.scaler.transform(features) + features_scaled = self._scaler.transform(features) - self.model.partial_fit(features_scaled, target) + self._model.partial_fit(features_scaled, target) def forecast(self, steps: int = 3): - if len(self.ohlcv) < 1: + if len(self._ohlcv) < 1: return [] self.update_model() - last_ohlcv = self.ohlcv[-1] + last_ohlcv = self._ohlcv[-1] last_hlcc4 = (last_ohlcv.high + last_ohlcv.low + 2 * last_ohlcv.close) / 4.0 last_true_range = max( last_ohlcv.high - last_ohlcv.low, - abs(last_ohlcv.high - self.ohlcv[-2].close), - abs(last_ohlcv.low - self.ohlcv[-2].close), + abs(last_ohlcv.high - self._ohlcv[-2].close), + abs(last_ohlcv.low - self._ohlcv[-2].close), ) last_hlcc4_lagged_1 = last_hlcc4 @@ -229,9 +239,9 @@ def forecast(self, steps: int = 3): ] ) - X_scaled = self.scaler.transform(X) + X_scaled = self._scaler.transform(X) - forecast = self.model.predict(X_scaled)[0] + forecast = self._model.predict(X_scaled)[0] predictions.append(forecast) last_hlcc4_lagged_2 = last_hlcc4_lagged_1 @@ -242,16 +252,16 @@ def forecast(self, steps: int = 3): last_true_range_lagged_1 = last_true_range last_true_range = max( forecast - last_ohlcv.close, - abs(forecast - self.ohlcv[-2].close), - abs(last_ohlcv.low - self.ohlcv[-2].close), + abs(forecast - self._ohlcv[-2].close), + abs(last_ohlcv.low - self._ohlcv[-2].close), ) return predictions def next(self, bar: OHLCV): - ohlcv = (self.ohlcv + [bar])[-OHLCV_SIZE:] + ohlcv = (self._ohlcv + [bar])[-OHLCV_SIZE:] ohlcv.sort(key=lambda x: x.timestamp) - return replace(self, ohlcv=ohlcv) + return replace(self, _ohlcv=ohlcv) def reset(self): return replace(self, type=PositionRiskType.NONE) @@ -300,7 +310,7 @@ def exit_price(self, side: PositionSide, tp: float, sl: float) -> "float": return close def sl_low(self, side: PositionSide, ta: TechAnalysis, sl: float) -> "float": - timestamps = np.array([candle.timestamp for candle in self.ohlcv]) + timestamps = np.array(self.time_points) ts_diff = np.diff(timestamps) if ts_diff.sum() < TIME_THRESHOLD: @@ -339,7 +349,7 @@ def sl_low(self, side: PositionSide, ta: TechAnalysis, sl: float) -> "float": return sl def tp_low(self, side: PositionSide, ta: TechAnalysis, tp: float) -> "float": - timestamps = np.array([candle.timestamp for candle in self.ohlcv]) + timestamps = np.array(self.time_points) ts_diff = np.diff(timestamps) if ts_diff.sum() < TIME_THRESHOLD: @@ -377,7 +387,7 @@ def tp_low(self, side: PositionSide, ta: TechAnalysis, tp: float) -> "float": return tp def sl_ats(self, side: PositionSide, ta: TechAnalysis, sl: float) -> "float": - timestamps = np.array([candle.timestamp for candle in self.ohlcv]) + timestamps = np.array(self.time_points) ts_diff = np.diff(timestamps) if ts_diff.sum() < TIME_THRESHOLD: @@ -385,9 +395,9 @@ def sl_ats(self, side: PositionSide, ta: TechAnalysis, sl: float) -> "float": max_lookback = max(len(timestamps), LOOKBACK) - close = np.array([candle.close for candle in self.ohlcv]) - low = np.array([candle.low for candle in self.ohlcv]) - high = np.array([candle.high for candle in self.ohlcv]) + close = np.array([candle.close for candle in self._ohlcv]) + low = np.array([candle.low for candle in self._ohlcv]) + high = np.array([candle.high for candle in self._ohlcv]) volatility = np.array(ta.volatility.gkyz)[-max_lookback:] min_length = min(len(close), len(volatility), len(high), len(low)) @@ -395,7 +405,9 @@ def sl_ats(self, side: PositionSide, ta: TechAnalysis, sl: float) -> "float": if min_length < 3: return sl - anomaly = lambda series: (series - np.mean(series)) / np.std(series) + def anomaly(series): + return (series - np.mean(series)) / np.std(series) + close_anomaly = anomaly(close[-min_length:]) if abs(close_anomaly[-1]) > 2: @@ -437,16 +449,3 @@ def sl_ats(self, side: PositionSide, ta: TechAnalysis, sl: float) -> "float": return min(sl, min(atr_stop, adjusted_sl)) return sl - - def to_dict(self): - return { - "type": self.type, - "trail_factor": self.trail_factor, - "ohlcv": self.curr_bar.to_dict(), - } - - def __str__(self): - return f"type={self.type}, ohlcv={self.curr_bar}" - - def __repr__(self): - return f"PositionRisk({self})" diff --git a/core/models/profit_target.py b/core/models/entity/profit_target.py similarity index 80% rename from core/models/profit_target.py rename to core/models/entity/profit_target.py index 72c5fe04..717075fe 100644 --- a/core/models/profit_target.py +++ b/core/models/entity/profit_target.py @@ -1,21 +1,18 @@ -from dataclasses import dataclass from functools import cached_property import numpy as np from core.models.side import SignalSide +from ._base import Entity -@dataclass(frozen=True) + +@Entity class ProfitTarget: - side: SignalSide + _side: SignalSide entry: float - volatility: float - noise_sigma: float = 0.001 - - @cached_property - def context_factor(self): - return 1.0 if self.side == SignalSide.BUY else -1.0 + _volatility: float + _noise_sigma: float = 0.001 @cached_property def targets(self): @@ -110,27 +107,25 @@ def targets(self): } ) - reverse = self.context_factor == -1 + reverse = self._context_factor() == -1 return levels if not reverse else levels[::-1] @cached_property def last(self): return self.targets[-1] + def _context_factor(self): + return 1.0 if self._side == SignalSide.BUY else -1.0 + def _pt(self, min_scale: float, max_scale: float) -> float: scale = np.random.uniform(min_scale, max_scale) - noise = np.random.lognormal(mean=0, sigma=self.noise_sigma) - 1 + noise = np.random.lognormal(mean=0, sigma=self._noise_sigma) - 1 target_price = self.entry * ( - 1 + self.volatility * self.context_factor * scale + noise + 1 + self._volatility * self._context_factor() * scale + noise ) return ( max(target_price, self.entry) - if self.context_factor == 1 + if self._context_factor() == 1 else min(target_price, self.entry) ) - - def to_dict(self): - return { - "targets": self.targets, - } diff --git a/core/models/signal.py b/core/models/entity/signal.py similarity index 57% rename from core/models/signal.py rename to core/models/entity/signal.py index 84973a8a..28833641 100644 --- a/core/models/signal.py +++ b/core/models/entity/signal.py @@ -1,13 +1,15 @@ -from dataclasses import dataclass, field +from dataclasses import field -from .entity.ohlcv import OHLCV -from .side import SignalSide -from .strategy import Strategy -from .symbol import Symbol -from .timeframe import Timeframe +from core.models.side import SignalSide +from core.models.strategy import Strategy +from core.models.symbol import Symbol +from core.models.timeframe import Timeframe +from ._base import Entity +from .ohlcv import OHLCV -@dataclass(frozen=True) + +@Entity class Signal: symbol: Symbol timeframe: Timeframe @@ -32,19 +34,5 @@ def __eq__(self, other: object) -> bool: and self.strategy == other.strategy ) - def to_dict(self): - return { - "symbol": str(self.symbol), - "timeframe": str(self.timeframe), - "strategy": str(self.strategy), - "side": str(self.side), - "ohlcv": self.ohlcv.to_dict(), - "entry": self.entry, - "stop_loss": self.stop_loss, - } - def __str__(self) -> str: return f"{self.symbol.name}_{self.timeframe}_{self.side}{self.strategy}" - - def __repr__(self) -> str: - return f"Signal({self})" diff --git a/core/models/entity/signal_risk.py b/core/models/entity/signal_risk.py new file mode 100644 index 00000000..96d395ff --- /dev/null +++ b/core/models/entity/signal_risk.py @@ -0,0 +1,12 @@ +from typing import Optional + +from core.models.risk_type import SignalRiskType + +from ._base import Entity + + +@Entity +class SignalRisk: + type: SignalRiskType = SignalRiskType.NONE + tp: Optional[float] = None + sl: Optional[float] = None diff --git a/core/models/signal_risk.py b/core/models/signal_risk.py deleted file mode 100644 index ceb04f7b..00000000 --- a/core/models/signal_risk.py +++ /dev/null @@ -1,24 +0,0 @@ -from dataclasses import dataclass -from typing import Optional - -from core.models.risk_type import SignalRiskType - - -@dataclass(frozen=True) -class SignalRisk: - type: SignalRiskType = SignalRiskType.NONE - tp: Optional[float] = None - sl: Optional[float] = None - - def to_dict(self): - return { - "type": self.type, - "tp": self.tp, - "sl": self.sl, - } - - def __str__(self): - return f"type={self.type}, tp={self.tp}, sl={self.sl}" - - def __repr__(self): - return f"SignalRisk({self})" diff --git a/core/models/strategy_ref.py b/core/models/strategy_ref.py index 70f8f3a9..89aacad1 100644 --- a/core/models/strategy_ref.py +++ b/core/models/strategy_ref.py @@ -15,8 +15,8 @@ ) from core.models.action import Action from core.models.entity.ohlcv import OHLCV +from core.models.entity.signal import Signal from core.models.side import SignalSide -from core.models.signal import Signal from core.models.strategy import Strategy from core.models.symbol import Symbol from core.models.timeframe import Timeframe diff --git a/core/queries/broker.py b/core/queries/broker.py index 30b3fa3a..ecee9559 100644 --- a/core/queries/broker.py +++ b/core/queries/broker.py @@ -2,7 +2,7 @@ from typing import List from core.events.base import EventMeta -from core.models.position import Position +from core.models.entity.position import Position from core.models.symbol import Symbol from .base import Query, QueryGroup diff --git a/core/queries/copilot.py b/core/queries/copilot.py index 28e05e28..5818d101 100644 --- a/core/queries/copilot.py +++ b/core/queries/copilot.py @@ -3,10 +3,10 @@ from core.events.base import EventMeta from core.models.entity.ohlcv import OHLCV +from core.models.entity.signal import Signal +from core.models.entity.signal_risk import SignalRisk from core.models.risk_type import SessionRiskType from core.models.side import PositionSide -from core.models.signal import Signal -from core.models.signal_risk import SignalRisk from core.models.ta import TechAnalysis from .base import Query, QueryGroup diff --git a/core/queries/portfolio.py b/core/queries/portfolio.py index e813742a..a331b324 100644 --- a/core/queries/portfolio.py +++ b/core/queries/portfolio.py @@ -2,7 +2,7 @@ from typing import List from core.events.base import EventMeta -from core.models.signal import Signal +from core.models.entity.signal import Signal from core.models.size import PositionSizeType from core.models.strategy import Strategy from core.models.symbol import Symbol diff --git a/core/queries/position.py b/core/queries/position.py index f807302e..45fe3fe1 100644 --- a/core/queries/position.py +++ b/core/queries/position.py @@ -2,7 +2,7 @@ from core.events.base import EventMeta from core.models.entity.order import Order -from core.models.position import Position +from core.models.entity.position import Position from core.queries.base import Query, QueryGroup diff --git a/executor/_paper_actor.py b/executor/_paper_actor.py index 8380c57d..72e4235c 100644 --- a/executor/_paper_actor.py +++ b/executor/_paper_actor.py @@ -12,8 +12,8 @@ from core.mixins import EventHandlerMixin from core.models.entity.ohlcv import OHLCV from core.models.entity.order import Order +from core.models.entity.position import Position from core.models.order_type import OrderStatus, OrderType -from core.models.position import Position from core.models.side import PositionSide from core.models.symbol import Symbol from core.models.timeframe import Timeframe diff --git a/portfolio/_portfolio.py b/portfolio/_portfolio.py index 9de5b362..8454bddd 100644 --- a/portfolio/_portfolio.py +++ b/portfolio/_portfolio.py @@ -3,7 +3,7 @@ from typing import Dict, Tuple from core.models.entity.portfolio import Performance -from core.models.position import Position +from core.models.entity.position import Position from core.models.strategy import Strategy from core.models.symbol import Symbol from core.models.timeframe import Timeframe diff --git a/position/_position_factory.py b/position/_position_factory.py index 8a8d0dab..e1ab936d 100644 --- a/position/_position_factory.py +++ b/position/_position_factory.py @@ -6,11 +6,11 @@ from core.interfaces.abstract_order_size_strategy import AbstractOrderSizeStrategy from core.interfaces.abstract_position_factory import AbstractPositionFactory from core.models.entity.ohlcv import OHLCV -from core.models.position import Position -from core.models.position_risk import PositionRisk -from core.models.profit_target import ProfitTarget -from core.models.signal import Signal -from core.models.signal_risk import SignalRisk +from core.models.entity.position import Position +from core.models.entity.position_risk import PositionRisk +from core.models.entity.profit_target import ProfitTarget +from core.models.entity.signal import Signal +from core.models.entity.signal_risk import SignalRisk from core.models.ta import TechAnalysis @@ -34,7 +34,7 @@ async def create( model, scaler = self._create_model(ta, signal.ohlcv) - position_risk = PositionRisk(model=model, scaler=scaler).next(signal.ohlcv) + position_risk = PositionRisk(_model=model, _scaler=scaler).next(signal.ohlcv) profit_target = ProfitTarget( signal.side, signal.ohlcv.close, ta.volatility.yz[-1] ) diff --git a/position/_state.py b/position/_state.py index 94a02a1d..2c19458e 100644 --- a/position/_state.py +++ b/position/_state.py @@ -2,7 +2,7 @@ from contextlib import asynccontextmanager from typing import List, Optional, Tuple -from core.models.position import Position +from core.models.entity.position import Position from core.models.side import PositionSide from core.models.symbol import Symbol from core.models.timeframe import Timeframe diff --git a/position/size/fixed.py b/position/size/fixed.py index f35c2839..c771743a 100644 --- a/position/size/fixed.py +++ b/position/size/fixed.py @@ -1,5 +1,5 @@ from core.interfaces.abstract_order_size_strategy import AbstractOrderSizeStrategy -from core.models.signal import Signal +from core.models.entity.signal import Signal from core.models.size import PositionSizeType from core.queries.portfolio import GetPositionRisk diff --git a/position/size/kelly.py b/position/size/kelly.py index f8260db6..1db20009 100644 --- a/position/size/kelly.py +++ b/position/size/kelly.py @@ -1,11 +1,11 @@ from core.interfaces.abstract_order_size_strategy import AbstractOrderSizeStrategy -from core.models.signal import Signal +from core.models.entity.signal import Signal from core.models.size import PositionSizeType from core.queries.portfolio import GetPositionRisk class PositionKellySizeStrategy(AbstractOrderSizeStrategy): - def __init__(self, kelly_factor: float = 0.033): + def __init__(self, kelly_factor: float = 0.1): super().__init__() self.kelly_factor = kelly_factor diff --git a/position/size/optimal_f.py b/position/size/optimal_f.py index 0da960ff..2f564c5f 100644 --- a/position/size/optimal_f.py +++ b/position/size/optimal_f.py @@ -1,5 +1,5 @@ from core.interfaces.abstract_order_size_strategy import AbstractOrderSizeStrategy -from core.models.signal import Signal +from core.models.entity.signal import Signal from core.models.size import PositionSizeType from core.queries.portfolio import GetPositionRisk diff --git a/risk/_actor.py b/risk/_actor.py index 96d7dfd2..9cc418cf 100644 --- a/risk/_actor.py +++ b/risk/_actor.py @@ -23,7 +23,7 @@ from core.interfaces.abstract_config import AbstractConfig from core.mixins import EventHandlerMixin from core.models.entity.ohlcv import OHLCV -from core.models.position import Position +from core.models.entity.position import Position from core.models.side import PositionSide from core.models.symbol import Symbol from core.models.timeframe import Timeframe @@ -186,8 +186,8 @@ async def _process_market( prev_bar = next_bar for bar in sorted(bars, key=lambda x: x.timestamp): - ohlcv = next_position.position_risk.ohlcv - ts = np.array([o.timestamp for o in ohlcv]) + risk = next_position.position_risk + ts = np.array(risk.time_points) if len(ts) > 2: ts_diff = _ema(np.diff(ts)) @@ -221,7 +221,7 @@ async def _process_market( ta = await self.ask(TA(self.symbol, self.timeframe, bar)) session_risk = await self.ask( - EvaluateSession(next_position.side, ohlcv, ta) + EvaluateSession(next_position.side, risk.session, ta) ) next_position = next_position.next(bar, ta, session_risk)