feat: capital floor protection — 25% max drawdown terminates episode
PDT $25K rule protection: if equity drops below 75% of peak_equity, the episode terminates (done=1) with a -1.0 penalty reward and forced flat. The model learns that approaching the floor = game over. Uses peak_equity (not initial_capital) so it adapts as account grows. With $35K initial, floor triggers at ~$26.25K — above the $25K minimum. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -649,12 +649,27 @@ extern "C" __global__ void experience_env_step(
|
||||
- hold_time_penalty;
|
||||
}
|
||||
|
||||
/* ---- Capital floor protection (PDT $25K rule) ---- */
|
||||
/* If equity drops to 25% drawdown from peak, terminate the episode.
|
||||
* With $35K initial, this triggers at ~$26.25K — above the $25K PDT minimum.
|
||||
* Uses peak_equity (not initial_capital) so it adapts as account grows.
|
||||
* The model learns: approaching the floor = game over = zero future reward. */
|
||||
float new_portfolio_value = cash + position * raw_next;
|
||||
float capital_floor = peak_equity * 0.75f;
|
||||
if (new_portfolio_value < capital_floor) {
|
||||
/* Force flat — emergency exit all positions */
|
||||
position = 0.0f;
|
||||
cash = new_portfolio_value;
|
||||
new_portfolio_value = cash;
|
||||
/* Massive penalty — approaching the floor is catastrophic */
|
||||
reward = -1.0f;
|
||||
}
|
||||
|
||||
/* ---- Done detection ---- */
|
||||
int next_bar = bar_idx + 1;
|
||||
int done = (next_bar >= total_bars) ? 1 : 0;
|
||||
int done = (next_bar >= total_bars || new_portfolio_value < capital_floor) ? 1 : 0;
|
||||
|
||||
/* ---- Update full portfolio state (PORTFOLIO_STRIDE=14) ---- */
|
||||
float new_portfolio_value = cash + position * raw_next;
|
||||
ps[0] = position;
|
||||
ps[1] = cash;
|
||||
ps[2] = new_portfolio_value;
|
||||
|
||||
Reference in New Issue
Block a user