Files
wickra/examples/c/wickra_strategy.h
T
kingchenc 12681e4b1b C ABI: full example suite + docs & About coverage (#224)
Stacked on #222 (base `feat/c-abi-hub`), so the diff is just the additions on top of the hub foundation — no merge of #222 required.

## What this adds

**Examples — full parity with rust/python/node (`examples/c/`)**
- `streaming.c` upgraded to the multi-indicator (SMA/EMA/RSI/MACD + signals) demo
- `backtest.c`, `multi_timeframe.c` (manual time-bucket resampling), `parallel_assets.c` (serial vs OpenMP fan-out, one handle per asset)
- three educational strategies: `strategy_rsi_mean_reversion.c`, `strategy_macd_adx.c`, `strategy_bollinger_squeeze.c`
- two network examples shelling out to `curl`: `fetch_btcusdt.c`, `live_binance.c` (REST poll)
- two header-only helpers (`wickra_csv.h`, `wickra_strategy.h`) since the C ABI ships no IO layer
- CMake builds all 11; the 9 offline ones run under `ctest` on 3 OS; the network two are built-only

**Docs & metadata — surface the C ABI everywhere it was missing**
- ARCHITECTURE diagram + crate table, SECURITY + THREAT_MODEL (the C ABI as the sole `unsafe` FFI surface), the three binding package READMEs, issue/PR templates, CHANGELOG, and the GitHub About template (live About + org description updated too)

**Cleanup**
- removed all references to the private generator tooling from public files (`bindings/c/src/lib.rs` header, `CONTRIBUTING.md`, `sync-about.yml`)

Verified locally: `cargo build -p wickra-c --release`, `cmake + ctest` (9/9 pass), and `-Wall -Wextra -Wpedantic` clean on gcc 13.
2026-06-09 02:14:28 +02:00

93 lines
3.4 KiB
C

/* Shared equity-curve summary for the Wickra C strategy examples.
*
* The Rust strategy examples repeat their `print_summary` per file; in C the
* presentation is factored into this header so each strategy .c file stays
* focused on its signal logic. Pure reporting — no indicator state.
*
* Header-only: define WICKRA_STRATEGY_IMPL in exactly one translation unit.
*/
#ifndef WICKRA_STRATEGY_H
#define WICKRA_STRATEGY_H
#include <stddef.h>
/* Print a one-screen summary of a strategy run: returns vs buy & hold, trade
* win/loss counts, max drawdown, per-trade Sharpe, best/worst trade. */
void wickra_print_summary(const char *name, double first_price, double last_price,
size_t bars, const double *closed_trades, size_t n_trades,
double final_equity, const double *equity_curve,
size_t n_curve);
#ifdef WICKRA_STRATEGY_IMPL
#include <math.h>
#include <stdio.h>
void wickra_print_summary(const char *name, double first_price, double last_price,
size_t bars, const double *closed_trades, size_t n_trades,
double final_equity, const double *equity_curve,
size_t n_curve) {
double buy_hold = last_price / first_price;
double strat_return = final_equity - 1.0;
double bh_return = buy_hold - 1.0;
size_t wins = 0, losses = 0;
double best = -INFINITY, worst = INFINITY;
double sum_ret = 0.0, sum_sq = 0.0;
for (size_t i = 0; i < n_trades; ++i) {
double r = closed_trades[i];
if (r > 0.0) {
wins++;
} else if (r < 0.0) {
losses++;
}
if (r > best) {
best = r;
}
if (r < worst) {
worst = r;
}
sum_ret += r;
sum_sq += r * r;
}
double n = (double)n_trades;
double mean_ret = n > 0.0 ? sum_ret / n : 0.0;
double var_ret = n > 1.0 ? (sum_sq - n * mean_ret * mean_ret) / (n - 1.0) : 0.0;
double sharpe = var_ret > 0.0 ? mean_ret / sqrt(var_ret) : 0.0;
if (n_trades == 0) {
best = 0.0;
worst = 0.0;
}
double peak = n_curve > 0 ? equity_curve[0] : 1.0;
double max_dd = 0.0;
for (size_t i = 0; i < n_curve; ++i) {
if (equity_curve[i] > peak) {
peak = equity_curve[i];
}
double dd = (peak - equity_curve[i]) / peak;
if (dd > max_dd) {
max_dd = dd;
}
}
printf("=== %s ===\n", name);
printf("Bars: %llu\n", (unsigned long long)bars);
printf("Trades: %llu (W%llu / L%llu)\n", (unsigned long long)n_trades,
(unsigned long long)wins, (unsigned long long)losses);
printf("Strategy return: %+.2f%%\n", strat_return * 100.0);
printf("Buy & Hold return: %+.2f%%\n", bh_return * 100.0);
printf("Excess over BH: %+.2f%%\n", (strat_return - bh_return) * 100.0);
printf("Max drawdown: %.2f%%\n", max_dd * 100.0);
printf("Per-trade Sharpe: %.2f (mean %+.4f, stddev %.4f)\n", sharpe,
mean_ret, sqrt(var_ret));
printf("Best / worst trade: %+.2f%% / %+.2f%%\n", best * 100.0, worst * 100.0);
printf("\n");
printf("NOTE: Educational example — fees, slippage, funding costs and tax "
"effects are simplified or omitted. Past performance is not indicative "
"of future results.\n");
}
#endif /* WICKRA_STRATEGY_IMPL */
#endif /* WICKRA_STRATEGY_H */