Phase 1: Repair runtime breakpoints
- Fix set_new_candle() to update cached candle instead of raising
- Fix trades.update() type mismatch: pass {symbol: price} dict
- Fix StrategyInstance.trades collision: rename list to trade_history
- Add missing ExchangeInterface methods for trade status/qty/price
- Add get_user_balance stub for paper trading
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
34637df478
commit
e245f80e18
|
|
@ -343,7 +343,12 @@ class BrighterTrades:
|
||||||
self.candles.set_new_candle(cdata)
|
self.candles.set_new_candle(cdata)
|
||||||
# i_updates = self.indicators.update_indicators()
|
# i_updates = self.indicators.update_indicators()
|
||||||
state_changes = self.signals.process_all_signals(self.indicators)
|
state_changes = self.signals.process_all_signals(self.indicators)
|
||||||
trade_updates = self.trades.update(float(cdata['close']))
|
|
||||||
|
# Build price updates dict: trades.update expects {symbol: price}
|
||||||
|
symbol = cdata.get('symbol', cdata.get('market', 'BTC/USDT'))
|
||||||
|
price_updates = {symbol: float(cdata['close'])}
|
||||||
|
trade_updates = self.trades.update(price_updates)
|
||||||
|
|
||||||
# stg_updates = self.strategies.update()
|
# stg_updates = self.strategies.update()
|
||||||
|
|
||||||
updates = {}
|
updates = {}
|
||||||
|
|
|
||||||
|
|
@ -317,3 +317,58 @@ class ExchangeInterface:
|
||||||
return self.default_exchange.get_price(symbol=symbol)
|
return self.default_exchange.get_price(symbol=symbol)
|
||||||
else:
|
else:
|
||||||
raise ValueError(f'No implementation for price source: {price_source}')
|
raise ValueError(f'No implementation for price source: {price_source}')
|
||||||
|
|
||||||
|
def get_trade_status(self, trade) -> str:
|
||||||
|
"""
|
||||||
|
Get the status of a trade order.
|
||||||
|
|
||||||
|
For paper/backtest modes, assumes immediate fill (returns 'FILLED').
|
||||||
|
For live mode, should query the exchange.
|
||||||
|
|
||||||
|
:param trade: The trade object.
|
||||||
|
:return: Status string ('FILLED', 'PARTIALLY_FILLED', 'PENDING', etc.)
|
||||||
|
"""
|
||||||
|
# If order is None, it hasn't been placed yet
|
||||||
|
if trade.order is None:
|
||||||
|
return 'PENDING'
|
||||||
|
|
||||||
|
# For paper trading / backtesting, assume immediate fill
|
||||||
|
# TODO: For live trading, query exchange via get_trade_info
|
||||||
|
return 'FILLED'
|
||||||
|
|
||||||
|
def get_trade_executed_qty(self, trade) -> float:
|
||||||
|
"""
|
||||||
|
Get the executed quantity of a trade order.
|
||||||
|
|
||||||
|
For paper/backtest modes, returns the full order quantity (assumes full fill).
|
||||||
|
|
||||||
|
:param trade: The trade object.
|
||||||
|
:return: Executed quantity.
|
||||||
|
"""
|
||||||
|
# For paper trading / backtesting, assume full fill
|
||||||
|
return trade.base_order_qty
|
||||||
|
|
||||||
|
def get_trade_executed_price(self, trade) -> float:
|
||||||
|
"""
|
||||||
|
Get the executed price of a trade order.
|
||||||
|
|
||||||
|
For paper/backtest modes, returns the order price.
|
||||||
|
|
||||||
|
:param trade: The trade object.
|
||||||
|
:return: Executed price.
|
||||||
|
"""
|
||||||
|
# For paper trading / backtesting, use order price
|
||||||
|
return trade.order_price
|
||||||
|
|
||||||
|
def get_user_balance(self, user_id: int) -> float:
|
||||||
|
"""
|
||||||
|
Get the balance for a user.
|
||||||
|
|
||||||
|
Stub implementation for paper trading.
|
||||||
|
|
||||||
|
:param user_id: The user ID.
|
||||||
|
:return: Balance amount (default 10000.0 for paper trading).
|
||||||
|
"""
|
||||||
|
# TODO: Implement proper balance tracking per user
|
||||||
|
# For paper trading, return a default balance
|
||||||
|
return 10000.0
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ class StrategyInstance:
|
||||||
self.exit: bool = False
|
self.exit: bool = False
|
||||||
self.exit_method: str = 'all'
|
self.exit_method: str = 'all'
|
||||||
self.start_time = dt.datetime.now()
|
self.start_time = dt.datetime.now()
|
||||||
self.trades = [] # List to store trade details
|
self.trade_history = [] # List to store trade details (not the Trades manager)
|
||||||
self.orders = [] # List to store order details
|
self.orders = [] # List to store order details
|
||||||
self.profit_loss = 0.0 # Total P&L
|
self.profit_loss = 0.0 # Total P&L
|
||||||
self.statistics = {
|
self.statistics = {
|
||||||
|
|
|
||||||
|
|
@ -79,25 +79,19 @@ class Candles:
|
||||||
# Return the results. The start_datetime was approximate, so we may have retrieved an extra result.
|
# Return the results. The start_datetime was approximate, so we may have retrieved an extra result.
|
||||||
return self.convert_candles(candles[-num_candles:])
|
return self.convert_candles(candles[-num_candles:])
|
||||||
|
|
||||||
def set_new_candle(self, cdata):
|
def set_new_candle(self, cdata: dict) -> bool:
|
||||||
"""
|
"""
|
||||||
Sets the last candle and updates the latest values list.
|
Updates the cached last candle with new candle data.
|
||||||
|
Called when live price data arrives via WebSocket.
|
||||||
|
|
||||||
:param cdata: A list of data for a single candle.[ot,o,h,l,c,ct,...]
|
:param cdata: Dictionary containing candle data with keys like
|
||||||
:return: True. todo: This method probably wont be needed.
|
'time', 'open', 'high', 'low', 'close', 'volume', 'symbol', etc.
|
||||||
|
:return: True if the candle was updated.
|
||||||
"""
|
"""
|
||||||
raise ValueError('set_new_candle')
|
# Update the cached last candle
|
||||||
# this will probably rename to update_cache()
|
self.cached_last_candle = cdata
|
||||||
|
log.debug(f"Candle updated: {cdata.get('symbol', 'unknown')} @ {cdata.get('close', 0)}")
|
||||||
#
|
return True
|
||||||
# if cdata[4] < self.cashed_candlesticks[-2][4]:
|
|
||||||
# color = 'rgba(255,82,82, 0.8)' # Red
|
|
||||||
# else:
|
|
||||||
# color = 'rgba(0, 150, 136, 0.8)' # Green
|
|
||||||
# self.cashed_vol.append({'time': cdata['time'], 'value': cdata['vol'], "color": color})
|
|
||||||
# self.cashed_vol.pop(0)
|
|
||||||
# return True
|
|
||||||
#
|
|
||||||
def set_cache(self, symbol=None, interval=None, exchange_name=None, user_name=None):
|
def set_cache(self, symbol=None, interval=None, exchange_name=None, user_name=None):
|
||||||
"""
|
"""
|
||||||
This method requests a chart from memory to ensure the data is initialized.
|
This method requests a chart from memory to ensure the data is initialized.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue