Calculate demo equity and PNL with open positions
Этот коммит содержится в:
@@ -23,6 +23,9 @@ class DemoAccount(BaseModel):
|
|||||||
balance: float
|
balance: float
|
||||||
equity: float
|
equity: float
|
||||||
realized_pnl: float = 0.0
|
realized_pnl: float = 0.0
|
||||||
|
unrealized_pnl: float = 0.0
|
||||||
|
total_pnl: float = 0.0
|
||||||
|
open_positions_value: float = 0.0
|
||||||
trades: list[DemoTrade] = Field(default_factory=list)
|
trades: list[DemoTrade] = Field(default_factory=list)
|
||||||
|
|
||||||
|
|
||||||
@@ -43,11 +46,19 @@ class DemoAccountService:
|
|||||||
def snapshot(self, db: Session) -> DemoAccount:
|
def snapshot(self, db: Session) -> DemoAccount:
|
||||||
state = self._get_or_create_state(db)
|
state = self._get_or_create_state(db)
|
||||||
trades = db.query(DemoTradeRecord).order_by(DemoTradeRecord.id.desc()).limit(100).all()
|
trades = db.query(DemoTradeRecord).order_by(DemoTradeRecord.id.desc()).limit(100).all()
|
||||||
|
open_value = self.open_positions_value(db)
|
||||||
|
unrealized = self.open_positions_unrealized_pnl(db)
|
||||||
|
state.equity = state.balance + open_value
|
||||||
|
db.add(state)
|
||||||
|
db.commit()
|
||||||
return DemoAccount(
|
return DemoAccount(
|
||||||
quote_asset=state.quote_asset,
|
quote_asset=state.quote_asset,
|
||||||
balance=state.balance,
|
balance=state.balance,
|
||||||
equity=state.equity,
|
equity=state.equity,
|
||||||
realized_pnl=state.realized_pnl,
|
realized_pnl=state.realized_pnl,
|
||||||
|
unrealized_pnl=unrealized,
|
||||||
|
total_pnl=state.realized_pnl + unrealized,
|
||||||
|
open_positions_value=open_value,
|
||||||
trades=[DemoTrade.model_validate(trade) for trade in reversed(trades)],
|
trades=[DemoTrade.model_validate(trade) for trade in reversed(trades)],
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -135,8 +146,6 @@ class DemoAccountService:
|
|||||||
position = self.get_open_position(db, market)
|
position = self.get_open_position(db, market)
|
||||||
if position is None or position.amount <= 0:
|
if position is None or position.amount <= 0:
|
||||||
raise ValueError(f'нет открытой позиции по {market} для полного закрытия')
|
raise ValueError(f'нет открытой позиции по {market} для полного закрытия')
|
||||||
# In demo mode the database position is the balance source of truth.
|
|
||||||
# In live mode the execution adapter must replace this with exchange balance verification.
|
|
||||||
verified_amount = position.amount
|
verified_amount = position.amount
|
||||||
return self.add_demo_trade(db, market, 'sell', price, verified_amount, f'{reason}; закрытие всей доступной суммы {verified_amount:g}')
|
return self.add_demo_trade(db, market, 'sell', price, verified_amount, f'{reason}; закрытие всей доступной суммы {verified_amount:g}')
|
||||||
|
|
||||||
@@ -156,7 +165,14 @@ class DemoAccountService:
|
|||||||
base = position.avg_entry_price * position.amount
|
base = position.avg_entry_price * position.amount
|
||||||
position.unrealized_pnl_pct = (position.unrealized_pnl / base * 100) if base else 0.0
|
position.unrealized_pnl_pct = (position.unrealized_pnl / base * 100) if base else 0.0
|
||||||
db.add(position)
|
db.add(position)
|
||||||
|
state = self._get_or_create_state(db)
|
||||||
|
state.equity = state.balance + self.open_positions_value(db)
|
||||||
|
db.add(state)
|
||||||
|
|
||||||
def open_positions_value(self, db: Session) -> float:
|
def open_positions_value(self, db: Session) -> float:
|
||||||
positions = db.query(DemoPosition).filter(DemoPosition.is_open.is_(True)).all()
|
positions = db.query(DemoPosition).filter(DemoPosition.is_open.is_(True)).all()
|
||||||
return sum(position.current_price * position.amount for position in positions)
|
return sum(position.current_price * position.amount for position in positions)
|
||||||
|
|
||||||
|
def open_positions_unrealized_pnl(self, db: Session) -> float:
|
||||||
|
positions = db.query(DemoPosition).filter(DemoPosition.is_open.is_(True)).all()
|
||||||
|
return sum(position.unrealized_pnl for position in positions)
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user