A quantitative research pipeline for Bitcoin/USD daily OHLCV data, combining MySQL-based data engineering and validation with a vectorized Python analytics engine.
The project is designed as a Phase 1 quantitative research foundation: first establish reliable market data, mathematically correct transformations, deterministic processing, and clear analytical visualizations before building higher-level trading systems.
This project processes historical Bitcoin daily OHLCV data through two primary layers:
Raw Bitcoin Data
│
▼
┌──────────────────────┐
│ MySQL / SQL │
│ │
│ Import │
│ Schema │
│ Validation │
│ Quality Checks │
│ Extraction │
└──────────┬───────────┘
│
▼
┌──────────────────────┐
│ Python Analytics │
│ │
│ Returns │
│ Log Returns │
│ Drawdowns │
│ Volatility │
│ Direction │
└──────────┬───────────┘
│
▼
┌──────────────────────┐
│ Visualization │
│ │
│ Candlestick │
│ Price Series │
│ Returns │
│ Log Returns │
│ Drawdowns │
│ Volatility │
└──────────────────────┘
The core design principle is:
Validate the data before analyzing it, and verify the mathematics before trusting the output.
Phase: 1 — Quantitative Analytics Foundation
Asset: Bitcoin / USD
Frequency: Daily
Market: 24/7 cryptocurrency market
Annualization convention: 365 observations/year
Primary technologies: MySQL, Python, NumPy, Pandas, Matplotlib
Phase 1 focuses on establishing a reliable analytical foundation.
- Import historical Bitcoin OHLCV data into MySQL.
- Validate the structure and integrity of the dataset.
- Extract clean market data into Python.
- Calculate simple and logarithmic returns.
- Calculate cumulative returns.
- Calculate historical drawdowns.
- Calculate rolling annualized volatility.
- Generate directional features.
- Produce analytical visualizations.
- Keep the numerical computation primarily vectorized.
- Separate data engineering from analytical computation.
- Create a foundation for future quantitative research.
This project is infrastructure and research tooling.
It is not yet a trading strategy or production trading system.
| Layer | Technology |
|---|---|
| Database | MySQL |
| SQL | MySQL SQL / CTEs |
| Programming | Python |
| Numerical Computing | NumPy |
| Data Processing | Pandas |
| Visualization | Matplotlib |
| Database Connection | MySQL Connector |
| Configuration | .env |
| Path Handling | pathlib |
Phase 1 Remastered/
│
├── .vscode/
│
├── docs/
│
├── Python/
│ │
│ ├── data/
│ │ └── Gemini_BTCUSD_1d.csv
│ │
│ │
│ │
│ ├── src/
│ │ ├── analytics_core/
│ │ │ ├── __init__.py
│ │ │ ├── features.py
│ │ │ ├── drawdown.py
│ │ │ ├── get_data.py
│ │ │ ├── plotting.py
│ │ │ ├── returns.py
│ │ │ └── volatility.py
│ │ │
│ │ └── demo_workflow.py
│ │
│ ├── tests/
│ ├── .env
│ ├── README.md
│ └── run_current.py
│
├── SQL_market_data_build/
│ │
│ ├── docs/
│ ├── notebook/
│ ├── samples/
│ │
│ ├── SQL/
│ │ ├── 00_table_creation.sql
│ │ ├── 01_inspect_source_table.sql
│ │ ├── 02_validate_join_keys.sql
│ │ ├── 03_base_ohlcv_extract.sql
│ │ ├── 04_date_filtered_extract.sql
│ │ ├── 05_quality_checks.sql
│ │ ├── 06_final_export_query.sql
│ │ └── data_import.sql
│ │
│ └── README.md
│
├── .gitignore
├── Project Overview.md
└── README.md
The primary dataset used in this project is:
Gemini_BTCUSD_1d.csv
The dataset contains daily Bitcoin/USD OHLCV observations.
The main market variables are:
| Variable | Description |
|---|---|
| Open | Opening price |
| High | Highest price during the period |
| Low | Lowest price during the period |
| Close | Closing price |
| Volume | Traded volume |
| Timestamp | Observation time |
The Python data layer retrieves the validated dataset from MySQL, converts the required fields to numerical types, and ensures the resulting time series is chronologically ordered.
The SQL layer is organized into a sequential data-engineering pipeline.
00_table_creation.sql
│
▼
01_inspect_source_table.sql
│
▼
02_validate_join_keys.sql
│
▼
03_base_ohlcv_extract.sql
│
▼
04_date_filtered_extract.sql
│
▼
05_quality_checks.sql
│
▼
06_final_export_query.sql
The raw dataset is imported through:
data_import.sql
Each stage has a specific responsibility rather than combining the entire database workflow into one script.
Before running:
data_import.sql
you must replace the existing CSV path with the full absolute path to your local Bitcoin dataset.
The path must point to:
Gemini_BTCUSD_1d.csv
located in:
Python/data/
For example:
LOAD DATA LOCAL INFILE
'C:/Users/YourName/Projects/Phase 1 Remastered/Python/data/Gemini_BTCUSD_1d.csv'Use the actual path on your machine.
Do not rely on:
Gemini_BTCUSD_1d.csv
alone if MySQL requires a full filesystem path.
data_import.sql
│
▼
Replace existing CSV path
│
▼
Full absolute filesystem path
│
▼
Gemini_BTCUSD_1d.csv
│
▼
Run SQL import
If MySQL has local file loading disabled, the appropriate LOCAL INFILE configuration must also be enabled.
The SQL layer is responsible for validating the market data before it reaches the Python analytics engine.
For an OHLC observation:
and therefore:
where:
-
$O_t$ = Open -
$H_t$ = High -
$L_t$ = Low -
$C_t$ = Close
The pipeline also checks for issues such as:
- Invalid OHLC relationships.
- Invalid timestamps.
- Duplicate observations.
- Invalid join keys.
- Missing required values.
- Chronological inconsistencies.
- Invalid price or volume observations.
The goal is to prevent structurally invalid market data from contaminating downstream calculations.
The Python numerical engine is located at:
Python/src/analytics_core/
The core modules are:
analytics_core/
├── features.py
├── drawdown.py
├── get_data.py
├── plotting.py
├── returns.py
└── volatility.py
| Module | Responsibility |
|---|---|
features.py |
Market feature generation |
drawdown.py |
Drawdown calculations |
get_data.py |
Database access and data preparation |
plotting.py |
Analytical visualizations |
returns.py |
Simple/log/cumulative return calculations |
volatility.py |
Rolling volatility calculations |
For closing prices
which is equivalent to:
A return of:
represents a 5% increase relative to the previous observation.
The logarithmic return is:
Log returns have the important additive property:
This makes log returns particularly useful for:
- Volatility estimation.
- Time-series analysis.
- Cumulative log-growth calculations.
- Statistical modeling.
Simple returns compound multiplicatively.
Given:
the cumulative simple return is:
For example, a +10% return followed by a -10% return gives:
Therefore the total compounded return is:
rather than 0%.
The cumulative log-return series is:
Since:
the cumulative log-return value represents logarithmic growth.
To convert it into a conventional compounded return:
The distinction matters:
Cumulative log return:
Σ log returns
Cumulative compounded return:
exp(Σ log returns) - 1
The analytical engine keeps these concepts distinct.
Let the running historical maximum be:
The drawdown at time (t) is:
Because:
we have:
A drawdown of:
means Bitcoin is currently 40% below its previous running peak.
Maximum drawdown is:
For example:
Maximum Drawdown = -0.73
corresponds to a 73% peak-to-trough decline.
The drawdown calculation uses cumulative maximum operations rather than unnecessary Python-level state iteration.
The volatility engine calculates rolling standard deviation from log returns.
For a rolling window of (N) observations:
The rolling statistic is based on the standard deviation of the observed log-return window.
A shorter window reacts more quickly to changes in market conditions but produces noisier estimates.
A longer window produces smoother estimates but reacts more slowly.
Bitcoin trades continuously:
24 hours/day
7 days/week
365 days/year
Therefore the project uses:
for annualization.
For daily volatility:
The project therefore uses:
rather than the traditional equity-market convention:
The distinction is intentional.
For Bitcoin daily data, the annualization factor is:
365
The features.py module generates features from the market data.
These features provide a compact representation of price direction that can later be used by:
- Signal research.
- Feature engineering.
- Backtesting.
- Statistical analysis.
The exact classification behavior is defined by the implementation in:
Python/src/analytics_core/features.py
rather than by an assumed universal definition of bullish or bearish behavior.
The analytical engine is designed around vectorized NumPy/Pandas operations.
For example:
log_returns = np.log(close / close.shift(1))and:
running_peak = close.cummax()
drawdown = close / running_peak - 1These operations allow calculations to be performed over entire arrays/Series rather than manually iterating through every observation.
The goal is not to eliminate every loop regardless of context.
The goal is:
Use vectorized operations when the mathematical transformation naturally maps to array operations.
This keeps the analytical layer concise and allows numerical operations to be handled by optimized underlying implementations.
The Python data layer retrieves database credentials through environment variables and establishes the MySQL connection using the configured settings.
After retrieving the data, the pipeline:
- Loads the SQL query.
- Executes the database query.
- Converts required fields into numerical types.
- Structures the time series.
- Sets the observation time as the temporal index.
- Verifies chronological ordering.
Chronological ordering is critical because returns, rolling volatility, and drawdowns are all time-dependent calculations.
A correctly calculated return on incorrectly ordered data is still a meaningless result.
The project includes six primary visualization functions:
plot_candlestick_chart(df)
plot_price_series(df)
plot_returns(df)
plot_log_returns(df)
plot_drawdowns(df)
plot_volatility(df, 30, 365)Together, these plots provide a visual diagnostic layer for the quantitative analytics engine.
Function:
plot_candlestick_chart(df)The candlestick chart displays Bitcoin's daily OHLC structure:
- Open
- High
- Low
- Close
It is useful for visually inspecting daily price ranges and historical price behavior.
Function:
plot_price_series(df)This plot displays the Bitcoin price series across the available historical dataset.
It provides the most direct representation of the evolution of BTC/USD price.
Function:
plot_returns(df)This visualization displays the return behavior of Bitcoin over time.
Simple returns are defined as:
The plot can be used to inspect:
- Positive and negative return events.
- Return clustering.
- Extreme daily movements.
- Changes in market activity.
Function:
plot_log_returns(df)This visualization displays Bitcoin's logarithmic return series:
Log returns are particularly useful for volatility and statistical analysis because they are additive through time.
Function:
plot_drawdowns(df)The drawdown plot measures the decline from Bitcoin's previous running peak.
where:
This visualization makes major historical declines immediately visible.
Function:
plot_volatility(df, 30, 365)The volatility plot uses:
Rolling window = 30 days
Annualization factor = 365
The rolling volatility is based on log returns and is annualized using:
This provides a view of how realized Bitcoin volatility changes through time.
The six visualizations provide different perspectives on the same underlying market data.
| Function | Purpose |
|---|---|
plot_candlestick_chart(df) |
Daily OHLC structure |
plot_price_series(df) |
Bitcoin price history |
plot_returns(df) |
Return behavior |
plot_log_returns(df) |
Log-return behavior |
plot_drawdowns(df) |
Historical peak-to-trough losses |
plot_volatility(df, 30, 365) |
30-day annualized volatility |
The relationship can be summarized as:
BTC/USD OHLCV
│
┌──────────────┴──────────────┐
│ │
▼ ▼
Price Structure Price Changes
│ │
┌────┴────┐ ┌────┴────┐
▼ ▼ ▼ ▼
Candlestick Price Returns Log Returns
│ │ │ │
└─────────┴───────────────────┴─────────┘
│
▼
Risk Analytics
│
┌──────┴──────┐
▼ ▼
Drawdowns Volatility
Recommended environment:
Python 3.10+
MySQL 8.0+
Install the Python dependencies:
pip install -r requirements.txtThe project uses packages including:
numpy
pandas
matplotlib
mysql-connector-python
python-dotenv
Exact dependency versions should eventually be pinned for fully reproducible environments.
Database credentials should not be hard-coded into source code.
Create a .env file containing the required database configuration.
Example:
DB_HOST=localhost
DB_PORT=3306
DB_NAME=your_database
DB_USER=your_username
DB_PASSWORD=your_passwordDo not commit real credentials to Git.
The .env file should remain excluded through .gitignore.
Navigate to:
SQL_market_data_build/SQL/
The database construction begins with:
00_table_creation.sql
The general pipeline is:
Create Tables
│
▼
Inspect Source
│
▼
Validate Join Keys
│
▼
Build Base OHLCV Extract
│
▼
Apply Date Filter
│
▼
Run Quality Checks
│
▼
Final Export
Before executing:
data_import.sql
replace the existing CSV path with the full absolute path to:
Python/data/Gemini_BTCUSD_1d.csv
Example:
LOAD DATA LOCAL INFILE
'C:/Users/YourName/Projects/Phase 1 Remastered/Python/data/Gemini_BTCUSD_1d.csv'Use the actual path on your computer.
Do not assume that the current terminal directory is the same as the location of the CSV.
From the Python/ directory:
python src/demo_workflow.pyThe primary workflow entry point is:
Python/src/demo_workflow.py
The analytics engine is located at:
Python/src/analytics_core/
The project is designed to keep data processing deterministic.
For reproducible results:
- Clone this repository:
git clone https://github.com/Jad-srifi/vectorized-quant-analytics.git- Use the same source dataset.
- Use the same database contents.
- Use the same SQL transformations.
- Use the same environment configuration.
- Use the same Python dependencies.
- Keep analytical parameters fixed.
- Avoid modifying the raw dataset between runs.
The Python data layer also verifies chronological ordering before performing temporal calculations.
Before trusting the output, verify the following.
- Database tables were created successfully.
- Bitcoin CSV imported successfully.
- Full absolute CSV path is configured in
data_import.sql. - Source data was inspected.
- Join keys are valid.
- Duplicate observations were checked.
- OHLC relationships were checked.
- Timestamp validity was checked.
- SQL quality checks passed.
- Required columns exist.
- Numerical types are correct.
- Prices are valid.
- Volumes are valid.
- Timestamps are ordered chronologically.
- Missing values are understood.
- Simple returns match:
[ \frac{P_t}{P_{t-1}}-1 ]
- Log returns match:
[ \ln\left(\frac{P_t}{P_{t-1}}\right) ]
- Simple returns compound multiplicatively.
- Cumulative log returns are interpreted correctly.
- Drawdowns are calculated from running peaks.
- Maximum drawdown equals the minimum drawdown.
- Rolling volatility uses the intended window.
- Bitcoin volatility uses (\sqrt{365}) for annualization.
-
.envis not committed. - Database credentials are externalized.
- Python modules import correctly.
- Tests pass.
- The workflow executes successfully.
- Identical inputs produce consistent outputs.
This repository is:
- A Bitcoin market-data engineering pipeline.
- A MySQL data-validation layer.
- A vectorized quantitative analytics engine.
- A return and risk-analysis framework.
- A visualization and diagnostic system.
- A foundation for future quantitative research.
This repository is not yet:
- A profitable trading strategy.
- A live trading system.
- A production execution engine.
- A complete backtesting framework.
- A portfolio optimizer.
- A market-making system.
- A market-microstructure engine.
- Evidence of predictive alpha.
- Evidence of out-of-sample profitability.
Correct mathematics does not imply predictive power.
A correctly calculated historical volatility series does not predict future volatility by itself.
A correctly calculated historical signal does not constitute alpha.
A fast vectorized implementation does not make an invalid research methodology valid.
The purpose of Phase 1 is to establish the infrastructure required to conduct that research correctly.
The current system is based on daily OHLCV data.
This means it does not contain complete information about:
- Order-book depth.
- Bid/ask spreads.
- Individual trades.
- Trade direction.
- Queue position.
- Order-flow imbalance.
- Market impact.
- Execution latency.
- Slippage.
- Real transaction costs.
Therefore, this system should not yet be used for serious execution or market-microstructure research.
OHLCV-based research can also suffer from:
- Look-ahead bias.
- Data leakage.
- Overfitting.
- Parameter selection bias.
- Unrealistic execution assumptions.
- Transaction-cost neglect.
- Regime dependence.
These problems must be explicitly addressed before a strategy derived from this infrastructure can be considered statistically credible.
[✓] Bitcoin daily OHLCV ingestion
[✓] MySQL schema construction
[✓] Source-data inspection
[✓] Join-key validation
[✓] OHLCV extraction
[✓] Date filtering
[✓] SQL quality checks
[✓] Python database access
[✓] Chronological validation
[✓] Simple returns
[✓] Log returns
[✓] Cumulative return calculations
[✓] Rolling volatility
[✓] Bitcoin-specific √365 annualization
[✓] Historical drawdown analysis
[✓] Directional features
[✓] Candlestick visualization
[✓] Price-series visualization
[✓] Returns visualization
[✓] Log-return visualization
[✓] Drawdown visualization
[✓] Volatility visualization
[ ] Expand automated test coverage
[ ] Benchmark vectorized operations
[ ] Formalize feature specifications
[ ] Transaction-cost model
[ ] Slippage model
[ ] Backtesting engine
[ ] Strategy interface
[ ] Position sizing
[ ] Portfolio construction
[ ] Sharpe ratio
[ ] Sortino ratio
[ ] Calmar ratio
[ ] Walk-forward validation
[ ] Out-of-sample testing
[ ] Regime analysis
[ ] Factor research
[ ] Higher-frequency market data
[ ] Order-book research
[ ] Execution simulation
[ ] Live market-data ingestion
The intended progression of the project is:
RAW DATA
│
▼
DATA VALIDATION
│
▼
MATHEMATICAL VALIDATION
│
▼
IMPLEMENTATION TESTS
│
▼
FEATURE ENGINEERING
│
▼
RESEARCH HYPOTHESIS
│
▼
BACKTEST
│
▼
OUT-OF-SAMPLE TEST
│
▼
REALISTIC EXECUTION
│
▼
RISK ANALYSIS
│
▼
PRODUCTION RESEARCH
The order matters.
A strategy should not be trusted because a chart looks convincing.
The data must be correct.
The mathematics must be correct.
The implementation must be tested.
The research methodology must avoid leakage and overfitting.
Only then does performance become meaningful.
The central engineering philosophy of the project is:
[ \boxed{ \text{Data Integrity} \rightarrow \text{Mathematical Correctness} \rightarrow \text{Reproducibility} \rightarrow \text{Statistical Validation} \rightarrow \text{Trading Research} } ]
The goal of Phase 1 is to make the first three stages reliable enough that future research is built on a trustworthy foundation.





