HomeSample Page

Sample Page Title


About 4 months in the past, I dove deep into the world of ensembles for constructing Foreign exchange knowledgeable advisors. Day and evening, I ran experiments, chasing a easy however highly effective thought. Mix a number of timeframes, a number of folds, and completely different views into one unified system that produces a consensus choice. At first, it felt nearly too elegant to fail.

The core instinct was easy: logits that appropriately detect their regime ought to overpower the noise from weaker indicators. When aggregated, these logits kind a clearer directional bias. Within the subplot “TF logits (avg)” (proven beneath), you may see how completely different timeframes regularly diverge—some pointing up, others down—creating moments the place the consensus turns into sturdy sufficient to justify a commerce or keep away from one solely.

TF-LOGITS

However in a short time, I ran right into a basic and irritating drawback: unknown future intervals. Think about two check home windows—August to December and November to March. Each span 5 months. You prepare one mannequin as much as August, and one other as much as November. And right here’s the catch: when one performs properly, the opposite fails. When the second succeeds, the primary collapses. This instability endured for months.

I attempted every thing. Mounted folds, the place the dataset is cut up into equal chunks—no success. Increasing folds, the place every new fold contains all earlier knowledge—nonetheless no luck. Then regime-based folds, isolating unstable, trending, or flat markets—once more, no consistency. Every method appeared promising, but in the end did not generalize.

Then got here a essential realization. Why ought to folds be tied to particular dates in any respect? Why anchor every thing to August or November as if these factors outline the longer term? What if a mannequin merely isn’t prepared by that date? That assumption alone might break the whole system.

The breakthrough was easy, but highly effective: as an alternative of anchoring folds to fastened endpoints, I started choosing them inside a rolling window—say, six months. Every subsequent fold would barely overlap with the earlier one, touching its boundary and increasing additional into the previous. This created a clean transition between folds, moderately than abrupt, synthetic splits.

Every fold has a set period and strikes ahead in time with a continuing step—one week. This leads to tons of of folds: over 500 on the 6-hour timeframe, greater than 400 on the 8-hour timeframe, and so forth. The range and continuity of those folds turned the important thing.

Beneath is a minimal piece of code that demonstrates this “easy magic” of producing weekly rolling folds:

def make_weekly_folds(
        self, span_train_months, span_val_months,
        log_path='empty',
        pass_num=0,
        fold_filter=None
    ):

    self._ensure()

    train_sec = span_train_months * SEC_IN_MONTH
    val_sec = span_val_months * SEC_IN_MONTH

    T0 = float(self._T.min())
    T1 = float(self._T.max())

    folds = []
    fold_id = 1

    if log_path != 'empty':
        f = open(log_path, "w", encoding="utf-8")

    
    def to_monday(ts):
        d = dt.datetime.fromtimestamp(ts)
        d = d.change(hour=0, minute=0, second=0, microsecond=0)
        return (d - dt.timedelta(days=d.weekday())).timestamp()

    current_start = to_monday(T0)
    if current_start < T0:
        current_start += 7 * 86400

    prev_train_start = None

    whereas True:
        train_start = current_start
        train_end = train_start + train_sec
        val_start = train_end
        val_end = val_start + val_sec

        
        if val_end > T1:
            break

        fold = self._make_fold(
            fold_id,
            train_start, train_end,
            val_start, val_end
        )

        if fold:
            if fold_filter is None or fold_id in fold_filter:
                folds.append(fold)

            if prev_train_start is None:
                shift_days_info = "N/A"
            else:
                shift_days_val = (train_start - prev_train_start) / 86400
                shift_days_info = f"{shift_days_val:.1f}d"

            def ts_to_str(ts):
                return dt.datetime.fromtimestamp(ts).strftime("%Y-%m-%d %H:%M")

            if log_path != 'empty':
                line = (
                    f"PASS-{pass_num} FOLD-{fold_id} | "
                    f"SHIFT: {shift_days_info} | "
                    f"TRAIN: {ts_to_str(train_start)} -> {ts_to_str(train_end)} | "
                    f"VAL: {ts_to_str(val_start)} -> {ts_to_str(val_end)}n"
                )
                f.write(line)

            fold_id += 1

        prev_train_start = train_start

        
        current_start = to_monday(current_start + 7 * 86400)

    return folds

This method lastly allowed me to construct ensembles that survive unknown intervals with stable profitability. Importantly, the identical methodology is utilized persistently throughout each coaching and ensemble building.

Test August through December

Within the August–December check, the advisor stays flat through the first month, then begins capturing sturdy earnings. Within the November–March check, efficiency is smoother: it begins accumulating positive aspects nearly instantly and scales up over time.

Test November through March

A notable sample is the choice for USDJPY, which, as we all know, was extremely unstable throughout this era. That volatility created precisely the type of alternative the ensemble was designed to detect and exploit.

The above outcomes come from the LSTM Ensemble with default settings.

For a balanced setup concentrating on round 10% drawdown and 400+ USD revenue over 5 months, I like to recommend:

  • Deposit: 1500 USD
  • Max trades: 2
  • Vary: 100
  • Threat: 0.5

At this level, I’m critically contemplating beginning a GitHub repository or perhaps a YouTube channel. The subject has grown far past a single submit. There’s additionally a meta-model layer, extra neural architectures, and cross-symbol coaching (gold + main FX pairs). There’s quite a lot of room to broaden—and I’m simply getting began.

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles