You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
pyne data convert-from wrote schedules on the wrong weekdays (#85). Schedule days were
numbered 1-7 (ISO) while SymInfo uses 0 (Monday) ... 6 (Sunday), and only one weekly session
start/end pair was written. Monday fell outside the schedule, so an unlagged request.security(..., "D", ...) on such a feed showed every Monday chart bar that day's own
close. The opening-hours analysis and the default schedules now use 0-6 weekdays, every
opening-hours interval gets its own session start and end, an even Monday-Friday intraday feed
is no longer inferred as 24/7, SymInfo.load_toml rejects a schedule day outside 0-6, and convert-from stops with an error on an unloadable existing TOML instead of overwriting it with
inferred defaults. Delete symbol TOMLs that an earlier convert-from generated and convert
again: a file with a day 7 now fails to load, and one that still loads keeps its days shifted,
because convert-from does not overwrite an existing, loadable TOML. Thanks to danielmayerfrank for the report.
Aggregation timezones resolve like the runner (#86). aggregate_ohlcv() defaults to UTC
instead of the host's local zone; the request.security resample and pyne data aggregate
resolve the TOML timezone the same way the runner does (empty means UTC). An unparseable
timezone in the security resample raises with the TOML path instead of silently falling back to
the host zone. An nD/nW/nM grid on a symbol without opening_hours and session_starts logs a
warning that periods are grouped by calendar date. Aggregating onto the source file (directly or
via a link) is rejected instead of truncating the input. Thanks to danielmayerfrank for the
report.
Conditional security writes that share only scalar inputs (an input bool, a timeframe
string) are each lifted into their own clone. Before, the second write lagged on every
higher-timeframe bar its guard skipped.
A write guarded by a condition only leaves its guard when every dependency is provably safe
ahead of it. Aliases of a mutated collection and method receivers keep the write guarded.
PYNE_SECURITY_TRACE logs each context's first chart-side read with the symbol and timeframe
its signal resolved to; a traced run defers missing feeds and answers na, so one pass names
every feed a script needs.
Strategy
A strategy.exit without any price level cancels its resting leg. A call whose price and
tick arguments all resolve to na arms no trigger and used to be ignored, leaving an earlier
same-id leg live. On TradingView it replaces that leg with an order that can never fill
(measured on CAPITALCOM:EURUSD 60, with and without qty_percent; a same-id entry order stays
pending). This is also the form PyneComp now emits for a pre-v5 strategy.exit without a price
level, which was previously translated into a market close. Thanks to Vesper for the report on
Discord.
A strategy.exit leg is no longer carried over to the reversing entry itself. Measured on
TradingView (BINANCE:BTCUSDT 30m, process_orders_on_close): the reversed position is first
covered by the next bar's re-issued exit call, 5/5 events.
Time, sessions and extended hours
time() / time_close() periods match TradingView (measured on CAPITALCOM EURUSD, BTCUSD,
GOLD and AAPL):
time("W") / time("M") open at the session open of the period's first scheduled trading
day (FX: Sunday 17:00 New York) instead of local midnight.
time_close() of a period longer than one trading day (W, M, nD, nW, nM) is the next period's
session open on an intraday chart and the last scheduled session end on a D/W/M chart.
On a D/W/M chart an intraday timeframe request resolves like "D"; an na timeframe selects
the chart's timeframe instead of raising TypeError.
A requested intraday bar that opens inside a trading day is cut at that day's end even when
its close passes the next overnight open (DST day).
bars_back is evaluated on the chart's real bar history.time(tf, bars_back) and time_close(tf, bars_back) read the chart bar that many bars back, stepping over weekends,
session breaks and bars missing from the data; the result is na until the chart has that many
bars. A negative bars_back (and a negative timeframe_bars_back on an intraday timeframe)
walks forward over the symbol's session schedule.
timeframe_bars_back on D/W/M and multi-period grids walks the session runs and crosses the
turn of the year the way TradingView does (1.48 million nW and 180 thousand nM values measured,
no mismatch; daily grids measured on CAPITALCOM US500, EURUSD, AAPL, GOLD and BTCUSD). Intraday
chart bars belong to the daily period of their scheduled close, so a session-end-shortened bar
stays in the day that ends there.
Session strings: an empty or non-numeric session string is the symbol's own session, read in
the timezone argument when one is given; "24x7" is the all-day session; HHMM is a minute count
taken modulo a day ("0930-2500" closes at 01:00); a multi-range session without days runs
Monday to Friday. Malformed numeric sessions still give na. An intraday request draws a session
run with its own endpoint resolution on a DST change night.
Extended trading hours.SymInfo stores a symbol's extended hours (pre-market through
post-market) with their dated exceptions, and which hours the bars follow. On extended-hours bars time(tf, "extended") and time(tf, "regular") read the two templates, the session.*
properties tell pre-market, market and post-market bars apart, and syminfo.session reports the
mode. New syminfo.extended_hours. Measured on NASDAQ:AAPL 60m on both hours.
CFD feeds count every weekday on nD/nW/nM grids. A CFD feed carries no exchange calendar, so
CAPITALCOM symbols use the weekday grid whatever their type, while exchange-listed stocks keep
the observed grid (NASDAQ:AAPL 2D-7D exact from 2000 on).
Math
math.log, math.log10, math.pow and math.atan reproduce TradingView bit for bit. log, log10 and pow model the processor's approximate reciprocal their algorithm is built
on, using a reciprocal table measured bin by bin on the venue; atan gets its own fdlibm port.
Verified exact on ~800k natural TradingView arguments, 9000+ crafted reciprocal-bin arguments and
an independent 400k-value holdout; atan 47116/47116 across every reduction branch.
math.pow with a negative base and a non-integer exponent returns NaN instead of a complex
number.
Builtin semantics
ta.cross / ta.crossover / ta.crossunder: a bar with an na source reads na and leaves the
armed state alone.
calc_bars_count: an uncalculated bar does not advance bar_index, and last_bar_index counts
the calculated window.
array.max / array.min: a rank the array's size covers but its non-na values do not repeats
the last ranked value.
CSV export writes an infinity as NaN, the way TradingView exports it.
A comparison standing in a conditional arm is cast to bool.
Live trading
Session corrections are honoured in live session checks. Exchange holidays and early closes
from SymInfo.session_corrections now reach the live runner's synth, stale-feed and reconnect
gates, the CLI gap classifier and the Pine session builtins. Before, only the backtest bar
calendar used them, so a live bot treated a venue holiday as an open session, synthesised idle
bars into it, dispatched orders the venue rejected and churned through reconnect backfills.
A venue-refused replayed close stays pending. After a restart into a closed market or symbol
holiday, a re-dispatched close the exchange refuses no longer kills the run: the row stays
pending and the sync engine replays it at the next sync, like after a connection error.
Configuration
Parallel pyne processes no longer wipe config files.ensure_config no longer rewrites an
unchanged config file and replaces a changed one atomically (keeping the symlink, mode and
owner). Before, one process could read a file another was rewriting and write the bare template
back over the user's values, credentials included.
Static typing
Pine ints are int to type checkers. A Pine int is still a double at runtime, but PyneInt
and na_int are now int in the stubs, so int values and literals are accepted where Pine
expects an int. Lib functions returning a Pine int (time parts, timestamp, sizes and indices,
strategy trade counters, input.int, ...) are typed accordingly; generic results (nz, fixnan, math.abs/max/min, ta.valuewhen/median/range, array and matrix reductions) follow
their source's type, and the for loop counter is typed from its bounds.
Result types corrected after TradingView measurements: color.r/g/b, math.sum/avg/sign and the ta.supertrend direction are float; timenow, dividends.future_ex_date/future_pay_date and syminfo.shares_outstanding_total are int; syminfo.target_price_estimates is float.
Function-property hybrids (time, year, time_close, ta.tr, ta.vwap, ...) are typed as a
value that is also callable with the function's own signature.
Performance
Compiled native math. A new optional Cython extension holds compiled twins of the math and
fdlibm functions, bit-identical to the pure-Python originals, which stay the reference and the
fallback. Platform wheels (Linux, Windows and macOS on x86_64 and arm64, CPython 3.11-3.14) are
now published with the extension built in, next to the sdist and a pure-Python wheel; every wheel
runs the native-vs-Python bit-identity test before release. PYNE_NO_NATIVE_MATH=1 disables the
extension at runtime, PYNE_BUILD_PURE=1 builds the pure wheel.
time("W") lookups: 1.65 -> 1.12 us through an exact validity-window cache for single-period
D/W/M bars on a session template.
Documentation
Compatibility claims updated with corpus metrics; FAQ, overview and barstate docs refreshed.
The docs state that PyneCore runs Pyne code and that PyneComp, a separate service used with a
PyneSys API key, converts Pine Script v4-v6 (v1-v3 on a best-effort basis) to Pyne code.