35 if (c >=
'0' && c <=
'9') val = val * 10 + (c -
'0');
38 return val > 0 ? val : 1;
51 return tf.find(
'W') != std::string::npos;
55 return !tf.empty() && tf.back() ==
'M';
59 return tf.find(
'S') != std::string::npos;
63bool tf_change(int64_t prev_ms, int64_t curr_ms,
const std::string& tf);
68int tf_ratio(
const std::string& input_tf,
const std::string& target_tf);
109 const std::string& tz,
const std::string& session);
110bool tf_change(int64_t prev_ms, int64_t curr_ms,
const std::string& tf,
111 const std::string& tz,
const std::string& session);
142 const std::string& session);
149 const std::string& session);
156 const std::string& session,
170 const std::string& tz,
171 const std::string& session);
181 const std::string& session);
188 const std::string& session,
200 const std::string& session,
252 const std::string& tz,
253 const std::string& session,
254 const std::vector<int64_t>& stamps,
255 const Bar* input_bars,
int n_input);
284#define PINEFORGE_HAS_NATIVE_DAY_PARTITION_V1 1
298 const std::string& input_tf);
305 const std::string& input_tf,
306 const std::string& tz,
307 const std::string& session =
"");
354 int64_t calling_close_ms);
423 std::vector<int64_t> trade_instants,
489 enum class Mode { PASSTHROUGH, RATIO, CALENDAR };
491 Mode mode_ = Mode::PASSTHROUGH;
494 int64_t target_seconds_ = 0;
495 int64_t input_seconds_ = 0;
496 std::string anchor_tz_ =
"UTC";
497 std::string anchor_session_;
502 std::vector<int64_t> native_stamps_;
503 std::vector<int64_t> native_group_open_;
504 int64_t native_last_bound_ = 0;
506 bool early_close_completes_ =
true;
509 Bar last_completed_bar_{};
510 int sub_bar_count_ = 0;
511 bool has_completed_ =
false;
512 bool current_emitted_complete_ =
false;
514 void reset_current(
const Bar& bar);
515 void merge_into_current(
const Bar& bar);
517 int native_index(int64_t ms)
const;
NativeDayPartitionScope & operator=(const NativeDayPartitionScope &)=delete
NativeDayPartitionScope(const NativeDayPartition *p)
NativeDayPartitionScope(const NativeDayPartitionScope &)=delete
~NativeDayPartitionScope()
AggregatedBar feed(const Bar &input_bar, int64_t next_input_ms, int64_t calling_close_ms)
feed(bar, next_input_ms) with the CALLING chart bar's nominal close known (0 = unknown,...
int64_t bucket_open_ms(int64_t ms) const
Open (Unix ms) of the target-TF bucket an input bar stamped ms belongs to, on the aggregator's anchor...
AggregatedBar feed(const Bar &input_bar, int64_t next_input_ms)
feed() with the NEXT input bar's timestamp known (0 = unknown, the form above).
Bar last_completed() const
Last completed aggregated bar.
TimeframeAggregator(const std::string &target_tf, const std::string &input_tf, const std::string &tz, const std::string &session="")
Calendar/ratio aggregation anchored on a symbol clock.
CalendarPeriod calendar_period() const
The D/W/M period a CALENDAR aggregator buckets on; NONE for RATIO and PASSTHROUGH.
bool has_native_periods() const
void set_early_close_completes(bool on)
Whether a session ending BEFORE its nominal close completes the running D/W/M bucket on that session'...
Bar current() const
Current in-progress bar.
TimeframeAggregator()
Default: passthrough mode (no aggregation).
AggregatedBar complete_pending_partial()
Finalize the pending partial bucket exactly as feed() finalizes a bucket – the sub-bars it holds ARE ...
bool period_changes(int64_t prev_ms, int64_t curr_ms) const
CALENDAR: whether prev_ms and curr_ms lie in different periods of this aggregator – different native ...
TimeframeAggregator(int ratio)
Ratio-based: every ratio input bars produce one output bar.
TimeframeAggregator(const std::string &target_tf, const std::string &input_tf)
Calendar-based: aggregate until day/week/month boundary.
AggregatedBar feed(const Bar &input_bar)
Feed one input bar. Returns aggregation state.
bool has_pending_partial() const
RATIO (fixed intraday target) only: whether the bucket in progress holds sub-bars no completion has e...
void set_native_periods(std::vector< int64_t > stamps, std::vector< int64_t > trade_instants, CalendarPeriod feed_period)
TradingView's own period partition for a CALENDAR aggregator, from the native request....
bool is_active() const
Whether aggregation is active (non-passthrough).
int64_t bar_label_ms(int64_t ms) const
Timestamp of the target-TF bar OPENED by an input bar stamped ms — what TradingView dates the aggrega...
bool early_close_completes() const
int64_t session_trading_day_index(int64_t ms, const std::string &tz, const std::string &session)
Broker trading-day ordinal on the unmerged symbol session clock.
int64_t session_covered_instant_ms(int64_t ms, const std::string &tz, const std::string &session)
The session instant a native CALENDAR chart stamp covers.
int64_t session_period_last_traded_close_ms(int64_t ms, const std::string &tz, const std::string &session, CalendarPeriod period)
Exclusive close (Unix ms) of the LAST TRADED session-day of the D/W/M bar that contains ms: DAY is se...
bool tf_is_weekly(const std::string &tf)
int tf_to_seconds(const std::string &tf)
Convert a TradingView timeframe string to seconds.
int tf_ratio(const std::string &input_tf, const std::string &target_tf)
Compute how many input bars fit into one target bar.
int64_t session_period_close_ms(int64_t ms, const std::string &tz, const std::string &session, CalendarPeriod period)
Exclusive close (Unix ms) of the symbol's D/W/M bar that contains ms: DAY -> session-day open + sessi...
CalendarPeriod calendar_period_for(const std::string &tf)
Determine the calendar period for a target TF string.
const NativeDayPartition * active_native_day_partition()
bool tf_change(int64_t prev_ms, int64_t curr_ms, const std::string &tf)
Check if prev/curr timestamps cross a timeframe boundary.
const NativeDayPartition * set_active_native_day_partition(const NativeDayPartition *p)
The calling thread's active chart partition, read by session_day_index / session_period_open_ms / ses...
bool tf_is_daily(const std::string &tf)
bool build_native_day_partition(NativeDayPartition &out, const std::string &tz, const std::string &session, const std::vector< int64_t > &stamps, const Bar *input_bars, int n_input)
Build the partition for the symbol clock (tz, session) from the native daily stamps and the chart's i...
constexpr int64_t kMsPerDay
std::string detect_timeframe(const Bar *bars, int n, int max_samples=100)
Detect the timeframe string from an array of bars by computing the median timestamp delta and mapping...
constexpr int64_t kSecPerDay
bool crosses_boundary(int64_t prev_ms, int64_t curr_ms, CalendarPeriod period)
Check if two timestamps (Unix milliseconds) fall in different calendar periods.
bool tf_is_daily_or_higher(const std::string &tf)
True for a daily-or-higher chart timeframe ("D", "1D", "2D", "W", "M"): a bar that covers whole sessi...
bool tf_is_intraday(const std::string &tf)
int64_t session_day_index(int64_t ms, const std::string &tz, const std::string &session)
Ordinal of the session day containing ms (days since epoch on the session clock).
int tf_multiplier(const std::string &tf)
Extract the numeric multiplier from a TF string (e.g. "15" -> 15, "D" -> 1).
int64_t session_intraday_bucket_open_ms(int64_t ms, int64_t bucket_sec, const std::string &tz, const std::string &session)
Open (Unix ms) of the bucket_sec-wide intraday bucket that contains ms on the symbol's day-stamp-anch...
int native_day_partition_index(const NativeDayPartition &p, int64_t ms)
Index of the native period holding ms under p: -1 before the first stamp and at / after the last stam...
bool tf_is_seconds(const std::string &tf)
bool tf_is_monthly(const std::string &tf)
int64_t session_period_open_ms(int64_t ms, const std::string &tz, const std::string &session, CalendarPeriod period)
Open (Unix ms) of the symbol's D/W/M bar that contains ms: the day stamp of the period's first sessio...
std::vector< int64_t > stamps
std::vector< int64_t > trade_day
std::vector< int64_t > week_open
std::vector< int64_t > month_open