Skip to content

v6.4.8 — Pine compatibility fixes + Databento OHLCV imports

Choose a tag to compare

@wallneradam wallneradam released this 23 May 20:24
· 481 commits to main since this release

What's new

Patch release covering Pine-compat correctness fixes across series indexing and drawing APIs, a strategy exit-order regression fix, and native Databento OHLCV CSV imports.

Core

Series subscripting returns na for NA keys and out-of-range indices

Pine treats <series>[na] and out-of-range subscripts (negative = future, positive >= size = past available history) as na. PyneCore previously raised TypeError on NA keys and IndexError on negative integer keys, crashing scripts that compile cleanly and run on TradingView. SeriesImpl.__getitem__ now returns NA(T) for NA keys before any int() coercion, and collapses negative-int handling into the existing past-end NA branch. New unit tests in test_014_series_indexing_pine_compat.py. Closes #57.

Strategy

Pending stop/limit entries no longer drop their attached SL/TP

_process_at_bar_open previously cleared every non-market exit order on flat bars unless the bound entry was a market order. A pending limit/stop entry therefore caused its stop/limit exit to be dropped before the entry ever filled, leaving the resulting position open with no SL/TP. The is_market_order carve-out has been replaced with a pending-entry check: any exit whose from_entry still has a pending entry survives, while true orphans (cancelled, margin-rejected, unknown entry) are still removed.

Lib

Drawing delete() is idempotent on missing or na ids

Pine treats <draw>.delete(na) and re-deleting an already-deleted drawing as a no-op. line.py, label.py and box.py previously crashed with ValueError: list.remove(x): x not in list. They now follow the existing polyline / linefill / matrix / table pattern: if id in _registry: _registry.remove(id).

label.new / line.new / box.new accept float bar coordinates

The custom pynecore.core.overload dispatcher rejected float bar indices on the coordinate-shape variant - e.g. (x_value + time) / 2, where Pine / always yields float - with TypeError: No matching implementation found. The three new() builders now use typing.overload stubs plus a single runtime implementation that branches on isinstance(first, ChartPoint) and casts float bar coordinates to int (left/right for box, x1/x2 for line, x for label), mirroring Pine's implicit float-to-int conversion on series int parameters.

label.new / line.new / box.new kwarg-style calls now work

Kwarg calls such as box.new(left=..., top=..., right=..., bottom=...) previously raised TypeError because the runtime implementations used merged parameter names (top_left_or_left, bottom_right_or_top, ...) that did not match either typing.overload stub. Runtime parameters were renamed to the coordinate-form names (left/top/right/bottom, x/y, x1/y1/x2/y2) so positional and keyword calls both work; the point-form overload stub was aligned to the same names.

Data

Native Databento OHLCV CSV imports

pyne data convert-from now ingests Databento OHLCV CSV exports out of the box - common for CME futures and US equity backtesting:

  • _find_timestamp_columns recognises ts_event and ts_recv as timestamp columns.
  • _parse_timestamp handles nanosecond integer timestamps (the /1000 downscale now loops to cover ms / us / ns) and ISO timestamps with sub-microsecond fractional seconds (a regex truncates the fractional part to 6 digits before strptime). Two new format strings cover ...HH:MM:SS.fffffffZ and ...HH:MM:SS.fffffff+HHMM.
  • DataConverter.guess_symbol_from_csv_content peeks the first data row to pick up the symbol / ticker column as ticker and tag the provider as databento when ts_event / ts_recv headers are present. It is used as a fallback from both the CLI convert_from and the API convert_to_ohlcv, so Databento exports - whose filenames carry the dataset and date range but not the symbol - generate proper TOML with zero extra flags.
  • ts_event / ts_recv are excluded from the .extra.csv sidecar.

Note: duplicate consecutive timestamps still raise Invalid interval: 0. Databento snapshot+update streams can produce these; drop them with drop_duplicates(subset="ts_event") before convert.