File size: 4,601 Bytes
fc115d5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# Testnet Trading Implementation Plan

## Goal
Mirror the DRL bot's LONG/SHORT trading decisions to Binance Testnet with real order execution and full dashboard visibility.

## Architecture

### Constraints
- Binance Testnet (testnet.binance.vision) is **SPOT only** β€” no futures/perpetuals
- LONG positions: execute real BUY orders on testnet
- CLOSE LONG: execute real SELL orders on testnet
- SHORT/CLOSE SHORT: recorded as conceptual trades (spot can't truly short); if base currency held, it is sold

### Components

#### 1. `src/api/testnet_executor.py` (NEW)
- `TestnetExecutor` class β€” singleton used by orchestrator and api_server
- `mirror_trade(bot_trade, bot_result)` β€” translates bot decision β†’ real testnet order
- `get_current_positions()` β€” live positions with current prices + unrealized PNL
- `get_trades(limit)` β€” read from `logs/testnet_trades.json`
- `get_pnl_summary()` β€” realized + unrealized PNL, win rate
- Stores each trade in `logs/testnet_trades.json` (line-delimited JSON)
- Uses `BinanceConnector` for all API calls
- Reads `BINANCE_TESTNET_API_KEY` / `BINANCE_TESTNET_API_SECRET` from env

#### 2. `src/ui/api_server.py` (MODIFIED β€” 4 new endpoints)
- `GET /api/testnet/trades` β€” trade history from testnet_trades.json
- `GET /api/testnet/positions` β€” open positions with live prices + unrealized PNL
- `GET /api/testnet/pnl` β€” realized + unrealized PNL summary + equity curve data
- `POST /api/testnet/execute` β€” manually trigger a testnet trade (for testing)

#### 3. `live_trading_multi.py` (MODIFIED β€” auto-execution hook)
- `MultiAssetOrchestrator.__init__`: instantiate `TestnetExecutor` if `TESTNET_MIRROR=true`
- `run_single_cycle()`: after each bot decision, call `self.testnet_executor.mirror_trade()`
- Log both dry-run result and testnet execution result
- Guard with try/except so testnet failures never block the main trading loop

#### 4. `src/ui/app.py` (MODIFIED β€” enhanced Testnet tab)
New sections added to the Testnet tab (all data from API endpoints):
- **Open Positions table**: symbol, side, entry price, current price, unrealized PNL, SL, TP
- **Trade History table**: timestamp, symbol, action, price, amount, PNL, order_id
- **PNL Summary**: realized, unrealized, total, win rate, total trades
- **Equity Curve chart**: cumulative PNL over time (Plotly line chart)
- **Live Order Book**: open/pending orders from `/api/testnet/orders`

#### 5. `tests/test_testnet_trading.py` (NEW)
- Test testnet connectivity
- Test place a small market order on testnet
- Test `/api/testnet/trades` returns list
- Test `/api/testnet/positions` returns list
- Test PNL calculation

## Data Flow

```
Bot run_iteration()
    └─> execute_trade() β†’ trade dict
                └─> [if TESTNET_MIRROR=true]
                        └─> TestnetExecutor.mirror_trade()
                                β”œβ”€> BinanceConnector.place_market_order()  (50%)
                                β”œβ”€> BinanceConnector.place_limit_order()   (50%)
                                └─> _save_trade() β†’ logs/testnet_trades.json

Dashboard (app.py Testnet Tab)
    β”œβ”€> GET /api/testnet/status    (existing β€” balance/portfolio)
    β”œβ”€> GET /api/testnet/positions (new β€” open bot-mirrored positions)
    β”œβ”€> GET /api/testnet/trades    (new β€” trade history)
    β”œβ”€> GET /api/testnet/pnl       (new β€” PNL + equity curve)
    └─> GET /api/testnet/orders    (existing β€” open orders)
```

## Trade Record Schema
```json
{
  "symbol": "BTCUSDT",
  "ccxt_symbol": "BTC/USDT",
  "action": "OPEN_LONG_SPLIT",
  "side": "BUY",
  "price": 43250.50,
  "filled_price": 43251.00,
  "amount": 0.00578,
  "sl": 41087.98,
  "tp": 46000.25,
  "confidence": 0.72,
  "timestamp": "2026-03-19T14:32:00.000Z",
  "order_id": "12345678",
  "limit_order_id": "12345679",
  "limit_price": 43034.87,
  "limit_amount": 0.00579,
  "executed": true,
  "error": null,
  "pnl": null,
  "dry_run": false
}
```

## Environment Variables
- `TESTNET_MIRROR=true` β€” enables auto-execution hook (default: false)
- `BINANCE_TESTNET_API_KEY` β€” testnet API key (already set)
- `BINANCE_TESTNET_API_SECRET` β€” testnet API secret (already set)
- `BINANCE_TESTNET_PROXY_URL` β€” optional Cloudflare proxy (already set)

## Risk Controls
- TestnetExecutor failures are caught and logged β€” never block main loop
- Minimum trade value: $10 USDT
- Max position: 25% of testnet USDT balance Γ— confidence scale
- Split entry: 50% market + 50% limit (mirrors bot logic)
- No automatic SL/TP orders placed (bot logic manages exits and mirrors them)