exness-data-preprocess 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- exness_data_preprocess-0.1.0/.cz.toml +12 -0
- exness_data_preprocess-0.1.0/.github/workflows/ci.yml +50 -0
- exness_data_preprocess-0.1.0/.github/workflows/pre-commit-autoupdate.yml +38 -0
- exness_data_preprocess-0.1.0/.github/workflows/publish.yml +52 -0
- exness_data_preprocess-0.1.0/.gitignore +100 -0
- exness_data_preprocess-0.1.0/.pre-commit-config.yaml +24 -0
- exness_data_preprocess-0.1.0/AUTHORS.md +24 -0
- exness_data_preprocess-0.1.0/CHANGELOG.md +35 -0
- exness_data_preprocess-0.1.0/CLAUDE.md +274 -0
- exness_data_preprocess-0.1.0/CONTRIBUTING.md +281 -0
- exness_data_preprocess-0.1.0/GITHUB_PYPI_SETUP.md +335 -0
- exness_data_preprocess-0.1.0/LICENSE +21 -0
- exness_data_preprocess-0.1.0/PKG-INFO +506 -0
- exness_data_preprocess-0.1.0/README.md +459 -0
- exness_data_preprocess-0.1.0/cliff.toml +144 -0
- exness_data_preprocess-0.1.0/docs/DATABASE_SCHEMA.md +736 -0
- exness_data_preprocess-0.1.0/docs/EXNESS_DATA_SOURCES.md +374 -0
- exness_data_preprocess-0.1.0/docs/README.md +197 -0
- exness_data_preprocess-0.1.0/docs/UNIFIED_DUCKDB_PLAN_v2.md +636 -0
- exness_data_preprocess-0.1.0/docs/archive/UNIFIED_DUCKDB_PLAN_v1.0.0_LEGACY.md +705 -0
- exness_data_preprocess-0.1.0/docs/implementation-plan.yaml +36 -0
- exness_data_preprocess-0.1.0/docs/planning-index.yaml +32 -0
- exness_data_preprocess-0.1.0/docs/research/compression-benchmarks/README.md +249 -0
- exness_data_preprocess-0.1.0/docs/research/compression-benchmarks/test_all_compression_methods.py +397 -0
- exness_data_preprocess-0.1.0/docs/research/compression-benchmarks/test_delta_encoding_properly.py +227 -0
- exness_data_preprocess-0.1.0/docs/research/compression-benchmarks/test_parquet_compression_methods.py +239 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-spread-analysis/01-methodology.md +244 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-spread-analysis/02-mode-truncated-analysis.md +292 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-spread-analysis/03-hurdle-model-analysis.md +304 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-spread-analysis/04-temporal-patterns.md +166 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-spread-analysis/05-final-recommendations.md +317 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-spread-analysis/README.md +142 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-spread-analysis/scripts/reproduction_guide.md +409 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-spread-analysis/visualizations/hurdle-model/hurdle_decomposition.png +0 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-spread-analysis/visualizations/mode-truncated/cv_mode_comparison.png +0 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-spread-analysis/visualizations/mode-truncated/distribution_overlay.png +0 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-spread-analysis/visualizations/mode-truncated/signal_quality_comparison.png +0 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-spread-analysis/visualizations/mode-truncated/variance_decomposition.png +0 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-spread-analysis/visualizations/temporal/concentration_curve.png +0 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-spread-analysis/visualizations/temporal/percentile_analysis.png +0 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-zero-spread-deviations/01-methodology.md +297 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-zero-spread-deviations/02-baseline-sep2024.md +186 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-zero-spread-deviations/03-multiperiod-validation.md +285 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-zero-spread-deviations/04-discoveries-and-plan-evolution.md +292 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-zero-spread-deviations/README.md +137 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-zero-spread-deviations/findings/baseline-sep2024-comprehensive-summary.md +482 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-zero-spread-deviations/findings/phase2-mean-reversion-report.md +29 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-zero-spread-deviations/findings/phase3-volatility-model-report.md +41 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-zero-spread-deviations/findings/phase4-5-statistical-tests-survivorship-report.md +319 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-zero-spread-deviations/scripts/baseline-sep2024/01_mean_reversion_analysis.py +499 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-zero-spread-deviations/scripts/baseline-sep2024/02_volatility_model_simple.py +501 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-zero-spread-deviations/scripts/baseline-sep2024/03_liquidity_crisis_detection.py +580 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-zero-spread-deviations/scripts/baseline-sep2024/04_regime_detection_analysis.py +637 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase1_data_validation.py +341 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase2_mean_reversion.py +333 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase3_volatility_model.py +486 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase4_statistical_tests.py +446 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase5_survivorship_bias.py +588 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase5_survivorship_bias_v1.0.1.py +603 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase6a_interval_analysis.py +459 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase6b_price_clustering.py +579 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase6c_combined_pattern.py +521 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-zero-spread-deviations/scripts/reproduction_guide.md +388 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-zero-spread-deviations/scripts/visualization/diagnostic_burst_decay.py +192 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-zero-spread-deviations/scripts/visualization/generate_interactive_dashboard.py +341 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-zero-spread-deviations/scripts/visualization/generate_lightweight_dashboard.py +271 -0
- exness_data_preprocess-0.1.0/docs/research/eurusd-zero-spread-deviations/scripts/visualization/prepare_visualization_data.py +405 -0
- exness_data_preprocess-0.1.0/examples/add_schema_comments.py +54 -0
- exness_data_preprocess-0.1.0/examples/basic_usage.py +216 -0
- exness_data_preprocess-0.1.0/examples/batch_processing.py +467 -0
- exness_data_preprocess-0.1.0/pyproject.toml +146 -0
- exness_data_preprocess-0.1.0/src/exness_data_preprocess/__init__.py +51 -0
- exness_data_preprocess-0.1.0/src/exness_data_preprocess/api.py +216 -0
- exness_data_preprocess-0.1.0/src/exness_data_preprocess/cli.py +199 -0
- exness_data_preprocess-0.1.0/src/exness_data_preprocess/processor.py +899 -0
- exness_data_preprocess-0.1.0/tests/README.md +157 -0
- exness_data_preprocess-0.1.0/tests/__init__.py +3 -0
- exness_data_preprocess-0.1.0/tests/conftest.py +90 -0
- exness_data_preprocess-0.1.0/tests/test_basic.py +31 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
[tool.commitizen]
|
|
2
|
+
name = "cz_conventional_commits"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
tag_format = "v$major.$minor.$patch"
|
|
5
|
+
update_changelog_on_bump = true
|
|
6
|
+
version_files = [
|
|
7
|
+
"pyproject.toml:version",
|
|
8
|
+
"src/exness_data_preprocess/__init__.py:__version__"
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
[tool.commitizen.settings]
|
|
12
|
+
major_version_zero = true
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
pre-commit:
|
|
11
|
+
name: Pre-commit hooks
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
|
|
16
|
+
- uses: actions/setup-python@v5
|
|
17
|
+
with:
|
|
18
|
+
python-version: '3.12'
|
|
19
|
+
|
|
20
|
+
- name: Run pre-commit hooks
|
|
21
|
+
uses: pre-commit/action@v3.0.1
|
|
22
|
+
|
|
23
|
+
test:
|
|
24
|
+
name: Tests (Python ${{ matrix.python-version }})
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
strategy:
|
|
27
|
+
fail-fast: false
|
|
28
|
+
matrix:
|
|
29
|
+
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
|
|
30
|
+
|
|
31
|
+
steps:
|
|
32
|
+
- uses: actions/checkout@v4
|
|
33
|
+
|
|
34
|
+
- uses: actions/setup-python@v5
|
|
35
|
+
with:
|
|
36
|
+
python-version: ${{ matrix.python-version }}
|
|
37
|
+
cache: pip
|
|
38
|
+
|
|
39
|
+
- name: Install package with test dependencies
|
|
40
|
+
run: pip install -e ".[test]"
|
|
41
|
+
|
|
42
|
+
- name: Run tests with coverage
|
|
43
|
+
run: pytest --cov=exness_data_preprocess --cov-report=xml --cov-report=term
|
|
44
|
+
|
|
45
|
+
- name: Upload coverage to GitHub
|
|
46
|
+
if: matrix.python-version == '3.12'
|
|
47
|
+
uses: actions/upload-artifact@v4
|
|
48
|
+
with:
|
|
49
|
+
name: coverage-report
|
|
50
|
+
path: coverage.xml
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
name: Pre-commit Auto-update
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
schedule:
|
|
5
|
+
# Run weekly on Sunday at midnight UTC
|
|
6
|
+
- cron: '0 0 * * 0'
|
|
7
|
+
workflow_dispatch: # Allow manual triggering
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
autoupdate:
|
|
11
|
+
name: Auto-update pre-commit hooks
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- uses: actions/setup-python@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: '3.12'
|
|
20
|
+
|
|
21
|
+
- name: Install pre-commit
|
|
22
|
+
run: pip install pre-commit
|
|
23
|
+
|
|
24
|
+
- name: Run pre-commit autoupdate
|
|
25
|
+
run: pre-commit autoupdate
|
|
26
|
+
|
|
27
|
+
- name: Create pull request
|
|
28
|
+
uses: peter-evans/create-pull-request@v6
|
|
29
|
+
with:
|
|
30
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
31
|
+
branch: pre-commit-autoupdate
|
|
32
|
+
title: 'chore: update pre-commit hooks'
|
|
33
|
+
commit-message: 'chore: update pre-commit hooks'
|
|
34
|
+
body: |
|
|
35
|
+
Auto-update pre-commit hooks to latest versions.
|
|
36
|
+
|
|
37
|
+
- Updated by [pre-commit-autoupdate workflow](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})
|
|
38
|
+
delete-branch: true
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
build:
|
|
9
|
+
name: Build distribution
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
|
|
15
|
+
- uses: actions/setup-python@v5
|
|
16
|
+
with:
|
|
17
|
+
python-version: '3.12'
|
|
18
|
+
|
|
19
|
+
- name: Install build dependencies
|
|
20
|
+
run: pip install build
|
|
21
|
+
|
|
22
|
+
- name: Build package
|
|
23
|
+
run: python -m build
|
|
24
|
+
|
|
25
|
+
- name: Upload distribution artifacts
|
|
26
|
+
uses: actions/upload-artifact@v4
|
|
27
|
+
with:
|
|
28
|
+
name: dist
|
|
29
|
+
path: dist/
|
|
30
|
+
|
|
31
|
+
publish:
|
|
32
|
+
name: Publish to PyPI
|
|
33
|
+
needs: build
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
permissions:
|
|
36
|
+
id-token: write # REQUIRED for Trusted Publishing
|
|
37
|
+
contents: read
|
|
38
|
+
environment:
|
|
39
|
+
name: release
|
|
40
|
+
url: https://pypi.org/p/exness-data-preprocess
|
|
41
|
+
|
|
42
|
+
steps:
|
|
43
|
+
- name: Download distribution artifacts
|
|
44
|
+
uses: actions/download-artifact@v4
|
|
45
|
+
with:
|
|
46
|
+
name: dist
|
|
47
|
+
path: dist/
|
|
48
|
+
|
|
49
|
+
- name: Publish to PyPI via Trusted Publishing
|
|
50
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
51
|
+
# No token needed! Uses GitHub OIDC via Trusted Publishing
|
|
52
|
+
# Digital attestations are generated automatically
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
build/
|
|
8
|
+
develop-eggs/
|
|
9
|
+
dist/
|
|
10
|
+
downloads/
|
|
11
|
+
eggs/
|
|
12
|
+
.eggs/
|
|
13
|
+
lib/
|
|
14
|
+
lib64/
|
|
15
|
+
parts/
|
|
16
|
+
sdist/
|
|
17
|
+
var/
|
|
18
|
+
wheels/
|
|
19
|
+
share/python-wheels/
|
|
20
|
+
*.egg-info/
|
|
21
|
+
.installed.cfg
|
|
22
|
+
*.egg
|
|
23
|
+
MANIFEST
|
|
24
|
+
|
|
25
|
+
# Virtual environments
|
|
26
|
+
.env
|
|
27
|
+
.venv
|
|
28
|
+
env/
|
|
29
|
+
venv/
|
|
30
|
+
ENV/
|
|
31
|
+
env.bak/
|
|
32
|
+
venv.bak/
|
|
33
|
+
|
|
34
|
+
# PyCharm
|
|
35
|
+
.idea/
|
|
36
|
+
|
|
37
|
+
# VSCode
|
|
38
|
+
.vscode/
|
|
39
|
+
|
|
40
|
+
# Jupyter Notebook
|
|
41
|
+
.ipynb_checkpoints
|
|
42
|
+
|
|
43
|
+
# pyenv
|
|
44
|
+
.python-version
|
|
45
|
+
|
|
46
|
+
# Environments
|
|
47
|
+
.env.local
|
|
48
|
+
.env.*.local
|
|
49
|
+
|
|
50
|
+
# Testing
|
|
51
|
+
.pytest_cache/
|
|
52
|
+
.coverage
|
|
53
|
+
htmlcov/
|
|
54
|
+
.tox/
|
|
55
|
+
.nox/
|
|
56
|
+
.hypothesis/
|
|
57
|
+
coverage.xml
|
|
58
|
+
*.cover
|
|
59
|
+
*.log
|
|
60
|
+
|
|
61
|
+
# Type checking
|
|
62
|
+
.mypy_cache/
|
|
63
|
+
.dmypy.json
|
|
64
|
+
dmypy.json
|
|
65
|
+
.pytype/
|
|
66
|
+
.pyre/
|
|
67
|
+
|
|
68
|
+
# Data directories (for local development)
|
|
69
|
+
data/
|
|
70
|
+
*.parquet
|
|
71
|
+
*.duckdb
|
|
72
|
+
*.zip
|
|
73
|
+
*.csv
|
|
74
|
+
temp/
|
|
75
|
+
|
|
76
|
+
# macOS
|
|
77
|
+
.DS_Store
|
|
78
|
+
.AppleDouble
|
|
79
|
+
.LSOverride
|
|
80
|
+
|
|
81
|
+
# Linux
|
|
82
|
+
*~
|
|
83
|
+
|
|
84
|
+
# Backup files
|
|
85
|
+
*.bak
|
|
86
|
+
*.swp
|
|
87
|
+
*.swo
|
|
88
|
+
*~
|
|
89
|
+
|
|
90
|
+
# Distribution / packaging
|
|
91
|
+
.Python
|
|
92
|
+
pip-log.txt
|
|
93
|
+
pip-delete-this-directory.txt
|
|
94
|
+
|
|
95
|
+
# UV
|
|
96
|
+
.uv/
|
|
97
|
+
uv.lock
|
|
98
|
+
|
|
99
|
+
# Pre-commit
|
|
100
|
+
# .pre-commit-config.yaml should be tracked, not ignored
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/commitizen-tools/commitizen
|
|
3
|
+
rev: v4.9.1
|
|
4
|
+
hooks:
|
|
5
|
+
- id: commitizen
|
|
6
|
+
stages: [commit-msg]
|
|
7
|
+
- id: commitizen-branch
|
|
8
|
+
stages: [pre-push]
|
|
9
|
+
args: [--rev-range, origin/main..HEAD]
|
|
10
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
11
|
+
rev: v4.4.0
|
|
12
|
+
hooks:
|
|
13
|
+
- id: trailing-whitespace
|
|
14
|
+
- id: end-of-file-fixer
|
|
15
|
+
- id: check-yaml
|
|
16
|
+
- id: check-added-large-files
|
|
17
|
+
- id: check-merge-conflict
|
|
18
|
+
- id: debug-statements
|
|
19
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
20
|
+
rev: v0.13.0
|
|
21
|
+
hooks:
|
|
22
|
+
- id: ruff
|
|
23
|
+
args: [--fix, --unsafe-fixes]
|
|
24
|
+
- id: ruff-format
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Authors
|
|
2
|
+
|
|
3
|
+
## Project Lead
|
|
4
|
+
|
|
5
|
+
- **Terry Li** <terry@eonlabs.com>
|
|
6
|
+
- Original author and maintainer
|
|
7
|
+
- Architecture and core implementation
|
|
8
|
+
|
|
9
|
+
## Organization
|
|
10
|
+
|
|
11
|
+
**Eon Labs**
|
|
12
|
+
- Website: https://eonlabs.com
|
|
13
|
+
- GitHub: https://github.com/Eon-Labs
|
|
14
|
+
|
|
15
|
+
## Contributors
|
|
16
|
+
|
|
17
|
+
We welcome contributions! See CONTRIBUTING.md for guidelines.
|
|
18
|
+
|
|
19
|
+
## Acknowledgments
|
|
20
|
+
|
|
21
|
+
- Exness for providing high-quality public tick data
|
|
22
|
+
- DuckDB team for embedded OLAP database
|
|
23
|
+
- Apache Arrow and Parquet communities
|
|
24
|
+
- Facebook's Zstd compression library
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Initial release of exness-data-preprocess
|
|
12
|
+
- Core `ExnessDataProcessor` class for tick data preprocessing
|
|
13
|
+
- Simple Python API with wrapper functions
|
|
14
|
+
- Command-line interface with `process`, `query`, `analyze`, and `stats` commands
|
|
15
|
+
- Parquet compression with Zstd-22 (9% smaller than ZIP, lossless)
|
|
16
|
+
- DuckDB OHLC generation with embedded metadata
|
|
17
|
+
- Automatic resampling to higher timeframes (5m, 15m, 30m, 1h, 4h, 1d)
|
|
18
|
+
- On-demand tick data analysis capabilities
|
|
19
|
+
- Atomic file operations for data integrity
|
|
20
|
+
- Comprehensive test suite with >90% coverage
|
|
21
|
+
- Full documentation with usage examples and benchmarks
|
|
22
|
+
|
|
23
|
+
### Technical Details
|
|
24
|
+
- Optimal compression: Parquet + Zstd-22 (4.77 MB per month EURUSD)
|
|
25
|
+
- DuckDB storage: 0.78 MB per month OHLC data
|
|
26
|
+
- Zero precision loss (lossless compression)
|
|
27
|
+
- Direct queryability via DuckDB SQL
|
|
28
|
+
- Support for Python 3.9+
|
|
29
|
+
|
|
30
|
+
## [0.1.0] - 2025-10-12
|
|
31
|
+
|
|
32
|
+
Initial PyPI release.
|
|
33
|
+
|
|
34
|
+
[Unreleased]: https://github.com/terrylica/exness-data-preprocess/compare/v0.1.0...HEAD
|
|
35
|
+
[0.1.0]: https://github.com/terrylica/exness-data-preprocess/releases/tag/v0.1.0
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
# exness-data-preprocess - Project Memory
|
|
2
|
+
|
|
3
|
+
**Architecture**: Professional forex tick data preprocessing with unified single-file DuckDB storage
|
|
4
|
+
|
|
5
|
+
**Full Documentation**: [`README.md`](README.md) - Installation, usage, API reference
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Quick Links
|
|
10
|
+
|
|
11
|
+
### Documentation
|
|
12
|
+
- **[README.md](README.md)** - Full API reference, installation, usage examples
|
|
13
|
+
- **[docs/README.md](docs/README.md)** - Documentation hub with research findings
|
|
14
|
+
- **[docs/DATABASE_SCHEMA.md](docs/DATABASE_SCHEMA.md)** - Complete database schema with self-documentation
|
|
15
|
+
- **[docs/UNIFIED_DUCKDB_PLAN_v2.md](docs/UNIFIED_DUCKDB_PLAN_v2.md)** - v2.0.0 architecture specification
|
|
16
|
+
- **[docs/EXNESS_DATA_SOURCES.md](docs/EXNESS_DATA_SOURCES.md)** - Data source variants and URLs
|
|
17
|
+
|
|
18
|
+
### Code Examples
|
|
19
|
+
- **[examples/basic_usage.py](examples/basic_usage.py)** - Download, query, coverage operations
|
|
20
|
+
- **[examples/batch_processing.py](examples/batch_processing.py)** - Multi-instrument parallel processing
|
|
21
|
+
- **[examples/add_schema_comments.py](examples/add_schema_comments.py)** - Retrofit self-documentation
|
|
22
|
+
|
|
23
|
+
### Development
|
|
24
|
+
- **[CONTRIBUTING.md](CONTRIBUTING.md)** - Contribution guidelines
|
|
25
|
+
- **[tests/README.md](tests/README.md)** - Test suite documentation
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Essential Architecture Decisions
|
|
30
|
+
|
|
31
|
+
### Unified Single-File DuckDB Storage v2.0.0 (✅ Implemented & Validated 2025-10-12)
|
|
32
|
+
|
|
33
|
+
**Decision**: Store all years of data in single DuckDB file per instrument (eurusd.duckdb, not monthly files)
|
|
34
|
+
|
|
35
|
+
**Implementation**: v2.0.0 refactoring completed
|
|
36
|
+
- ✅ **Single file per instrument**: eurusd.duckdb contains all years
|
|
37
|
+
- ✅ **Dual-variant storage**: Raw_Spread + Standard in same database
|
|
38
|
+
- ✅ **PRIMARY KEY constraints**: Prevents duplicates during incremental updates
|
|
39
|
+
- ✅ **Automatic gap detection**: Downloads only missing months
|
|
40
|
+
- ✅ **Phase7 9-column OHLC**: Dual spreads + dual tick counts
|
|
41
|
+
- ✅ **Date range queries**: Sub-15ms query performance
|
|
42
|
+
- ✅ **On-demand resampling**: Any timeframe (5m, 1h, 1d) in <15ms
|
|
43
|
+
|
|
44
|
+
**Validation Results** (13 months, Oct 2024 - Oct 2025):
|
|
45
|
+
- ✅ **Raw_Spread ticks**: 18.6M ticks
|
|
46
|
+
- ✅ **Standard ticks**: 19.6M ticks
|
|
47
|
+
- ✅ **OHLC bars**: 413K bars (1-minute)
|
|
48
|
+
- ✅ **Database size**: 2.08 GB
|
|
49
|
+
- ✅ **Query performance**: <15ms for all operations
|
|
50
|
+
- ✅ **Incremental updates**: Working correctly (0 months added when up to date)
|
|
51
|
+
|
|
52
|
+
**Architecture Benefits**:
|
|
53
|
+
- **No file fragmentation**: All years in one database
|
|
54
|
+
- **No duplicates**: PRIMARY KEY constraints prevent duplicate data
|
|
55
|
+
- **Fast queries**: Date range filtering without loading entire dataset
|
|
56
|
+
- **Scalability**: 2.08 GB for 13 months (3 years ~4.8 GB)
|
|
57
|
+
|
|
58
|
+
**Comprehensive Plan**: [`docs/UNIFIED_DUCKDB_PLAN_v2.md`](docs/UNIFIED_DUCKDB_PLAN_v2.md) - Complete v2.0.0 specification
|
|
59
|
+
|
|
60
|
+
**Legacy Plan**: [`docs/archive/UNIFIED_DUCKDB_PLAN_v1.0.0_LEGACY.md`](docs/archive/UNIFIED_DUCKDB_PLAN_v1.0.0_LEGACY.md) - Monthly-file architecture (archived)
|
|
61
|
+
|
|
62
|
+
**Test Artifacts**:
|
|
63
|
+
- `/tmp/exness-duckdb-test/refactored/eurusd.duckdb` - 2.08 GB unified database
|
|
64
|
+
- `/tmp/exness-duckdb-test/test_refactored_processor.py` - Validation test
|
|
65
|
+
- `/tmp/exness-duckdb-test/test_queries_only.py` - Query validation test
|
|
66
|
+
|
|
67
|
+
### Phase7 9-Column OHLC Schema (✅ Implemented)
|
|
68
|
+
|
|
69
|
+
**Decision**: Dual-variant BID-only OHLC with 9 columns capturing both Raw_Spread and Standard characteristics
|
|
70
|
+
|
|
71
|
+
**Schema**: `Timestamp | Open | High | Low | Close | raw_spread_avg | standard_spread_avg | tick_count_raw_spread | tick_count_standard`
|
|
72
|
+
|
|
73
|
+
**Key Features**:
|
|
74
|
+
- ✅ **BID-only OHLC**: Uses Raw_Spread Bid prices (execution prices)
|
|
75
|
+
- ✅ **Dual spreads**: Tracks both Raw_Spread (zero-spreads) and Standard (market spreads)
|
|
76
|
+
- ✅ **Dual tick counts**: Records tick counts from both variants
|
|
77
|
+
- ✅ **LEFT JOIN methodology**: Raw_Spread primary, Standard reference
|
|
78
|
+
|
|
79
|
+
**Implementation**: [`src/exness_data_preprocess/processor.py`](src/exness_data_preprocess/processor.py) (lines 453-485)
|
|
80
|
+
|
|
81
|
+
**Specification**: [`docs/research/eurusd-zero-spread-deviations/data/plan/phase7_bid_ohlc_construction_v1.1.0.md`](docs/research/eurusd-zero-spread-deviations/data/plan/phase7_bid_ohlc_construction_v1.1.0.md)
|
|
82
|
+
|
|
83
|
+
**Complete Schema Details**: [`docs/DATABASE_SCHEMA.md`](docs/DATABASE_SCHEMA.md)
|
|
84
|
+
|
|
85
|
+
### DuckDB Self-Documentation (✅ Implemented)
|
|
86
|
+
|
|
87
|
+
**Decision**: Use DuckDB's `COMMENT ON` statements to store metadata inside the database
|
|
88
|
+
|
|
89
|
+
**Implementation**: All tables and columns have embedded documentation
|
|
90
|
+
- ✅ **Table comments**: Purpose, data source URLs, characteristics
|
|
91
|
+
- ✅ **Column comments**: Type, constraints, nullability explanations
|
|
92
|
+
- ✅ **Machine-readable**: Query via `duckdb_tables()`, `duckdb_columns()`
|
|
93
|
+
- ✅ **Version-controlled**: Comments stored in database schema
|
|
94
|
+
|
|
95
|
+
**Benefits**:
|
|
96
|
+
- **Self-documenting**: Anyone connecting to database can query metadata
|
|
97
|
+
- **Single source of truth**: Documentation lives with the data
|
|
98
|
+
- **Tool integration**: BI tools and IDEs can display inline help
|
|
99
|
+
- **No external docs needed**: Schema is fully self-explanatory
|
|
100
|
+
|
|
101
|
+
**Query Examples**:
|
|
102
|
+
```sql
|
|
103
|
+
-- Get all table comments
|
|
104
|
+
SELECT table_name, comment FROM duckdb_tables();
|
|
105
|
+
|
|
106
|
+
-- Get all column comments with types
|
|
107
|
+
SELECT table_name, column_name, data_type, comment FROM duckdb_columns();
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
**Retrofit Methods**:
|
|
111
|
+
- `add_schema_comments(pair)` - Add comments to single database
|
|
112
|
+
- `add_schema_comments_all()` - Batch-update all databases
|
|
113
|
+
|
|
114
|
+
**Implementation**: [`src/exness_data_preprocess/processor.py`](src/exness_data_preprocess/processor.py) (lines 138-215, 698-797)
|
|
115
|
+
|
|
116
|
+
**Usage Example**: [`examples/add_schema_comments.py`](examples/add_schema_comments.py)
|
|
117
|
+
|
|
118
|
+
**Complete Schema Reference**: [`docs/DATABASE_SCHEMA.md`](docs/DATABASE_SCHEMA.md) - Human-readable documentation with introspection queries
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Exness Data Sources
|
|
123
|
+
|
|
124
|
+
**Source**: https://ticks.ex2archive.com/ - Public tick data repository with 4 variants per instrument
|
|
125
|
+
|
|
126
|
+
**Phase7 Uses**:
|
|
127
|
+
- **Primary**: Raw_Spread variant (97.81% zero-spreads, execution prices)
|
|
128
|
+
- **Reference**: Standard variant (0% zero-spreads, traditional quotes)
|
|
129
|
+
|
|
130
|
+
**Key Characteristics**:
|
|
131
|
+
- Monthly ZIP files with microsecond-precision CSV tick data
|
|
132
|
+
- Institutional ECN/STP quality
|
|
133
|
+
- Fixed URL pattern: `https://ticks.ex2archive.com/ticks/{VARIANT}/{YEAR}/{MONTH}/`
|
|
134
|
+
|
|
135
|
+
**Complete Guide**: [`docs/EXNESS_DATA_SOURCES.md`](docs/EXNESS_DATA_SOURCES.md) - All 4 variants, URL patterns, download examples
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Research Areas
|
|
140
|
+
|
|
141
|
+
### Zero-Spread Deviation Analysis
|
|
142
|
+
|
|
143
|
+
**Research Period**: Sep 2024 baseline + 16-month validation (Jan-Aug 2024+2025)
|
|
144
|
+
|
|
145
|
+
**Key Findings**:
|
|
146
|
+
- ✅ **Mean Reversion**: 87.3% ± 1.9% stable across 16 months
|
|
147
|
+
- ⚠️ **Volatility Prediction**: Regime shift between 2024 (R²=0.371) and 2025 (R²=0.209)
|
|
148
|
+
- ✅ **Phase7 Methodology**: Dual-variant BID-only OHLC construction validated
|
|
149
|
+
|
|
150
|
+
**Documentation**: [`docs/research/eurusd-zero-spread-deviations/README.md`](docs/research/eurusd-zero-spread-deviations/README.md)
|
|
151
|
+
|
|
152
|
+
**Methodology**: [`docs/research/eurusd-zero-spread-deviations/01-methodology.md`](docs/research/eurusd-zero-spread-deviations/01-methodology.md)
|
|
153
|
+
|
|
154
|
+
### Compression Benchmarks
|
|
155
|
+
|
|
156
|
+
**Decision**: DuckDB native storage (no Parquet files in v2.0.0)
|
|
157
|
+
|
|
158
|
+
**Legacy Benchmarks** (v1.0.0): Parquet Zstd-22 over Brotli-11 (too slow) and Delta Encoding (lossy)
|
|
159
|
+
|
|
160
|
+
**Documentation**: [`docs/research/compression-benchmarks/README.md`](docs/research/compression-benchmarks/README.md)
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Development Setup
|
|
165
|
+
|
|
166
|
+
**Quick Start**:
|
|
167
|
+
```bash
|
|
168
|
+
git clone https://github.com/Eon-Labs/exness-data-preprocess.git
|
|
169
|
+
cd exness-data-preprocess
|
|
170
|
+
uv sync --dev
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**Complete Setup Guide**: [`README.md`](README.md) - Installation, testing, code quality, building
|
|
174
|
+
|
|
175
|
+
**Contributing**: [`CONTRIBUTING.md`](CONTRIBUTING.md) - Contribution guidelines and workflow
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## Current Implementation Status
|
|
180
|
+
|
|
181
|
+
### v2.0.0 Architecture (✅ Completed 2025-10-12)
|
|
182
|
+
|
|
183
|
+
- ✅ **Unified single-file DuckDB** - One file per instrument (eurusd.duckdb)
|
|
184
|
+
- ✅ **Dual-variant storage** - Raw_Spread + Standard in same database
|
|
185
|
+
- ✅ **PRIMARY KEY constraints** - Prevents duplicates during incremental updates
|
|
186
|
+
- ✅ **Automatic gap detection** - Downloads only missing months
|
|
187
|
+
- ✅ **Phase7 9-column OHLC** - Dual spreads + dual tick counts
|
|
188
|
+
- ✅ **Date range queries** - Sub-15ms query performance
|
|
189
|
+
- ✅ **On-demand resampling** - Any timeframe in <15ms
|
|
190
|
+
- ✅ **SQL filter support** - Direct SQL WHERE clauses on ticks
|
|
191
|
+
- ✅ **API refactoring** - Clean unified API
|
|
192
|
+
- ✅ **Examples updated** - basic_usage.py, batch_processing.py
|
|
193
|
+
- ✅ **Documentation updated** - README.md, CLAUDE.md, docs/README.md
|
|
194
|
+
|
|
195
|
+
### Usage Examples
|
|
196
|
+
|
|
197
|
+
**Basic Operations**: [`examples/basic_usage.py`](examples/basic_usage.py) - Download, query, coverage
|
|
198
|
+
|
|
199
|
+
**Batch Processing**: [`examples/batch_processing.py`](examples/batch_processing.py) - Multi-instrument, parallel processing
|
|
200
|
+
|
|
201
|
+
**Schema Comments**: [`examples/add_schema_comments.py`](examples/add_schema_comments.py) - Retrofit self-documentation to existing databases
|
|
202
|
+
|
|
203
|
+
**Complete API Reference**: [`README.md`](README.md) - All methods, parameters, and usage patterns
|
|
204
|
+
|
|
205
|
+
### Pending Tasks
|
|
206
|
+
|
|
207
|
+
- ⏳ **CLI enhancements** - Add variant selection, OHLC resampling commands
|
|
208
|
+
- ⏳ **Test suite** - Update test_processor.py, test_api.py, test_cli.py for v2.0.0
|
|
209
|
+
- ⏳ **API expansion** - Add streaming query methods, batch operations
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## File Locations
|
|
214
|
+
|
|
215
|
+
**Project Root**: `/Users/terryli/eon/exness-data-preprocess/ `
|
|
216
|
+
|
|
217
|
+
**Data Storage** (default): `~/eon/exness-data/`
|
|
218
|
+
```
|
|
219
|
+
~/eon/exness-data/
|
|
220
|
+
├── eurusd.duckdb # Single file for all EURUSD data
|
|
221
|
+
├── gbpusd.duckdb # Single file for all GBPUSD data
|
|
222
|
+
├── xauusd.duckdb # Single file for all XAUUSD data
|
|
223
|
+
└── temp/
|
|
224
|
+
└── (temporary ZIP files)
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
**Database Schema** (per instrument):
|
|
228
|
+
```
|
|
229
|
+
eurusd.duckdb:
|
|
230
|
+
├── raw_spread_ticks # Timestamp (PK), Bid, Ask
|
|
231
|
+
├── standard_ticks # Timestamp (PK), Bid, Ask
|
|
232
|
+
├── ohlc_1m # Phase7 9-column schema
|
|
233
|
+
└── metadata # Coverage tracking
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
**Test Artifacts**: `/tmp/exness-duckdb-test/`
|
|
237
|
+
- `refactored/eurusd.duckdb` - 2.08 GB unified database (13 months)
|
|
238
|
+
- `test_refactored_processor.py` - Validation test
|
|
239
|
+
- `test_queries_only.py` - Query validation test
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## Migration from v1.0.0
|
|
244
|
+
|
|
245
|
+
**v1.0.0 (Legacy)**:
|
|
246
|
+
- Monthly DuckDB files: `eurusd_ohlc_2024_08.duckdb`
|
|
247
|
+
- Parquet tick storage: `eurusd_ticks_2024_08.parquet`
|
|
248
|
+
- Functions: `process_month()`, `process_date_range()`, `analyze_ticks()`
|
|
249
|
+
|
|
250
|
+
**v2.0.0 (Current)**:
|
|
251
|
+
- Single DuckDB file: `eurusd.duckdb`
|
|
252
|
+
- No Parquet files (everything in DuckDB)
|
|
253
|
+
- Unified API: `processor.update_data()`, `processor.query_ohlc()`, `processor.query_ticks()`
|
|
254
|
+
|
|
255
|
+
**Migration Steps**:
|
|
256
|
+
1. Run `processor.update_data(pair, start_date)` to create new unified database
|
|
257
|
+
2. Delete old monthly files: `rm eurusd_ohlc_2024_*.duckdb eurusd_ticks_2024_*.parquet`
|
|
258
|
+
3. Update code to use new API methods
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
## References
|
|
263
|
+
|
|
264
|
+
- **Exness Data**: https://ticks.ex2archive.com/
|
|
265
|
+
- **Official Exness**: https://www.exness.com/tick-history/ (Cloudflare protected)
|
|
266
|
+
- **DuckDB**: https://duckdb.org/
|
|
267
|
+
- **Apache Parquet**: https://parquet.apache.org/
|
|
268
|
+
- **Zstd Compression**: https://facebook.github.io/zstd/
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
**Version**: 2.0.0
|
|
273
|
+
**Last Updated**: 2025-10-12
|
|
274
|
+
**Architecture**: Unified Single-File DuckDB Storage with Incremental Updates
|