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:
rob 2026-02-28 16:47:13 -04:00
parent 34637df478
commit e245f80e18
4 changed files with 72 additions and 18 deletions

View File

@ -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 = {}

View File

@ -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

View File

@ -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 = {

View File

@ -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.