PineForge v0.13.1-379-g9b50973
Deterministic PineScript v6 backtest runtime — C ABI reference
Loading...
Searching...
No Matches
hello_kernel.cpp
Go to the documentation of this file.
1// hello, kernel — the smallest complete PineForge native strategy.
2//
3// Subclass NativeStrategyHost, describe the run once, hand it bars, read the
4// closed trades back. No PineScript, no codegen, no C ABI, no dlopen.
5//
6// c++ -std=c++17 hello_kernel.cpp -lpineforge -o hello_kernel
7
9
10#include <iostream>
11
12namespace {
13
14class HelloKernel : public pineforge::NativeStrategyHost {
15 int bars_ = 0;
16
17 void on_native_run_begin() override { bars_ = 0; }
18
19 // One calculation point per closed script bar. Requests submitted here are
20 // matched from the next eligible point on, never on the bar just closed.
21 void on_native_bar(const pineforge::Bar&,
22 const pineforge::NativeDecisionContext&) override {
23 ++bars_;
24 if (bars_ == 1) {
25 submit_market({pineforge::order_action::Transact{1.0}, "hello-long", ""});
26 } else if (bars_ == 3) {
27 submit_market({pineforge::execution::Flatten{}, "hello-flat", ""});
28 }
29 }
30};
31
32// Nothing is inferred: the spec names the clock, the instrument and the
33// account. Validation refuses an incomplete value at configure time.
36 spec.identity.session_key = "hello-kernel";
37 spec.identity.run_number = 1;
38 spec.input_tf = "5";
39 spec.script_tf = "5";
40 spec.ticker = "MOCK";
41 spec.tickerid = "TEST:MOCK";
42 spec.type = "crypto";
43 spec.currency = "USDT";
44 spec.basecurrency = "ETH";
45 spec.timezone = "UTC";
46 spec.session = "24x7";
47 spec.initial_capital = 10000.0;
48 spec.point_value = 1.0;
49 spec.account_fx = 1.0;
50 spec.price_tick = 0.01;
51 spec.fee_kind = pineforge::NativeFeeKind::Percent;
52 spec.fee_value = 0.0;
53 return spec;
54}
55
56// open, high, low, close, volume, timestamp (Unix milliseconds).
57const pineforge::Bar kBars[] = {
58 {100.0, 102.0, 99.0, 101.0, 4.0, 0},
59 {102.0, 103.0, 101.0, 102.0, 4.0, 300000},
60 {103.0, 104.0, 102.0, 103.5, 4.0, 600000},
61 {103.5, 105.0, 103.0, 104.0, 4.0, 900000},
62};
63constexpr int kBarCount = 4;
64
65} // namespace
66
67int main() {
68 HelloKernel host;
69 if (host.configure_native(make_spec()).status
70 != pineforge::NativeSetupStatus::Applied) {
71 std::cerr << "configure: " << host.last_error() << '\n';
72 return 1;
73 }
74
75 host.run(kBars, kBarCount);
76 if (host.native_state().kind != pineforge::NativeLifecycleKind::Completed) {
77 std::cerr << "run: " << host.last_error() << '\n';
78 return 1;
79 }
80
81 std::cout << "closed trades: " << host.trade_count() << '\n';
82 for (int i = 0; i < host.trade_count(); ++i) {
83 const auto& trade = host.get_trade(i);
84 std::cout << " " << (trade.is_long ? "long " : "short")
85 << " qty=" << trade.qty
86 << " entry=" << trade.entry_price
87 << " exit=" << trade.exit_price
88 << " pnl=" << trade.pnl << '\n';
89 }
90 return host.trade_count() > 0 ? 0 : 1;
91}
The public native host: an abstract subclass of BacktestEngine with no PineScript on it.
int main()
static const pf_bar_t kBars[]
static pf_native_run_spec_v1 make_spec(void)
@ kBarCount
One complete setup value, staged/copied by NativeStrategyHost before it is applied at begin.