exness-data-preprocess 0.3.0__tar.gz → 0.4.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.3.0 → exness_data_preprocess-0.4.0}/.cz.toml +1 -1
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/.gitignore +1 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/CHANGELOG.md +16 -1
- exness_data_preprocess-0.4.0/CLAUDE.md +170 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/GITHUB_PYPI_SETUP.md +1 -1
- exness_data_preprocess-0.4.0/Makefile +62 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/PKG-INFO +37 -29
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/README.md +35 -28
- exness_data_preprocess-0.4.0/RELEASE_NOTES.md +26 -0
- exness_data_preprocess-0.4.0/cliff-release-notes.toml +131 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/DATABASE_SCHEMA.md +139 -27
- exness_data_preprocess-0.4.0/docs/MODULE_ARCHITECTURE.md +688 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/README.md +51 -4
- exness_data_preprocess-0.4.0/docs/RESEARCH_PATTERNS.md +223 -0
- exness_data_preprocess-0.4.0/docs/TRADING_HOURS_RESEARCH.md +1620 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/UNIFIED_DUCKDB_PLAN_v2.md +12 -7
- exness_data_preprocess-0.3.0/PYDANTIC_REFACTORING_PLAN.md → exness_data_preprocess-0.4.0/docs/archive/PYDANTIC_REFACTORING_PLAN_v0.2.0_COMPLETE.md +9 -10
- exness_data_preprocess-0.4.0/docs/plans/CLAUDE_MD_AUDIT_2025-10-16_PASS2.md +356 -0
- exness_data_preprocess-0.4.0/docs/plans/CLAUDE_MD_VERIFICATION_CHECKLIST_2025-10-16.md +382 -0
- exness_data_preprocess-0.4.0/docs/plans/CLAUDE_MD_VERIFICATION_FINDINGS_2025-10-16.md +312 -0
- exness_data_preprocess-0.4.0/docs/plans/DOCUMENTATION_AUDIT_2025-10-15.md +331 -0
- exness_data_preprocess-0.4.0/docs/plans/DOCUMENTATION_AUDIT_PASS2_2025-10-15.md +192 -0
- exness_data_preprocess-0.4.0/docs/plans/DOCUMENTATION_BEST_PRACTICES_LINE_COUNTS.md +512 -0
- exness_data_preprocess-0.4.0/docs/plans/EXCHANGE_SESSION_AUDIT_2025-10-17.md +480 -0
- exness_data_preprocess-0.4.0/docs/plans/FUNCTIONALITY_VALIDATION_REPORT_2025-10-15.md +382 -0
- exness_data_preprocess-0.4.0/docs/plans/FUNCTIONALITY_VALIDATION_REPORT_2025-10-16.md +362 -0
- exness_data_preprocess-0.4.0/docs/plans/PHASE7_v1.5.0_REFACTORING_PLAN.md +544 -0
- exness_data_preprocess-0.4.0/docs/plans/PHASE7_v1.6.0_REFACTORING_PROGRESS.md +1140 -0
- exness_data_preprocess-0.4.0/docs/plans/REFACTORING_CHECKLIST.md +202 -0
- exness_data_preprocess-0.4.0/docs/plans/RESEARCH_PATTERNS_CANONICALIZATION_2025-10-17.md +291 -0
- exness_data_preprocess-0.4.0/docs/plans/SCHEMA_v1.6.0_AUDIT_FINDINGS.md +399 -0
- exness_data_preprocess-0.4.0/docs/plans/SCHEMA_v1.6.0_MIGRATION_GUIDE.md +545 -0
- exness_data_preprocess-0.4.0/docs/plans/SESSION_2025-10-15_SUMMARY.md +315 -0
- exness_data_preprocess-0.4.0/docs/research/HYBRID_SESSION_DETECTION_ANALYSIS.md +858 -0
- exness_data_preprocess-0.4.0/docs/validation/E2E_VALIDATION_RESULTS_v1.6.0.md +288 -0
- exness_data_preprocess-0.4.0/docs/validation/WEEKEND_GAP_VALIDATION_SUMMARY.md +96 -0
- exness_data_preprocess-0.4.0/docs/validation/WORKSPACE_SURVEY_2025-10-17.md +246 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/examples/basic_usage.py +3 -3
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/examples/batch_processing.py +1 -1
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/pyproject.toml +3 -1
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/src/exness_data_preprocess/__init__.py +2 -2
- exness_data_preprocess-0.4.0/src/exness_data_preprocess/api.py +290 -0
- exness_data_preprocess-0.4.0/src/exness_data_preprocess/database_manager.py +208 -0
- exness_data_preprocess-0.4.0/src/exness_data_preprocess/downloader.py +82 -0
- exness_data_preprocess-0.4.0/src/exness_data_preprocess/exchanges.py +212 -0
- exness_data_preprocess-0.4.0/src/exness_data_preprocess/gap_detector.py +157 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/src/exness_data_preprocess/models.py +1 -3
- exness_data_preprocess-0.4.0/src/exness_data_preprocess/ohlc_generator.py +199 -0
- exness_data_preprocess-0.4.0/src/exness_data_preprocess/processor.py +412 -0
- exness_data_preprocess-0.4.0/src/exness_data_preprocess/query_engine.py +290 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/src/exness_data_preprocess/schema.py +79 -12
- exness_data_preprocess-0.4.0/src/exness_data_preprocess/session_detector.py +150 -0
- exness_data_preprocess-0.4.0/src/exness_data_preprocess/tick_loader.py +67 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/tests/README.md +2 -2
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/tests/conftest.py +2 -5
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/tests/test_functional_regression.py +12 -19
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/tests/test_models.py +8 -3
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/tests/test_processor_pydantic.py +3 -2
- exness_data_preprocess-0.3.0/CLAUDE.md +0 -404
- exness_data_preprocess-0.3.0/RELEASE_NOTES.md +0 -22
- exness_data_preprocess-0.3.0/src/exness_data_preprocess/processor.py +0 -773
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/.github/workflows/ci.yml +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/.github/workflows/pre-commit-autoupdate.yml +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/.github/workflows/publish.yml +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/.pre-commit-config.yaml +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/AUTHORS.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/CONTRIBUTING.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/LICENSE +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/cliff.toml +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/EXNESS_DATA_SOURCES.md +0 -0
- /exness_data_preprocess-0.3.0/PYDANTIC_REFACTORING_STATUS.md → /exness_data_preprocess-0.4.0/docs/archive/PYDANTIC_REFACTORING_STATUS_v0.2.0_COMPLETE.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/archive/UNIFIED_DUCKDB_PLAN_v1.0.0_LEGACY.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/implementation-plan.yaml +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/planning-index.yaml +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/compression-benchmarks/README.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/compression-benchmarks/test_all_compression_methods.py +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/compression-benchmarks/test_delta_encoding_properly.py +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/compression-benchmarks/test_parquet_compression_methods.py +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-spread-analysis/01-methodology.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-spread-analysis/02-mode-truncated-analysis.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-spread-analysis/03-hurdle-model-analysis.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-spread-analysis/04-temporal-patterns.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-spread-analysis/05-final-recommendations.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-spread-analysis/README.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-spread-analysis/scripts/reproduction_guide.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-spread-analysis/visualizations/hurdle-model/hurdle_decomposition.png +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-spread-analysis/visualizations/mode-truncated/cv_mode_comparison.png +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-spread-analysis/visualizations/mode-truncated/distribution_overlay.png +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-spread-analysis/visualizations/mode-truncated/signal_quality_comparison.png +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-spread-analysis/visualizations/mode-truncated/variance_decomposition.png +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-spread-analysis/visualizations/temporal/concentration_curve.png +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-spread-analysis/visualizations/temporal/percentile_analysis.png +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-zero-spread-deviations/01-methodology.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-zero-spread-deviations/02-baseline-sep2024.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-zero-spread-deviations/03-multiperiod-validation.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-zero-spread-deviations/04-discoveries-and-plan-evolution.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-zero-spread-deviations/README.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-zero-spread-deviations/findings/baseline-sep2024-comprehensive-summary.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-zero-spread-deviations/findings/phase2-mean-reversion-report.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-zero-spread-deviations/findings/phase3-volatility-model-report.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-zero-spread-deviations/findings/phase4-5-statistical-tests-survivorship-report.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-zero-spread-deviations/scripts/baseline-sep2024/01_mean_reversion_analysis.py +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-zero-spread-deviations/scripts/baseline-sep2024/02_volatility_model_simple.py +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-zero-spread-deviations/scripts/baseline-sep2024/03_liquidity_crisis_detection.py +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-zero-spread-deviations/scripts/baseline-sep2024/04_regime_detection_analysis.py +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase1_data_validation.py +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase2_mean_reversion.py +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase3_volatility_model.py +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase4_statistical_tests.py +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase5_survivorship_bias.py +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase5_survivorship_bias_v1.0.1.py +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase6a_interval_analysis.py +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase6b_price_clustering.py +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase6c_combined_pattern.py +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-zero-spread-deviations/scripts/reproduction_guide.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-zero-spread-deviations/scripts/visualization/diagnostic_burst_decay.py +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-zero-spread-deviations/scripts/visualization/generate_interactive_dashboard.py +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-zero-spread-deviations/scripts/visualization/generate_lightweight_dashboard.py +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-zero-spread-deviations/scripts/visualization/prepare_visualization_data.py +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/src/exness_data_preprocess/cli.py +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/tests/__init__.py +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/tests/archive/E2E_TESTING_PLAN_v1.0.0.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/tests/test_basic.py +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/tests/test_types.py +0 -0
|
@@ -6,11 +6,23 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
8
|
|
|
9
|
+
### ♻️ Refactoring
|
|
10
|
+
|
|
11
|
+
- **schema**: Centralize OHLC schema in schema.py module - Create schema.py with OHLCSchema class as single source of truth - Reduce coupling from 42 to 5 update locations (88% reduction) - Replace hardcoded column lists in docs with pointers to schema.py - Delete obsolete PYDANTIC_TEST_STRATEGY.md (tests implemented) - Delete add_schema_comments.py (functionality merged into processor) - Update tests to use OHLCSchema.get_required_columns() - Achieve maximum DRY: future column additions require 1-2 file updates BREAKING CHANGE: None (additive refactoring, no API changes)
|
|
12
|
+
|
|
13
|
+
- Extract 7 specialized modules from processor.py (Phase 1-5) Refactor processor.py using facade pattern with 7 focused modules implementing separation of concerns. Modules Created: - downloader.py: HTTP download operations - tick_loader.py: CSV parsing - database_manager.py: Database operations - session_detector.py: Holiday/session detection - gap_detector.py: Incremental update logic - ohlc_generator.py: Phase7 OHLC generation - query_engine.py: Query operations Design Principles: - Facade pattern: processor.py delegates to specialized modules - SLO-based: All modules define Availability, Correctness, Observability, Maintainability - Off-the-shelf: httpx, pandas, DuckDB, exchange_calendars (no custom implementations) - Zero regressions: All 48 tests pass, all ruff checks pass Documentation: - Updated CLAUDE.md with module structure and facade pattern - Updated docs/README.md with implementation architecture v1.3.0 - Added planning documents (REFACTORING_CHECKLIST.md, PHASE7_v1.6.0_REFACTORING_PROGRESS.md) Version: 1.3.0 (Implementation) Validation: 48 tests pass, ruff checks pass, backward compatible
|
|
14
|
+
|
|
15
|
+
|
|
9
16
|
### ✨ Features
|
|
10
17
|
|
|
11
18
|
- Implement pydantic v2 models with dual-variant e2e testing - Add Pydantic v2 models (UpdateResult, CoverageInfo) for type-safe API - Update processor to use Pydantic types (PairType, TimeframeType, VariantType) - Remove deprecated api.py module (broken functionality) - Implement comprehensive test suite (48 tests, 100% passing): * test_models.py - Pydantic model validation (13 tests) * test_types.py - Type safety and helpers (15 tests) * test_processor_pydantic.py - Integration tests (6 tests) * test_functional_regression.py - v2.0.0 regression tests (10 tests) - Fix Standard variant downloads (variant="" not "Standard") - Add true end-to-end testing with real Exness downloads - Test data: EURUSD August 2024 (815K Raw_Spread + 877K Standard ticks) - Update documentation and add refactoring status tracking - Coverage: models.py 100%, __init__.py 100%, processor.py 45% BREAKING CHANGE: api.py removed (use ExnessDataProcessor directly)
|
|
12
19
|
|
|
13
20
|
|
|
21
|
+
### 📚 Documentation
|
|
22
|
+
|
|
23
|
+
- Update all schema references from 9-column to 13-column (v1.2.0) Update outdated "9-column" or "Phase7 9 columns" references to "13-column (v1.2.0)" across all documentation files to reflect the current schema version with normalized spread metrics. Files updated: - GITHUB_PYPI_SETUP.md - Release notes reference - PYDANTIC_REFACTORING_PLAN.md - API documentation and examples (4 locations) - docs/DATABASE_SCHEMA.md - Version history (2 locations) - docs/README.md - Validation results - docs/UNIFIED_DUCKDB_PLAN_v2.md - Table descriptions and return types (2 locations) - tests/README.md - Test descriptions (2 locations) All outdated schema references now consistently reference the Phase7 13-column (v1.2.0) schema with normalized metrics (range_per_spread, range_per_tick, body_per_spread, body_per_tick). CHANGELOG.md and research/archive files intentionally preserved for historical accuracy.
|
|
24
|
+
|
|
25
|
+
|
|
14
26
|
### 🔧 Continuous Integration
|
|
15
27
|
|
|
16
28
|
- Modernize publish workflow with uv and validation pipeline Update GitHub Actions publish workflow to match gapless-crypto-data standards: Build System: - Replace pip+build with uv for consistency with local development - Add UV_SYSTEM_PYTHON=1 environment variable - Use uv sync --dev for dependency installation Validation Pipeline: - Add file encoding validation (UTF-8/ASCII enforcement) - Add ruff linting and format checking - Add pytest test suite execution before build Security: - Add Sigstore artifact signing for published packages - Maintain PyPI Trusted Publishing (OIDC) authentication Configuration: - Change environment name: release → pypi (semantic clarity) - Change artifact name: dist → python-package-distributions (consistency) - Add verbose output to PyPI publish step Security Note: - Added .token-info.md to .gitignore to prevent accidental token documentation commits - Workflow uses OIDC (no API token needed)
|
|
@@ -20,6 +32,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
20
32
|
|
|
21
33
|
- **release**: Bump version 0.1.0 → 0.2.0 [skip ci]
|
|
22
34
|
|
|
35
|
+
- **release**: Bump version 0.2.0 → 0.3.0 [skip ci]
|
|
36
|
+
|
|
37
|
+
- **release**: Bump version 0.3.0 → 0.3.1 [skip ci]
|
|
38
|
+
|
|
23
39
|
|
|
24
40
|
### ✨ Features
|
|
25
41
|
|
|
@@ -50,4 +66,3 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
50
66
|
### 🧰 Maintenance
|
|
51
67
|
|
|
52
68
|
- Prepare v0.1.0 release
|
|
53
|
-
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
**Architecture**: Forex tick data preprocessing with unified single-file DuckDB storage
|
|
6
|
+
|
|
7
|
+
**Full Documentation**: [`README.md`](README.md) - Installation, usage, API reference
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Documentation Hub
|
|
12
|
+
|
|
13
|
+
### User Documentation
|
|
14
|
+
- **[README.md](README.md)** - Installation, API reference, usage examples
|
|
15
|
+
- **[examples/basic_usage.py](examples/basic_usage.py)** - Download, query, coverage operations
|
|
16
|
+
- **[examples/batch_processing.py](examples/batch_processing.py)** - Multi-instrument parallel processing
|
|
17
|
+
|
|
18
|
+
### AI Assistant Documentation
|
|
19
|
+
- **[docs/README.md](docs/README.md)** - Architecture, planning, research findings
|
|
20
|
+
- **[docs/MODULE_ARCHITECTURE.md](docs/MODULE_ARCHITECTURE.md)** - Complete module documentation with SLOs
|
|
21
|
+
- **[docs/DATABASE_SCHEMA.md](docs/DATABASE_SCHEMA.md)** - Complete database schema with self-documentation
|
|
22
|
+
- **[docs/RESEARCH_PATTERNS.md](docs/RESEARCH_PATTERNS.md)** - Research lifecycle and tool selection (v1.0.0)
|
|
23
|
+
- **[docs/UNIFIED_DUCKDB_PLAN_v2.md](docs/UNIFIED_DUCKDB_PLAN_v2.md)** - v2.0.0 architecture specification
|
|
24
|
+
- **[docs/EXNESS_DATA_SOURCES.md](docs/EXNESS_DATA_SOURCES.md)** - Data source variants and URLs
|
|
25
|
+
- **[Makefile](Makefile)** - Module introspection commands (module-stats, module-complexity, module-deps)
|
|
26
|
+
|
|
27
|
+
### Implementation
|
|
28
|
+
- **src/exness_data_preprocess/** - Source code (7 specialized modules + facade)
|
|
29
|
+
- **tests/** - Test suite (48 tests, 100% passing)
|
|
30
|
+
- **[CONTRIBUTING.md](CONTRIBUTING.md)** - Contribution guidelines
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Architecture Summary
|
|
35
|
+
|
|
36
|
+
### Storage Pattern (v2.0.0)
|
|
37
|
+
- **Single DuckDB file per instrument** (e.g., eurusd.duckdb containing all historical data)
|
|
38
|
+
- **Dual-variant storage** (Raw_Spread + Standard in same database)
|
|
39
|
+
- **Incremental updates** with automatic gap detection
|
|
40
|
+
- **PRIMARY KEY constraints** prevent duplicates during updates
|
|
41
|
+
- **Sub-15ms query performance** with date range filtering
|
|
42
|
+
- **On-demand resampling** to any timeframe (5m, 1h, 1d)
|
|
43
|
+
|
|
44
|
+
**Complete Specification**: [`docs/UNIFIED_DUCKDB_PLAN_v2.md`](docs/UNIFIED_DUCKDB_PLAN_v2.md)
|
|
45
|
+
|
|
46
|
+
### Module Pattern (v1.3.0)
|
|
47
|
+
- **Facade orchestrator** (processor.py) coordinating 7 specialized modules
|
|
48
|
+
- **Separation of concerns** with single-responsibility modules
|
|
49
|
+
- **SLO-based design** (Availability, Correctness, Observability, Maintainability)
|
|
50
|
+
- **Off-the-shelf libraries** (httpx, pandas, DuckDB, exchange_calendars)
|
|
51
|
+
- **Zero regressions** (48 tests pass)
|
|
52
|
+
|
|
53
|
+
**Modules**:
|
|
54
|
+
1. **processor.py** - Thin orchestrator facade
|
|
55
|
+
2. **downloader.py** - HTTP download operations
|
|
56
|
+
3. **tick_loader.py** - CSV parsing
|
|
57
|
+
4. **database_manager.py** - Database operations
|
|
58
|
+
5. **session_detector.py** - Holiday and session detection
|
|
59
|
+
6. **gap_detector.py** - Incremental update logic
|
|
60
|
+
7. **ohlc_generator.py** - Phase7 OHLC generation
|
|
61
|
+
8. **query_engine.py** - Query operations
|
|
62
|
+
|
|
63
|
+
**Complete Details**: [`docs/MODULE_ARCHITECTURE.md`](docs/MODULE_ARCHITECTURE.md)
|
|
64
|
+
|
|
65
|
+
### Schema (v1.6.0)
|
|
66
|
+
- **Phase7 30-column OHLC** with dual-variant spreads
|
|
67
|
+
- **BID-only OHLC** from Raw_Spread execution prices
|
|
68
|
+
- **Normalized metrics** (range_per_spread, range_per_tick, body_per_spread, body_per_tick)
|
|
69
|
+
- **10 global exchange sessions with trading hour detection** (NYSE, LSE, XSWX, XFRA, XTSE, XNZE, XTKS, XASX, XHKG, XSES)
|
|
70
|
+
- **Holiday tracking** (US, UK, major holidays)
|
|
71
|
+
- **Self-documenting** via COMMENT ON statements
|
|
72
|
+
|
|
73
|
+
**Complete Schema**: [`docs/DATABASE_SCHEMA.md`](docs/DATABASE_SCHEMA.md)
|
|
74
|
+
|
|
75
|
+
### Data Sources
|
|
76
|
+
- **Source**: https://ticks.ex2archive.com/ (public Exness tick data)
|
|
77
|
+
- **Primary**: Raw_Spread variant (97.81% zero-spreads, execution prices)
|
|
78
|
+
- **Reference**: Standard variant (0% zero-spreads, market quotes)
|
|
79
|
+
- **Format**: Monthly ZIP files with microsecond-precision CSV
|
|
80
|
+
|
|
81
|
+
**Complete Guide**: [`docs/EXNESS_DATA_SOURCES.md`](docs/EXNESS_DATA_SOURCES.md)
|
|
82
|
+
|
|
83
|
+
### Research Patterns (v1.0.0)
|
|
84
|
+
- **Lifecycle**: Explore (pandas/Polars) → Validate → Graduate (DuckDB) → Query (SQL)
|
|
85
|
+
- **ASOF Performance**: pandas/Polars 0.04s, DuckDB 0.89s at 880K ticks (24x difference)
|
|
86
|
+
- **Tool Selection**: pandas/Polars for tick-level temporal matching, DuckDB for materialized results
|
|
87
|
+
- **Hybrid Pattern**: ASOF operations stay in pandas, validated findings materialize to DuckDB tables
|
|
88
|
+
- **Single Source of Truth**: DuckDB stores validated research outcomes with COMMENT ON documentation
|
|
89
|
+
|
|
90
|
+
**Complete Specification**: [`docs/RESEARCH_PATTERNS.md`](docs/RESEARCH_PATTERNS.md)
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Development Commands
|
|
95
|
+
|
|
96
|
+
### Setup
|
|
97
|
+
```bash
|
|
98
|
+
# Install with development dependencies
|
|
99
|
+
uv sync --dev
|
|
100
|
+
|
|
101
|
+
# Or with pip
|
|
102
|
+
pip install -e ".[dev]"
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Testing
|
|
106
|
+
```bash
|
|
107
|
+
# Run all tests
|
|
108
|
+
uv run pytest
|
|
109
|
+
|
|
110
|
+
# Run with coverage
|
|
111
|
+
uv run pytest --cov=exness_data_preprocess --cov-report=html
|
|
112
|
+
|
|
113
|
+
# Run specific test file
|
|
114
|
+
uv run pytest tests/test_basic.py -v
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Code Quality
|
|
118
|
+
```bash
|
|
119
|
+
# Format code
|
|
120
|
+
uv run ruff format .
|
|
121
|
+
|
|
122
|
+
# Lint and auto-fix
|
|
123
|
+
uv run ruff check --fix .
|
|
124
|
+
|
|
125
|
+
# Type checking
|
|
126
|
+
uv run mypy src/
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Module Introspection
|
|
130
|
+
```bash
|
|
131
|
+
# Show current line counts (always accurate)
|
|
132
|
+
make module-stats
|
|
133
|
+
|
|
134
|
+
# Show cyclomatic complexity (requires radon)
|
|
135
|
+
make module-complexity
|
|
136
|
+
|
|
137
|
+
# Show dependency tree (requires pipdeptree)
|
|
138
|
+
make module-deps
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Building and Publishing
|
|
142
|
+
```bash
|
|
143
|
+
# Build package
|
|
144
|
+
uv build
|
|
145
|
+
|
|
146
|
+
# Test installation locally
|
|
147
|
+
uv tool install --editable .
|
|
148
|
+
|
|
149
|
+
# Publish to PyPI (requires PYPI_TOKEN)
|
|
150
|
+
doppler run --project claude-config --config dev -- uv publish --token "$PYPI_TOKEN"
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**Complete Development Guide**: [`README.md`](README.md) (Installation section)
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## References
|
|
158
|
+
|
|
159
|
+
- **Exness Data**: https://ticks.ex2archive.com/
|
|
160
|
+
- **DuckDB**: https://duckdb.org/
|
|
161
|
+
- **Apache Parquet**: https://parquet.apache.org/
|
|
162
|
+
- **Zstd Compression**: https://facebook.github.io/zstd/
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
**Version**: 2.0.0 (Architecture) + 1.3.0 (Implementation) + 1.0.0 (Research Patterns)
|
|
167
|
+
**Last Updated**: 2025-10-17
|
|
168
|
+
**Architecture**: Unified Single-File DuckDB Storage with Incremental Updates
|
|
169
|
+
**Implementation**: Facade Pattern with 7 Specialized Modules
|
|
170
|
+
**Research**: Hybrid Materialization (pandas/Polars exploration, DuckDB validated results)
|
|
@@ -173,7 +173,7 @@ gh release create v0.1.0 \
|
|
|
173
173
|
|
|
174
174
|
**Architecture v2.0.0:**
|
|
175
175
|
- Unified single-file DuckDB storage per instrument
|
|
176
|
-
- Phase7
|
|
176
|
+
- Phase7 13-column (v1.2.0) OHLC schema with dual-variant spreads and normalized metrics
|
|
177
177
|
- Sub-15ms query performance with date range filtering
|
|
178
178
|
- PRIMARY KEY constraints prevent duplicates
|
|
179
179
|
- Automatic gap detection for incremental updates
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Makefile for exness-data-preprocess
|
|
2
|
+
#
|
|
3
|
+
# Introspection commands for module statistics and project metrics
|
|
4
|
+
|
|
5
|
+
.PHONY: module-stats module-complexity module-deps clean test help
|
|
6
|
+
|
|
7
|
+
# Show current line counts for all modules
|
|
8
|
+
module-stats:
|
|
9
|
+
@echo "Module Statistics (current line counts)"
|
|
10
|
+
@echo "========================================"
|
|
11
|
+
@cd src/exness_data_preprocess && \
|
|
12
|
+
for f in *.py; do \
|
|
13
|
+
echo "$$f: $$(wc -l < "$$f") lines"; \
|
|
14
|
+
done | sort
|
|
15
|
+
@echo ""
|
|
16
|
+
@echo "Note: Line counts include comments, docstrings, and blank lines"
|
|
17
|
+
|
|
18
|
+
# Show module complexity using radon (requires: pip install radon)
|
|
19
|
+
module-complexity:
|
|
20
|
+
@echo "Module Complexity Analysis"
|
|
21
|
+
@echo "=========================="
|
|
22
|
+
@which radon > /dev/null 2>&1 || (echo "Error: radon not installed. Run: uv pip install radon" && exit 1)
|
|
23
|
+
@radon cc src/exness_data_preprocess/*.py -s -a
|
|
24
|
+
@echo ""
|
|
25
|
+
@echo "Complexity Ratings: A=simple, B=low, C=moderate, D=high, E=very high, F=extremely high"
|
|
26
|
+
|
|
27
|
+
# Show module dependencies using pipdeptree (requires: pip install pipdeptree)
|
|
28
|
+
module-deps:
|
|
29
|
+
@echo "Module Dependencies"
|
|
30
|
+
@echo "==================="
|
|
31
|
+
@which pipdeptree > /dev/null 2>&1 || (echo "Error: pipdeptree not installed. Run: uv pip install pipdeptree" && exit 1)
|
|
32
|
+
@pipdeptree --packages exness-data-preprocess
|
|
33
|
+
|
|
34
|
+
# Run test suite
|
|
35
|
+
test:
|
|
36
|
+
@uv run pytest -v --tb=short
|
|
37
|
+
|
|
38
|
+
# Run test suite with coverage
|
|
39
|
+
test-cov:
|
|
40
|
+
@uv run pytest --cov=exness_data_preprocess --cov-report=html --cov-report=term
|
|
41
|
+
|
|
42
|
+
# Clean build artifacts
|
|
43
|
+
clean:
|
|
44
|
+
@rm -rf dist/ build/ *.egg-info
|
|
45
|
+
@rm -rf .pytest_cache .ruff_cache .mypy_cache
|
|
46
|
+
@rm -rf htmlcov/
|
|
47
|
+
@find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
|
|
48
|
+
@echo "✓ Cleaned build artifacts"
|
|
49
|
+
|
|
50
|
+
# Show help
|
|
51
|
+
help:
|
|
52
|
+
@echo "Available commands:"
|
|
53
|
+
@echo ""
|
|
54
|
+
@echo " make module-stats Show current line counts for all modules"
|
|
55
|
+
@echo " make module-complexity Show cyclomatic complexity analysis (requires radon)"
|
|
56
|
+
@echo " make module-deps Show package dependency tree (requires pipdeptree)"
|
|
57
|
+
@echo " make test Run test suite"
|
|
58
|
+
@echo " make test-cov Run test suite with coverage report"
|
|
59
|
+
@echo " make clean Remove build artifacts and caches"
|
|
60
|
+
@echo " make help Show this help message"
|
|
61
|
+
@echo ""
|
|
62
|
+
@echo "Documentation: See CLAUDE.md for architecture and design patterns"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: exness-data-preprocess
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: Professional Exness forex tick data preprocessing with optimal compression (Parquet Zstd-22) and DuckDB OHLC generation. Provides efficient storage (9% smaller than ZIP) with lossless precision and direct queryability.
|
|
5
5
|
Project-URL: Homepage, https://github.com/terrylica/exness-data-preprocess
|
|
6
6
|
Project-URL: Documentation, https://github.com/terrylica/exness-data-preprocess#readme
|
|
@@ -30,6 +30,7 @@ Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
|
30
30
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
31
31
|
Requires-Python: >=3.9
|
|
32
32
|
Requires-Dist: duckdb>=0.9.0
|
|
33
|
+
Requires-Dist: exchange-calendars>=4.5.6
|
|
33
34
|
Requires-Dist: httpx>=0.25.0
|
|
34
35
|
Requires-Dist: pandas>=2.0.0
|
|
35
36
|
Requires-Dist: pyarrow>=16.0.0
|
|
@@ -55,14 +56,14 @@ Description-Content-Type: text/markdown
|
|
|
55
56
|
[](https://pypi.org/project/exness-data-preprocess/)
|
|
56
57
|
[](https://github.com/astral-sh/ruff)
|
|
57
58
|
|
|
58
|
-
Professional forex tick data preprocessing with unified single-file DuckDB storage. Provides incremental updates, dual-variant storage (Raw_Spread + Standard), and Phase7
|
|
59
|
+
Professional forex tick data preprocessing with unified single-file DuckDB storage. Provides incremental updates, dual-variant storage (Raw_Spread + Standard), and Phase7 30-column OHLC schema (v1.6.0) with 10 global exchange sessions (trading hour detection) and sub-15ms query performance.
|
|
59
60
|
|
|
60
61
|
## Features
|
|
61
62
|
|
|
62
63
|
- **Unified Single-File Architecture**: One DuckDB file per instrument (eurusd.duckdb)
|
|
63
64
|
- **Incremental Updates**: Automatic gap detection and download only missing months
|
|
64
65
|
- **Dual-Variant Storage**: Raw_Spread (primary) + Standard (reference) in same database
|
|
65
|
-
- **Phase7 OHLC Schema**:
|
|
66
|
+
- **Phase7 OHLC Schema**: 30-column bars (v1.6.0) with dual spreads, tick counts, normalized metrics, and 10 global exchange sessions with trading hour detection
|
|
66
67
|
- **Fast Queries**: Date range queries with sub-15ms performance
|
|
67
68
|
- **On-Demand Resampling**: Any timeframe (5m, 1h, 1d) resampled in <15ms
|
|
68
69
|
- **PRIMARY KEY Constraints**: Prevents duplicate data during incremental updates
|
|
@@ -138,7 +139,7 @@ Download Only Missing Months (Raw_Spread + Standard)
|
|
|
138
139
|
↓
|
|
139
140
|
DuckDB Single-File Storage (PRIMARY KEY prevents duplicates)
|
|
140
141
|
↓
|
|
141
|
-
Phase7
|
|
142
|
+
Phase7 30-Column OHLC Generation (v1.6.0 - dual spreads, tick counts, normalized metrics, 10 global exchange sessions with trading hour detection)
|
|
142
143
|
↓
|
|
143
144
|
Query Interface (date ranges, SQL filters, on-demand resampling)
|
|
144
145
|
```
|
|
@@ -148,15 +149,17 @@ Query Interface (date ranges, SQL filters, on-demand resampling)
|
|
|
148
149
|
**Single File Per Instrument**: `~/eon/exness-data/eurusd.duckdb`
|
|
149
150
|
|
|
150
151
|
**Schema**:
|
|
152
|
+
|
|
151
153
|
- `raw_spread_ticks` table: Timestamp (PK), Bid, Ask
|
|
152
154
|
- `standard_ticks` table: Timestamp (PK), Bid, Ask
|
|
153
|
-
- `ohlc_1m` table: Phase7
|
|
155
|
+
- `ohlc_1m` table: Phase7 30-column schema (v1.6.0)
|
|
154
156
|
- `metadata` table: Coverage tracking
|
|
155
157
|
|
|
156
|
-
**Phase7
|
|
158
|
+
**Phase7 30-Column OHLC (v1.6.0)**:
|
|
159
|
+
|
|
157
160
|
- **Column Definitions**: See [`schema.py`](src/exness_data_preprocess/schema.py) - Single source of truth
|
|
158
161
|
- **Comprehensive Reference**: See [`DATABASE_SCHEMA.md`](docs/DATABASE_SCHEMA.md) - Query examples and usage patterns
|
|
159
|
-
- **Key Features**: BID-only OHLC with dual spreads (Raw_Spread + Standard)
|
|
162
|
+
- **Key Features**: BID-only OHLC with dual spreads (Raw_Spread + Standard), normalized spread metrics, and 10 global exchange sessions with trading hour detection (XNYS, XLON, XSWX, XFRA, XTSE, XNZE, XTKS, XASX, XHKG, XSES)
|
|
160
163
|
|
|
161
164
|
### Directory Structure
|
|
162
165
|
|
|
@@ -172,6 +175,7 @@ Query Interface (date ranges, SQL filters, on-demand resampling)
|
|
|
172
175
|
```
|
|
173
176
|
|
|
174
177
|
**Why Single-File Per Instrument?**
|
|
178
|
+
|
|
175
179
|
- **Unified Storage**: All years in one database
|
|
176
180
|
- **Incremental Updates**: Automatic gap detection and download only missing months
|
|
177
181
|
- **No Duplicates**: PRIMARY KEY constraints prevent duplicate data
|
|
@@ -394,6 +398,7 @@ uv tool install --editable .
|
|
|
394
398
|
## Data Source
|
|
395
399
|
|
|
396
400
|
Data is sourced from Exness's public tick data repository:
|
|
401
|
+
|
|
397
402
|
- **URL**: https://ticks.ex2archive.com/
|
|
398
403
|
- **Format**: Monthly ZIP files with CSV tick data
|
|
399
404
|
- **Variants**: Raw_Spread (zero-spreads) + Standard (market spreads)
|
|
@@ -404,35 +409,35 @@ Data is sourced from Exness's public tick data repository:
|
|
|
404
409
|
|
|
405
410
|
### Database Size (3-Year History, EURUSD)
|
|
406
411
|
|
|
407
|
-
| Metric
|
|
408
|
-
|
|
409
|
-
| Raw_Spread ticks | ~18.6M
|
|
410
|
-
| Standard ticks
|
|
411
|
-
| OHLC bars (1m)
|
|
412
|
-
| Database size
|
|
413
|
-
| Date range
|
|
412
|
+
| Metric | Value |
|
|
413
|
+
| ---------------- | ------------------------ |
|
|
414
|
+
| Raw_Spread ticks | ~18.6M |
|
|
415
|
+
| Standard ticks | ~19.6M |
|
|
416
|
+
| OHLC bars (1m) | ~413K |
|
|
417
|
+
| Database size | ~2.08 GB |
|
|
418
|
+
| Date range | 2022-01-01 to 2025-01-10 |
|
|
414
419
|
|
|
415
420
|
### Query Performance
|
|
416
421
|
|
|
417
|
-
| Operation
|
|
418
|
-
|
|
422
|
+
| Operation | Time |
|
|
423
|
+
| -------------------------- | ----- |
|
|
419
424
|
| Query 880K ticks (1 month) | <15ms |
|
|
420
|
-
| Query 1m OHLC (1 month)
|
|
421
|
-
| Resample to 1h (1 month)
|
|
422
|
-
| Resample to 1d (1 year)
|
|
425
|
+
| Query 1m OHLC (1 month) | <10ms |
|
|
426
|
+
| Resample to 1h (1 month) | <15ms |
|
|
427
|
+
| Resample to 1d (1 year) | <20ms |
|
|
423
428
|
|
|
424
429
|
### Architecture Benefits
|
|
425
430
|
|
|
426
|
-
| Feature
|
|
427
|
-
|
|
428
|
-
| Single file per instrument | Unified storage, no file fragmentation
|
|
429
|
-
| PRIMARY KEY constraints
|
|
430
|
-
| Automatic gap detection
|
|
431
|
-
| Dual-variant storage
|
|
432
|
-
| Phase7 OHLC schema
|
|
433
|
-
| Date range queries
|
|
434
|
-
| On-demand resampling
|
|
435
|
-
| SQL filter support
|
|
431
|
+
| Feature | Benefit |
|
|
432
|
+
| -------------------------- | -------------------------------------------------- |
|
|
433
|
+
| Single file per instrument | Unified storage, no file fragmentation |
|
|
434
|
+
| PRIMARY KEY constraints | Prevents duplicates during incremental updates |
|
|
435
|
+
| Automatic gap detection | Download only missing months |
|
|
436
|
+
| Dual-variant storage | Raw_Spread + Standard in same database |
|
|
437
|
+
| Phase7 OHLC schema | Dual spreads + dual tick counts |
|
|
438
|
+
| Date range queries | Efficient filtering without loading entire dataset |
|
|
439
|
+
| On-demand resampling | Any timeframe in <15ms |
|
|
440
|
+
| SQL filter support | Direct SQL WHERE clauses on ticks |
|
|
436
441
|
|
|
437
442
|
## API Reference
|
|
438
443
|
|
|
@@ -461,16 +466,19 @@ processor = edp.ExnessDataProcessor(base_dir="~/eon/exness-data")
|
|
|
461
466
|
## Migration from v1.0.0
|
|
462
467
|
|
|
463
468
|
**v1.0.0 (Legacy)**:
|
|
469
|
+
|
|
464
470
|
- Monthly DuckDB files: `eurusd_ohlc_2024_08.duckdb`
|
|
465
471
|
- Parquet tick storage: `eurusd_ticks_2024_08.parquet`
|
|
466
472
|
- Functions: `process_month()`, `process_date_range()`, `analyze_ticks()`
|
|
467
473
|
|
|
468
474
|
**v2.0.0 (Current)**:
|
|
475
|
+
|
|
469
476
|
- Single DuckDB file: `eurusd.duckdb`
|
|
470
477
|
- No Parquet files (everything in DuckDB)
|
|
471
478
|
- Unified API: `processor.update_data()`, `processor.query_ohlc()`, `processor.query_ticks()`
|
|
472
479
|
|
|
473
480
|
**Migration Steps**:
|
|
481
|
+
|
|
474
482
|
1. Run `processor.update_data(pair, start_date)` to create new unified database
|
|
475
483
|
2. Delete old monthly files: `rm eurusd_ohlc_2024_*.duckdb eurusd_ticks_2024_*.parquet`
|
|
476
484
|
3. Update code to use new API methods
|
|
@@ -7,14 +7,14 @@
|
|
|
7
7
|
[](https://pypi.org/project/exness-data-preprocess/)
|
|
8
8
|
[](https://github.com/astral-sh/ruff)
|
|
9
9
|
|
|
10
|
-
Professional forex tick data preprocessing with unified single-file DuckDB storage. Provides incremental updates, dual-variant storage (Raw_Spread + Standard), and Phase7
|
|
10
|
+
Professional forex tick data preprocessing with unified single-file DuckDB storage. Provides incremental updates, dual-variant storage (Raw_Spread + Standard), and Phase7 30-column OHLC schema (v1.6.0) with 10 global exchange sessions (trading hour detection) and sub-15ms query performance.
|
|
11
11
|
|
|
12
12
|
## Features
|
|
13
13
|
|
|
14
14
|
- **Unified Single-File Architecture**: One DuckDB file per instrument (eurusd.duckdb)
|
|
15
15
|
- **Incremental Updates**: Automatic gap detection and download only missing months
|
|
16
16
|
- **Dual-Variant Storage**: Raw_Spread (primary) + Standard (reference) in same database
|
|
17
|
-
- **Phase7 OHLC Schema**:
|
|
17
|
+
- **Phase7 OHLC Schema**: 30-column bars (v1.6.0) with dual spreads, tick counts, normalized metrics, and 10 global exchange sessions with trading hour detection
|
|
18
18
|
- **Fast Queries**: Date range queries with sub-15ms performance
|
|
19
19
|
- **On-Demand Resampling**: Any timeframe (5m, 1h, 1d) resampled in <15ms
|
|
20
20
|
- **PRIMARY KEY Constraints**: Prevents duplicate data during incremental updates
|
|
@@ -90,7 +90,7 @@ Download Only Missing Months (Raw_Spread + Standard)
|
|
|
90
90
|
↓
|
|
91
91
|
DuckDB Single-File Storage (PRIMARY KEY prevents duplicates)
|
|
92
92
|
↓
|
|
93
|
-
Phase7
|
|
93
|
+
Phase7 30-Column OHLC Generation (v1.6.0 - dual spreads, tick counts, normalized metrics, 10 global exchange sessions with trading hour detection)
|
|
94
94
|
↓
|
|
95
95
|
Query Interface (date ranges, SQL filters, on-demand resampling)
|
|
96
96
|
```
|
|
@@ -100,15 +100,17 @@ Query Interface (date ranges, SQL filters, on-demand resampling)
|
|
|
100
100
|
**Single File Per Instrument**: `~/eon/exness-data/eurusd.duckdb`
|
|
101
101
|
|
|
102
102
|
**Schema**:
|
|
103
|
+
|
|
103
104
|
- `raw_spread_ticks` table: Timestamp (PK), Bid, Ask
|
|
104
105
|
- `standard_ticks` table: Timestamp (PK), Bid, Ask
|
|
105
|
-
- `ohlc_1m` table: Phase7
|
|
106
|
+
- `ohlc_1m` table: Phase7 30-column schema (v1.6.0)
|
|
106
107
|
- `metadata` table: Coverage tracking
|
|
107
108
|
|
|
108
|
-
**Phase7
|
|
109
|
+
**Phase7 30-Column OHLC (v1.6.0)**:
|
|
110
|
+
|
|
109
111
|
- **Column Definitions**: See [`schema.py`](src/exness_data_preprocess/schema.py) - Single source of truth
|
|
110
112
|
- **Comprehensive Reference**: See [`DATABASE_SCHEMA.md`](docs/DATABASE_SCHEMA.md) - Query examples and usage patterns
|
|
111
|
-
- **Key Features**: BID-only OHLC with dual spreads (Raw_Spread + Standard)
|
|
113
|
+
- **Key Features**: BID-only OHLC with dual spreads (Raw_Spread + Standard), normalized spread metrics, and 10 global exchange sessions with trading hour detection (XNYS, XLON, XSWX, XFRA, XTSE, XNZE, XTKS, XASX, XHKG, XSES)
|
|
112
114
|
|
|
113
115
|
### Directory Structure
|
|
114
116
|
|
|
@@ -124,6 +126,7 @@ Query Interface (date ranges, SQL filters, on-demand resampling)
|
|
|
124
126
|
```
|
|
125
127
|
|
|
126
128
|
**Why Single-File Per Instrument?**
|
|
129
|
+
|
|
127
130
|
- **Unified Storage**: All years in one database
|
|
128
131
|
- **Incremental Updates**: Automatic gap detection and download only missing months
|
|
129
132
|
- **No Duplicates**: PRIMARY KEY constraints prevent duplicate data
|
|
@@ -346,6 +349,7 @@ uv tool install --editable .
|
|
|
346
349
|
## Data Source
|
|
347
350
|
|
|
348
351
|
Data is sourced from Exness's public tick data repository:
|
|
352
|
+
|
|
349
353
|
- **URL**: https://ticks.ex2archive.com/
|
|
350
354
|
- **Format**: Monthly ZIP files with CSV tick data
|
|
351
355
|
- **Variants**: Raw_Spread (zero-spreads) + Standard (market spreads)
|
|
@@ -356,35 +360,35 @@ Data is sourced from Exness's public tick data repository:
|
|
|
356
360
|
|
|
357
361
|
### Database Size (3-Year History, EURUSD)
|
|
358
362
|
|
|
359
|
-
| Metric
|
|
360
|
-
|
|
361
|
-
| Raw_Spread ticks | ~18.6M
|
|
362
|
-
| Standard ticks
|
|
363
|
-
| OHLC bars (1m)
|
|
364
|
-
| Database size
|
|
365
|
-
| Date range
|
|
363
|
+
| Metric | Value |
|
|
364
|
+
| ---------------- | ------------------------ |
|
|
365
|
+
| Raw_Spread ticks | ~18.6M |
|
|
366
|
+
| Standard ticks | ~19.6M |
|
|
367
|
+
| OHLC bars (1m) | ~413K |
|
|
368
|
+
| Database size | ~2.08 GB |
|
|
369
|
+
| Date range | 2022-01-01 to 2025-01-10 |
|
|
366
370
|
|
|
367
371
|
### Query Performance
|
|
368
372
|
|
|
369
|
-
| Operation
|
|
370
|
-
|
|
373
|
+
| Operation | Time |
|
|
374
|
+
| -------------------------- | ----- |
|
|
371
375
|
| Query 880K ticks (1 month) | <15ms |
|
|
372
|
-
| Query 1m OHLC (1 month)
|
|
373
|
-
| Resample to 1h (1 month)
|
|
374
|
-
| Resample to 1d (1 year)
|
|
376
|
+
| Query 1m OHLC (1 month) | <10ms |
|
|
377
|
+
| Resample to 1h (1 month) | <15ms |
|
|
378
|
+
| Resample to 1d (1 year) | <20ms |
|
|
375
379
|
|
|
376
380
|
### Architecture Benefits
|
|
377
381
|
|
|
378
|
-
| Feature
|
|
379
|
-
|
|
380
|
-
| Single file per instrument | Unified storage, no file fragmentation
|
|
381
|
-
| PRIMARY KEY constraints
|
|
382
|
-
| Automatic gap detection
|
|
383
|
-
| Dual-variant storage
|
|
384
|
-
| Phase7 OHLC schema
|
|
385
|
-
| Date range queries
|
|
386
|
-
| On-demand resampling
|
|
387
|
-
| SQL filter support
|
|
382
|
+
| Feature | Benefit |
|
|
383
|
+
| -------------------------- | -------------------------------------------------- |
|
|
384
|
+
| Single file per instrument | Unified storage, no file fragmentation |
|
|
385
|
+
| PRIMARY KEY constraints | Prevents duplicates during incremental updates |
|
|
386
|
+
| Automatic gap detection | Download only missing months |
|
|
387
|
+
| Dual-variant storage | Raw_Spread + Standard in same database |
|
|
388
|
+
| Phase7 OHLC schema | Dual spreads + dual tick counts |
|
|
389
|
+
| Date range queries | Efficient filtering without loading entire dataset |
|
|
390
|
+
| On-demand resampling | Any timeframe in <15ms |
|
|
391
|
+
| SQL filter support | Direct SQL WHERE clauses on ticks |
|
|
388
392
|
|
|
389
393
|
## API Reference
|
|
390
394
|
|
|
@@ -413,16 +417,19 @@ processor = edp.ExnessDataProcessor(base_dir="~/eon/exness-data")
|
|
|
413
417
|
## Migration from v1.0.0
|
|
414
418
|
|
|
415
419
|
**v1.0.0 (Legacy)**:
|
|
420
|
+
|
|
416
421
|
- Monthly DuckDB files: `eurusd_ohlc_2024_08.duckdb`
|
|
417
422
|
- Parquet tick storage: `eurusd_ticks_2024_08.parquet`
|
|
418
423
|
- Functions: `process_month()`, `process_date_range()`, `analyze_ticks()`
|
|
419
424
|
|
|
420
425
|
**v2.0.0 (Current)**:
|
|
426
|
+
|
|
421
427
|
- Single DuckDB file: `eurusd.duckdb`
|
|
422
428
|
- No Parquet files (everything in DuckDB)
|
|
423
429
|
- Unified API: `processor.update_data()`, `processor.query_ohlc()`, `processor.query_ticks()`
|
|
424
430
|
|
|
425
431
|
**Migration Steps**:
|
|
432
|
+
|
|
426
433
|
1. Run `processor.update_data(pair, start_date)` to create new unified database
|
|
427
434
|
2. Delete old monthly files: `rm eurusd_ohlc_2024_*.duckdb eurusd_ticks_2024_*.parquet`
|
|
428
435
|
3. Update code to use new API methods
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
## 0.3.1 - 2025-10-16
|
|
2
|
+
|
|
3
|
+
### Architecture Improvements
|
|
4
|
+
|
|
5
|
+
Refactored processor.py from monolithic file into 7 focused modules using facade pattern with separation of concerns.
|
|
6
|
+
|
|
7
|
+
**Modules Created**:
|
|
8
|
+
- `downloader.py`: HTTP download operations
|
|
9
|
+
- `tick_loader.py`: CSV parsing
|
|
10
|
+
- `database_manager.py`: Database operations
|
|
11
|
+
- `session_detector.py`: Holiday and session detection
|
|
12
|
+
- `gap_detector.py`: Incremental update logic
|
|
13
|
+
- `ohlc_generator.py`: Phase7 OHLC generation
|
|
14
|
+
- `query_engine.py`: Query operations
|
|
15
|
+
|
|
16
|
+
**Design Principles**:
|
|
17
|
+
- Facade pattern: processor.py delegates to specialized modules
|
|
18
|
+
- SLO-based: All modules define Availability, Correctness, Observability, Maintainability
|
|
19
|
+
- Off-the-shelf libraries: httpx, pandas, DuckDB, exchange_calendars (no custom implementations)
|
|
20
|
+
- Zero regressions: All 48 tests pass, backward compatible
|
|
21
|
+
|
|
22
|
+
**For Users**:
|
|
23
|
+
No API changes - all existing code continues to work. Internal refactoring improves maintainability and sets foundation for future enhancements.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
**Full Changelog**: https://github.com/terrylica/exness-data-preprocess/compare/v0.3.0...v0.3.1
|