exness-data-preprocess 2.1.1__tar.gz → 3.0.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-2.1.1 → exness_data_preprocess-3.0.1}/.github/workflows/publish.yml +4 -4
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/.prototools +1 -1
- exness_data_preprocess-3.0.1/.python-version +1 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/CHANGELOG.md +26 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/CLAUDE.md +3 -2
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/PKG-INFO +3 -3
- exness_data_preprocess-3.0.1/docs/release-notes/3.0.0.md +29 -0
- exness_data_preprocess-3.0.1/docs/release-notes/3.0.1.md +18 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/package-lock.json +210 -235
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/package.json +4 -4
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/pyproject.toml +3 -11
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/scripts/e2e-ephemeral.sh +2 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/scripts/publish-release-notes.sh +3 -1
- exness_data_preprocess-3.0.1/scripts/validate_clickhouse.py +388 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/src/exness_data_preprocess/clickhouse_manager.py +131 -26
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/src/exness_data_preprocess/clickhouse_ohlc_generator.py +70 -46
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/src/exness_data_preprocess/clickhouse_query_engine.py +77 -40
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/src/exness_data_preprocess/downloader.py +5 -1
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/src/exness_data_preprocess/models.py +7 -6
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/src/exness_data_preprocess/processor.py +36 -21
- exness_data_preprocess-3.0.1/tests/test_date_bounds.py +31 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/tests/test_package_structure.py +0 -1
- exness_data_preprocess-3.0.1/tests/test_tick_seq.py +53 -0
- exness_data_preprocess-2.1.1/.python-version +0 -1
- exness_data_preprocess-2.1.1/scripts/validate_clickhouse.py +0 -185
- exness_data_preprocess-2.1.1/src/exness_data_preprocess/config.py +0 -123
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/.github/dependabot.yml +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/.gitignore +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/.moon/toolchain.yml +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/.moon/workspace.yml +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/.pre-commit-config.yaml +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/.releaserc.yml +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/CONTRIBUTING.md +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/LICENSE +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/README.md +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/CLICKHOUSE_USER_GUIDE.md +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/EXNESS_DATA_SOURCES.md +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/README.md +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/adr/2025-12-09-codebase-pruning.md +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/adr/2025-12-09-exness-clickhouse-migration.md +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/adr/2025-12-10-clickhouse-e2e-validation-pipeline.md +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/adr/2025-12-10-clickhouse-pydantic-config.md +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/adr/2025-12-11-duckdb-removal-clickhouse.md +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/adr/diagrams/2025-12-10-clickhouse-pydantic-config-after.dot +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/adr/diagrams/2025-12-10-clickhouse-pydantic-config-arch.dot +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/adr/diagrams/2025-12-10-clickhouse-pydantic-config-before.dot +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/design/2025-12-09-codebase-pruning/spec.md +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/design/2025-12-09-exness-clickhouse-migration/spec.md +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/design/2025-12-10-clickhouse-e2e-validation-pipeline/spec.md +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/design/2025-12-10-clickhouse-pydantic-config/spec.md +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/design/2025-12-11-duckdb-removal-clickhouse/spec.md +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/release-notes/2.1.1.md +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/HYBRID_SESSION_DETECTION_ANALYSIS.md +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/compression-benchmarks/README.md +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/compression-benchmarks/test_all_compression_methods.py +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/compression-benchmarks/test_delta_encoding_properly.py +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/compression-benchmarks/test_parquet_compression_methods.py +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-spread-analysis/01-methodology.md +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-spread-analysis/02-mode-truncated-analysis.md +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-spread-analysis/03-hurdle-model-analysis.md +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-spread-analysis/04-temporal-patterns.md +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-spread-analysis/05-final-recommendations.md +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-spread-analysis/README.md +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-spread-analysis/scripts/reproduction_guide.md +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-spread-analysis/visualizations/hurdle-model/hurdle_decomposition.png +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-spread-analysis/visualizations/mode-truncated/cv_mode_comparison.png +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-spread-analysis/visualizations/mode-truncated/distribution_overlay.png +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-spread-analysis/visualizations/mode-truncated/signal_quality_comparison.png +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-spread-analysis/visualizations/mode-truncated/variance_decomposition.png +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-spread-analysis/visualizations/temporal/concentration_curve.png +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-spread-analysis/visualizations/temporal/percentile_analysis.png +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-zero-spread-deviations/01-methodology.md +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-zero-spread-deviations/02-baseline-sep2024.md +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-zero-spread-deviations/03-multiperiod-validation.md +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-zero-spread-deviations/04-discoveries-and-plan-evolution.md +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-zero-spread-deviations/README.md +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-zero-spread-deviations/findings/baseline-sep2024-comprehensive-summary.md +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-zero-spread-deviations/findings/phase2-mean-reversion-report.md +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-zero-spread-deviations/findings/phase3-volatility-model-report.md +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-zero-spread-deviations/findings/phase4-5-statistical-tests-survivorship-report.md +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-zero-spread-deviations/scripts/baseline-sep2024/01_mean_reversion_analysis.py +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-zero-spread-deviations/scripts/baseline-sep2024/02_volatility_model_simple.py +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-zero-spread-deviations/scripts/baseline-sep2024/03_liquidity_crisis_detection.py +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-zero-spread-deviations/scripts/baseline-sep2024/04_regime_detection_analysis.py +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase1_data_validation.py +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase2_mean_reversion.py +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase3_volatility_model.py +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase4_statistical_tests.py +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase5_survivorship_bias.py +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase5_survivorship_bias_v1.0.1.py +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase6a_interval_analysis.py +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase6b_price_clustering.py +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase6c_combined_pattern.py +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-zero-spread-deviations/scripts/reproduction_guide.md +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-zero-spread-deviations/scripts/visualization/diagnostic_burst_decay.py +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-zero-spread-deviations/scripts/visualization/generate_interactive_dashboard.py +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-zero-spread-deviations/scripts/visualization/generate_lightweight_dashboard.py +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/docs/research/eurusd-zero-spread-deviations/scripts/visualization/prepare_visualization_data.py +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/examples/basic_usage.py +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/moon.yml +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/scripts/clickhouse-start.sh +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/scripts/clickhouse-stop.sh +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/scripts/generate_dbeaver_config.py +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/scripts/smoke_install.sh +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/src/exness_data_preprocess/__init__.py +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/src/exness_data_preprocess/clickhouse_base.py +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/src/exness_data_preprocess/clickhouse_client.py +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/src/exness_data_preprocess/clickhouse_gap_detector.py +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/src/exness_data_preprocess/exchanges.py +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/src/exness_data_preprocess/session_detector.py +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/src/exness_data_preprocess/tick_loader.py +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/tests/README.md +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/tests/__init__.py +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/tests/conftest.py +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/tests/test_basic.py +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/tests/test_database_bootstrap_order.py +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/tests/test_functional_regression.py +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/tests/test_models.py +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/tests/test_processor_pydantic.py +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/tests/test_types.py +0 -0
- {exness_data_preprocess-2.1.1 → exness_data_preprocess-3.0.1}/uv.toml +0 -0
|
@@ -10,9 +10,9 @@ jobs:
|
|
|
10
10
|
runs-on: ubuntu-latest
|
|
11
11
|
|
|
12
12
|
steps:
|
|
13
|
-
- uses: actions/checkout@
|
|
13
|
+
- uses: actions/checkout@v7
|
|
14
14
|
|
|
15
|
-
- uses: actions/setup-python@
|
|
15
|
+
- uses: actions/setup-python@v7
|
|
16
16
|
with:
|
|
17
17
|
python-version: '3.12'
|
|
18
18
|
|
|
@@ -23,7 +23,7 @@ jobs:
|
|
|
23
23
|
run: python -m build
|
|
24
24
|
|
|
25
25
|
- name: Upload distribution artifacts
|
|
26
|
-
uses: actions/upload-artifact@
|
|
26
|
+
uses: actions/upload-artifact@v7
|
|
27
27
|
with:
|
|
28
28
|
name: dist
|
|
29
29
|
path: dist/
|
|
@@ -41,7 +41,7 @@ jobs:
|
|
|
41
41
|
|
|
42
42
|
steps:
|
|
43
43
|
- name: Download distribution artifacts
|
|
44
|
-
uses: actions/download-artifact@
|
|
44
|
+
uses: actions/download-artifact@v8
|
|
45
45
|
with:
|
|
46
46
|
name: dist
|
|
47
47
|
path: dist/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.15
|
|
@@ -1,3 +1,29 @@
|
|
|
1
|
+
## [3.0.1](https://github.com/terrylica/exness-data-preprocess/compare/v3.0.0...v3.0.1) (2026-10-19)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **ohlc:** compute tick_count_standard and standard_spread_avg per minute from standard_ticks ([a26ec2c](https://github.com/terrylica/exness-data-preprocess/commit/a26ec2cca0e8e2b326c8b5c6f93f2c9f2a658986)), closes [#25](https://github.com/terrylica/exness-data-preprocess/issues/25)
|
|
7
|
+
|
|
8
|
+
# [3.0.0](https://github.com/terrylica/exness-data-preprocess/compare/v2.1.1...v3.0.0) (2026-10-19)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
* fix!: keep distinct ticks that share a timestamp; read with FINAL; make force_redownload work ([e7ac22b](https://github.com/terrylica/exness-data-preprocess/commit/e7ac22ba659c7eb1c03f3ad1f223d23bff515304)), closes [#23](https://github.com/terrylica/exness-data-preprocess/issues/23)
|
|
12
|
+
* refactor!: remove the unused config module, ExnessDataProcessor(config=...) and pyyaml ([b43be4a](https://github.com/terrylica/exness-data-preprocess/commit/b43be4a09702c6135a41b27256345952c83e6708)), closes [#21](https://github.com/terrylica/exness-data-preprocess/issues/21)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
* apply review findings (inclusive end_date day, cursor pruning, scoped ASOF build side, forced re-download) ([dd3a0b3](https://github.com/terrylica/exness-data-preprocess/commit/dd3a0b373689116d600f43ff489e3076a66eb13e)), closes [#23](https://github.com/terrylica/exness-data-preprocess/issues/23) [#24](https://github.com/terrylica/exness-data-preprocess/issues/24)
|
|
18
|
+
* **query:** bind datetime parameters as DateTime64(6, 'UTC') so filters are not shifted on non-UTC servers ([1f88c41](https://github.com/terrylica/exness-data-preprocess/commit/1f88c41b372306bb5e929d131e1338d71e9ac539)), closes [#24](https://github.com/terrylica/exness-data-preprocess/issues/24)
|
|
19
|
+
* report real storage_bytes and OHLC bar counts instead of placeholders ([a970be5](https://github.com/terrylica/exness-data-preprocess/commit/a970be5f75b8dbddff890e92a628388261f10026)), closes [#19](https://github.com/terrylica/exness-data-preprocess/issues/19)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
### BREAKING CHANGES
|
|
23
|
+
|
|
24
|
+
* raw_spread_ticks and standard_ticks gain a `seq` column and sort by (instrument, timestamp, seq); existing tables are migrated in place by ensure_schema() (re-download months with update_data(..., force_redownload=True) to restore ticks the old key collapsed). CursorResult.next_cursor is now an opaque "<timestamp>#<seq>" string rather than a plain timestamp. Tick counts, tick queries and OHLC generation read with FINAL.
|
|
25
|
+
* ExnessDataProcessor() no longer accepts a `config` argument, the exness_data_preprocess.config module (ConfigModel, load_config, get_default_config_path) is removed, and PyYAML is no longer installed as a dependency. Configure through environment variables (CLICKHOUSE_*, EXNESS_DOWNLOAD_DIR).
|
|
26
|
+
|
|
1
27
|
## [2.1.1](https://github.com/terrylica/exness-data-preprocess/compare/v2.1.0...v2.1.1) (2026-10-19)
|
|
2
28
|
|
|
3
29
|
|
|
@@ -16,7 +16,7 @@ moon run repo:build # sdist + wheel into dist/
|
|
|
16
16
|
|
|
17
17
|
## Toolchain
|
|
18
18
|
|
|
19
|
-
- proto pins uv (`.prototools`); uv owns Python. `.python-version
|
|
19
|
+
- proto pins uv (`latest`) and moon (`.prototools`); uv owns Python. Development runs on the latest CPython (`.python-version`, currently 3.15); the published floor stays `requires-python >=3.11`, and ruff/mypy target 3.11 so code keeps working there. Never export `UV_PYTHON`: an env var outranks `.python-version`.
|
|
20
20
|
- Releases: write `docs/release-notes/<next>.md` (narrative paragraph + Keep a Changelog bullets, one line each) in the PR before releasing; semantic-release (`npm run release`) refuses to release without it, runs `uv version <next> --frozen`, and `scripts/publish-release-notes.sh` rebuilds the GitHub Release body as narrative + generated section. pyproject.toml is the only place the version lives; `__version__` reads installed metadata. Publishing is `.github/workflows/publish.yml` (PyPI Trusted Publishing on a GitHub Release), the only publish path.
|
|
21
21
|
- Dependency update PRs come from `.github/dependabot.yml`. No other CI runs in Actions; gates are local.
|
|
22
22
|
|
|
@@ -24,7 +24,8 @@ moon run repo:build # sdist + wheel into dist/
|
|
|
24
24
|
|
|
25
25
|
- `ensure_database_bootstrap()` must run before the first `get_client()` that binds the `exness` database (`tests/test_database_bootstrap_order.py`).
|
|
26
26
|
- Insert DataFrames with `client.insert_df(...)`, never `client.insert(data=df)` (that takes row sequences).
|
|
27
|
-
- Tables are ReplacingMergeTree
|
|
27
|
+
- Tables are ReplacingMergeTree. Tick tables dedupe on `(instrument, timestamp, seq)`: `seq` (`assign_tick_seq`) numbers same-timestamp ticks in source order, so distinct ticks sharing a timestamp are kept and re-inserting a month is idempotent. Duplicates only collapse at merge time, so every read whose answer depends on duplicates (counts, tick/OHLC rows, the OHLC build) uses `FINAL`; keep it that way.
|
|
28
|
+
- Datetime query parameters are typed `DateTime64(6, 'UTC')`, never bare `DateTime64`: a bare one parses naive text in the server's time zone and shifts every filter on a non-UTC server. `repo:e2e` runs its server in America/New_York to catch this.
|
|
28
29
|
- ClickHouse-backed tests are marked `clickhouse` or use `processor_with_clickhouse` (fixture users get the marker at collection, so `-m clickhouse` selects them); `conftest.py` skips them with the probe's reason unless `EXNESS_REQUIRE_CLICKHOUSE=1`. A server that holds :8123 but rejects the credentials (el02's shared system ClickHouse) counts as unavailable. Use `repo:e2e`, not that server.
|
|
29
30
|
- `gapless-crypto-clickhouse` also uses localhost:8123. `clickhouse-stop` only stops the PID in this repo's pidfile.
|
|
30
31
|
- ADRs and design specs under `docs/adr/` and `docs/design/` are historical records: add new ones, don't rewrite old ones.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: exness-data-preprocess
|
|
3
|
-
Version:
|
|
3
|
+
Version: 3.0.1
|
|
4
4
|
Summary: Professional Exness forex tick data preprocessing with ClickHouse backend. Provides efficient storage 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
|
|
@@ -22,15 +22,15 @@ Classifier: Programming Language :: Python :: 3
|
|
|
22
22
|
Classifier: Programming Language :: Python :: 3.11
|
|
23
23
|
Classifier: Programming Language :: Python :: 3.12
|
|
24
24
|
Classifier: Programming Language :: Python :: 3.13
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
25
26
|
Classifier: Topic :: Office/Business :: Financial :: Investment
|
|
26
27
|
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
27
28
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
28
29
|
Requires-Python: >=3.11
|
|
29
|
-
Requires-Dist: clickhouse-connect>=
|
|
30
|
+
Requires-Dist: clickhouse-connect>=1.11.0
|
|
30
31
|
Requires-Dist: exchange-calendars>=4.5.6
|
|
31
32
|
Requires-Dist: pandas>=2.0.0
|
|
32
33
|
Requires-Dist: pydantic>=2.0.0
|
|
33
|
-
Requires-Dist: pyyaml>=6.0.0
|
|
34
34
|
Provides-Extra: examples
|
|
35
35
|
Requires-Dist: tqdm>=4.65.0; extra == 'examples'
|
|
36
36
|
Description-Content-Type: text/markdown
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
## 3.0.0 (2026-10-19)
|
|
2
|
+
|
|
3
|
+
This release is about trusting the numbers this package stores and reports. The tick tables silently merged distinct Exness ticks that shared a timestamp: about 0.17% of Raw_Spread ticks on recent EURUSD months, gone without a trace. Date filters were shifted by the server's UTC offset whenever ClickHouse ran outside UTC. Storage size, the up-to-date bar count and `force_redownload` were placeholders that returned 0, ticks ÷ 1000 and nothing at all. Each is now measured and gated by `repo:e2e`, which loads real Exness months on a deliberately non-UTC server and checks that every inserted tick survives a merge, that re-loading changes nothing, and that pagination returns every tick sharing a timestamp. It is a major version for three reasons: the tick tables gain a `seq` column and a new sort key (existing tables are migrated in place automatically), the pagination cursor format changed, and the unused `config` parameter and PyYAML dependency are gone.
|
|
4
|
+
|
|
5
|
+
### Upgrading
|
|
6
|
+
|
|
7
|
+
- Nothing to do for the schema: the first `ExnessDataProcessor()` against a pre-3.0 database migrates both tick tables in place (`ADD COLUMN seq`, `MODIFY ORDER BY (instrument, timestamp, seq)`) and logs a warning.
|
|
8
|
+
- To recover ticks the old key already merged away, re-load the affected months: `update_data(pair, start_date=..., force_redownload=True)`.
|
|
9
|
+
- Remove any `ExnessDataProcessor(config=...)` argument; configure with `CLICKHOUSE_*` and `EXNESS_DOWNLOAD_DIR` environment variables.
|
|
10
|
+
- Treat `CursorResult.next_cursor` as opaque (`"<timestamp>#<seq>"`); pass it back unchanged.
|
|
11
|
+
- `clickhouse-connect` 1.11.0 or newer is now required.
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- Distinct ticks that share a timestamp are kept: tick tables deduplicate on `(instrument, timestamp, seq)`, with `seq` numbering same-timestamp ticks in source order, so re-loading a month stays idempotent (#23).
|
|
16
|
+
- Date filters are no longer shifted on non-UTC ClickHouse servers; every datetime parameter is bound as `DateTime64(6, 'UTC')` (#24).
|
|
17
|
+
- A date-only `end_date` now includes that whole day, as documented; it used to stop at 00:00:00 of that day (#24).
|
|
18
|
+
- Counts, tick and OHLC queries, and the OHLC build read with `FINAL`, so results are correct before ClickHouse's background merges; a re-load had reported 157,316 bars for 78,658 (#23).
|
|
19
|
+
- `update_data(force_redownload=True)` now re-processes every month from `start_date`; it was previously accepted and ignored (#23).
|
|
20
|
+
- Cursor pagination no longer skips ticks that share the last timestamp of a page (#23).
|
|
21
|
+
- `storage_bytes` reports the real on-disk size of the package tables, and the up-to-date path of `update_data` reports the real OHLC bar count instead of ticks ÷ 1000 (#19, #20).
|
|
22
|
+
|
|
23
|
+
### Removed
|
|
24
|
+
|
|
25
|
+
- `exness_data_preprocess.config` (`ConfigModel`, `load_config`, `get_default_config_path`), the `ExnessDataProcessor(config=...)` parameter, and the PyYAML runtime dependency, none of which had any effect (#21, #22).
|
|
26
|
+
|
|
27
|
+
### Known issues
|
|
28
|
+
|
|
29
|
+
- `ohlc_1m.tick_count_standard` equals the Raw_Spread tick count of each minute rather than counting Standard ticks; this predates 3.0.0 and is tracked in #25.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
## 3.0.1 (2026-10-19)
|
|
2
|
+
|
|
3
|
+
Two `ohlc_1m` columns did not measure what their documentation says. `tick_count_standard` is documented as the number of Standard ticks in the bar, but it always equalled the Raw_Spread count: it was computed as `countIf(... IS NOT NULL)` over an ASOF join that never produces NULLs. `standard_spread_avg` is documented as the average Standard spread in the bar, but it averaged whichever Standard quote preceded each Raw_Spread tick, and the choice among tied quotes could change between rebuilds. Each variant is now aggregated per minute on its own and the two are joined on the minute, so both columns match their definitions, rebuilds are deterministic, and the build no longer runs a per-tick join. On the E2E months the counts now differ on 64,889 of 78,658 bars, where before they were identical on every bar.
|
|
4
|
+
|
|
5
|
+
### Upgrading
|
|
6
|
+
|
|
7
|
+
- Bars already stored keep the old values until they are rebuilt. Rebuild an instrument's bars with `update_data(pair, start_date=..., force_redownload=True)`, which re-downloads and regenerates from `start_date`, or call `ExnessDataProcessor().ch_ohlc_generator.regenerate_ohlc(pair)` to rebuild every bar from the stored ticks.
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- `tick_count_standard` counts the Standard ticks in the bar's minute (0 when there are none) (#25).
|
|
12
|
+
- `standard_spread_avg` is the mean Standard `ask - bid` in the bar's minute (NULL when there are none), deterministic across rebuilds (#25).
|
|
13
|
+
- `repo:e2e` checks that `sum(tick_count_raw_spread)` equals the stored Raw_Spread ticks and `sum(tick_count_standard)` equals the Standard ticks in bar minutes, that the two counts differ, and that a sampled `standard_spread_avg` equals a direct per-minute average (#25).
|
|
14
|
+
- Stale docstrings describing the v1 30-column schema, normalized metrics and the ASOF join are corrected (#25).
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- Development runs on Python 3.15.0 and moon 2.6.2; the supported range is unchanged (`requires-python >=3.11`) (#27, #28).
|