diff --git a/src/static/trade.js b/src/static/trade.js index 78ac778..1819123 100644 --- a/src/static/trade.js +++ b/src/static/trade.js @@ -19,6 +19,7 @@ class TradeUIManager { this.stopLossInput = null; this.takeProfitInput = null; this.timeInForceSelect = null; + this.exchangeRow = null; this.onCloseTrade = null; // Exchanges known to support testnet/sandbox mode @@ -56,7 +57,8 @@ class TradeUIManager { testnetRowId = 'testnet-row', stopLossId = 'stopLoss', takeProfitId = 'takeProfit', - timeInForceId = 'timeInForce' + timeInForceId = 'timeInForce', + exchangeRowId = 'exchange-row' } = config; this.targetEl = document.getElementById(targetId); @@ -83,6 +85,7 @@ class TradeUIManager { this.stopLossInput = document.getElementById(stopLossId); this.takeProfitInput = document.getElementById(takeProfitId); this.timeInForceSelect = document.getElementById(timeInForceId); + this.exchangeRow = document.getElementById(exchangeRowId); // Set up event listeners this._setupFormListeners(); @@ -129,10 +132,11 @@ class TradeUIManager { this.qtyInput.addEventListener('input', updateTradeValue); } - // Trade target (exchange) changes affect testnet visibility and SELL availability + // Trade target (exchange) changes affect testnet visibility, exchange row, and SELL availability if (this.targetSelect) { this.targetSelect.addEventListener('change', () => { this._updateTestnetVisibility(); + this._updateExchangeRowVisibility(); this._updateSellAvailability(); }); } @@ -298,6 +302,25 @@ class TradeUIManager { } } + /** + * Updates exchange row visibility based on trade mode. + * Paper trades use a single synthetic market, so exchange selection is irrelevant. + */ + _updateExchangeRowVisibility() { + if (!this.exchangeRow || !this.targetSelect) return; + + const selectedTarget = this.targetSelect.value; + const isPaperTrade = selectedTarget === 'test_exchange'; + + if (isPaperTrade) { + // Hide exchange row for paper trading (uses single synthetic market) + this.exchangeRow.style.display = 'none'; + } else { + // Show exchange row for live exchanges + this.exchangeRow.style.display = 'contents'; + } + } + /** * Populates the exchange selector with connected exchanges. * @param {string[]} connectedExchanges - List of connected exchange names. @@ -404,13 +427,17 @@ class TradeUIManager { const exchangeToUse = chartExchange || 'binance'; await this._populateSymbolDropdown(exchangeToUse, symbol); - // Reset to paper trade and hide testnet row + // Reset to paper trade and hide testnet/exchange rows if (this.targetSelect) { this.targetSelect.value = 'test_exchange'; } if (this.testnetRow) { this.testnetRow.style.display = 'none'; } + if (this.exchangeRow) { + // Hide exchange row for paper trading (uses single synthetic market) + this.exchangeRow.style.display = 'none'; + } if (this.testnetCheckbox) { this.testnetCheckbox.checked = true; } diff --git a/src/templates/new_trade_popup.html b/src/templates/new_trade_popup.html index a6e382d..2dde530 100644 --- a/src/templates/new_trade_popup.html +++ b/src/templates/new_trade_popup.html @@ -31,11 +31,13 @@ - - - + +
+ + +
diff --git a/src/trade.py b/src/trade.py index d5383d3..56b6e2c 100644 --- a/src/trade.py +++ b/src/trade.py @@ -685,9 +685,10 @@ class Trades: trade_status = status_map.get(result.status, 'pending') # Create Trade with full broker tracking + # Note: Trade.__init__ normalizes exchange to 'paper' for paper trades trade = Trade( target=target, - exchange=exchange or (target if not is_paper else 'binance'), + exchange=exchange, symbol=symbol, side=side.upper(), order_price=effective_price,