|
📉 Active-strategy results can change sharply after fees and slippage. |
✨ Seven notebooks keep the data pipeline, assumptions, modeled costs, and failed experiments inspectable.
Public OHLCV → Clean hourly candles → Strategy and ML hypotheses → Cost-aware backtests → Recorded conclusions
📚 Snapshot · 🧭 Research tracks · 📊 Recorded results · 🗺️ Workflow · ⚡ Install · 🚀 Reproduce · 🧪 Methodology · 🔐 Data and privacy · 📁 Project structure · 📌 Limitations
English · 简体中文 · Español · Deutsch · 日本語 · Русский · Português · 한국어
This repository records an exploratory BTC/USDT research sequence from public market data through strategy comparison. The saved notebook outputs make both successful and failed hypotheses inspectable.
| Evidence | Recorded value |
|---|---|
| Market | Binance BTC/USDT spot OHLCV |
| Sample | Hourly candles from 2021-01-01 through 2024-12-31 |
| Raw data | 35,050 candles; 14 missing intervals; 99.96% completeness |
| Cleaned data | 35,064 rows after forward-filling price and setting missing volume to zero |
| Research artifacts | 7 ordered Jupyter notebooks with 65 executed non-empty code cells |
| Recorded runtime | Python 3.13.5 in every notebook kernel metadata block |
The generated data/btc_usdt_1h_clean.parquet file is intentionally excluded from Git.
| Notebook | Research question | Recorded artifact |
|---|---|---|
| NB1 · Data pipeline | Can a consistent hourly dataset be built from public exchange candles? | Quality report, cleaned Parquet, and configuration |
| NB2 · Classic indicators | How do MA, RSI, and Bollinger signals behave after fees? | Long-only baseline backtests and stop-loss variants |
| NB3 · Statistical strategy | Does price recover after a negative rolling Z-score? | Window and entry-threshold parameter sweep |
| NB4 · ML signals | Does XGBoost predict the next 24-hour direction on a later holdout? | 20 features, chronological split, and holdout backtest |
| NB5 · Backtest engine | How much do fixed fees and slippage change results? | Capital curve, position changes, and standardized report |
| NB6 · Performance analysis | How do full-period rule strategies compare under one cost model? | Returns, volatility, simplified Sharpe, and drawdown |
| NB7 · Conclusions | Which findings survive a final evidence review? | Consolidated tables and documented limitations |
The following tables preserve two different evaluation setups. Their values should be read within their own window and cost model.
Window: 2021-01-01 through 2024-12-31
Cost model: 0.10% fee plus 0.05% fixed slippage for each position change
| Strategy | Total return | Simplified Sharpe | Max drawdown |
|---|---|---|---|
| Buy & Hold | +222.7% | 0.54 | -77.2% |
| MA Cross | -35.2% | -0.24 | -76.4% |
| RSI | -77.0% | -0.68 | -84.2% |
| Bollinger Bands | -42.8% | -0.27 | -66.8% |
| Z-score · 7 days | +17.4% | 0.10 | -50.6% |
| Z-score · 30 days | +30.9% | 0.19 | -55.3% |
These are exploratory full-sample results. NB3 selected its displayed Z-score parameters from a sweep over the same 2021–2024 sample.
Window: approximately 2023-10 through 2024-12
Cost model: 0.10% fee only; the fixed slippage used above is absent from this notebook
| Metric | XGBoost | Buy & Hold | Context |
|---|---|---|---|
| Total return | -33.9% | +174.2% | Later 30% chronological holdout |
| Simplified Sharpe | -1.29 | 2.63 | Same holdout window |
| Max drawdown | -43.3% | -32.3% | Same holdout window |
NB4 uses one 70/30 chronological split. Its final 24 rows have no observable future 24-hour return, and the current boolean conversion records those labels as class 0. Treat the saved ML metrics as exploratory evidence.
flowchart LR
A([Public Binance OHLCV]) --> B[NB1 Fetch + clean]
B --> C[NB2 Classic signals] --> F[NB5–NB6 Costs + comparison] --> G([NB7 Recorded conclusions])
B --> D[NB3 Z-score search] --> F
B --> E[NB4 XGBoost holdout] --> G
style A fill:#FEF3C7,stroke:#F59E0B,stroke-width:2px,color:#000,font-size:12px
style B fill:#EDE9FE,stroke:#8B5CF6,stroke-width:2px,color:#000,font-size:12px
style C fill:#DBEAFE,stroke:#3B82F6,stroke-width:2px,color:#000,font-size:12px
style D fill:#DBEAFE,stroke:#3B82F6,stroke-width:2px,color:#000,font-size:12px
style E fill:#DBEAFE,stroke:#3B82F6,stroke-width:2px,color:#000,font-size:12px
style F fill:#FEF2F2,stroke:#EF4444,stroke-width:1px,color:#000,font-size:12px
style G fill:#DCFCE7,stroke:#22C55E,stroke-width:2px,color:#000,font-size:12px
NB2 and NB3 feed the later cost-aware comparison. NB4 keeps its separate chronological holdout path so its results retain their own evaluation basis.
git clone https://github.com/okht/crypto-trading-research.git
cd crypto-trading-research
python -m pip install -r requirements.txt
python -m pip install notebook nbconvertnotebook and nbconvert are installed separately because they are not listed in requirements.txt.
Start Jupyter from the repository root:
jupyter notebook notebooksRun the notebooks strictly in filename order:
| Order | Notebook | Observable result |
|---|---|---|
| 1 | 01_数据获取与清洗.ipynb |
Downloads public candles and writes the ignored local Parquet file |
| 2–4 | 02_经典技术指标.ipynb through 04_机器学习信号.ipynb |
Rebuilds rule and ML research tracks |
| 5–7 | 05_回测引擎.ipynb through 07_策略对比与结论.ipynb |
Applies cost models, compares results, and records conclusions |
NB1 requires network access to Binance. It reads an optional proxy from HTTPS_PROXY or HTTP_PROXY; when neither variable is set, no proxy configuration is passed to CCXT.
| Topic | Current implementation | Interpretation boundary |
|---|---|---|
| Positions | Long-only signals between 0 and 1, shifted by one bar before returns | No short selling or live execution |
| Full-period costs | 0.10% fee plus 0.05% fixed slippage per position change in NB5–NB7 | Simplified constant model |
| Simplified Sharpe | Annualized return divided by annualized volatility | No risk-free rate adjustment |
| Z-score search | Multiple windows and entry thresholds evaluated on the full sample | In-sample parameter selection |
| ML evaluation | One chronological 70/30 train/holdout split | No repeated or cross-validated estimate |
| Annualization | 8,760 hourly periods per year | Assumes continuously traded crypto hours |
The code imports TimeSeriesSplit, but the recorded NB4 experiment uses the single chronological split described above.
| Topic | Current behavior |
|---|---|
| Exchange access | Calls public fetch_ticker and fetch_ohlcv endpoints only |
| Credentials | No API key, account, balance, position, order, withdrawal, or transfer interface |
| Local storage | Writes cleaned candles to data/btc_usdt_1h_clean.parquet, which Git ignores |
| Proxy | Reads HTTPS_PROXY or HTTP_PROXY when present and otherwise connects without an explicit proxy |
| Repository data | Commits configuration and saved notebook outputs; the downloaded Parquet dataset stays local |
Public market data remains subject to the exchange's availability and terms. The MIT license covers this repository's software and documentation; it does not grant rights to third-party market data.
crypto-trading-research/
├── README.md / README_*.md
├── requirements.txt
├── data/
│ ├── config.json
│ └── btc_usdt_1h_clean.parquet # generated locally, ignored by Git
└── notebooks/
├── 01_数据获取与清洗.ipynb
├── 02_经典技术指标.ipynb
├── 03_统计驱动策略.ipynb
├── 04_机器学习信号.ipynb
├── 05_回测引擎.ipynb
├── 06_绩效分析.ipynb
└── 07_策略对比与结论.ipynb
The numbered filenames define the data and research dependency order.
- The evidence covers one market, one hourly interval, and one historical window.
- Fourteen missing candles are synthesized with forward-filled prices and zero volume before later analysis.
- The fixed cost model excludes variable spread, market impact, funding, latency, taxes, outages, and liquidity constraints.
- Rule parameters are selected in-sample; the ML track uses one holdout and contains the documented final-24-row label boundary.
- Dependency lower bounds are declared without a lockfile, so later environments can produce different outputs.
- The repository has no automated test suite, CI workflow, tag, or release.
- Every result is a backtest or saved notebook observation. The project does not execute trades and does not provide investment advice.
Issues and pull requests are welcome.
A trading result is useful when its assumptions, costs, and failures remain inspectable.
MIT License · Maintained by okht