/**
 * Signal-to-action conversion for supervised model backtest evaluation.
 *
 * Takes scalar model predictions and converts to greedy action indices
 * using threshold-based bucketing:
 *   pred < -high_bps  → 0 (Short100)
 *   -high ≤ pred < -low → 1 (Short50)
 *   -low ≤ pred ≤ low  → 2 (Flat)
 *   low < pred ≤ high  → 3 (Long50)
 *   pred > high_bps    → 4 (Long100)
 *
 * This replaces the Candle tensor-op pipeline (signal_to_action_scores + argmax)
 * with a single fused kernel, eliminating intermediate tensor allocations and
 * kernel launch overhead in the backtest hot loop.
 *
 * Does NOT require common_device_functions.cuh (standalone kernel).
 * Launch config: grid=(ceil(N/256), 1, 1), block=(256, 1, 1).
 * One thread per sample.
 */

extern "C" __global__ void signal_to_action_kernel(
    const float* __restrict__ predictions,  /* [N] or [N,1] scalar signals */
    int* __restrict__ out_actions,          /* [N] action indices 0-4      */
    float high_threshold_bps,
    float low_threshold_bps,
    int N
) {
    int idx = blockIdx.x * blockDim.x + threadIdx.x;
    if (idx >= N) return;

    float pred = predictions[idx];
    int action;

    if (pred < -high_threshold_bps) {
        action = 0;  /* Short100 */
    } else if (pred < -low_threshold_bps) {
        action = 1;  /* Short50 */
    } else if (pred > high_threshold_bps) {
        action = 4;  /* Long100 */
    } else if (pred > low_threshold_bps) {
        action = 3;  /* Long50 */
    } else {
        action = 2;  /* Flat */
    }

    out_actions[idx] = action;
}
