Open Net Worth
Open Net Worth는 직접 운영하는 오픈소스 개인 AI 자산 비서로, 전체 재무를 하나의 원장에 기록하고 사용자가 제어하는 AI가 관리
정확성 우선의 이벤트 기반 백테스팅으로, 결정적 재생, 데이터 스냅샷 보존, 사전 예측 없이 전략 실행, 원장 기반 결과를 제공합니다
Correctness-first, event-sourced backtesting for research workflows, with deterministic replay, sealed data snapshots, no-lookahead strategy execution, and ledger-derived results.
금융R · PythonGitHub @blechturm온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
Deterministic, event-sourced EOD backtesting for R. Sealed market-data snapshots and an append-only trade ledger give every experiment a reproducible identity.
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
ledgr is an event-sourced systematic trading research framework for R.
Use it when you want a backtest result to be more than a temporary
object in an R session. ledgr starts from sealed market-data snapshots,
runs strategies through an experiment boundary, records event-sourced
results, and lets you reopen the evidence later.
The setup is not overhead. The setup is the audit trail.
ledgr is research software, not investment advice. Backtests and audit trails
are evidence tools; they do not predict future returns or provide compliance
guarantees. See DISCLAIMER.md.README 전문 보기 ↗Backtests you can trust, and reopen later.
ledgr is an R package for systematic trading research. It is built so that the usual ways a backtest fools you fail loudly instead of quietly:
sealed snapshot -> experiment -> run -> event ledger -> results
ledgr is deliberately narrow. It does one kind of backtest completely before it adds the next:
Long-only is the supported use, but not yet a default every run
enforces. An availability-aware run refuses a new short and a fill the
account cannot afford. A dense run does neither: a negative target opens
a short with no borrow cost, margin or financing, and a fill can take
cash below zero. Add ledgr_risk_long_only() to the risk chain to drop
short targets in either mode, and size targets from the account's cash
and equity when capital matters.
Shorting and leverage, intraday bars, other asset classes, and order types such as limits and stops come later, each only once its accounting is specified and tested. Share-changing corporate actions such as splits and mergers are next; Cash Distributions describes what is modelled today. This release does not claim corporate-action completeness, broker-exact settlement, net cash, tax correctness, or exact recipient exposure. Sub-second trading is not a goal.
If you need any of those today, another backtester will serve you better. If you need daily research you can trust and reopen later, that is what ledgr is built for.
Parallel sweeps trade time for memory because each worker receives prepared
run state. In one retained v0.2.2 long-window workload, two workers peaked at
4.46 GiB. Treat that as workload-specific sizing evidence, and use
workers = 1L when memory is the tighter constraint; parallel dispatch does
not change strategy semantics. The Sweeps
article gives the
matching single-worker record and context.
ledgr needs R 4.6.0 or later. Install it from GitHub. The install needs network access, so it is not run when this page is built:
if (!requireNamespace("pak", quietly = TRUE)) install.packages("pak")
pak::pak("blechturm/ledgr")
library(ledgr)
library(dplyr)
A strategy is a function of the current decision context, ctx, and
your parameters, params. It returns the holdings you want after the
next fill: a number of shares for every instrument.
above_trend <- function(ctx, params) {
trend <- ctx$vec$feature("sma_20")
if (!ledgr_passed_warmup(trend)) return(ctx$flat())
above <- ctx$vec$close > trend * (1 + params$buffer)
targets <- ctx$flat()
targets[above] <- params$qty
targets
}
This one holds qty shares of every instrument whose close is above its
20-day moving average by at least buffer, and nothing otherwise.
ctx$flat() starts from zero shares for every instrument, and ctx$vec
holds today's values for all of them at once. For the first 19 bars the
average does not exist yet, so the strategy holds nothing until it does.
Run it on the package's demo data. The data is sealed into a snapshot first, so every run records exactly which data it used. The snapshot lives in a temporary store here; a real project passes a persistent path, so the evidence outlives the R session:
bars <- ledgr_demo_bars |>
filter(
instrument_id %in% c("DEMO_01", "DEMO_02", "DEMO_03"),
between(ts_utc, ledgr_utc("2019-01-01"), ledgr_utc("2019-12-31"))
)
snapshot <- ledgr_snapshot_from_df(
bars,
snapshot_id = "readme_demo",
db_path = ledgr_temp_store()
)
exp <- ledgr_experiment(
snapshot = snapshot,
strategy = above_trend,
features = list(ledgr_ind_sma(20)),
opening = ledgr_opening(cash = 10000),
cost_model = ledgr_cost_zero()
)
bt <- ledgr_run(
exp,
params = list(qty = 10, buffer = 0),
run_id = "readme_first_run"
)
bt
#> ledgr Backtest Results
#> ======================
#>
#> Run ID: readme_first_run
#> Period: 2019-01-01 to 2019-12-31
#> Opening Cash: $10000.00
#> Final Equity: $10344.56
#> Total Return: 3.45%
#> Max Drawdown: -1.34%
#> Closed Trades: 38
#> Metric Calendar: US equity daily (default) (252 days/year * 1 bars/day = 252 bars/year)
#>
#> Economic events: NOT SUPPLIED - returns may omit distributions
#> Price basis: UNDECLARED - distribution double counting cannot be ruled out
#>
#> Use summary(bt) for metrics and evidence
여기까지가 README 앞부분입니다. 나머지는 원문에서 읽을 수 있습니다. README 전문 보기 ↗