fix(D7/N7): zero out_q_gaps during contrarian mode — prevents full-conviction sizing on argmin trades
Addresses reviewer's IMPORTANT flag: the conviction Q-gap was not sign-flipped when contrarian_active, so downstream env_step would size contrarian (argmin) positions with maximum conviction, amplifying losses. During contrarian override, set out_q_gaps=0 so those trades size minimally — the override is deliberate and temporary; we don't want to compound it with aggressive position sizing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1010,13 +1010,22 @@ extern "C" __global__ void experience_action_select(
|
||||
|
||||
/* Output Q-gap for conviction-based position sizing.
|
||||
* Q-gap = Q(best_direction) - Q(Flat). Higher = more conviction.
|
||||
* Used by env_step to scale target_position. */
|
||||
* Used by env_step to scale target_position.
|
||||
*
|
||||
* D7/N7: During contrarian override, the action selected is argmin rather
|
||||
* than argmax. The raw Q(best) - Q(Flat) gap would mislead the position
|
||||
* sizer into full conviction for what's actually the "deliberately wrong"
|
||||
* action. Zero out the gap so contrarian trades size minimal. */
|
||||
if (out_q_gaps != NULL) {
|
||||
int flat_idx = 3; /* Flat = index 3 for direction(4): Short(0)/Hold(1)/Long(2)/Flat(3) */
|
||||
float q_best = q_b0[argmax_n(q_b0, b0_size)];
|
||||
float q_flat = q_b0[flat_idx];
|
||||
float gap = q_best - q_flat;
|
||||
out_q_gaps[i] = (gap > 0.0f) ? gap : 0.0f;
|
||||
if (contrarian_active != 0) {
|
||||
out_q_gaps[i] = 0.0f;
|
||||
} else {
|
||||
int flat_idx = 3; /* Flat = index 3 for direction(4): Short(0)/Hold(1)/Long(2)/Flat(3) */
|
||||
float q_best = q_b0[argmax_n(q_b0, b0_size)];
|
||||
float q_flat = q_b0[flat_idx];
|
||||
float gap = q_best - q_flat;
|
||||
out_q_gaps[i] = (gap > 0.0f) ? gap : 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user