Migrating from Python fincore
fincore_cpp is a native library, not a Python binding. It does not provide
import fincore compatibility, Python exception inheritance, pandas views or
NumPy dtypes. Port workflows by matching the native typed inputs and outputs,
not by mechanically renaming Python objects.
Mapping table
Python / pandas |
Native equivalent |
Note |
|---|---|---|
|
|
Index is a signed 64-bit UTC nanosecond timestamp |
|
|
Returned as a span/view; copy if it must outlive the frame |
|
|
Drops the first observation, keeps the later timestamp |
|
Not provided as a primitive |
Most APIs take the lag explicitly ( |
|
|
Complete windows only |
|
|
The native field divides by the count (population), not |
|
|
Bucket ordering is explicit, not insertion order |
|
|
Treated as missing, never as zero |
|
|
Carries category, code and structured fields |
|
|
Render one typed document, not a frame |
|
|
Pairwise alignment on shared timestamps |
Porting checklist
Find the native symbol. Every public symbol is in the API ledger; if a Python call has no native counterpart, it is not implemented, and a wrapper that pretends otherwise will drift.
Check the unit contract. Native functions take decimal returns, not percentages, and never convert units implicitly.
Check the alignment contract. Pairwise APIs join on shared timestamps; strict ones reject duplicated or unsorted indexes. A Python query that relied on positional order must be rewritten, not translated.
Check the failure contract. A
NaNresult and an exception mean different things here; see conventions.Keep the oracle budget. Reuse the same fixture and the same reference values you used in Python, so a port is verified against evidence rather than against itself.
Known differences that bite
Signed zero and NaN payloads. Digests serialize doubles as IEEE-754 bit patterns; some writers normalize negative zero because the bytes are hashed.
Annualization defaults. 252 for daily. A Python helper that used 365 will disagree by the square root of the ratio.
Deviation divisor.
calc_distribution_statsreports the population deviation, while pandas defaults toddof=1; the difference is visible on short samples and vanishes only asymptotically. It also does not filterNaN.Drawdown signs.
max_drawdownreturns a negative fraction, whilegen_drawdown_tablereports a positive percentage of the prior peak.Backtest verdicts.
inconclusiveis a real outcome, not a failure; the five-expected-exception floor is applied on purpose.Optional routes. Provider or extension surfaces marked optional are not parity claims. The iteration records list what is implemented and what is deferred.
What parity means here
The repository’s parity records describe the implemented native surface and its declared variances. The iteration-8 record is the authoritative scope snapshot; later performance work does not retroactively expand it. Check the dated acceptance records for dependency and platform status rather than inferring it from a phase count.
For a migration review, map each Python call to a public native symbol, verify its unit and alignment contract, and retain the same fixture or oracle budget. A port that changes both the code and the reference values proves nothing.