Dollar-cost averaging, value averaging & dip-buying — backtested across a multi-asset portfolio, in Python.
Buy on a cadence, buy harder on dips, target a growing value, track your real cost basis, and measure ROI & drawdown.
Built and maintained by Viprasol Tech — Fintech Experts. Full-Stack Builders.
This software is for educational purposes only and is not financial advice. Trading is highly volatile and involves substantial risk, including the total loss of capital. Backtest results are not indicative of future performance. Always validate on historical data first and comply with your local laws. Use at your own risk — Viprasol Tech assumes no responsibility for your trading results.
- 💵 Dollar-cost averaging — buy a fixed quote amount every
intervalticks, regardless of price. - 📈 Value averaging — target a portfolio value that grows by a fixed step each interval; buy more on dips and less on spikes (with an optional per-buy cap).
- 🩸 Dip-buying — scale every buy up in proportion to the drawdown from the running high, so you accumulate faster when the market is down.
- 🧺 Multi-asset portfolios — track many symbols at once with per-asset cost basis, value, PnL and value-weighted allocations.
- 📊 Performance reports — average cost vs. market price, cost advantage, ROI and max drawdown, rolled up into one capital-weighted summary.
- 🧾 Typed config — declare your assets and strategies in JSON, validated by pydantic;
init-configwrites a ready-to-edit example. - 🖥️ Rich CLI —
demo,backtest,report,init-config,version— all keyless and risk-free on synthetic data. - ⚙️ Modern tooling — ruff, mypy (strict), pytest (55 tests), GitHub Actions CI.
git clone https://github.com/Viprasol-Tech/dca-bot.git
cd dca-bot
python -m pip install -e ".[dev]"
# Run a DCA backtest on synthetic data:
dca-bot demo --interval 10 --quote-amount 250
# Try the dip-buy strategy:
dca-bot backtest --strategy dip-buy --amount 100 --symbol BTC
# Scaffold a multi-asset config, then report on the whole portfolio:
dca-bot init-config --path dca-config.json
dca-bot report --config dca-config.jsonfrom dca_bot import build_strategy, report_strategy
prices = [100.0, 80.0, 120.0, 90.0, 110.0]
for kind in ("dca", "value-averaging", "dip-buy"):
strat = build_strategy(kind, amount=100.0, interval=1)
r = report_strategy("BTC", strat, prices)
print(f"{r.strategy:>16} avg=${r.average_cost:7.2f} ROI={r.roi:+.2%} maxDD={r.max_drawdown:.2%}")from dca_bot import BotConfig, report_portfolio
config = BotConfig.load("dca-config.json")
prices = {
"BTC": [...], # your historical price series per symbol
"ETH": [...],
"SOL": [...],
}
report = report_portfolio(config, prices)
print(report.total_value, report.roi, report.worst_drawdown)
for asset in report.assets:
print(asset.symbol, asset.average_cost, asset.cost_advantage)from dca_bot import MultiAssetPortfolio
book = MultiAssetPortfolio()
book.buy("BTC", quote_amount=100.0, price=20_000.0)
book.buy("ETH", quote_amount=100.0, price=1_500.0)
prices = {"BTC": 25_000.0, "ETH": 1_800.0}
print(book.value(prices)) # mark-to-market across all holdings
print(book.unrealized_pnl(prices)) # aggregate PnL
print(book.weights(prices)) # value-weighted allocation per symbolflowchart LR
CFG[BotConfig JSON] --> FACT[build_strategy]
FACT --> S{Strategy protocol}
S --> DCA[DCAStrategy]
S --> VA[ValueAveragingStrategy]
S --> DIP[DipBuyStrategy]
FEED[Price series] --> BT[run_backtest]
S --> BT
BT --> PORT[Portfolio / MultiAssetPortfolio]
BT --> REP[AssetReport]
REP --> ROLL[PortfolioReport: ROI / drawdown / cost advantage]
ROLL --> CLI[Rich CLI tables]
| Component | Import | What it does |
|---|---|---|
DCAStrategy |
dca_bot.dca |
Fixed quote amount every interval ticks |
ValueAveragingStrategy |
dca_bot.strategies |
Buys toward a linearly growing target value; optional max_buy cap |
DipBuyStrategy |
dca_bot.strategies |
Scales buys by drawdown (dip_multiplier, max_multiple) |
build_strategy(kind, ...) |
dca_bot.strategies |
Factory: dca / value-averaging / dip-buy (+ aliases) |
Portfolio |
dca_bot.portfolio |
Single-asset units, cost basis, value, PnL |
MultiAssetPortfolio |
dca_bot.portfolio |
Many symbols, aggregate value/PnL, allocation weights |
run_backtest(strategy, prices) |
dca_bot.backtest |
Replays a strategy; reports units, avg cost, ROI, max drawdown |
report_strategy / report_portfolio |
dca_bot.report |
Cost advantage, ROI & drawdown per asset and rolled up |
BotConfig / AssetConfig |
dca_bot.config |
Pydantic-validated JSON config |
| Command | Purpose |
|---|---|
dca-bot demo |
DCA backtest on synthetic data |
dca-bot backtest |
Backtest one strategy with a full report |
dca-bot report --config FILE |
Backtest every asset in a config and roll up |
dca-bot init-config |
Write an example multi-strategy config |
dca-bot version |
Print the installed version |
- DCA strategy + cost-basis math
- Portfolio accounting + backtest runner
- Value-averaging and dip-buying variants
- Multi-asset portfolios + capital-weighted reports
- Max-drawdown and cost-advantage metrics
- JSON config + CLI subcommands
- Real schedulers (cron / interval clock) for live execution
- Exchange adapters for live buys
- CSV / Parquet price ingestion for backtests
Does this place real trades? No. Everything runs against price series you supply (or synthetic data) — there are no exchange keys or live order routing yet.
What's the difference between DCA, value averaging and dip-buying? DCA spends the same amount every interval. Value averaging spends whatever it takes to hit a growing target value, so it buys more when prices fall. Dip-buying keeps DCA's cadence but multiplies each buy by how far the price is below its running high.
What does "cost advantage" mean? The percentage by which your average entry price undercuts the final market price — a positive number means your averaged-in cost basis is cheaper than buying everything at the end.
Which Python versions are supported? 3.11, 3.12 and 3.13.
PRs welcome — see CONTRIBUTING.md and our Code of Conduct. Run ruff check ., mypy src and pytest before opening a PR.
- Website: viprasol.com
- Email: support@viprasol.com
- Telegram: t.me/viprasol_help | WhatsApp: +91 96336 52112
- GitHub: @Viprasol-Tech | LinkedIn | X @viprasol
MIT (c) 2025 Viprasol Tech Private Limited
