Pramaana is a crypto research and trading system I built around one constraint: a model prediction is only useful when it describes the event that will actually decide the position. This article focuses on its path-passage classifier, which estimates which price barrier an asset reaches first.
A 24-hour closing-price forecast can be directionally correct and still describe the wrong trade outcome. Bracketed positions close when the take-profit level is reached, the stop-loss level is reached, or the holding window expires. Pramaana trains on that sequence directly: upper barrier first, lower barrier first, or neither within 24 hours.
The feature is interesting because the statistical target and the capital decision refer to the same event.
1. A closing price cannot recover the trade path
A common market model predicts the return between now and a fixed horizon:
That target supports many research tasks. It does not describe a bracketed position.
A bracket order has two exit levels. One secures a gain and the other limits a loss. The trade ends when either level is touched, or when the holding period expires. Sequence determines the result.
Pramaana's earlier close-to-close targets discarded the high and low path inside the holding window. A later close therefore could not tell the model whether the upper or lower bracket had already been touched. The repository names the missing information directly: wicks, drawdowns, take-profit hits, and the order in which the barriers were reached.
The problem was in the training target before model choice or tuning entered the discussion.
2. First-passage classification labels the event that closes the position
First-passage is the first time a process reaches a defined level. Pramaana uses the next hourly bar's open as the reference price because that is the first point available after a signal is formed.
The current methodology places a 200 basis point threshold on each side for most assets. One basis point is 0.01 percent, so 200 basis points equals 2 percent.
The target schema is explicit in the label module:
def first_passage_col_names(horizon_bars: int, barrier_bps: float) -> tuple[str, str, str]:
h = f"h{horizon_bars}"
b = f"b{int(round(barrier_bps))}"
return (
f"target_up_first_{h}_{b}",
f"target_down_first_{h}_{b}",
f"target_none_{h}_{b}",
)
The helper keeps the three outcomes explicit for each horizon and barrier width. The next function writes those outcomes into the training frame while preserving rows whose future window is incomplete:
def _add_first_passage_columns(
df: pd.DataFrame,
horizon_bars: int,
barrier_bps: float,
) -> pd.DataFrame:
up_col, dn_col, none_col = first_passage_col_names(horizon_bars, barrier_bps)
up, dn, none, valid = _first_passage_for_barrier(df, horizon_bars, barrier_bps)
df[up_col] = np.where(valid, up.astype(np.float32), np.nan)
df[dn_col] = np.where(valid, dn.astype(np.float32), np.nan)
df[none_col] = np.where(valid, none.astype(np.float32), np.nan)
return df
Invalid trailing rows stay undefined instead of being forced into one of the three classes. The diagram shows the full path from signal to the cost-aware score used later in the trading decision.
An hourly bar can cross both thresholds. Its high and low prove that both levels were touched, but hourly data cannot recover their order. Pramaana does not invent one. That observation is treated as unresolved.
Rows near the dataset tail also remain undefined when a complete 24-hour future window does not exist. Every valid label can therefore be traced back to a specific entry reference, two thresholds, and an observable first touch.
3. The model and the order use the same geometry
The training target uses the same 24-hour horizon and symmetric 2 percent levels as the trade structure.
Pramaana does not predict a broad idea of direction and then ask another component to reinterpret it. The classifier estimates the outcomes the execution rule can encounter.
up_first means the upper exit should occur before the lower exit. down_first carries the opposite ordering. none means the bracket remained unresolved when time expired.
This matters because a directional call can eventually be correct after the position has already stopped out. A long forecast has no value when the loss level is touched before the anticipated rise.
One three-class distribution supports both sides. The system does not need separate long and short models. It evaluates the same outcome probabilities under the payoff structure of each position.
4. Three probabilities become expected basis points
Pramaana trains one LightGBM model per asset. LightGBM is a tree-based classifier that estimates:
P(up_first), P(down_first), P(none)
Those probabilities are inputs, not orders. The decision layer maps the outcome distribution into a long score and a short score:
If the upper barrier arrives first, the long side receives the positive bracket payoff after cost and the short side receives the negative one. The signs reverse when the lower barrier arrives first. An unresolved window is valued at the horizon close, with trading cost still deducted.
The output is expected basis points, so the ranking layer receives a financial quantity rather than raw model confidence.
A large P(up_first) can still produce a weak long score. The competing outcome may remain material, the unresolved probability may be high, or fees may consume the margin. Expected value forces the whole probability distribution through the actual payoff map before a candidate can rank highly.
That distinction makes the score readable from two directions. An engineer can inspect the probability model. A portfolio reader can inspect the economic consequence.
5. Real trading cost changed the entry rule
A model can identify direction better than chance and still lose money.
Trading cost reduces every gross forecast. In Pramaana, that became decisive when the strategy was stressed against the real 35 basis point round-trip cost used by the Coinbase configuration.
Pramaana includes cost in the score instead of subtracting it after ranking. That prevents a high-confidence but low-value candidate from outranking a less dramatic signal with better net economics.
The first version admitted any score above zero. Later testing applied the real 35 basis point round-trip cost used in the Coinbase configuration. The simple threshold failed.
The response changed the decision layer. The current configuration uses a rolling-percentile gate and a smaller seven-asset universe. A candidate must rank strongly against the recent score distribution rather than remain barely positive under an easier fee assumption.
The classifier answers what may happen. The gate determines whether the estimated advantage deserves capital under current execution conditions.
6. Smaller trees produced more credible probabilities
Expected-value scoring depends on probability scale. A model that reports 99.9 percent for an event occurring roughly half the time will overstate the money attached to that branch.
An audit found that the original LightGBM settings allowed terminal leaves to become too specific. Some out-of-sample estimates exceeded 99.9 percent even though realized frequencies inside those confidence ranges were much lower.
The model was deliberately constrained:
| Setting | Hardened value | Reason |
|---|---|---|
| Maximum leaves | 8 | Prevent narrow terminal regions |
| Maximum depth | 3 | Restrict interaction complexity |
| Minimum rows per leaf | 400 | Require broad empirical support |
| Feature sampling | 50 percent | Reduce dependence on one feature subset |
| L1 and L2 regularization | 0.1 | Pull extreme leaf weights inward |
After hardening, the largest observed P(down_first) across the audited cycles fell from 0.999 to about 0.83. Median expected calibration error declined from about 0.21 to 0.08 while rank order remained useful.
Lower confidence was the correct result. The revised probabilities tracked observed frequencies more closely and stopped one narrow leaf from dominating the expected-return calculation.
Accuracy measures whether the ranking contains information. Calibration determines whether its probabilities can be multiplied by money.
7. The target pipeline received its own audit
Time-series research can fail before model fitting begins. A future window placed on the wrong row can leak information from beyond the intended horizon into the target.
Pramaana's audit found such an error in vectorized path-excursion fields used for maximum favorable excursion, maximum adverse excursion, and horizon close. A double shift moved part of the calculation farther forward than intended.
The three first-passage classes were unaffected. They come from a separate forward scan that checks each subsequent bar in order. The per-asset classifiers train on those classes, so their labels remained clean.
One related value did require correction. The payoff for none used the contaminated horizon close, which inflated part of the backtest return. The field was fixed and the validation suite was rerun.
The corrected result did not collapse. Passing parameter combinations moved from 133 of 270 to 134 of 270. The best top-decile return estimate decreased from 112.6 to 87.5 basis points after the inflated portion was removed.
That outcome is more credible than preserving the larger number. The ranking survived while the reported payoff became more conservative.
8. How to read the signal without knowing the model internals
A reader who understands markets does not need to know how LightGBM constructs a tree to evaluate the decision.
The signal exposes a defined event, a 24-hour horizon, a payoff map, a cost assumption, and an admission rule. The model estimates the outcome distribution. The scoring layer converts it into net expected value for long and short positions. The rolling gate then compares that value with the recent score distribution before capital is admitted.
That structure supports direct scrutiny. Which event is being forecast? What thresholds define the position? How is an unresolved trade valued? Which fee schedule is applied? How selective is the gate? Were the probabilities calibrated outside the training sample?
Those questions also expose the main risks. Regime changes can alter the outcome distribution. Higher fees can erase small edges. Calibration can drift. Score compression can reduce the number of entries worth taking.
The prediction is useful because every number refers to a specified path, holding period, and cost model.
9. The forecast should match the action it controls
Pramaana moved from forecasting where price ends to estimating which exit occurs first.
That decision changed the labels, probability model, long and short scoring, fee test, validation process, and operator view. Each layer now refers to the same 24-hour bracket.
The principle extends beyond this system. A machine-learning target should encode the event that determines the action. When execution closes on the first threshold touch, an end-of-window label omits the part of the path that decides the trade.
Predicting exit order gives the model a question that capital can verify.
