exness-data-preprocess 0.3.0__tar.gz → 0.3.1__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.3.1}/.cz.toml +1 -1
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/.gitignore +1 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/CHANGELOG.md +7 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/CLAUDE.md +112 -41
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/GITHUB_PYPI_SETUP.md +1 -1
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/PKG-INFO +8 -7
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/PYDANTIC_REFACTORING_PLAN.md +9 -10
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/README.md +6 -6
- exness_data_preprocess-0.3.1/RELEASE_NOTES.md +6 -0
- exness_data_preprocess-0.3.1/cliff-release-notes.toml +131 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/docs/DATABASE_SCHEMA.md +122 -26
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/docs/README.md +32 -3
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/docs/UNIFIED_DUCKDB_PLAN_v2.md +2 -2
- exness_data_preprocess-0.3.1/docs/plans/PHASE7_v1.5.0_REFACTORING_PLAN.md +544 -0
- exness_data_preprocess-0.3.1/docs/plans/PHASE7_v1.6.0_REFACTORING_PROGRESS.md +1119 -0
- exness_data_preprocess-0.3.1/docs/plans/REFACTORING_CHECKLIST.md +202 -0
- exness_data_preprocess-0.3.1/docs/plans/SESSION_2025-10-15_SUMMARY.md +305 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/pyproject.toml +2 -1
- exness_data_preprocess-0.3.1/src/exness_data_preprocess/database_manager.py +208 -0
- exness_data_preprocess-0.3.1/src/exness_data_preprocess/downloader.py +82 -0
- exness_data_preprocess-0.3.1/src/exness_data_preprocess/exchanges.py +164 -0
- exness_data_preprocess-0.3.1/src/exness_data_preprocess/gap_detector.py +157 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/src/exness_data_preprocess/models.py +1 -3
- exness_data_preprocess-0.3.1/src/exness_data_preprocess/ohlc_generator.py +199 -0
- exness_data_preprocess-0.3.1/src/exness_data_preprocess/processor.py +412 -0
- exness_data_preprocess-0.3.1/src/exness_data_preprocess/query_engine.py +290 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/src/exness_data_preprocess/schema.py +77 -11
- exness_data_preprocess-0.3.1/src/exness_data_preprocess/session_detector.py +121 -0
- exness_data_preprocess-0.3.1/src/exness_data_preprocess/tick_loader.py +67 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/tests/README.md +2 -2
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/tests/conftest.py +2 -5
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/tests/test_functional_regression.py +12 -18
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/tests/test_models.py +8 -3
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/tests/test_processor_pydantic.py +3 -2
- 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.3.1}/.github/workflows/ci.yml +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/.github/workflows/pre-commit-autoupdate.yml +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/.github/workflows/publish.yml +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/.pre-commit-config.yaml +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/AUTHORS.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/CONTRIBUTING.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/LICENSE +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/PYDANTIC_REFACTORING_STATUS.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/cliff.toml +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/docs/EXNESS_DATA_SOURCES.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/docs/archive/UNIFIED_DUCKDB_PLAN_v1.0.0_LEGACY.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/docs/implementation-plan.yaml +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/docs/planning-index.yaml +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/docs/research/compression-benchmarks/README.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/docs/research/compression-benchmarks/test_all_compression_methods.py +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/docs/research/compression-benchmarks/test_delta_encoding_properly.py +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/docs/research/compression-benchmarks/test_parquet_compression_methods.py +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/docs/research/eurusd-spread-analysis/01-methodology.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/docs/research/eurusd-spread-analysis/02-mode-truncated-analysis.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/docs/research/eurusd-spread-analysis/03-hurdle-model-analysis.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/docs/research/eurusd-spread-analysis/04-temporal-patterns.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/docs/research/eurusd-spread-analysis/05-final-recommendations.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/docs/research/eurusd-spread-analysis/README.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/docs/research/eurusd-spread-analysis/scripts/reproduction_guide.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/docs/research/eurusd-spread-analysis/visualizations/hurdle-model/hurdle_decomposition.png +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/docs/research/eurusd-spread-analysis/visualizations/mode-truncated/cv_mode_comparison.png +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/docs/research/eurusd-spread-analysis/visualizations/mode-truncated/distribution_overlay.png +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/docs/research/eurusd-spread-analysis/visualizations/mode-truncated/signal_quality_comparison.png +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/docs/research/eurusd-spread-analysis/visualizations/mode-truncated/variance_decomposition.png +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/docs/research/eurusd-spread-analysis/visualizations/temporal/concentration_curve.png +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/docs/research/eurusd-spread-analysis/visualizations/temporal/percentile_analysis.png +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/docs/research/eurusd-zero-spread-deviations/01-methodology.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/docs/research/eurusd-zero-spread-deviations/02-baseline-sep2024.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/docs/research/eurusd-zero-spread-deviations/03-multiperiod-validation.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/docs/research/eurusd-zero-spread-deviations/04-discoveries-and-plan-evolution.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/docs/research/eurusd-zero-spread-deviations/README.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/docs/research/eurusd-zero-spread-deviations/findings/baseline-sep2024-comprehensive-summary.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/docs/research/eurusd-zero-spread-deviations/findings/phase2-mean-reversion-report.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/docs/research/eurusd-zero-spread-deviations/findings/phase3-volatility-model-report.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/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.3.1}/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.3.1}/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.3.1}/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.3.1}/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.3.1}/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.3.1}/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.3.1}/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.3.1}/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.3.1}/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.3.1}/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.3.1}/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.3.1}/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.3.1}/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.3.1}/docs/research/eurusd-zero-spread-deviations/scripts/reproduction_guide.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/docs/research/eurusd-zero-spread-deviations/scripts/visualization/diagnostic_burst_decay.py +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/docs/research/eurusd-zero-spread-deviations/scripts/visualization/generate_interactive_dashboard.py +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/docs/research/eurusd-zero-spread-deviations/scripts/visualization/generate_lightweight_dashboard.py +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/docs/research/eurusd-zero-spread-deviations/scripts/visualization/prepare_visualization_data.py +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/examples/basic_usage.py +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/examples/batch_processing.py +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/src/exness_data_preprocess/__init__.py +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/src/exness_data_preprocess/cli.py +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/tests/__init__.py +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/tests/archive/E2E_TESTING_PLAN_v1.0.0.md +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/tests/test_basic.py +0 -0
- {exness_data_preprocess-0.3.0 → exness_data_preprocess-0.3.1}/tests/test_types.py +0 -0
|
@@ -6,6 +6,11 @@ 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
|
+
|
|
9
14
|
### ✨ Features
|
|
10
15
|
|
|
11
16
|
- 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)
|
|
@@ -20,6 +25,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
20
25
|
|
|
21
26
|
- **release**: Bump version 0.1.0 → 0.2.0 [skip ci]
|
|
22
27
|
|
|
28
|
+
- **release**: Bump version 0.2.0 → 0.3.0 [skip ci]
|
|
29
|
+
|
|
23
30
|
|
|
24
31
|
### ✨ Features
|
|
25
32
|
|
|
@@ -68,45 +68,105 @@ doppler run --project claude-config --config dev -- uv publish --token "$PYPI_TO
|
|
|
68
68
|
|
|
69
69
|
## Codebase Architecture
|
|
70
70
|
|
|
71
|
-
### Module Structure
|
|
72
|
-
|
|
73
|
-
**
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
- **
|
|
79
|
-
- **
|
|
80
|
-
- **Lines
|
|
81
|
-
- **Lines
|
|
82
|
-
- **Lines
|
|
83
|
-
- **Lines
|
|
84
|
-
- **Lines
|
|
85
|
-
- **Lines
|
|
86
|
-
- **Lines
|
|
87
|
-
- **Lines
|
|
88
|
-
|
|
89
|
-
|
|
71
|
+
### Module Structure (v1.3.0 - Facade Pattern)
|
|
72
|
+
|
|
73
|
+
**Architecture**: Thin facade orchestrator with 7 focused modules (414 lines processor, 1,146 lines extracted)
|
|
74
|
+
|
|
75
|
+
**Core Facade**:
|
|
76
|
+
|
|
77
|
+
1. **`processor.py`** (`/Users/terryli/eon/exness-data-preprocess/src/exness_data_preprocess/processor.py`) - Thin orchestrator facade (414 lines)
|
|
78
|
+
- **Responsibility**: Coordinate workflow, delegate to specialized modules
|
|
79
|
+
- **Pattern**: Facade pattern - all public methods delegate to modules
|
|
80
|
+
- **Lines 76-110**: `__init__()` - Initialize 7 module dependencies
|
|
81
|
+
- **Lines 111-132**: `download_exness_zip()` - Delegates to downloader module
|
|
82
|
+
- **Lines 134-145**: `_get_or_create_db()` - Delegates to database_manager module
|
|
83
|
+
- **Lines 147-150**: `_load_ticks_from_zip()` - Delegates to tick_loader module
|
|
84
|
+
- **Lines 152-162**: `_append_ticks_to_db()` - Delegates to database_manager module
|
|
85
|
+
- **Lines 164-176**: `_discover_missing_months()` - Delegates to gap_detector module
|
|
86
|
+
- **Lines 178-315**: `update_data()` - Main workflow orchestrator
|
|
87
|
+
- **Lines 317-326**: `_regenerate_ohlc()` - Delegates to ohlc_generator module
|
|
88
|
+
- **Lines 328-357**: `query_ticks()` - Delegates to query_engine module
|
|
89
|
+
- **Lines 359-386**: `query_ohlc()` - Delegates to query_engine module
|
|
90
|
+
- **Lines 388-414**: `get_data_coverage()` - Delegates to query_engine module
|
|
91
|
+
|
|
92
|
+
**Specialized Modules**:
|
|
93
|
+
|
|
94
|
+
2. **`downloader.py`** (`/Users/terryli/eon/exness-data-preprocess/src/exness_data_preprocess/downloader.py`) - HTTP download operations (89 lines)
|
|
95
|
+
- **Responsibility**: Download Exness ZIP files from ticks.ex2archive.com
|
|
96
|
+
- **SLOs**: Availability (raise on failure), Correctness (URL patterns), Observability (logging), Maintainability (httpx library)
|
|
97
|
+
- **Class**: `ExnessDownloader`
|
|
98
|
+
- **Methods**: `download_zip(year, month, pair, variant)`
|
|
99
|
+
|
|
100
|
+
3. **`tick_loader.py`** (`/Users/terryli/eon/exness-data-preprocess/src/exness_data_preprocess/tick_loader.py`) - CSV parsing (67 lines)
|
|
101
|
+
- **Responsibility**: Load tick data from ZIP files into pandas DataFrames
|
|
102
|
+
- **SLOs**: Availability (raise on failure), Correctness (timestamp parsing), Observability (logging), Maintainability (pandas library)
|
|
103
|
+
- **Class**: `TickLoader`
|
|
104
|
+
- **Methods**: `load_from_zip(zip_path)` (static method)
|
|
105
|
+
|
|
106
|
+
4. **`database_manager.py`** (`/Users/terryli/eon/exness-data-preprocess/src/exness_data_preprocess/database_manager.py`) - Database operations (213 lines)
|
|
107
|
+
- **Responsibility**: Database initialization, schema creation, tick insertion with PRIMARY KEY duplicate prevention
|
|
108
|
+
- **SLOs**: Availability (raise on failure), Correctness (schema integrity), Observability (DuckDB logging), Maintainability (DuckDB library)
|
|
109
|
+
- **Class**: `DatabaseManager`
|
|
110
|
+
- **Methods**: `get_or_create_db(pair)`, `append_ticks(duckdb_path, df, table_name)`
|
|
111
|
+
|
|
112
|
+
5. **`session_detector.py`** (`/Users/terryli/eon/exness-data-preprocess/src/exness_data_preprocess/session_detector.py`) - Holiday and session detection (121 lines)
|
|
113
|
+
- **Responsibility**: Detect holidays (US, UK, major) and trading sessions for 10 global exchanges using exchange_calendars
|
|
114
|
+
- **SLOs**: Availability (raise on failure), Correctness (official calendars), Observability (logging), Maintainability (exchange_calendars library)
|
|
115
|
+
- **Class**: `SessionDetector`
|
|
116
|
+
- **Methods**: `detect_sessions_and_holidays(dates_df)`
|
|
117
|
+
|
|
118
|
+
6. **`gap_detector.py`** (`/Users/terryli/eon/exness-data-preprocess/src/exness_data_preprocess/gap_detector.py`) - Incremental update logic (163 lines)
|
|
119
|
+
- **Responsibility**: Discover missing months for incremental database updates
|
|
120
|
+
- **SLOs**: Availability (raise on failure), Correctness (gap detection), Observability (logging), Maintainability (DuckDB library)
|
|
121
|
+
- **Class**: `GapDetector`
|
|
122
|
+
- **Methods**: `discover_missing_months(pair, start_date)`
|
|
123
|
+
|
|
124
|
+
7. **`ohlc_generator.py`** (`/Users/terryli/eon/exness-data-preprocess/src/exness_data_preprocess/ohlc_generator.py`) - OHLC generation (210 lines)
|
|
125
|
+
- **Responsibility**: Generate Phase7 30-column OHLC from dual-variant tick data with LEFT JOIN, normalized metrics, and exchange session detection
|
|
126
|
+
- **SLOs**: Availability (raise on failure), Correctness (Phase7 schema), Observability (logging), Maintainability (DuckDB + exchange_calendars)
|
|
127
|
+
- **Class**: `OHLCGenerator`
|
|
128
|
+
- **Methods**: `regenerate_ohlc(duckdb_path)`
|
|
129
|
+
|
|
130
|
+
8. **`query_engine.py`** (`/Users/terryli/eon/exness-data-preprocess/src/exness_data_preprocess/query_engine.py`) - Query operations (283 lines)
|
|
131
|
+
- **Responsibility**: Query tick and OHLC data with date filtering, SQL filters, and on-demand resampling (1m/5m/15m/1h/4h/1d)
|
|
132
|
+
- **SLOs**: Availability (raise on failure), Correctness (SQL queries), Observability (DuckDB logging), Maintainability (DuckDB library)
|
|
133
|
+
- **Class**: `QueryEngine`
|
|
134
|
+
- **Methods**: `query_ticks()`, `query_ohlc()`, `get_data_coverage()`
|
|
135
|
+
|
|
136
|
+
**Legacy Components**:
|
|
137
|
+
|
|
138
|
+
9. **`api.py`** (`/Users/terryli/eon/exness-data-preprocess/src/exness_data_preprocess/api.py`) - Simple wrapper functions
|
|
90
139
|
- Convenience functions wrapping `ExnessDataProcessor` methods
|
|
91
140
|
- Legacy v1.0.0 API compatibility layer (to be deprecated)
|
|
92
141
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
142
|
+
10. **`cli.py`** (`/Users/terryli/eon/exness-data-preprocess/src/exness_data_preprocess/cli.py`) - Command-line interface
|
|
143
|
+
- Entry point: `exness-preprocess` command
|
|
144
|
+
- Commands for download, query, coverage operations
|
|
96
145
|
|
|
97
146
|
### Key Design Patterns
|
|
98
147
|
|
|
148
|
+
**Facade Pattern** (v1.3.0):
|
|
149
|
+
- **processor.py** is a thin orchestrator (414 lines) coordinating 7 specialized modules
|
|
150
|
+
- All public methods delegate to modules (no business logic in processor)
|
|
151
|
+
- **Separation of concerns**: Each module has single responsibility
|
|
152
|
+
- **SLO-based design**: All modules define SLOs (Availability, Correctness, Observability, Maintainability)
|
|
153
|
+
- **Zero regressions**: All 48 tests pass after 7-module extraction (53% line reduction)
|
|
154
|
+
- **Off-the-shelf libraries**: httpx, pandas, DuckDB, exchange_calendars (no custom implementations)
|
|
155
|
+
|
|
99
156
|
**Unified Single-File Architecture** (v2.0.0):
|
|
100
157
|
- ONE DuckDB file per instrument (e.g., `eurusd.duckdb`) containing all historical data
|
|
101
158
|
- NO monthly file separation (major change from v1.0.0)
|
|
102
159
|
- Incremental updates with automatic gap detection
|
|
103
160
|
- PRIMARY KEY constraints prevent duplicates during updates
|
|
104
161
|
|
|
105
|
-
**Phase7
|
|
162
|
+
**Phase7 30-Column OHLC Schema** (v1.5.0):
|
|
106
163
|
- BID-only OHLC from Raw_Spread variant
|
|
107
164
|
- Dual spreads: `raw_spread_avg` and `standard_spread_avg`
|
|
108
165
|
- Dual tick counts: `tick_count_raw_spread` and `tick_count_standard`
|
|
109
166
|
- Normalized metrics: `range_per_spread`, `range_per_tick`, `body_per_spread`, `body_per_tick`
|
|
167
|
+
- Timezone/session tracking: `ny_hour`, `london_hour`, `ny_session`, `london_session` (v1.3.0+)
|
|
168
|
+
- Holiday tracking: `is_us_holiday`, `is_uk_holiday`, `is_major_holiday` (v1.4.0+)
|
|
169
|
+
- Global exchange sessions: 10 binary flags (`is_nyse_session`, `is_lse_session`, `is_xswx_session`, `is_xfra_session`, `is_xtse_session`, `is_xnze_session`, `is_xtks_session`, `is_xasx_session`, `is_xhkg_session`, `is_xses_session`) covering 24-hour forex trading (v1.5.0)
|
|
110
170
|
- Generated via LEFT JOIN between Raw_Spread and Standard variants
|
|
111
171
|
|
|
112
172
|
**Self-Documentation**:
|
|
@@ -114,14 +174,16 @@ doppler run --project claude-config --config dev -- uv publish --token "$PYPI_TO
|
|
|
114
174
|
- Queryable via `duckdb_tables()` and `duckdb_columns()` system functions
|
|
115
175
|
- Enables BI tools and IDEs to display inline help
|
|
116
176
|
|
|
117
|
-
**Data Flow
|
|
177
|
+
**Data Flow** (Module-Based Architecture v1.3.0):
|
|
118
178
|
```
|
|
119
179
|
Exness Repository (monthly ZIPs)
|
|
120
|
-
→
|
|
121
|
-
→
|
|
122
|
-
→
|
|
123
|
-
→
|
|
124
|
-
→
|
|
180
|
+
→ gap_detector.py (discover missing months)
|
|
181
|
+
→ downloader.py (download Raw_Spread + Standard)
|
|
182
|
+
→ tick_loader.py (parse CSV from ZIP)
|
|
183
|
+
→ database_manager.py (append to DuckDB, PRIMARY KEY prevents duplicates)
|
|
184
|
+
→ ohlc_generator.py (Phase7 30-column OHLC with LEFT JOIN)
|
|
185
|
+
→ session_detector.py (holidays + 10 exchange sessions)
|
|
186
|
+
→ query_engine.py (tick/OHLC queries, date filters, resampling)
|
|
125
187
|
```
|
|
126
188
|
|
|
127
189
|
### Database Schema (per instrument)
|
|
@@ -139,8 +201,8 @@ Each `.duckdb` file contains:
|
|
|
139
201
|
- Reference data for spread comparison
|
|
140
202
|
|
|
141
203
|
3. **`ohlc_1m`** table:
|
|
142
|
-
- **Schema**: Phase7
|
|
143
|
-
- **Details**: BID-only OHLC with dual-variant spreads, tick counts, and
|
|
204
|
+
- **Schema**: Phase7 30-column (v1.5.0) - See [`schema.py`](src/exness_data_preprocess/schema.py)
|
|
205
|
+
- **Details**: BID-only OHLC with dual-variant spreads, tick counts, normalized metrics, and 10 global exchange sessions
|
|
144
206
|
- **Reference**: [`DATABASE_SCHEMA.md`](docs/DATABASE_SCHEMA.md)
|
|
145
207
|
|
|
146
208
|
4. **`metadata`** table:
|
|
@@ -180,7 +242,7 @@ Each `.duckdb` file contains:
|
|
|
180
242
|
- ✅ **Dual-variant storage**: Raw_Spread + Standard in same database
|
|
181
243
|
- ✅ **PRIMARY KEY constraints**: Prevents duplicates during incremental updates
|
|
182
244
|
- ✅ **Automatic gap detection**: Downloads only missing months
|
|
183
|
-
- ✅ **Phase7
|
|
245
|
+
- ✅ **Phase7 30-column OHLC (v1.5.0)**: Dual spreads + dual tick counts + 10 global exchange sessions
|
|
184
246
|
- ✅ **Date range queries**: Sub-15ms query performance
|
|
185
247
|
- ✅ **On-demand resampling**: Any timeframe (5m, 1h, 1d) in <15ms
|
|
186
248
|
|
|
@@ -207,21 +269,29 @@ Each `.duckdb` file contains:
|
|
|
207
269
|
- `/tmp/exness-duckdb-test/test_refactored_processor.py` - Validation test
|
|
208
270
|
- `/tmp/exness-duckdb-test/test_queries_only.py` - Query validation test
|
|
209
271
|
|
|
210
|
-
### Phase7
|
|
272
|
+
### Phase7 30-Column OHLC Schema v1.5.0 (✅ Implemented)
|
|
211
273
|
|
|
212
|
-
**Decision**: Dual-variant BID-only OHLC with
|
|
274
|
+
**Decision**: Dual-variant BID-only OHLC with 30 columns capturing Raw_Spread and Standard characteristics, normalized metrics, and 10 global exchange sessions
|
|
213
275
|
|
|
214
|
-
**Schema**: Phase7
|
|
276
|
+
**Schema**: Phase7 30-column (v1.5.0)
|
|
215
277
|
- **Definition**: See [`schema.py`](src/exness_data_preprocess/schema.py)
|
|
216
278
|
- **Documentation**: See [`DATABASE_SCHEMA.md`](docs/DATABASE_SCHEMA.md)
|
|
279
|
+
- **Architecture**: Exchange Registry Pattern for dynamic session column generation
|
|
217
280
|
|
|
218
281
|
**Key Features**:
|
|
219
282
|
- ✅ **BID-only OHLC**: Uses Raw_Spread Bid prices (execution prices)
|
|
220
283
|
- ✅ **Dual spreads**: Tracks both Raw_Spread (zero-spreads) and Standard (market spreads)
|
|
221
284
|
- ✅ **Dual tick counts**: Records tick counts from both variants
|
|
285
|
+
- ✅ **Normalized metrics** (v1.2.0): range_per_spread, range_per_tick, body_per_spread, body_per_tick
|
|
286
|
+
- ✅ **Timezone/session tracking** (v1.3.0): ny_hour, london_hour, ny_session, london_session with automatic DST handling
|
|
287
|
+
- ✅ **Holiday tracking** (v1.4.0): is_us_holiday, is_uk_holiday, is_major_holiday via exchange_calendars
|
|
288
|
+
- ✅ **10 Global Exchange Sessions** (v1.5.0): is_nyse_session, is_lse_session, is_xswx_session, is_xfra_session, is_xtse_session, is_xnze_session, is_xtks_session, is_xasx_session, is_xhkg_session, is_xses_session covering 24-hour forex trading
|
|
222
289
|
- ✅ **LEFT JOIN methodology**: Raw_Spread primary, Standard reference
|
|
223
290
|
|
|
224
|
-
**Implementation**:
|
|
291
|
+
**Implementation**:
|
|
292
|
+
- **OHLC Generation**: [`src/exness_data_preprocess/ohlc_generator.py`](src/exness_data_preprocess/ohlc_generator.py) (210 lines)
|
|
293
|
+
- **Session Detection**: [`src/exness_data_preprocess/session_detector.py`](src/exness_data_preprocess/session_detector.py) (121 lines)
|
|
294
|
+
- **Orchestration**: [`src/exness_data_preprocess/processor.py`](src/exness_data_preprocess/processor.py) (lines 317-326, delegation)
|
|
225
295
|
|
|
226
296
|
**Specification**: [`docs/research/eurusd-zero-spread-deviations/data/plan/phase7_bid_ohlc_construction_v1.1.0.md`](docs/research/eurusd-zero-spread-deviations/data/plan/phase7_bid_ohlc_construction_v1.1.0.md)
|
|
227
297
|
|
|
@@ -256,7 +326,7 @@ SELECT table_name, column_name, data_type, comment FROM duckdb_columns();
|
|
|
256
326
|
- `add_schema_comments(pair)` - Add comments to single database
|
|
257
327
|
- `add_schema_comments_all()` - Batch-update all databases
|
|
258
328
|
|
|
259
|
-
**Implementation**: [`src/exness_data_preprocess/
|
|
329
|
+
**Implementation**: [`src/exness_data_preprocess/database_manager.py`](src/exness_data_preprocess/database_manager.py) (schema comments in get_or_create_db method)
|
|
260
330
|
|
|
261
331
|
**Usage Example**: [`examples/add_schema_comments.py`](examples/add_schema_comments.py)
|
|
262
332
|
|
|
@@ -314,7 +384,7 @@ SELECT table_name, column_name, data_type, comment FROM duckdb_columns();
|
|
|
314
384
|
- ✅ **Dual-variant storage** - Raw_Spread + Standard in same database
|
|
315
385
|
- ✅ **PRIMARY KEY constraints** - Prevents duplicates during incremental updates
|
|
316
386
|
- ✅ **Automatic gap detection** - Downloads only missing months
|
|
317
|
-
- ✅ **Phase7
|
|
387
|
+
- ✅ **Phase7 30-column OHLC (v1.5.0)** - Dual spreads + dual tick counts + 10 global exchange sessions
|
|
318
388
|
- ✅ **Date range queries** - Sub-15ms query performance
|
|
319
389
|
- ✅ **On-demand resampling** - Any timeframe in <15ms
|
|
320
390
|
- ✅ **SQL filter support** - Direct SQL WHERE clauses on ticks
|
|
@@ -359,7 +429,7 @@ SELECT table_name, column_name, data_type, comment FROM duckdb_columns();
|
|
|
359
429
|
eurusd.duckdb:
|
|
360
430
|
├── raw_spread_ticks # Timestamp (PK), Bid, Ask
|
|
361
431
|
├── standard_ticks # Timestamp (PK), Bid, Ask
|
|
362
|
-
├── ohlc_1m # Phase7
|
|
432
|
+
├── ohlc_1m # Phase7 30-column schema (v1.5.0)
|
|
363
433
|
└── metadata # Coverage tracking
|
|
364
434
|
```
|
|
365
435
|
|
|
@@ -399,6 +469,7 @@ eurusd.duckdb:
|
|
|
399
469
|
|
|
400
470
|
---
|
|
401
471
|
|
|
402
|
-
**Version**: 2.0.0
|
|
403
|
-
**Last Updated**: 2025-10-
|
|
472
|
+
**Version**: 2.0.0 (Architecture) + 1.3.0 (Implementation)
|
|
473
|
+
**Last Updated**: 2025-10-15
|
|
404
474
|
**Architecture**: Unified Single-File DuckDB Storage with Incremental Updates
|
|
475
|
+
**Implementation**: Facade Pattern with 7 Specialized Modules (Phase 1-4 Complete)
|
|
@@ -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
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: exness-data-preprocess
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.1
|
|
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.5.0) with 10 global exchange sessions 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.5.0) with dual spreads, tick counts, normalized metrics, and 10 global exchange sessions
|
|
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.5.0 - dual spreads, tick counts, normalized metrics, 10 global exchange sessions)
|
|
142
143
|
↓
|
|
143
144
|
Query Interface (date ranges, SQL filters, on-demand resampling)
|
|
144
145
|
```
|
|
@@ -150,13 +151,13 @@ Query Interface (date ranges, SQL filters, on-demand resampling)
|
|
|
150
151
|
**Schema**:
|
|
151
152
|
- `raw_spread_ticks` table: Timestamp (PK), Bid, Ask
|
|
152
153
|
- `standard_ticks` table: Timestamp (PK), Bid, Ask
|
|
153
|
-
- `ohlc_1m` table: Phase7
|
|
154
|
+
- `ohlc_1m` table: Phase7 30-column schema (v1.5.0)
|
|
154
155
|
- `metadata` table: Coverage tracking
|
|
155
156
|
|
|
156
|
-
**Phase7
|
|
157
|
+
**Phase7 30-Column OHLC (v1.5.0)**:
|
|
157
158
|
- **Column Definitions**: See [`schema.py`](src/exness_data_preprocess/schema.py) - Single source of truth
|
|
158
159
|
- **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)
|
|
160
|
+
- **Key Features**: BID-only OHLC with dual spreads (Raw_Spread + Standard), normalized spread metrics, and 10 global exchange sessions (XNYS, XLON, XSWX, XFRA, XTSE, XNZE, XTKS, XASX, XHKG, XSES)
|
|
160
161
|
|
|
161
162
|
### Directory Structure
|
|
162
163
|
|
|
@@ -159,7 +159,7 @@ class UpdateResult(BaseModel):
|
|
|
159
159
|
)
|
|
160
160
|
ohlc_bars: int = Field(
|
|
161
161
|
ge=0,
|
|
162
|
-
description="Total 1-minute OHLC bars in database (Phase7
|
|
162
|
+
description="Total 1-minute OHLC bars in database (Phase7 13-column v1.2.0 schema)"
|
|
163
163
|
)
|
|
164
164
|
duckdb_size_mb: float = Field(
|
|
165
165
|
ge=0,
|
|
@@ -347,7 +347,7 @@ def update_data(
|
|
|
347
347
|
1. Discover missing months between start_date and current month
|
|
348
348
|
2. Download missing months from ticks.ex2archive.com (both variants)
|
|
349
349
|
3. Insert ticks into DuckDB with PRIMARY KEY duplicate prevention
|
|
350
|
-
4. Regenerate Phase7
|
|
350
|
+
4. Regenerate Phase7 13-column (v1.2.0) OHLC with dual spreads and normalized metrics
|
|
351
351
|
5. Update metadata table with coverage statistics
|
|
352
352
|
|
|
353
353
|
Args:
|
|
@@ -559,13 +559,12 @@ def query_ohlc(
|
|
|
559
559
|
timeframes. All resampling is performed in-database using DuckDB's window
|
|
560
560
|
functions for optimal performance (<15ms for most queries).
|
|
561
561
|
|
|
562
|
-
The returned DataFrame contains Phase7
|
|
563
|
-
-
|
|
564
|
-
- Open, High, Low, Close
|
|
565
|
-
-
|
|
566
|
-
-
|
|
567
|
-
-
|
|
568
|
-
- tick_count_standard: Tick count from Standard variant
|
|
562
|
+
The returned DataFrame contains Phase7 13-column (v1.2.0) schema:
|
|
563
|
+
- See schema.py for complete 13-column definition
|
|
564
|
+
- Core: Timestamp, Open, High, Low, Close (BID prices from Raw_Spread)
|
|
565
|
+
- Dual Spreads: raw_spread_avg, standard_spread_avg
|
|
566
|
+
- Dual Tick Counts: tick_count_raw_spread, tick_count_standard
|
|
567
|
+
- Normalized Metrics: range_per_spread, range_per_tick, body_per_spread, body_per_tick
|
|
569
568
|
|
|
570
569
|
Args:
|
|
571
570
|
pair: Currency pair (EURUSD, GBPUSD, XAUUSD, USDJPY, AUDUSD)
|
|
@@ -574,7 +573,7 @@ def query_ohlc(
|
|
|
574
573
|
end_date: Optional end date in YYYY-MM-DD format (inclusive)
|
|
575
574
|
|
|
576
575
|
Returns:
|
|
577
|
-
DataFrame with Phase7
|
|
576
|
+
DataFrame with Phase7 13-column (v1.2.0) OHLC schema. Empty if no data in range.
|
|
578
577
|
|
|
579
578
|
Raises:
|
|
580
579
|
FileNotFoundError: If database doesn't exist (call update_data first)
|
|
@@ -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.5.0) with 10 global exchange sessions 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.5.0) with dual spreads, tick counts, normalized metrics, and 10 global exchange sessions
|
|
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.5.0 - dual spreads, tick counts, normalized metrics, 10 global exchange sessions)
|
|
94
94
|
↓
|
|
95
95
|
Query Interface (date ranges, SQL filters, on-demand resampling)
|
|
96
96
|
```
|
|
@@ -102,13 +102,13 @@ Query Interface (date ranges, SQL filters, on-demand resampling)
|
|
|
102
102
|
**Schema**:
|
|
103
103
|
- `raw_spread_ticks` table: Timestamp (PK), Bid, Ask
|
|
104
104
|
- `standard_ticks` table: Timestamp (PK), Bid, Ask
|
|
105
|
-
- `ohlc_1m` table: Phase7
|
|
105
|
+
- `ohlc_1m` table: Phase7 30-column schema (v1.5.0)
|
|
106
106
|
- `metadata` table: Coverage tracking
|
|
107
107
|
|
|
108
|
-
**Phase7
|
|
108
|
+
**Phase7 30-Column OHLC (v1.5.0)**:
|
|
109
109
|
- **Column Definitions**: See [`schema.py`](src/exness_data_preprocess/schema.py) - Single source of truth
|
|
110
110
|
- **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)
|
|
111
|
+
- **Key Features**: BID-only OHLC with dual spreads (Raw_Spread + Standard), normalized spread metrics, and 10 global exchange sessions (XNYS, XLON, XSWX, XFRA, XTSE, XNZE, XTKS, XASX, XHKG, XSES)
|
|
112
112
|
|
|
113
113
|
### Directory Structure
|
|
114
114
|
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# git-cliff configuration for GitHub release notes generation
|
|
2
|
+
# Optimized for user-friendly, marketing-style release announcements
|
|
3
|
+
|
|
4
|
+
[changelog]
|
|
5
|
+
header = ""
|
|
6
|
+
body = """
|
|
7
|
+
## {% if version %}{{ version | trim_start_matches(pat="v") }}{% else %}Unreleased{% endif %} - {{ timestamp | date(format="%Y-%m-%d") }}
|
|
8
|
+
|
|
9
|
+
{% for group, commits in commits | group_by(attribute="group") %}
|
|
10
|
+
### {{ group }}
|
|
11
|
+
{% for commit in commits | unique(attribute="message") %}
|
|
12
|
+
- {% if commit.breaking %}⚠️ **BREAKING**: {% endif %}\
|
|
13
|
+
{{ commit.message | upper_first }}\
|
|
14
|
+
{% if commit.github.username %} (by @{{ commit.github.username }}){% endif %}
|
|
15
|
+
{% endfor %}
|
|
16
|
+
|
|
17
|
+
{% endfor %}
|
|
18
|
+
---
|
|
19
|
+
**Full Changelog**: https://github.com/Eon-Labs/rangebar/compare/{{ previous.version }}...{{ version }}
|
|
20
|
+
"""
|
|
21
|
+
footer = ""
|
|
22
|
+
trim = true
|
|
23
|
+
|
|
24
|
+
[git]
|
|
25
|
+
conventional_commits = true
|
|
26
|
+
filter_unconventional = false
|
|
27
|
+
split_commits = false
|
|
28
|
+
tag_pattern = "v[0-9]*"
|
|
29
|
+
tag_prefix = "v"
|
|
30
|
+
skip_tags = ""
|
|
31
|
+
ignore_tags = ""
|
|
32
|
+
|
|
33
|
+
[[git.commit_parsers]]
|
|
34
|
+
# Breaking changes (most prominent)
|
|
35
|
+
message = "^.*!:"
|
|
36
|
+
group = "⚠️ Breaking Changes"
|
|
37
|
+
|
|
38
|
+
[[git.commit_parsers]]
|
|
39
|
+
body = ".*BREAKING[- ]CHANGE.*"
|
|
40
|
+
group = "⚠️ Breaking Changes"
|
|
41
|
+
|
|
42
|
+
# Features (user-facing semantic grouping)
|
|
43
|
+
[[git.commit_parsers]]
|
|
44
|
+
message = "^feat\\(sanitization\\)"
|
|
45
|
+
group = "🧹 Codebase Sanitization"
|
|
46
|
+
|
|
47
|
+
[[git.commit_parsers]]
|
|
48
|
+
message = "^feat\\(security\\)"
|
|
49
|
+
group = "🔒 Security Enhancements"
|
|
50
|
+
|
|
51
|
+
[[git.commit_parsers]]
|
|
52
|
+
message = "^feat\\(perf\\)"
|
|
53
|
+
group = "🚀 Performance Improvements"
|
|
54
|
+
|
|
55
|
+
[[git.commit_parsers]]
|
|
56
|
+
message = "^feat\\(deps\\)"
|
|
57
|
+
group = "📦 Dependency Management"
|
|
58
|
+
|
|
59
|
+
[[git.commit_parsers]]
|
|
60
|
+
message = "^feat"
|
|
61
|
+
group = "✨ New Features"
|
|
62
|
+
|
|
63
|
+
# Fixes (user-impacting only)
|
|
64
|
+
[[git.commit_parsers]]
|
|
65
|
+
message = "^fix\\(security\\)"
|
|
66
|
+
group = "🔒 Security Fixes"
|
|
67
|
+
|
|
68
|
+
[[git.commit_parsers]]
|
|
69
|
+
message = "^fix\\(perf\\)"
|
|
70
|
+
group = "🚀 Performance Fixes"
|
|
71
|
+
|
|
72
|
+
[[git.commit_parsers]]
|
|
73
|
+
message = "^fix"
|
|
74
|
+
group = "🐛 Bug Fixes & Improvements"
|
|
75
|
+
|
|
76
|
+
# Infrastructure (consolidated)
|
|
77
|
+
[[git.commit_parsers]]
|
|
78
|
+
message = "^(fix|feat)\\(ci\\)"
|
|
79
|
+
group = "🔧 Infrastructure & CI/CD"
|
|
80
|
+
|
|
81
|
+
[[git.commit_parsers]]
|
|
82
|
+
message = "^(fix|feat)\\(fmt\\)"
|
|
83
|
+
group = "🔧 Infrastructure & CI/CD"
|
|
84
|
+
|
|
85
|
+
[[git.commit_parsers]]
|
|
86
|
+
message = "^(fix|feat)\\(clippy\\)"
|
|
87
|
+
group = "🔧 Infrastructure & CI/CD"
|
|
88
|
+
|
|
89
|
+
# Skip non-user-facing commits (chore, docs, test, etc.)
|
|
90
|
+
[[git.commit_parsers]]
|
|
91
|
+
message = "^chore"
|
|
92
|
+
skip = true
|
|
93
|
+
|
|
94
|
+
[[git.commit_parsers]]
|
|
95
|
+
message = "^docs"
|
|
96
|
+
skip = true
|
|
97
|
+
|
|
98
|
+
[[git.commit_parsers]]
|
|
99
|
+
message = "^test"
|
|
100
|
+
skip = true
|
|
101
|
+
|
|
102
|
+
[[git.commit_parsers]]
|
|
103
|
+
message = "^build"
|
|
104
|
+
skip = true
|
|
105
|
+
|
|
106
|
+
[[git.commit_parsers]]
|
|
107
|
+
message = "^ci"
|
|
108
|
+
skip = true
|
|
109
|
+
|
|
110
|
+
[[git.commit_parsers]]
|
|
111
|
+
message = "^style"
|
|
112
|
+
skip = true
|
|
113
|
+
|
|
114
|
+
[[git.commit_parsers]]
|
|
115
|
+
message = "^refactor"
|
|
116
|
+
skip = true
|
|
117
|
+
|
|
118
|
+
# Catch-all for anything else
|
|
119
|
+
[[git.commit_parsers]]
|
|
120
|
+
message = ".*"
|
|
121
|
+
group = "📝 Other Changes"
|
|
122
|
+
|
|
123
|
+
[[git.commit_preprocessors]]
|
|
124
|
+
# Remove gitmoji to avoid duplication with our emoji groups
|
|
125
|
+
pattern = ':\w+:'
|
|
126
|
+
replace = ""
|
|
127
|
+
|
|
128
|
+
[[git.commit_preprocessors]]
|
|
129
|
+
# Clean up extra whitespace
|
|
130
|
+
pattern = '\s+'
|
|
131
|
+
replace = " "
|