Skip to content

fix: use net PP&E in capex formula to prevent depreciation double-count (#354)#540

Merged
AlexFiliakov merged 1 commit intodevelopfrom
bugfix/354_capex_double_counts_dep
Feb 8, 2026
Merged

fix: use net PP&E in capex formula to prevent depreciation double-count (#354)#540
AlexFiliakov merged 1 commit intodevelopfrom
bugfix/354_capex_double_counts_dep

Conversation

@AlexFiliakov
Copy link
Owner

Summary

  • Bug: _calculate_capex used gross_ppe (not reduced by depreciation), so adding depreciation back double-counted it — cash flow from investing was too negative by the full depreciation amount each period
  • Fix: Switch to net_ppe (gross_ppe − accumulated_depreciation) which is reduced by depreciation, making Capex = Δ(Net PP&E) + Depreciation correct
  • Updated all affected test fixtures (5 files) with net_ppe values and recalculated expected cash/capex amounts

Closes #354

Test plan

  • test_cash_flow_statement.py — 18 tests pass (capex, investing CF, reconciliation)
  • test_cash_reconciliation.py — 9 tests pass (all reconciliation scenarios)
  • test_financial_statements.py — 37 tests pass (generator, balance sheet, income statement, cash flow)
  • test_financial_statements_coverage.py — 41 tests pass (coverage edge cases including capex missing-dep error)
  • test_depreciation_tracking.py, test_balance_sheet_classification.py, test_working_capital_changes.py, test_dividend_phantom_payments.py — 59 tests pass (no regressions)
  • test_manufacturer_methods.py, test_manufacturer_coverage.py, test_roe_insurance.py, test_excel_reporter.py — 94 tests pass (no regressions)
  • All pre-commit hooks pass (black, isort, mypy, pylint, conventional commit)

…nt (#354)

The cash flow statement's capex calculation used gross PP&E, which is not
reduced by depreciation.  The formula Capex = ΔPP&E + Depreciation is
only correct with **net** PP&E.  With gross PP&E the depreciation was
added back in operating activities *and* subtracted again as investing
capex, making cash flow from investing too negative by the full
depreciation amount.

Switch _calculate_capex to read net_ppe instead of gross_ppe and update
all affected test fixtures (cash balances, expected capex, comments).
@github-actions
Copy link

github-actions bot commented Feb 8, 2026

Coverage Report

Name Stmts Miss Cover
__init__.py 71 3 96%
_run_analysis.py 171 3 98%
_version.py 1 0 100%
accrual_manager.py 147 0 100%
accuracy_validator.py 275 18 93%
adaptive_stopping.py 307 1 99%
batch_processor.py 292 2 99%
benchmarking.py 265 17 94%
bootstrap_analysis.py 220 0 100%
business_optimizer.py 443 2 99%
claim_development.py 142 2 99%
claim_liability.py 63 7 89%
config/__init__.py 10 0 100%
config/constants.py 2 0 100%
config/core.py 178 2 99%
config/insurance.py 62 0 100%
config/manufacturer.py 142 0 100%
config/market.py 74 0 100%
config/optimizer.py 60 0 100%
config/presets.py 60 0 100%
config/reporting.py 37 0 100%
config/simulation.py 46 0 100%
config_compat.py 128 14 89%
config_loader.py 101 3 97%
config_manager.py 201 10 95%
config_migrator.py 162 8 95%
convergence.py 168 3 98%
convergence_advanced.py 268 0 100%
convergence_plots.py 308 4 99%
decimal_utils.py 29 1 97%
decision_engine.py 688 6 99%
ergodic_analyzer.py 266 1 99%
examples/__init__.py 0 0 100%
examples/__main__.py 9 9 0%
examples/benchmark_parallel.py 142 142 0%
examples/demo_claim_development.py 118 118 0%
examples/demo_collateral_management.py 79 79 0%
examples/demo_config_practical.py 167 167 0%
examples/demo_config_v2.py 155 155 0%
examples/demo_excel_reports.py 106 106 0%
examples/demo_insurance_pricing.py 183 183 0%
examples/demo_manufacturer.py 69 69 0%
examples/demo_stochastic.py 144 144 0%
examples/improved_retention_optimization.py 129 129 0%
examples/simple_retention_optimization.py 114 114 0%
examples/test_notebook_comprehensive.py 113 113 0%
examples/test_notebook_fixes.py 57 57 0%
examples/test_smart_annotations.py 97 97 0%
excel_reporter.py 517 16 97%
exposure_base.py 252 0 100%
financial_statements.py 716 3 99%
hjb_solver.py 476 21 96%
insurance.py 110 0 100%
insurance_accounting.py 104 0 100%
insurance_pricing.py 187 2 99%
insurance_program.py 544 10 98%
internals.py 4 0 100%
ledger.py 329 1 99%
loss_distributions.py 366 2 99%
manufacturer.py 292 20 93%
manufacturer_balance_sheet.py 229 7 97%
manufacturer_claims.py 290 15 95%
manufacturer_income.py 87 9 90%
manufacturer_metrics.py 104 5 95%
manufacturer_solvency.py 100 5 95%
monte_carlo.py 706 1 99%
monte_carlo_worker.py 81 0 100%
optimal_control.py 307 3 99%
optimization.py 312 0 100%
parallel_executor.py 280 13 95%
parameter_sweep.py 299 9 97%
pareto_frontier.py 302 2 99%
performance_optimizer.py 254 10 96%
progress_monitor.py 179 3 98%
reporting/__init__.py 10 0 100%
reporting/cache_manager.py 440 4 99%
reporting/config.py 92 0 100%
reporting/executive_report.py 183 0 100%
reporting/formatters.py 227 0 100%
reporting/insight_extractor.py 219 0 100%
reporting/report_builder.py 202 4 98%
reporting/scenario_comparator.py 242 2 99%
reporting/table_generator.py 254 1 99%
reporting/technical_report.py 171 0 100%
reporting/validator.py 211 0 100%
result_aggregator.py 246 4 98%
risk_metrics.py 427 19 96%
ruin_probability.py 273 0 100%
safe_pickle.py 55 0 100%
scenario_manager.py 162 1 99%
sensitivity.py 247 0 100%
sensitivity_visualization.py 184 1 99%
simulation.py 286 1 99%
statistical_tests.py 150 0 100%
stochastic_processes.py 67 1 99%
strategy_backtester.py 208 0 100%
summary_statistics.py 475 7 99%
tax_handler.py 77 7 91%
tests/__init__.py 0 0 100%
tests/conftest.py 22 2 91%
tests/integration/__init__.py 0 0 100%
tests/integration/test_claim_development_wrapper.py 19 0 100%
tests/integration/test_critical_integrations.py 420 69 84%
tests/integration/test_financial_integration.py 178 3 98%
tests/integration/test_fixtures.py 146 56 62%
tests/integration/test_helpers.py 163 114 30%
tests/integration/test_insurance_stack.py 244 1 99%
tests/integration/test_parallel_worker.py 10 0 100%
tests/integration/test_simulation_pipeline.py 314 61 81%
tests/test_accrual_integration.py 99 0 100%
tests/test_accrual_manager.py 181 0 100%
tests/test_accuracy_validator.py 322 0 100%
tests/test_adaptive_stopping.py 236 6 97%
tests/test_balance_sheet_classification.py 109 0 100%
tests/test_batch_processor.py 344 0 100%
tests/test_batch_processor_coverage.py 199 0 100%
tests/test_benchmarking.py 347 0 100%
tests/test_bootstrap.py 306 0 100%
tests/test_bootstrap_analysis_coverage.py 113 0 100%
tests/test_bootstrap_ci_seed_bug400.py 23 0 100%
tests/test_business_optimizer.py 361 0 100%
tests/test_cache_manager.py 517 0 100%
tests/test_cash_flow_statement.py 136 0 100%
tests/test_cash_reconciliation.py 116 0 100%
tests/test_claim_development.py 276 0 100%
tests/test_config.py 227 0 100%
tests/test_config_compat.py 301 0 100%
tests/test_config_loader.py 298 0 100%
tests/test_config_manager.py 252 1 99%
tests/test_config_manager_coverage.py 191 0 100%
tests/test_config_migrator.py 109 7 94%
tests/test_config_v2.py 280 0 100%
tests/test_config_v2_integration.py 25 0 100%
tests/test_config_validation.py 109 0 100%
tests/test_convergence_advanced.py 188 9 95%
tests/test_convergence_advanced_coverage.py 149 0 100%
tests/test_convergence_bug350.py 77 1 99%
tests/test_convergence_bug396.py 49 0 100%
tests/test_convergence_bug476.py 69 0 100%
tests/test_convergence_ess.py 227 9 96%
tests/test_convergence_extended.py 184 1 99%
tests/test_convergence_plots.py 173 0 100%
tests/test_coverage_gaps_batch1.py 344 0 100%
tests/test_coverage_gaps_batch2.py 397 0 100%
tests/test_coverage_gaps_batch3.py 354 0 100%
tests/test_coverage_gaps_batch4.py 400 1 99%
tests/test_coverage_gaps_parallel_executor.py 338 0 100%
tests/test_decision_engine.py 350 0 100%
tests/test_decision_engine_edge_cases.py 323 2 99%
tests/test_decision_engine_scenarios.py 192 5 97%
tests/test_deep_copy.py 252 0 100%
tests/test_depreciation_tracking.py 169 3 98%
tests/test_dividend_phantom_payments.py 172 1 99%
tests/test_dynamic_premium_scaling.py 109 0 100%
tests/test_end_to_end.py 188 2 99%
tests/test_ergodic_analyzer.py 170 0 100%
tests/test_ergodic_analyzer_coverage.py 383 0 100%
tests/test_excel_reporter.py 273 6 98%
tests/test_execution_semantics.py 160 0 100%
tests/test_executive_visualizations.py 257 1 99%
tests/test_exposure_base.py 241 0 100%
tests/test_exposure_base_coverage.py 211 0 100%
tests/test_figure_factory.py 349 0 100%
tests/test_financial_statements.py 491 2 99%
tests/test_financial_statements_coverage.py 320 0 100%
tests/test_fixtures.py 87 28 68%
tests/test_hjb_numerical.py 739 0 100%
tests/test_hjb_solver.py 260 5 98%
tests/test_imports.py 95 5 95%
tests/test_industry_configs.py 100 0 100%
tests/test_industry_switching.py 94 0 100%
tests/test_insight_extractor.py 313 4 99%
tests/test_insurance.py 272 0 100%
tests/test_insurance_accounting.py 151 0 100%
tests/test_insurance_coverage.py 82 0 100%
tests/test_insurance_pricing.py 276 0 100%
tests/test_insurance_pricing_coverage.py 119 0 100%
tests/test_insurance_program.py 489 0 100%
tests/test_insurance_program_coverage.py 326 0 100%
tests/test_integration.py 228 14 94%
tests/test_ledger.py 371 0 100%
tests/test_ledger_coverage.py 119 0 100%
tests/test_limit_types.py 147 0 100%
tests/test_loss_distributions.py 464 0 100%
tests/test_loss_distributions_coverage.py 111 0 100%
tests/test_manufacturer.py 654 2 99%
tests/test_manufacturer_coverage.py 213 2 99%
tests/test_manufacturer_methods.py 315 0 100%
tests/test_misc_gaps_coverage.py 670 2 99%
tests/test_monte_carlo.py 483 96 80%
tests/test_monte_carlo_coverage.py 619 0 100%
tests/test_monte_carlo_extended.py 193 0 100%
tests/test_monte_carlo_parallel.py 209 7 97%
tests/test_monte_carlo_trajectory_storage.py 86 0 100%
tests/test_monte_carlo_worker_config.py 212 0 100%
tests/test_nol_carryforward.py 207 0 100%
tests/test_optimal_control.py 327 0 100%
tests/test_optimization.py 348 14 96%
tests/test_optimization_coverage.py 136 4 97%
tests/test_parallel_executor.py 280 160 43%
tests/test_parallel_executor_coverage.py 317 70 78%
tests/test_parallel_independence.py 112 0 100%
tests/test_parameter_combinations.py 304 20 93%
tests/test_parameter_sweep.py 243 8 97%
tests/test_pareto_frontier.py 183 1 99%
tests/test_pareto_frontier_coverage.py 122 1 99%
tests/test_performance.py 326 313 4%
tests/test_performance_optimizer.py 336 2 99%
tests/test_periodic_ruin_tracking.py 101 0 100%
tests/test_premium_amortization.py 97 0 100%
tests/test_pricing_scenarios.py 125 0 100%
tests/test_progress_monitor.py 235 0 100%
tests/test_progress_monitor_coverage.py 156 0 100%
tests/test_properties.py 106 0 100%
tests/test_recovery_accounting.py 94 0 100%
tests/test_report_generation.py 356 6 98%
tests/test_reporting_coverage.py 913 7 99%
tests/test_reserve_development.py 286 0 100%
tests/test_result_aggregation.py 593 1 99%
tests/test_result_aggregator_coverage.py 131 0 100%
tests/test_retention_calculation.py 177 0 100%
tests/test_risk_metrics.py 459 0 100%
tests/test_risk_metrics_coverage.py 350 0 100%
tests/test_roe_insurance.py 169 0 100%
tests/test_ruin_probability.py 289 1 99%
tests/test_ruin_probability_coverage.py 119 0 100%
tests/test_run_analysis.py 116 0 100%
tests/test_safe_pickle_coverage.py 132 0 100%
tests/test_scenario_batch.py 334 0 100%
tests/test_scenario_comparator.py 188 0 100%
tests/test_scenario_manager.py 290 0 100%
tests/test_sensitivity.py 251 0 100%
tests/test_sensitivity_coverage.py 204 1 99%
tests/test_sensitivity_visualization.py 174 0 100%
tests/test_setup.py 30 2 93%
tests/test_simulation.py 172 6 97%
tests/test_simulation_coverage.py 344 1 99%
tests/test_skipped_slow_tests.py 161 149 7%
tests/test_std_ddof1_bug478.py 66 0 100%
tests/test_stochastic.py 120 0 100%
tests/test_strategy_backtester_coverage.py 448 0 100%
tests/test_summary_statistics_coverage.py 413 0 100%
tests/test_table_generation.py 290 3 99%
tests/test_tax_handling.py 262 0 100%
tests/test_technical_plots.py 447 3 99%
tests/test_trajectory_storage.py 253 0 100%
tests/test_trends.py 354 2 99%
tests/test_validation_metrics_coverage.py 103 0 100%
tests/test_visualization.py 228 0 100%
tests/test_visualization_comprehensive.py 520 0 100%
tests/test_visualization_extended.py 506 3 99%
tests/test_visualization_factory.py 372 0 100%
tests/test_visualization_gaps_coverage.py 1006 2 99%
tests/test_visualization_simple.py 213 1 99%
tests/test_walk_forward.py 305 20 93%
tests/test_working_capital_calculation.py 142 1 99%
tests/test_working_capital_changes.py 100 0 100%
trajectory_storage.py 227 0 100%
trends.py 197 3 98%
validation_metrics.py 124 0 100%
visualization/__init__.py 13 0 100%
visualization/annotations.py 282 13 95%
visualization/batch_plots.py 205 0 100%
visualization/core.py 69 0 100%
visualization/executive_plots.py 812 21 97%
visualization/export.py 96 5 95%
visualization/figure_factory.py 258 16 94%
visualization/improved_tower_plot.py 153 153 0%
visualization/interactive_plots.py 82 0 100%
visualization/style_manager.py 180 0 100%
visualization/technical_plots.py 810 42 95%
visualization_infra/__init__.py 3 0 100%
visualization_infra/figure_factory.py 256 10 96%
visualization_infra/style_manager.py 180 0 100%
visualization_legacy.py 678 678 0%
walk_forward_validator.py 346 1 99%
TOTAL 64165 4270 93%

Coverage threshold (80%): PASSED

Copy link
Owner Author

@AlexFiliakov AlexFiliakov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good

@AlexFiliakov AlexFiliakov merged commit 2d3a947 into develop Feb 8, 2026
3 checks passed
@AlexFiliakov AlexFiliakov deleted the bugfix/354_capex_double_counts_dep branch February 8, 2026 15:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant