rust-pyfunc 0.76.7__tar.gz → 0.76.9__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.
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/Cargo.lock +1 -1
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/Cargo.toml +1 -1
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/PKG-INFO +1 -1
- rust_pyfunc-0.76.9/ds_plan_true.md +268 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/python/rust_pyfunc/__init__.py +2 -2
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/python/rust_pyfunc/parallel_computing.pyi +7 -2
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/backup_column_cache.rs +315 -109
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/tail_v4_pipeline.rs +71 -11
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/.factory/settings.json +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/.github/workflows/CI.yml +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/.github/workflows/deploy.yml +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/.gitignore +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/AGENTS.md +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/CLAUDE.md +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/CRUSH.md +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/FACTOR_NEUTRALIZATION_REQUIREMENTS.md +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/README.md +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/agents/skills/agent-trading-builder/SKILL.md +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/alter.sh +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/PriceTree.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/PriceTreeViz.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/RollingFutureAccessor.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/TRADE_PEAK_ANALYSIS_README.md +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/brachistochrone_curve.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/calculate_shannon_entropy_change.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/calculate_shannon_entropy_change_at_low.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/compute_max_eigenvalue.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/dct_basis_functions.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/dct_path_patterns.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/dct_reconstruction.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/dct_visualization.py +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/dtw_distance.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/find_follow_volume_sum_same_price.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/find_follow_volume_sum_same_price_and_flag.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/find_half_energy_time.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/find_local_peaks_within_window.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/find_max_range_product.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/identify_segments.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/index.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/jaccard_similarity.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/mark_follow_groups.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/mark_follow_groups_with_flag.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/max_range_loop.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/min_range_loop.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/min_word_edit_distance.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/ols.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/ols_predict.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/ols_residuals.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/parallel_computing_system.md +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/rolling_cv.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/rolling_qcv.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/rolling_volatility.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/rolling_window_stat.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/search_data.json +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/static/search.js +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/static/style.css +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/sum_as_string.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/transfer_entropy.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/trend.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/trend_fast.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/vectorize_sentences.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs/vectorize_sentences_list.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs//344/275/277/347/224/250/350/257/264/346/230/216.md" +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs//345/256/214/346/210/220/346/200/273/347/273/223.md" +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/docs_generator.py +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/hmm_visualizer.py +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/pyproject.toml +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/python/rust_pyfunc/__init__.pyi +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/python/rust_pyfunc/abm_analysis.py +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/python/rust_pyfunc/agent_simulator.pyi +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/python/rust_pyfunc/agent_trading_daily.py +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/python/rust_pyfunc/agent_trading_daily.pyi +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/python/rust_pyfunc/copula.pyi +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/python/rust_pyfunc/core_functions.pyi +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/python/rust_pyfunc/pandas_correlation.py +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/python/rust_pyfunc/pandas_correlation.pyi +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/python/rust_pyfunc/pandas_corrwith.py +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/python/rust_pyfunc/pandas_extensions.pyi +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/python/rust_pyfunc/pandas_merge.py +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/python/rust_pyfunc/pandas_rank.py +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/python/rust_pyfunc/rolling_future.py +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/python/rust_pyfunc/rolling_past.py +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/python/rust_pyfunc/statistical_analysis.pyi +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/python/rust_pyfunc/text_analysis.pyi +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/python/rust_pyfunc/theme_cluster_factors.pyi +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/python/rust_pyfunc/theme_feature_expansion.pyi +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/python/rust_pyfunc/theme_feature_expansion_data.py +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/python/rust_pyfunc/theme_feature_expansion_data.pyi +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/python/rust_pyfunc/time_series.pyi +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/python/rust_pyfunc/trading_analysis.pyi +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/python/rust_pyfunc/trading_data_utils.py +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/python/rust_pyfunc/trading_data_utils.pyi +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/python/rust_pyfunc/trading_day.py +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/python/rust_pyfunc/tree_structures.pyi +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/python/rust_pyfunc/treevisual.py +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/python/rust_pyfunc/web_manager.py +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/python/rust_pyfunc/web_manager.pyi +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/rust-toolchain.toml +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/abnormal_asks_analyzer.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/agent_simulator/acceleration_follow_agent.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/agent_simulator/bottom_fishing_agent.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/agent_simulator/buy_ratio_agent.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/agent_simulator/exhaustion_reversal_agent.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/agent_simulator/follow_flow_agent.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/agent_simulator/mod.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/agent_simulator/momentum_agent.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/agent_simulator/py_bindings.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/agent_simulator/simulator.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/agent_simulator/trait_def.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/agent_simulator/types.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/agent_simulator/utils.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/agent_trading_features/core.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/agent_trading_features/metrics.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/agent_trading_features/mod.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/agent_trading_features/py_bindings.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/agent_trading_features/types.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/allo_microstructure.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/allo_microstructure_v2.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/allo_microstructure_v3.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/backup_reader.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/backup_writer.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/column_correlation.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/copula.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/corr_diff_features.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/dct_transform.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/difference_matrix.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/effective_memory_length.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/entropy_analysis.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/error/mod.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/factor_neutralization_io_optimized.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/frontier_dist.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/ghost_market_maker.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/gp_correlation_dimension.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/grouping.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/hawkes_advisor.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/hawkes_analysis.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/illusion_liquidity_distance.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/integer_small_peak_features.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/lagged_regression.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/lagged_regression_incremental.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/lagged_regression_optimized.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/lagged_regression_simd.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/lib.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/limit_order_lifecycle.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/limit_order_lifecycle_v2.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/long_order_analysis.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/lz_complexity.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/lz_complexity_detailed.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/market_correlation.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/microstructure_pattern_features.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/microstructure_pattern_features_optimized.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/microstructure_pattern_features_v2.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/mutual_information.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/mutual_information_2d.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/mutual_information_2d_final.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/mutual_information_2d_fixed.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/order_contamination.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/order_neighborhood.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/order_pair_metrics.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/order_price_statistics.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/order_price_statistics_bucketed.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/order_price_statistics_order_level.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/order_records_ultra_sorted.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/order_records_ultra_sorted_bucketed.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/order_records_ultra_sorted_v2_optimized.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/order_records_ultra_sorted_v3.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/orderbook_volume_cov_factors.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/pandas_ext/mod.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/parallel_computing.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/parallel_computing_date_only.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/passive_order_features.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/permutation_analysis_v0816_fixed.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/personalized_meeting_features.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/price_breakthrough_stats.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/price_cycle_b_segments_enhanced.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/safe_eigenvalue.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/sequence/mod.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/series_rank.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/simple_parallel.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/skewness.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/statistics/eigenvalue_analysis.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/statistics/eigenvalue_analysis_modified.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/statistics/fast_correlation.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/statistics/fast_correlation_v2.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/statistics/hmm_trend_prediction.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/statistics/local_correlation.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/statistics/mod.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/statistics/rolling_correlation_mean.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/statistics/rolling_window_core_feature.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/statistics/rolling_window_core_feature_optimized.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/statistics/rolling_window_core_feature_simd.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/statistics/rolling_window_core_feature_ultra.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/tail_v2_backtest_block.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/tail_v2_block_neutralizer.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/tail_v2_ic_corr_filter.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/tail_v2_rank_roll_factor.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/text/mod.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/text/string_proximity.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/theme_cluster_factors.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/theme_cluster_factors_batch.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/theme_feature_expansion.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/time_irreversibility.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/time_series/fast_extreme.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/time_series/lyapunov.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/time_series/mod.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/time_series/retreat_advance.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/time_series/retreat_advance_v2.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/time_series/super_extreme.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/time_series/trend_mod.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/topk_corr_matrix.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/trade_analysis_ultra_turbo.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/trade_peak_analysis.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/trade_records_ultra_sorted.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/tree/mod.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/vector_similarity.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/src/vector_similarity_optimized.rs +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/templates/base.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/templates/function.html +0 -0
- {rust_pyfunc-0.76.7 → rust_pyfunc-0.76.9}/templates/index.html +0 -0
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
# build_backup_column_block_cache_single_thread 内存优化方案
|
|
2
|
+
|
|
3
|
+
## 问题诊断
|
|
4
|
+
|
|
5
|
+
当前实现存在 **两处内存峰值叠加**:
|
|
6
|
+
|
|
7
|
+
### 峰值1:v4 全量解压缓冲区(第735行)
|
|
8
|
+
|
|
9
|
+
```rust
|
|
10
|
+
let mut decompressed = Vec::with_capacity(record_count * record_size);
|
|
11
|
+
for chunk in &chunks {
|
|
12
|
+
let decompressed_chunk = zstd::decode_all(compressed_data)?;
|
|
13
|
+
decompressed.extend_from_slice(&decompressed_chunk);
|
|
14
|
+
}
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
一次性将所有压缩块解压到连续 `Vec<u8>` 中,大小 = `record_count * record_size`。
|
|
18
|
+
|
|
19
|
+
### 峰值2:全量 block_f32_data(第660行)
|
|
20
|
+
|
|
21
|
+
```rust
|
|
22
|
+
let mut block_f32_data: Vec<Vec<f32>> = vec![Vec::new(); block_count];
|
|
23
|
+
// ... 遍历 sort_index,按 block 分别 push f32 值
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
所有 block 的 f32 数据同时驻留内存,大小 = `record_count * factor_count * 4`。
|
|
27
|
+
|
|
28
|
+
### 叠加效应
|
|
29
|
+
|
|
30
|
+
以 `record_count=10,666,713, factor_count=24,192, block_count=756` 为例:
|
|
31
|
+
- decompressed: ~962 GB
|
|
32
|
+
- block_f32_data: ~961 GB
|
|
33
|
+
- **合计峰值: ~1.9 TB**(物理内存仅 1.5 TB)
|
|
34
|
+
|
|
35
|
+
两阶段设计导致 `decompressed` 在第735行分配后直到 `build_cache_from_v3_buffer` 返回前都不释放,
|
|
36
|
+
与第660行的 `block_f32_data` 同时存在,形成叠加峰值。
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 核心设计思想:分块组 + 逆索引
|
|
41
|
+
|
|
42
|
+
**关键约束**:缓存文件要求数据按 `(date_id, code_id)` 排序后写入。这意味着不能简单地对原始顺序的数据做流式写入。
|
|
43
|
+
|
|
44
|
+
**解决思路**:
|
|
45
|
+
1. 第一遍:构建字典 + sort_index(不变)
|
|
46
|
+
2. 构建 **逆索引** `position_in_sorted[original_row] = sorted_position`
|
|
47
|
+
3. 第二遍:**逐块组处理**——每次只处理 G 个 block,需要多少分配多少,写完立刻释放
|
|
48
|
+
|
|
49
|
+
这样做的原理:
|
|
50
|
+
- 有了逆索引,可以在**原始顺序**遍历数据时,直接 O(1) 定位每条记录在各 block 中的写入位置
|
|
51
|
+
- 每次只分配 G 个 block 的 f32 buffer,写完释放后再处理下一组
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## 详细设计
|
|
56
|
+
|
|
57
|
+
### 第一步:新增逆索引构建
|
|
58
|
+
|
|
59
|
+
在 `build_cache_from_v3_buffer` 和 `build_cache_from_v2` 中,sort_index 构建完成后,新增:
|
|
60
|
+
|
|
61
|
+
```rust
|
|
62
|
+
// 构建逆索引:position_in_sorted[original_row] = sorted_position
|
|
63
|
+
let mut position_in_sorted: Vec<u32> = vec![0u32; record_count];
|
|
64
|
+
for (sorted_pos, &original_row) in sort_index.iter().enumerate() {
|
|
65
|
+
position_in_sorted[original_row] = sorted_pos as u32;
|
|
66
|
+
}
|
|
67
|
+
// sort_index 现在可以释放(如果后续用不到的话)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**注意**:`sort_index` 仍需保留,因为写 meta.bin 时需要按排序后的顺序写 `(date_id, code_id)` 对。
|
|
71
|
+
|
|
72
|
+
内存开销:`position_in_sorted: Vec<u32>` = `record_count * 4` 字节。对于 10,666,713 条记录约 **41 MB**,可接受。
|
|
73
|
+
|
|
74
|
+
### 第二步:改造第二遍为逐块组处理
|
|
75
|
+
|
|
76
|
+
**核心循环结构**:
|
|
77
|
+
|
|
78
|
+
```rust
|
|
79
|
+
// 写入 meta.bin(按 sort_index 顺序)
|
|
80
|
+
let mut meta_writer = BufWriter::new(File::create(meta_path(cache_dir))?);
|
|
81
|
+
for &row in &sort_index {
|
|
82
|
+
meta_writer.write_all(&row_date_ids[row].to_le_bytes())?;
|
|
83
|
+
meta_writer.write_all(&row_code_ids[row].to_le_bytes())?;
|
|
84
|
+
}
|
|
85
|
+
meta_writer.flush()?;
|
|
86
|
+
|
|
87
|
+
// 逐块组处理 f32 数据
|
|
88
|
+
let group_size = (memory_budget_bytes / (record_count * block_cols * 4)).max(1);
|
|
89
|
+
for group_start in (0..block_count).step_by(group_size) {
|
|
90
|
+
let group_end = min(group_start + group_size, block_count);
|
|
91
|
+
let group_block_count = group_end - group_start;
|
|
92
|
+
|
|
93
|
+
// 为当前组分配 f32 buffer
|
|
94
|
+
let mut group_buffers: Vec<Vec<f32>> = (group_start..group_end)
|
|
95
|
+
.map(|blk_idx| {
|
|
96
|
+
let cols = min(block_cols, factor_count - blk_idx * block_cols);
|
|
97
|
+
Vec::with_capacity(record_count * cols)
|
|
98
|
+
})
|
|
99
|
+
.collect();
|
|
100
|
+
|
|
101
|
+
// 按原始顺序遍历所有记录,填充当前组的 buffer
|
|
102
|
+
for row in 0..record_count {
|
|
103
|
+
let sorted_pos = position_in_sorted[row] as usize;
|
|
104
|
+
let offset = data_start + row * record_size;
|
|
105
|
+
let record = &data[offset..offset + record_size];
|
|
106
|
+
|
|
107
|
+
for (local_idx, blk_idx) in (group_start..group_end).enumerate() {
|
|
108
|
+
let start_col = blk_idx * block_cols;
|
|
109
|
+
let end_col = min(start_col + block_cols, factor_count);
|
|
110
|
+
let cols = end_col - start_col;
|
|
111
|
+
let base = sorted_pos * cols;
|
|
112
|
+
for (j, col) in (start_col..end_col).enumerate() {
|
|
113
|
+
let byte_offset = FACTOR_BASE_OFFSET + col * FACTOR_SIZE;
|
|
114
|
+
let bits = u32::from_le_bytes(record[byte_offset..byte_offset + 4].try_into().unwrap());
|
|
115
|
+
group_buffers[local_idx][base + j] = f32::from_bits(bits);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// 逐个 block 压缩写入,释放 buffer
|
|
121
|
+
for (local_idx, blk_idx) in (group_start..group_end).enumerate() {
|
|
122
|
+
let f32_slice = &group_buffers[local_idx];
|
|
123
|
+
let raw_bytes = /* f32 转 bytes */;
|
|
124
|
+
let compressed = zstd::encode_all(raw_bytes, 9)?;
|
|
125
|
+
let mut w = BufWriter::new(File::create(block_path(cache_dir, blk_idx))?);
|
|
126
|
+
w.write_all(&(raw_bytes.len() as u64).to_le_bytes())?;
|
|
127
|
+
w.write_all(&compressed)?;
|
|
128
|
+
w.flush()?;
|
|
129
|
+
}
|
|
130
|
+
// group_buffers 离开作用域,内存释放
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**关键变化**:
|
|
135
|
+
- 遍历顺序从 `for &row in &sort_index`(排序后顺序)改为 `for row in 0..record_count`(原始顺序)
|
|
136
|
+
- 通过 `position_in_sorted[row]` 获取排序后的写入位置
|
|
137
|
+
- 外层循环从"一次处理所有 block"变为"每次处理 group_size 个 block"
|
|
138
|
+
|
|
139
|
+
### 第三步:改造 v4 解压逻辑
|
|
140
|
+
|
|
141
|
+
不再全量解压,改为**按需解压**——每次处理一个块组时,重新解压所有 v4 压缩块。
|
|
142
|
+
|
|
143
|
+
```rust
|
|
144
|
+
fn build_cache_from_v4(...) -> PyResult<CacheManifest> {
|
|
145
|
+
let chunks = build_chunk_index_v4(mmap)?;
|
|
146
|
+
|
|
147
|
+
// 第一遍:构建字典 + sort_index + position_in_sorted + 写 meta.bin
|
|
148
|
+
// 这需要逐 chunk 解压,提取 date/code,但不保留因子数据
|
|
149
|
+
// (或直接用现有的第一遍逻辑,因为 v3_buffer 的第一遍只需要 date 和 code)
|
|
150
|
+
|
|
151
|
+
// 第二遍:逐块组处理
|
|
152
|
+
for group_start in (0..block_count).step_by(group_size) {
|
|
153
|
+
// 为当前组分配 buffer
|
|
154
|
+
let mut group_buffers = ...;
|
|
155
|
+
|
|
156
|
+
// 重新解压所有 chunk
|
|
157
|
+
let mut global_row = 0usize;
|
|
158
|
+
for chunk in &chunks {
|
|
159
|
+
let compressed_data = &mmap[chunk.data_offset..];
|
|
160
|
+
let decompressed = zstd::decode_all(compressed_data)?;
|
|
161
|
+
for local_row in 0..chunk.record_count {
|
|
162
|
+
let row = global_row + local_row;
|
|
163
|
+
let sorted_pos = position_in_sorted[row] as usize;
|
|
164
|
+
let offset = local_row * record_size;
|
|
165
|
+
let record = &decompressed[offset..offset + record_size];
|
|
166
|
+
// 填充 group_buffers
|
|
167
|
+
...
|
|
168
|
+
}
|
|
169
|
+
global_row += chunk.record_count;
|
|
170
|
+
// decompressed 离开作用域,内存释放
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// 写入当前组的 block 文件
|
|
174
|
+
...
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
**v4 的权衡**:
|
|
180
|
+
- 需要重新解压所有 chunk 多次(每次块组一遍)
|
|
181
|
+
- 解压次数 = `ceil(block_count / group_size)`
|
|
182
|
+
- 用 CPU 换内存:解压更多次,但每次只需保留一个 chunk 的解压数据 + 当前块组的 f32 buffer
|
|
183
|
+
|
|
184
|
+
### group_size 自动计算
|
|
185
|
+
|
|
186
|
+
不再由用户手动指定 `group_size`,改为接受 **`memory_budget_gb`**(分配给 f32 buffer 的内存预算),内部自动计算:
|
|
187
|
+
|
|
188
|
+
```rust
|
|
189
|
+
let memory_budget_bytes = memory_budget_gb * 1024 * 1024 * 1024;
|
|
190
|
+
// 单个 block 的 f32 buffer 大小 = record_count * block_cols * 4
|
|
191
|
+
let group_size = (memory_budget_bytes / (record_count * block_cols * 4)).max(1);
|
|
192
|
+
group_size = group_size.min(block_count); // 不超过 block 总数
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
**`memory_budget_gb` 的默认值**:通过系统 API 读取物理内存总量,取 1/3 作为默认预算。例如:
|
|
196
|
+
- 1.5 TB 机器 → 默认 500 GB → group_size ≈ 400 → 仅需 2 遍扫描
|
|
197
|
+
- 256 GB 机器 → 默认 85 GB → group_size ≈ 68 → 约需 12 遍扫描
|
|
198
|
+
- 64 GB 机器 → 默认 21 GB → group_size ≈ 17 → 约需 45 遍扫描
|
|
199
|
+
|
|
200
|
+
用户也可以通过 Python 参数覆盖默认值。
|
|
201
|
+
|
|
202
|
+
### 预估耗时(以 10.67M 记录、24,192 因子、756 blocks 为例)
|
|
203
|
+
|
|
204
|
+
瓶颈是 zstd 解压 + 压缩的 CPU 时间,磁盘 I/O 次之:
|
|
205
|
+
|
|
206
|
+
| memory_budget_gb | group_size | v4 解压遍数 | 预估总耗时 |
|
|
207
|
+
|------------------|-----------|------------|----------|
|
|
208
|
+
| 500 | 400 | 3 | ~40 分钟 |
|
|
209
|
+
| 200 | 156 | 6 | ~80 分钟 |
|
|
210
|
+
| 50 | 39 | 21 | ~280 分钟 |
|
|
211
|
+
| 20 | 15 | 52 | ~700 分钟 |
|
|
212
|
+
|
|
213
|
+
**说明**:耗时估算基于单线程 zstd 解压/压缩吞吐约 3-4 GB/s。实际耗时受具体机器 CPU 和磁盘性能影响。用户可以根据能接受的耗时反推需要给多少 `memory_budget_gb`。
|
|
214
|
+
|
|
215
|
+
### v3 的情况
|
|
216
|
+
|
|
217
|
+
v3 使用 mmap,不需要重新解压,只需要重新遍历 mmap 数据(内存映射访问,OS 管理页换入换出)。
|
|
218
|
+
对于超大文件,可能会有页面抖动,但不影响正确性,且远好于 OOM。
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## 内存峰值估算(改造后)
|
|
223
|
+
|
|
224
|
+
| 组件 | 大小(10M 记录) | 备注 |
|
|
225
|
+
|------|-----------------|------|
|
|
226
|
+
| sort_index | ~81 MB | `Vec<usize>` |
|
|
227
|
+
| position_in_sorted | ~41 MB | `Vec<u32>` |
|
|
228
|
+
| row_date_ids | ~20 MB | `Vec<u16>` |
|
|
229
|
+
| row_code_ids | ~20 MB | `Vec<u16>` |
|
|
230
|
+
| 单个块组 f32 buffer | ~`memory_budget_gb` GB | 用户指定上限 |
|
|
231
|
+
| v4 解压临时 buffer | ~chunk_record_count × record_size | 一个 chunk,释放快 |
|
|
232
|
+
|
|
233
|
+
固定开销约 162 MB + f32 buffer 由 `memory_budget_gb` 控制。例如默认取物理内存 1/3,1.5 TB 机器上峰值约 500 GB,远低于原来的 1.9 TB。
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## 需要修改的函数
|
|
238
|
+
|
|
239
|
+
### 1. `build_cache_from_v3_buffer` (第581行)
|
|
240
|
+
- 新增 `position_in_sorted` 构建
|
|
241
|
+
- 将第二遍改为逐块组处理
|
|
242
|
+
- meta.bin 的写入与 f32 数据收集分离
|
|
243
|
+
|
|
244
|
+
### 2. `build_cache_from_v2` (第417行)
|
|
245
|
+
- 同样新增 `position_in_sorted` 构建
|
|
246
|
+
- 同样将第二遍改为逐块组处理
|
|
247
|
+
|
|
248
|
+
### 3. `build_cache_from_v4` (第720行)
|
|
249
|
+
- 删除全量解压逻辑
|
|
250
|
+
- 第一遍:逐 chunk 解压,构建字典 + sort_index
|
|
251
|
+
- 第二遍:逐块组处理,每遍重新解压所有 chunk
|
|
252
|
+
- 或者:将第一遍和第二遍融合(边解压边处理),减少解压次数
|
|
253
|
+
|
|
254
|
+
### 4. 新增参数 `memory_budget_gb`
|
|
255
|
+
在 `build_backup_column_block_cache_single_thread` 的 Python 接口中新增 `memory_budget_gb: Option<f64>` 参数。
|
|
256
|
+
- `None`(默认):自动读取物理内存的 1/3 作为预算
|
|
257
|
+
- 指定值:按给定 GB 数分配 f32 buffer 内存
|
|
258
|
+
|
|
259
|
+
内部自动推导 `group_size`,无需用户关心 block 内部结构。
|
|
260
|
+
|
|
261
|
+
---
|
|
262
|
+
|
|
263
|
+
## 验证方案
|
|
264
|
+
|
|
265
|
+
1. **正确性验证**:用改造前后的代码分别构建缓存,比较所有 blk_*.bin 文件是否一致(MD5)
|
|
266
|
+
2. **内存验证**:用 `/usr/bin/time -v` 监控最大 RSS,确认峰值显著降低
|
|
267
|
+
3. **性能验证**:在 10M 记录的数据集上比较改造前后的总耗时
|
|
268
|
+
4. **边界测试**:用不同 `memory_budget_gb`(如 1/10/50/500)测试,验证结果一致性
|
|
@@ -2,10 +2,10 @@ from importlib import import_module
|
|
|
2
2
|
|
|
3
3
|
from rust_pyfunc.rust_pyfunc import *
|
|
4
4
|
from rust_pyfunc import *
|
|
5
|
+
from rust_pyfunc.rolling_future import RollingFutureAccessor
|
|
6
|
+
from rust_pyfunc.rolling_past import RollingPastAccessor
|
|
5
7
|
|
|
6
8
|
_LAZY_EXPORTS = {
|
|
7
|
-
"RollingFutureAccessor": (".rolling_future", "RollingFutureAccessor"),
|
|
8
|
-
"RollingPastAccessor": (".rolling_past", "RollingPastAccessor"),
|
|
9
9
|
"corrwith": (".pandas_corrwith", "corrwith"),
|
|
10
10
|
"rank_axis1_df": (".pandas_rank", "rank_axis1_df"),
|
|
11
11
|
"rank_axis0_df": (".pandas_rank", "rank_axis0_df"),
|
|
@@ -716,9 +716,14 @@ def query_backup_single_column(
|
|
|
716
716
|
def build_backup_column_block_cache_single_thread(
|
|
717
717
|
backup_file: str,
|
|
718
718
|
block_cols: int = 32,
|
|
719
|
-
force_rebuild: bool = False
|
|
719
|
+
force_rebuild: bool = False,
|
|
720
|
+
memory_budget_gb: float | None = None
|
|
720
721
|
) -> dict:
|
|
721
|
-
"""构建单线程列块缓存(v2/v3备份格式 → v2缓存格式)。
|
|
722
|
+
"""构建单线程列块缓存(v2/v3/v4备份格式 → v2缓存格式)。
|
|
723
|
+
|
|
724
|
+
参数:
|
|
725
|
+
- memory_budget_gb: 控制峰值内存的预算(GB)。None=自动使用物理内存的1/3。
|
|
726
|
+
减小此值可降低内存占用,但会增加处理时间(v4格式下需多次解压)。
|
|
722
727
|
|
|
723
728
|
返回字段:
|
|
724
729
|
- cache_dir: 缓存目录
|