Three bugs fixed:
1. **Weighted average entry price for risk management**:
- Previously, entry_price was overwritten on each buy, causing stop loss
to be calculated from the latest buy price instead of average
- Added cost_basis tracking and average_entry_price property
- Stop loss now correctly uses weighted average across all buys
2. **Portfolio value accumulation in _calculate_metrics**:
- Bug: running_position = trade['quantity'] was OVERWRITING position
- Fix: running_position += trade['quantity'] to properly accumulate DCA
3. **Risk management exit reset**:
- Added cost_basis reset when position is closed
Max drawdown is now correctly bounded by stop loss percentage (~5%)
instead of showing inflated values like 59%.
Two bugs fixed:
1. final_balance was incorrectly calculated as balance + balance when position=0 due to expression structure
2. take_profit check needed epsilon for floating point precision (95 * 1.10 = 104.50000000000001 instead of 104.5)
Bug: The expression was evaluating incorrectly due to operator precedence:
final_balance = balance + (position * price if condition else balance)
When condition=False (position=0), this became: balance + balance = 2x balance!
Fixed by restructuring to if/else block.
The bug was that running_balance was set to trade['amount'] which is
the amount SPENT on a buy (not remaining balance), causing inflated
portfolio values and incorrect max drawdown calculation.
Now properly tracks:
- After BUY: balance decreases by amount spent
- After SELL: balance increases by amount received
- Track last_kline_price during kline processing
- Use last_kline_price instead of entry price for open position valuation
- Add final marked-to-market value to portfolio_values for max_drawdown calculation
- This fixes the issue where max_drawdown exceeded stop_loss percentage