PineForge HPO 1.11.0
Native hyperparameter optimization for PineForge strategies
Loading...
Searching...
No Matches
return_stats.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <cstddef>
4#include <cstdint>
5#include <limits>
6#include <optional>
7#include <string_view>
8#include <vector>
9
10namespace pineforge::hpo {
11
13inline constexpr std::string_view kReturnStatsContract = "pineforge-hpo-return-stats/v1";
14
17inline constexpr std::string_view kReturnBlocksContract = "pineforge-hpo-return-blocks/v1";
18
21inline constexpr double kReturnStatsRiskFreeAnnual = 0.02;
22
29inline constexpr std::int64_t kReturnStatsUtcMinMs = -1099511627775000;
30
32inline constexpr std::int64_t kReturnStatsUtcMaxMs = 1099511627775999;
33
35inline constexpr std::size_t kReturnStatisticCount = 9;
36
38inline constexpr std::size_t kReturnStatsMetricCount = 18;
39
41enum class ReturnSeries : std::uint8_t {
42 Bar,
43 Monthly,
44};
45
47enum class ReturnStatistic : std::uint8_t {
48 Count,
49 Skipped,
51 Mean,
52 Std,
54 Skew,
55 KurtRaw,
56 Status,
57};
58
65enum class ReturnStatsStatus : std::uint8_t {
66 Ok = 0,
68 ZeroVariance = 2,
69 NonfiniteInput = 4,
73};
74
76enum class ReturnPeriodFailure : std::uint8_t {
77 None,
81 UtcRange,
82};
83
91 const void* records = nullptr;
92 std::size_t count = 0;
93 std::size_t stride = 0;
94 std::size_t time_offset = 0;
95 std::size_t equity_offset = 0;
96};
97
100template <typename Record>
102 std::size_t count,
103 std::int64_t Record::*time_ms,
104 double Record::*equity) noexcept {
105 EquityPointsView view;
106 view.records = records;
107 view.count = count;
108 view.stride = sizeof(Record);
109 if (records != nullptr && count != 0) {
110 const auto* base = reinterpret_cast<const unsigned char*>(records);
111 view.time_offset = static_cast<std::size_t>(
112 reinterpret_cast<const unsigned char*>(&(records->*time_ms)) - base);
113 view.equity_offset = static_cast<std::size_t>(
114 reinterpret_cast<const unsigned char*>(&(records->*equity)) - base);
115 }
116 return view;
117}
118
121 bool bar = false;
122 bool monthly = false;
125 std::string_view chart_timezone;
126};
127
135 ReturnStatsStatus status = ReturnStatsStatus::NonfiniteInput;
136 std::optional<std::int64_t> count;
137 std::optional<std::int64_t> skipped;
138 double periods_per_year = std::numeric_limits<double>::quiet_NaN();
139 double mean = std::numeric_limits<double>::quiet_NaN();
140 double std_dev = std::numeric_limits<double>::quiet_NaN();
141 double sharpe_per_period = std::numeric_limits<double>::quiet_NaN();
142 double skew = std::numeric_limits<double>::quiet_NaN();
143 double kurt_raw = std::numeric_limits<double>::quiet_NaN();
144
146 ReturnPeriodFailure period_failure = ReturnPeriodFailure::None;
149 std::int64_t intervals = 0;
152 std::int64_t nonfinite_returns = 0;
153
155 double value(ReturnStatistic statistic) const noexcept;
156
158 bool all_fields_finite() const noexcept;
159
161 bool status_invariant_holds() const noexcept;
162
166 void enforce_status_invariant() noexcept;
167};
168
171 std::optional<ReturnSeriesStats> bar;
172 std::optional<ReturnSeriesStats> monthly;
173};
174
185 const ReturnStatsRequest& request) noexcept;
186
188bool is_utc_chart_timezone(std::string_view chart_timezone) noexcept;
189
191std::string_view return_stats_metric_name(ReturnSeries series, ReturnStatistic statistic) noexcept;
192
195 ReturnSeries series = ReturnSeries::Bar;
196 ReturnStatistic statistic = ReturnStatistic::Count;
197};
198
200std::optional<ReturnStatsMetric> parse_return_stats_metric(std::string_view name) noexcept;
201
207
208// ---------------------------------------------------------------------------------------------
209// Return blocks (contract pineforge-hpo-return-blocks/v1)
210//
211// Per trial, the block object reports how many intervals every block of the bar-return series
212// holds and their sum and centred second moment; the result-level object declares the layout all
213// of its rows were reduced under. Only three of the statuses below are wire texts: the others are
214// library outcomes that are never published as a payload status.
215// ---------------------------------------------------------------------------------------------
216
223enum class ReturnBlocksStatus : std::uint8_t {
224 NotRequested = 0,
225 Ok = 1,
230 Nonfinite = 3,
232 UnusableCurve = 4,
236 UnusableLayout = 5,
237};
238
241std::string_view return_blocks_status_text(ReturnBlocksStatus status) noexcept;
242
258 std::uint32_t blocks = 0;
259 std::int64_t intervals = 0;
260 bool usable = false;
261 std::vector<std::int64_t> n_b;
262 std::vector<std::int64_t> boundary_time_ms;
263};
264
275 ReturnBlocksStatus status = ReturnBlocksStatus::NotRequested;
276 std::vector<std::int64_t> count;
277 std::vector<double> sum;
278 std::vector<double> m2;
279};
280
289 std::uint32_t blocks);
290
308 const ReturnBlockLayout& layout);
309
310} // namespace pineforge::hpo
ReturnBlockMoments reduce_return_blocks(const EquityPointsView &points, const ReturnBlockLayout &layout)
Reduces the bar returns of a curve into the blocks of its own layout.
ReturnPeriodFailure
Why the period or time basis of a series is unavailable. Diagnostic only; not on the wire.
@ TooFewPoints
Bar series with fewer than three points.
@ NonPositiveSpan
Bar series whose last timestamp does not exceed its first.
@ SpanOverflow
Bar series whose timestamp difference overflows 64 bits.
@ UtcRange
Monthly series with a timestamp outside the supported UTC range.
ReturnSeries
Return frequency of one statistics series.
@ Monthly
Simple returns between consecutive last points of UTC calendar-month buckets.
@ Bar
Simple returns between adjacent curve points.
ReturnStatsStatus
Stable numeric status of one series.
@ NonfiniteInput
An input equity is not finite, or the view is unusable; all null.
@ InsufficientCount
Fewer than four valid returns: the full statistic set is undefined.
@ UnsupportedTimezone
Monthly series requested for a chart timezone other than UTC.
@ Ok
Every field is finite.
@ PeriodUnavailable
The period or time basis is unavailable.
@ ZeroVariance
The computed variance is exactly zero.
@ DerivedNonfinite
A derived return, sum, moment or ratio is not finite.
EquityPointsView make_equity_points_view(const Record *records, std::size_t count, std::int64_t Record::*time_ms, double Record::*equity) noexcept
Builds an EquityPointsView over count records of type Record from pointers to its time_ms and equity ...
constexpr std::int64_t kReturnStatsUtcMaxMs
Latest Unix millisecond timestamp whose UTC month can be derived (inclusive).
std::string_view return_stats_metric_name(ReturnSeries series, ReturnStatistic statistic) noexcept
Returns the wire metric name, for example returns.bar.sharpe_per_period.
ReturnBlockLayout compute_block_layout(const EquityPointsView &points, std::uint32_t blocks)
Cuts the adjacent intervals of a curve into blocks (S) blocks, and reads the opening timestamp of eve...
ReturnBlocksStatus
Status of one row's block moments.
@ UnusableCurve
The borrowed view cannot be read; no reduction was attempted.
@ UnusableLayout
No layout can be formed for this curve: S is odd or below 2, K is below S, a block-size rule of the m...
@ NotRequested
No blocks were requested: no layout and no payload.
@ Nonfinite
An equity, a return or a moment is not finite; wire text non_finite.
@ NonPositiveEquity
An interval was skipped because a prior equity is not positive; wire text non_positive_equity.
@ None
Evaluation succeeded.
bool is_utc_chart_timezone(std::string_view chart_timezone) noexcept
True for the chart timezone names that select UTC bucketing: empty, UTC and Etc/UTC.
bool return_stats_contraction_free() noexcept
Sanity probe of this translation unit's build: true when a multiply followed by an add is evaluated a...
constexpr std::size_t kReturnStatsMetricCount
Number of metric names of this contract (two series times nine fields).
constexpr double kReturnStatsRiskFreeAnnual
Fixed annual risk-free rate.
constexpr std::int64_t kReturnStatsUtcMinMs
Earliest Unix millisecond timestamp whose UTC month can be derived (inclusive).
ReturnStatistic
One published field of a series. Declaration order is the wire order of the metric names.
@ PeriodsPerYear
Annualization basis P of the series; reported, never applied.
@ KurtRaw
Population-moment raw kurtosis b2 (a normal distribution gives 3).
@ Skew
Population-moment skewness g1.
@ Mean
Raw mean of the valid returns.
@ Skipped
Intervals skipped because the prior equity is not positive.
@ Std
Sample standard deviation (T - 1 divisor).
@ Count
Number of valid returns of the series (T), never a bar counter.
@ Status
Numeric ReturnStatsStatus code.
@ SharpePerPeriod
Unannualised excess Sharpe ratio.
constexpr std::size_t kReturnStatisticCount
Number of published fields per series.
std::optional< ReturnStatsMetric > parse_return_stats_metric(std::string_view name) noexcept
Resolves a metric name; returns an empty value for every name outside the eighteen.
constexpr std::string_view kReturnStatsContract
Contract string of the result-level return_stats object (legacy mode, version 1).
ReturnStatsResult compute_return_stats(const EquityPointsView &points, const ReturnStatsRequest &request) noexcept
Computes the requested return statistics from a borrowed equity curve.
constexpr std::string_view kReturnBlocksContract
Contract string of the per-row block_returns object and of the result-level return_blocks object that...
std::string_view return_blocks_status_text(ReturnBlocksStatus status) noexcept
Returns the wire text of a status: ok, non_positive_equity, non_finite, and empty for the statuses th...
Borrowed, strided view of an ordered array of records holding (time_ms, equity).
std::size_t equity_offset
Byte offset of the binary64 equity member.
const void * records
Address of record 0; may be null only when count is 0.
std::size_t count
Number of records (points).
std::size_t time_offset
Byte offset of the 64-bit signed time_ms member.
std::size_t stride
Bytes between consecutive records.
Block layout of one bar-return series: how many intervals each block holds and which curve point open...
std::vector< std::int64_t > boundary_time_ms
S + 1 opening timestamps, in milliseconds.
std::vector< std::int64_t > n_b
S block sizes, ascending block.
Moments of every block of one bar-return series, ascending block.
std::vector< std::int64_t > count
Usable returns per block.
std::vector< double > sum
Sum of the usable returns per block.
std::vector< double > m2
Centred second moment per block.
All published fields of one series plus diagnostics.
std::optional< std::int64_t > skipped
Skipped intervals; empty with count.
bool all_fields_finite() const noexcept
True when count, skipped and all six real fields are finite.
double value(ReturnStatistic statistic) const noexcept
Returns the field as the double the metric layer publishes; NaN stands for null.
std::optional< std::int64_t > count
T; empty when the series is not interpretable.
One of the eighteen metric names, decomposed.
Selects the series to compute. A series that is not requested costs nothing.
std::string_view chart_timezone
Chart timezone name.
The series that were requested; an absent series was not requested.
std::optional< ReturnSeriesStats > monthly
Present when ReturnStatsRequest::monthly is set.
std::optional< ReturnSeriesStats > bar
Present when ReturnStatsRequest::bar is set.