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.
Files changed (124) hide show
  1. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/.cz.toml +1 -1
  2. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/.gitignore +1 -0
  3. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/CHANGELOG.md +16 -1
  4. exness_data_preprocess-0.4.0/CLAUDE.md +170 -0
  5. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/GITHUB_PYPI_SETUP.md +1 -1
  6. exness_data_preprocess-0.4.0/Makefile +62 -0
  7. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/PKG-INFO +37 -29
  8. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/README.md +35 -28
  9. exness_data_preprocess-0.4.0/RELEASE_NOTES.md +26 -0
  10. exness_data_preprocess-0.4.0/cliff-release-notes.toml +131 -0
  11. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/DATABASE_SCHEMA.md +139 -27
  12. exness_data_preprocess-0.4.0/docs/MODULE_ARCHITECTURE.md +688 -0
  13. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/README.md +51 -4
  14. exness_data_preprocess-0.4.0/docs/RESEARCH_PATTERNS.md +223 -0
  15. exness_data_preprocess-0.4.0/docs/TRADING_HOURS_RESEARCH.md +1620 -0
  16. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/UNIFIED_DUCKDB_PLAN_v2.md +12 -7
  17. 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
  18. exness_data_preprocess-0.4.0/docs/plans/CLAUDE_MD_AUDIT_2025-10-16_PASS2.md +356 -0
  19. exness_data_preprocess-0.4.0/docs/plans/CLAUDE_MD_VERIFICATION_CHECKLIST_2025-10-16.md +382 -0
  20. exness_data_preprocess-0.4.0/docs/plans/CLAUDE_MD_VERIFICATION_FINDINGS_2025-10-16.md +312 -0
  21. exness_data_preprocess-0.4.0/docs/plans/DOCUMENTATION_AUDIT_2025-10-15.md +331 -0
  22. exness_data_preprocess-0.4.0/docs/plans/DOCUMENTATION_AUDIT_PASS2_2025-10-15.md +192 -0
  23. exness_data_preprocess-0.4.0/docs/plans/DOCUMENTATION_BEST_PRACTICES_LINE_COUNTS.md +512 -0
  24. exness_data_preprocess-0.4.0/docs/plans/EXCHANGE_SESSION_AUDIT_2025-10-17.md +480 -0
  25. exness_data_preprocess-0.4.0/docs/plans/FUNCTIONALITY_VALIDATION_REPORT_2025-10-15.md +382 -0
  26. exness_data_preprocess-0.4.0/docs/plans/FUNCTIONALITY_VALIDATION_REPORT_2025-10-16.md +362 -0
  27. exness_data_preprocess-0.4.0/docs/plans/PHASE7_v1.5.0_REFACTORING_PLAN.md +544 -0
  28. exness_data_preprocess-0.4.0/docs/plans/PHASE7_v1.6.0_REFACTORING_PROGRESS.md +1140 -0
  29. exness_data_preprocess-0.4.0/docs/plans/REFACTORING_CHECKLIST.md +202 -0
  30. exness_data_preprocess-0.4.0/docs/plans/RESEARCH_PATTERNS_CANONICALIZATION_2025-10-17.md +291 -0
  31. exness_data_preprocess-0.4.0/docs/plans/SCHEMA_v1.6.0_AUDIT_FINDINGS.md +399 -0
  32. exness_data_preprocess-0.4.0/docs/plans/SCHEMA_v1.6.0_MIGRATION_GUIDE.md +545 -0
  33. exness_data_preprocess-0.4.0/docs/plans/SESSION_2025-10-15_SUMMARY.md +315 -0
  34. exness_data_preprocess-0.4.0/docs/research/HYBRID_SESSION_DETECTION_ANALYSIS.md +858 -0
  35. exness_data_preprocess-0.4.0/docs/validation/E2E_VALIDATION_RESULTS_v1.6.0.md +288 -0
  36. exness_data_preprocess-0.4.0/docs/validation/WEEKEND_GAP_VALIDATION_SUMMARY.md +96 -0
  37. exness_data_preprocess-0.4.0/docs/validation/WORKSPACE_SURVEY_2025-10-17.md +246 -0
  38. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/examples/basic_usage.py +3 -3
  39. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/examples/batch_processing.py +1 -1
  40. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/pyproject.toml +3 -1
  41. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/src/exness_data_preprocess/__init__.py +2 -2
  42. exness_data_preprocess-0.4.0/src/exness_data_preprocess/api.py +290 -0
  43. exness_data_preprocess-0.4.0/src/exness_data_preprocess/database_manager.py +208 -0
  44. exness_data_preprocess-0.4.0/src/exness_data_preprocess/downloader.py +82 -0
  45. exness_data_preprocess-0.4.0/src/exness_data_preprocess/exchanges.py +212 -0
  46. exness_data_preprocess-0.4.0/src/exness_data_preprocess/gap_detector.py +157 -0
  47. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/src/exness_data_preprocess/models.py +1 -3
  48. exness_data_preprocess-0.4.0/src/exness_data_preprocess/ohlc_generator.py +199 -0
  49. exness_data_preprocess-0.4.0/src/exness_data_preprocess/processor.py +412 -0
  50. exness_data_preprocess-0.4.0/src/exness_data_preprocess/query_engine.py +290 -0
  51. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/src/exness_data_preprocess/schema.py +79 -12
  52. exness_data_preprocess-0.4.0/src/exness_data_preprocess/session_detector.py +150 -0
  53. exness_data_preprocess-0.4.0/src/exness_data_preprocess/tick_loader.py +67 -0
  54. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/tests/README.md +2 -2
  55. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/tests/conftest.py +2 -5
  56. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/tests/test_functional_regression.py +12 -19
  57. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/tests/test_models.py +8 -3
  58. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/tests/test_processor_pydantic.py +3 -2
  59. exness_data_preprocess-0.3.0/CLAUDE.md +0 -404
  60. exness_data_preprocess-0.3.0/RELEASE_NOTES.md +0 -22
  61. exness_data_preprocess-0.3.0/src/exness_data_preprocess/processor.py +0 -773
  62. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/.github/workflows/ci.yml +0 -0
  63. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/.github/workflows/pre-commit-autoupdate.yml +0 -0
  64. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/.github/workflows/publish.yml +0 -0
  65. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/.pre-commit-config.yaml +0 -0
  66. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/AUTHORS.md +0 -0
  67. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/CONTRIBUTING.md +0 -0
  68. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/LICENSE +0 -0
  69. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/cliff.toml +0 -0
  70. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/EXNESS_DATA_SOURCES.md +0 -0
  71. /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
  72. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/archive/UNIFIED_DUCKDB_PLAN_v1.0.0_LEGACY.md +0 -0
  73. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/implementation-plan.yaml +0 -0
  74. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/planning-index.yaml +0 -0
  75. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/compression-benchmarks/README.md +0 -0
  76. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/compression-benchmarks/test_all_compression_methods.py +0 -0
  77. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/compression-benchmarks/test_delta_encoding_properly.py +0 -0
  78. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/compression-benchmarks/test_parquet_compression_methods.py +0 -0
  79. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-spread-analysis/01-methodology.md +0 -0
  80. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-spread-analysis/02-mode-truncated-analysis.md +0 -0
  81. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-spread-analysis/03-hurdle-model-analysis.md +0 -0
  82. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-spread-analysis/04-temporal-patterns.md +0 -0
  83. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-spread-analysis/05-final-recommendations.md +0 -0
  84. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-spread-analysis/README.md +0 -0
  85. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-spread-analysis/scripts/reproduction_guide.md +0 -0
  86. {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
  87. {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
  88. {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
  89. {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
  90. {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
  91. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-spread-analysis/visualizations/temporal/concentration_curve.png +0 -0
  92. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-spread-analysis/visualizations/temporal/percentile_analysis.png +0 -0
  93. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-zero-spread-deviations/01-methodology.md +0 -0
  94. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-zero-spread-deviations/02-baseline-sep2024.md +0 -0
  95. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-zero-spread-deviations/03-multiperiod-validation.md +0 -0
  96. {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
  97. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-zero-spread-deviations/README.md +0 -0
  98. {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
  99. {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
  100. {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
  101. {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
  102. {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
  103. {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
  104. {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
  105. {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
  106. {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
  107. {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
  108. {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
  109. {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
  110. {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
  111. {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
  112. {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
  113. {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
  114. {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
  115. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/docs/research/eurusd-zero-spread-deviations/scripts/reproduction_guide.md +0 -0
  116. {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
  117. {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
  118. {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
  119. {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
  120. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/src/exness_data_preprocess/cli.py +0 -0
  121. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/tests/__init__.py +0 -0
  122. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/tests/archive/E2E_TESTING_PLAN_v1.0.0.md +0 -0
  123. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/tests/test_basic.py +0 -0
  124. {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.4.0}/tests/test_types.py +0 -0
@@ -1,6 +1,6 @@
1
1
  [tool.commitizen]
2
2
  name = "cz_conventional_commits"
3
- version = "0.2.0"
3
+ version = "0.4.0"
4
4
  tag_format = "v$major.$minor.$patch"
5
5
  update_changelog_on_bump = true
6
6
  version_files = [
@@ -72,6 +72,7 @@ data/
72
72
  *.zip
73
73
  *.csv
74
74
  temp/
75
+ eurusd
75
76
 
76
77
  # macOS
77
78
  .DS_Store
@@ -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 9-column OHLC schema with dual-variant spreads
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.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
  [![Downloads](https://img.shields.io/pypi/dm/exness-data-preprocess.svg)](https://pypi.org/project/exness-data-preprocess/)
56
57
  [![Code style: ruff](https://img.shields.io/badge/code%20style-ruff-000000.svg)](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 13-column OHLC schema (v1.2.0) with sub-15ms query performance.
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**: 13-column bars (v1.2.0) with dual spreads, tick counts, and normalized metrics
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 13-Column OHLC Generation (v1.2.0 - dual spreads, tick counts, normalized metrics)
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 13-column schema (v1.2.0)
155
+ - `ohlc_1m` table: Phase7 30-column schema (v1.6.0)
154
156
  - `metadata` table: Coverage tracking
155
157
 
156
- **Phase7 13-Column OHLC (v1.2.0)**:
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) and normalized spread metrics
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 | Value |
408
- |--------|-------|
409
- | Raw_Spread ticks | ~18.6M |
410
- | Standard ticks | ~19.6M |
411
- | OHLC bars (1m) | ~413K |
412
- | Database size | ~2.08 GB |
413
- | Date range | 2022-01-01 to 2025-01-10 |
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 | Time |
418
- |-----------|------|
422
+ | Operation | Time |
423
+ | -------------------------- | ----- |
419
424
  | Query 880K ticks (1 month) | <15ms |
420
- | Query 1m OHLC (1 month) | <10ms |
421
- | Resample to 1h (1 month) | <15ms |
422
- | Resample to 1d (1 year) | <20ms |
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 | Benefit |
427
- |---------|---------|
428
- | Single file per instrument | Unified storage, no file fragmentation |
429
- | PRIMARY KEY constraints | Prevents duplicates during incremental updates |
430
- | Automatic gap detection | Download only missing months |
431
- | Dual-variant storage | Raw_Spread + Standard in same database |
432
- | Phase7 OHLC schema | Dual spreads + dual tick counts |
433
- | Date range queries | Efficient filtering without loading entire dataset |
434
- | On-demand resampling | Any timeframe in <15ms |
435
- | SQL filter support | Direct SQL WHERE clauses on ticks |
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
  [![Downloads](https://img.shields.io/pypi/dm/exness-data-preprocess.svg)](https://pypi.org/project/exness-data-preprocess/)
8
8
  [![Code style: ruff](https://img.shields.io/badge/code%20style-ruff-000000.svg)](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 13-column OHLC schema (v1.2.0) with sub-15ms query performance.
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**: 13-column bars (v1.2.0) with dual spreads, tick counts, and normalized metrics
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 13-Column OHLC Generation (v1.2.0 - dual spreads, tick counts, normalized metrics)
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 13-column schema (v1.2.0)
106
+ - `ohlc_1m` table: Phase7 30-column schema (v1.6.0)
106
107
  - `metadata` table: Coverage tracking
107
108
 
108
- **Phase7 13-Column OHLC (v1.2.0)**:
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) and normalized spread metrics
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 | Value |
360
- |--------|-------|
361
- | Raw_Spread ticks | ~18.6M |
362
- | Standard ticks | ~19.6M |
363
- | OHLC bars (1m) | ~413K |
364
- | Database size | ~2.08 GB |
365
- | Date range | 2022-01-01 to 2025-01-10 |
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 | Time |
370
- |-----------|------|
373
+ | Operation | Time |
374
+ | -------------------------- | ----- |
371
375
  | Query 880K ticks (1 month) | <15ms |
372
- | Query 1m OHLC (1 month) | <10ms |
373
- | Resample to 1h (1 month) | <15ms |
374
- | Resample to 1d (1 year) | <20ms |
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 | Benefit |
379
- |---------|---------|
380
- | Single file per instrument | Unified storage, no file fragmentation |
381
- | PRIMARY KEY constraints | Prevents duplicates during incremental updates |
382
- | Automatic gap detection | Download only missing months |
383
- | Dual-variant storage | Raw_Spread + Standard in same database |
384
- | Phase7 OHLC schema | Dual spreads + dual tick counts |
385
- | Date range queries | Efficient filtering without loading entire dataset |
386
- | On-demand resampling | Any timeframe in <15ms |
387
- | SQL filter support | Direct SQL WHERE clauses on ticks |
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