ResearchFeatureEngine 0.1.0

dotnet add package ResearchFeatureEngine --version 0.1.0
                    
NuGet\Install-Package ResearchFeatureEngine -Version 0.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ResearchFeatureEngine" Version="0.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ResearchFeatureEngine" Version="0.1.0" />
                    
Directory.Packages.props
<PackageReference Include="ResearchFeatureEngine" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add ResearchFeatureEngine --version 0.1.0
                    
#r "nuget: ResearchFeatureEngine, 0.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package ResearchFeatureEngine@0.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=ResearchFeatureEngine&version=0.1.0
                    
Install as a Cake Addin
#tool nuget:?package=ResearchFeatureEngine&version=0.1.0
                    
Install as a Cake Tool

ResearchFeatureEngine

A platform-independent quantitative research feature engine that transforms market data into deterministic, mathematically defined research features through a composable pipeline.

The core engine assembly has no cTrader dependencies — the cTrader API is referenced only by the adapter assembly and the cTrader applications (see Architecture boundary). The same production pipeline drives cTrader, historical backtesting, replay, and research tooling.

Tests CI

Total tests: 496 (CI runs the 491 portable tests; 5 source-identity tests V11_10V11_12 pin private local captures and run only on the author's machine).<br> M10.1: 34 BulkExport golden tests (G1–G19 + V11_1–V11_9).<br> M11.1: 354 reference/engine tests + 2 HmaAtrSmooth geometry tests.<br> M11.2A: 4 BulkExport source-admission tests (V11_11, V11_12) — 38 golden tests total.


Architecture

Market Data → Reference → Distance → (Darvas / HMA composites) →
  Regime Segment → Reversal → Scale → Normalization → Statistics → EngineValues

A single published-value surface (EngineValues) reaches every consumer — indicators, BulkExport, tests, tooling — with no duplicated mathematics. See docs/architecture.svg for the layered diagram (applications → adapters → core with the boundary line), and Project Vision and Architecture.md for the full architecture write-up.


Adapters

Platform Status Surface
cTrader indicator ✅ Shipped Adapters/ResearchFeatureEngine.CTrader
Python (CSV harness) ✅ Shipped tools/CTraderHarness
Python adapter (pip install research-feature-engine) 🚧 Planned pythonnet wrapper, PyPI release
MT5 indicator 🚧 Planned C# wrapper DLL + MQL5 indicator
MT4 indicator ❌ Out of scope

Pipeline

The canonical measurement pipeline, in registration order:

Market Data (IMarketData)
    ↓
Reference      ← selected reference source (ATRSmooth2 equilibrium level,
                 Darvas Box midpoint, HMA, or the HmaAtrSmooth composite —
                 exactly one active model per engine)
    ↓
Distance       ← close vs reference (directional + absolute)
    ↓
Darvas / HMA composites ← mode-gated research stages
                 (Darvas closing distances; HMA–ATRSmooth distance
                 and alignment)
    ↓
Regime Segment ← ATRSmooth regime segment metadata (M9; ATRSmooth-based
                 modes only)
    ↓
Reversal       ← strict regime-transition state machine
    ↓
Scale          ← characteristic scale (ATR)
    ↓
Normalization ← distance / scale (dimensionless feature)
    ↓
Statistics     ← rolling mean / std dev / median / MAD / range /
                 skewness / kurtosis
    ↓
EngineValues   → single published-value surface for every consumer
                 (indicator, BulkExport, tests, tooling)

Each stage is an EngineBase with the Template-Method lifecycle (Processing → OnUpdate → Ready), owns its own runtime sub-object inside EngineValues (single ownership), validates its output before publishing, and is composed by ResearchFeatureEngineBuilder with type-gated registration — stages for one reference mode are never constructed in another mode.

See Project Vision and Architecture.md for the full architecture.


Reversal vs. regime-segment semantics

Two distinct regime-related quantities are published; they are not the same event counter:

  • EngineValues.Reversal (ReversalEngine) counts strict published regime changes, including the first establishment. The first 0 → ±1 establishment of the regime IS a reversal bar (IsReversalBar = true, BarsSinceReversal = 0, direction set). Every later strict regime change (a trailing-stop position flip in ATRSmooth modes) is another reversal.
  • EngineValues.AtrSmoothRegimeSegment (M9 segment stage) tracks bounded temporal segments of the same canonical regime. A segment transition represents only established directional flips (−1 ↔ +1). The first 0 → ±1 establishment starts segment 0 but does not constitute a segment transitionRegimeTransition stays None on the establishment bar, and the segment ID counter does not increment.

In short: establishment counts as a reversal but not as a segment transition; after establishment, every regime flip is both. Crossing the published reference line is neither — for ATRSmooth the regime is the trailing-stop position bias, so only the trailing-stop position flip changes the regime.

See Reversal/Reversal.md and Engines/AtrSmoothRegimeSegment.md for full semantics.


Reference models

Exactly ONE reference model is active per engine instance, selected by the Reference Type parameter and constructed exclusively at initialization (ReferenceSourceFactory — the non-selected model is never instantiated and its parameters are inert):

Type Reference.Price Reference.Regime Reversal
ATRSmooth2 (VWMA(close, smoothLength) + ATRTrailingStop) / 2 trailing-stop position bias: +1 bullish / -1 bearish / 0 initial strict transition of the regime — a trailing-stop flip. Crossing the ATRSmooth published reference line is not itself an ATRSmooth reversal.
DarvasBox (Upper + Lower) / 2 of the current box positional state: +1 close above Upper / 0 inside (real persistent state) / -1 close below Lower strict transitions of the positional regime — includes breakout and return-to-box transitions. The box midpoint jumps on box replacement; that structural effect is intentional and is never smoothed.
Hma canonical HMA of close (direct window recompute) initial 0 strict transitions
HmaAtrSmooth ATRSmooth2 equilibrium (the composite keeps the ATRSmooth2 pipeline semantics bit-identically) trailing-stop position bias (ATRSmooth2) identical to ATRSmooth2 — the HMA is an additive parallel canonical value, not a replacement measurement level.

Reference.Price is the source-defined scalar measurement level against which Distance measures signed price deviation — it is not universally an "equilibrium price" (the Darvas box midpoint is a measurement level, not an equilibrium).

Dual-reference mode

HmaAtrSmooth is the explicit composite dual-reference mode: the engine owns exactly one canonical HmaReferenceSource (HMA of close, period HMA Period; direct window recompute — O(P^1.5)/bar, no incremental state) and one canonical ATRSmoothReferenceSource, both advanced once per bar by HmaAtrSmoothCompositeSource. Selecting Hma alone constructs only the HMA source — ATRSmooth is never silently instantiated. The canonical HMA value is published in ReferenceRuntime.Hma (NaN until index P + floor(sqrt(P)) - 2; e.g. bar 18 at P=16).

Two research stages are registered only in this mode (after Reference, before Reversal):

Stage Formula Notes
Mean HMA–ATRSmooth Distance mean(HMA − ATRSmooth) over Mean HMA-ATRSmooth Window signed; + = HMA above the smoothed equilibrium. True O(1)/bar (running sum, no per-bar allocation). NaN until Runtime.Hma is genuinely valid.
HMA/Price–ATRSmooth Alignment Aligned(+1) iff (HMA > ATRSmooth) == (Close > ATRSmooth), else Misaligned(−1); Unavailable(0) during warm-up or exact equality current-bar state only — no rolling mean, no smoothing, no hysteresis, no epsilon (strict > / <).

Both stages consume the canonical producer runtimes directly — no duplicate indicator calculations. The HMA implementation is pinned by oracle-first golden tests (Tests/Reference/HmaReferenceSourceGoldenTests.cs): constant series produce exactly the constant, ramp/random fixtures match an independent direct-definition oracle bit-for-bit, and the warm-up boundary is exact.

ATRSmooth regime segment metadata (M9)

A AtrSmoothRegimeSegmentEngine pipeline stage (after Reference, before Reversal) layers bounded temporal-segment metadata on the canonical ATRSmooth regime — the trailing-stop position bias (Reference.Regime) — and publishes into EngineValues.AtrSmoothRegimeSegment:

Output Type Description
Regime AtrSmoothRegimeDirection Bullish / Bearish / Unavailable (warm-up).
RegimeId int? Monotonic segment ID: first established regime = 0, every flip +1, shared by all bars of a segment. null during warm-up.
RegimeStartIndex int? First bar of the current segment; changes exactly on a flip. null during warm-up.
RegimeAge int? Zero-based bars since the segment began (t − start; first bar = 0). null during warm-up.
RegimeTransition AtrSmoothRegimeTransition Up (+1) bearish→bullish flip, Down (−1) bullish→bearish flip, None (0) otherwise. The flip itself — never a price crossing of the ATRSmooth line.

The stage is a pure consumer of the canonical published regime (no second ATRSmooth calculation, no second reversal definition). It is registered only for the ATRSmooth-based compositions (ATRSmooth2, HmaAtrSmooth); every other mode leaves the values at their unavailable defaults. See Engines/AtrSmoothRegimeSegment.md.


Measurement export (BulkExport)

tools/BulkExport is the canonical measurement extraction boundary: it turns the engine's published runtime values into deterministic, hash-pinned CSV research artifacts. It contains zero engine mathematics — every exported token is read directly from EngineValues after the engine's own Update(), on a pipeline composed by the production ResearchFeatureEngineBuilder.

Guarantees:

  • deterministic output — fixed column order, invariant-culture formatting, byte-identical on rerun;
  • frozen source identity — the capture must be registered and SHA-256-pinned before processing (live data has no path at all);
  • SHA-256 verification — source hash checked before and after the run; every artifact ships with a manifest carrying the artifact hash;
  • first-calendar-year research partition — per dataset, leap-correct calendar-year boundary;
  • holdout firewall — everything after the research partition is sealed from research use;
  • atomic finalization — output is written to a .partial file and atomically renamed; an existing artifact is never overwritten;
  • no duplicated engine mathematics — extraction only.

M10 status

Production Year-1 measurement artifacts were certified for EURUSD Tick100 and XAUUSD Tick50 at M10.1 (four reference modes each), produced from owner-ratified frozen recorder captures. M11.2A extended the Distance certification chain to admit XAUUSD Tick25 and XAUUSD Tick100 — both registered with SHA-256 pins and verified Year-1 row-count invariants (2,234,316 and 68,255 respectively; Tick50 at 130,665 is the unchanged control). Artifacts live outside the repository under out/ (gitignored) and are the handoff surface for downstream research programs.


Architecture boundary

Applications (cTrader indicators, tools)
    ↓ reference
Adapters (ResearchFeatureEngine.CTrader assembly — cAlgo.API)
    ↓ reference
Core (ResearchFeatureEngine assembly — pure engine abstractions,
      models, algorithms; NO cTrader API, NO adapter reference)
  • The core engine (ResearchFeatureEngine.csproj) is platform-independent: its project references contain no cTrader API package and its sources contain no cTrader-specific dependency — a future accidental cTrader dependency inside Core is a compile error, not a silent linkage.
  • The adapter assembly (Adapters/ResearchFeatureEngine.CTrader.csproj) references Core and cAlgo.API, and owns CTraderMarketData / CTraderPriceSeries (adapting cTrader Bars/DataSeries to the platform-independent IMarketData/IPriceSeries).
  • Applications (the indicators under Indicators/) reference Core and the adapter; the adapter is a thin layer with no engine mathematics.
  • The dependency direction is one-way: Core never references Adapters or Applications.

Adding a new measurement family follows the documented canonical protocol in Composition/MeasurementFamilyAddition.md — explicit, type-gated, multi-location wiring by design.


cTrader indicator

The indicator (Indicators/ResearchFeatureEngineIndicator/) is a thin adapter — it contains no math. It wires cTrader's bar stream to the production pipeline via CTraderMarketData and publishes EngineValues to output series.

Outputs

Output Color Notes
Reference DodgerBlue selected reference model's measurement level
Directional Distance Orange close − reference (signed)
Absolute Distance Magenta |close − reference|
Scale (ATR) Gray characteristic scale
Normalized Lime dimensionless feature
Mean (Rolling) Aqua rolling mean of close
Std Dev (Rolling) Yellow rolling std dev of close
Skewness (Rolling) Pink Fisher–Pearson G1; retained value on flat windows
Kurtosis (Rolling) Cyan Fisher G2 excess; retained value on flat windows
Bars Since Reversal White 0 on reversal, increments; gap before first reversal
Reversal Direction Red +1 Up / -1 Down; gap before first reversal
Reversal Bar White (histogram) 1 on the reversal bar, 0 otherwise; gap before first reversal

Parameters

Parameter Group Default
Reference Type Reference ATRSmooth2 (selects the single active reference model)
ATR Period Reference: ATRSmooth2 16
ATR Multiplier Reference: ATRSmooth2 5.1
VWMA Smooth Length Reference: ATRSmooth2 100
Box Length Reference: Darvas Box 5 (min 3)
HMA Period Reference: HMA 16 (min 2)
Mean HMA-ATRSmooth Window Research Features 20
Mean Darvas Window Research Features 20
Scale ATR Period Scale 14
Statistics Window Statistics 252
Reversal Mode Reversal TrailingStopPosition (regime-transition semantic; CloseToReference is the explicit opt-in)

The indicator renders in a dedicated sub-pane (IsOverlay = false), so it does not obscure the price chart. Statistics are current-bar-inclusive (the live bar's latest close is in the rolling window on every tick), so the rolling statistics respond to the live bar like the rest of the pipeline.


Build & test

# Build the platform-independent core engine (net6.0)
dotnet build ResearchFeatureEngine.csproj

# Build the cTrader adapter assembly
dotnet build Adapters/ResearchFeatureEngine.CTrader.csproj

# Build the cTrader indicator (application)
dotnet build Indicators/ResearchFeatureEngineIndicator/ResearchFeatureEngineIndicator.csproj

# Run the full test suite (xUnit, net10.0)
dotnet test Tests/ResearchFeatureEngine.Tests.csproj -c Release

Both .NET SDK 6 and 10 are supported (6 for the engine/adapter/indicator, 10 for the test project).

<a name="testing"></a>Testing

  • Full Release suite: 496/496 passing.
  • M10.1: 34 BulkExport golden tests (G1–G19 + V11_1–V11_9). Certified production Year-1 artifacts: EURUSD Tick100, XAUUSD Tick50 (4 reference modes each).
  • M11.2A: 38 BulkExport golden tests total (adds V11_11 source-identity pins and V11_12 Year-1 row-count invariants). XAUUSD Tick25 and XAUUSD Tick100 are admitted to the Distance certification chain — source identity + Year-1 invariants only. Their M11.2 production artifacts are not yet generated.
  • M11.1: 354 reference/engine tests + 2 HmaAtrSmooth geometry tests (HmaAtrSmoothDistance, Alignment).
  • Mathematical correctness (hand-computed golden oracles per reference source), determinism, long-run stability (100k bars), performance benchmarks, real-market-data validation (10k EURUSD M1 bars), and cross-platform consistency.
  • Reversal semantics (regime-transition and close-to-reference modes), re-tick idempotency, lookahead, and real-data comparison against the original indicator.
  • M9 segment stage: hand-computed golden oracle, adversarial price-crossing fixtures (10 000 real EURUSD M1 bars), executable invariants, reset/replay determinism.
  • Skewness/kurtosis: independent golden references (Python two-pass computation), convention and minimum-n semantics, numerical stability at a 1e6 baseline.
  • BulkExport (M10): golden export tests — schema/column gating per mode, manifest determinism, hash-pinned source identity, refuse-overwrite, atomic finalization, Year-1 partition and holdout firewall, recorder schema validation (6- and 7-column captures).
  • No regressions in the existing ATRSmooth / statistics / determinism / long-run suites; the suite count only grows across milestones.

Project layout

Core/                EngineContext, EngineBase, EngineValues, enums
Reference/          IReferenceSource, ATRSmoothReferenceSource,
                     DarvasBoxReferenceSource, HmaReferenceSource,
                     HmaAtrSmoothCompositeSource, ReferenceRuntime,
                     configuration, validation
Engines/            ReferenceEngine, DistanceEngine, research-stage
                     engines, validators
Reversal/           ReversalEngine, ReversalRuntimeValues, validator, docs
Scale/              ScaleEngine, ATRScaleModel
Normalization/       NormalizationEngine, ScaleNormalizationModel
Statistics/         StatisticsEngine, StatisticsWindow, models, publisher
Composition/         ResearchFeatureEngine, builder, configuration, options,
                     ReferenceSourceFactory (exclusive selection),
                     MeasurementFamilyAddition.md (family protocol)
Models/             EngineValues + per-stage runtime values and models
Interfaces/         IMarketData, IPriceSeries, IEngine
Adapters/           CTrader adapter ASSEMBLY (ResearchFeatureEngine.CTrader):
                     CTraderMarketData, CTraderPriceSeries (cAlgo.API here)
Indicators/          cTrader applications (thin adapters, no math)
tools/               BulkExport (canonical measurement export),
                     CTraderHarness (CSV runner)
Tests/               xUnit tests + test data (EURUSD_M1_10000.csv)

License

MIT — Copyright (c) 2026 Osat Zoghi.

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net6.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.0 38 9/17/2026