25 auto& value = result.value;
26 value.entry_time = row.entry_time;
27 value.exit_time = row.exit_time;
28 value.entry_price = row.entry_price;
29 value.exit_price = row.exit_price;
31 value.pnl_pct = row.pnl_pct;
32 value.is_long = row.is_long ? 1 : 0;
33 value.max_runup = row.max_runup;
34 value.max_drawdown = row.max_drawdown;
36 value.commission = row.commission;
37 value.entry_bar_index = row.entry_bar_index;
38 value.exit_bar_index = row.exit_bar_index;
39 value.open_at_end = row.open_at_end ? 1 : 0;
40 result.entry_incarnation = row.entry_incarnation;
41 result.close_cause = BacktestEngine::classify_report_close_cause(row);
42 result.exit_from_bracket = row.exit_from_bracket ? 1 : 0;
47 std::size_t capacity)
const override {
49 if (capacity && !out)
throw std::invalid_argument(
"trade page buffer");
50 const auto count =
static_cast<std::size_t
>(
51 std::min<LogicalIndexV1>(capacity,
size() - from));
52 for (std::size_t i = 0; i < count; ++i) out[i] =
at(from + i);
58 return visit_values(from, count, context, visitor,
false);
63 return visit_values(from, count, context, visitor,
true);
67 check_text(index, field);
72 std::uint64_t byte_offset,
char* out,
73 std::size_t capacity)
const override {
74 check_text(index, field);
76 if (byte_offset > text.size())
throw std::out_of_range(
"trade text offset");
77 if (capacity && !out)
throw std::invalid_argument(
"trade text buffer");
78 const auto offset =
static_cast<std::size_t
>(byte_offset);
79 const auto count = std::min(capacity, text.size() - offset);
80 if (count) std::memcpy(out, text.data() + offset, count);
90 if (index >=
size())
throw std::out_of_range(
"trade source index");
93 const auto length =
size();
94 if (from > length || count > length - from)
95 throw std::out_of_range(
"trade source range");
99 if (
static_cast<std::uint32_t
>(field) > 3)
100 throw std::invalid_argument(
"trade text selector");
104 check_range(from, count);
105 if (!visitor)
throw std::invalid_argument(
"trade source visitor");
106 VisitResultV1 result{};
107 while (result.visited < count) {
108 const auto index = reverse ? from + (count - result.visited - 1)
109 : from + result.visited;
110 const auto row =
at(index);
112 if (!visitor(context, index, row))
return result;
114 result.complete =
true;
130 return ledger_.
numeric_at(
static_cast<std::size_t
>(index));
133 const auto row =
static_cast<std::size_t
>(index);
140 throw std::invalid_argument(
"trade text selector");
142 const TradeLedger& ledger_;
164 throw std::invalid_argument(
"trade text selector");
166 const BacktestEngine& engine_;
Trade get_report_trade(int i) const
std::string entry_id_at(size_type global) const
std::string exit_id_at(size_type global) const
Trade numeric_at(size_type global) const
std::string entry_comment_at(size_type global) const
std::string exit_comment_at(size_type global) const
EngineReportTradeSourceV1(const BacktestEngine &engine)
LogicalIndexV1 size() const override
LogicalIndexV1 size() const override
LedgerTradeSourceV1(const TradeLedger &ledger)
virtual LogicalIndexV1 size() const =0
TradeRowV1 at(LogicalIndexV1 index) const override
VisitResultV1 visit(LogicalIndexV1 from, LogicalIndexV1 count, void *context, TradeVisitorV1 visitor) const override
virtual Trade numeric_value(LogicalIndexV1 index) const =0
virtual std::string text_value(LogicalIndexV1 index, TradeTextV1 field) const =0
std::uint64_t text_size(LogicalIndexV1 index, TradeTextV1 field) const override
std::size_t read_text(LogicalIndexV1 index, TradeTextV1 field, std::uint64_t byte_offset, char *out, std::size_t capacity) const override
std::size_t read_page(LogicalIndexV1 from, TradeRowV1 *out, std::size_t capacity) const override
VisitResultV1 visit_backward(LogicalIndexV1 from, LogicalIndexV1 count, void *context, TradeVisitorV1 visitor) const override
std::uint64_t LogicalIndexV1
bool(*)(void *, LogicalIndexV1, TradeRowV1) TradeVisitorV1