openfactsheet 0.1.0a1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (361) hide show
  1. openfactsheet-0.1.0a1/.gitignore +87 -0
  2. openfactsheet-0.1.0a1/CHANGELOG.md +309 -0
  3. openfactsheet-0.1.0a1/DISCLAIMER.md +56 -0
  4. openfactsheet-0.1.0a1/LICENSE +202 -0
  5. openfactsheet-0.1.0a1/PKG-INFO +454 -0
  6. openfactsheet-0.1.0a1/README.md +367 -0
  7. openfactsheet-0.1.0a1/THIRD_PARTY_NOTICES.md +94 -0
  8. openfactsheet-0.1.0a1/docs/ATTRIBUTION.md +229 -0
  9. openfactsheet-0.1.0a1/docs/assets/openfactsheet_logo.png +0 -0
  10. openfactsheet-0.1.0a1/docs/assumptions.md +71 -0
  11. openfactsheet-0.1.0a1/docs/audits/bacon_wave1_monthly_gap_audit.md +91 -0
  12. openfactsheet-0.1.0a1/docs/audits/regulatory_disclosure_review.md +202 -0
  13. openfactsheet-0.1.0a1/docs/audits/security_alpha_review.md +198 -0
  14. openfactsheet-0.1.0a1/docs/getting_started.md +158 -0
  15. openfactsheet-0.1.0a1/docs/index.md +65 -0
  16. openfactsheet-0.1.0a1/docs/interpretation/active_return.md +95 -0
  17. openfactsheet-0.1.0a1/docs/interpretation/alpha.md +103 -0
  18. openfactsheet-0.1.0a1/docs/interpretation/annualized_arithmetic_mean.md +90 -0
  19. openfactsheet-0.1.0a1/docs/interpretation/annualized_volatility.md +99 -0
  20. openfactsheet-0.1.0a1/docs/interpretation/appraisal_ratio.md +108 -0
  21. openfactsheet-0.1.0a1/docs/interpretation/arithmetic_mean.md +89 -0
  22. openfactsheet-0.1.0a1/docs/interpretation/autocorrelation_lag1.md +89 -0
  23. openfactsheet-0.1.0a1/docs/interpretation/autocorrelation_lag2.md +89 -0
  24. openfactsheet-0.1.0a1/docs/interpretation/autocorrelation_lag3.md +89 -0
  25. openfactsheet-0.1.0a1/docs/interpretation/average_drawdown.md +90 -0
  26. openfactsheet-0.1.0a1/docs/interpretation/average_drawdown_duration.md +90 -0
  27. openfactsheet-0.1.0a1/docs/interpretation/average_recovery_duration.md +91 -0
  28. openfactsheet-0.1.0a1/docs/interpretation/batting_average.md +92 -0
  29. openfactsheet-0.1.0a1/docs/interpretation/bear_beta.md +97 -0
  30. openfactsheet-0.1.0a1/docs/interpretation/best_calendar_year.md +93 -0
  31. openfactsheet-0.1.0a1/docs/interpretation/best_period.md +87 -0
  32. openfactsheet-0.1.0a1/docs/interpretation/best_rolling_year.md +94 -0
  33. openfactsheet-0.1.0a1/docs/interpretation/beta.md +98 -0
  34. openfactsheet-0.1.0a1/docs/interpretation/bias_ratio.md +91 -0
  35. openfactsheet-0.1.0a1/docs/interpretation/bull_beta.md +97 -0
  36. openfactsheet-0.1.0a1/docs/interpretation/burke_ratio.md +98 -0
  37. openfactsheet-0.1.0a1/docs/interpretation/cagr.md +96 -0
  38. openfactsheet-0.1.0a1/docs/interpretation/calmar_ratio.md +100 -0
  39. openfactsheet-0.1.0a1/docs/interpretation/capture_ratio.md +101 -0
  40. openfactsheet-0.1.0a1/docs/interpretation/cdar_95.md +91 -0
  41. openfactsheet-0.1.0a1/docs/interpretation/correlation.md +92 -0
  42. openfactsheet-0.1.0a1/docs/interpretation/cumulative_return.md +92 -0
  43. openfactsheet-0.1.0a1/docs/interpretation/current_drawdown.md +88 -0
  44. openfactsheet-0.1.0a1/docs/interpretation/downside_capture.md +100 -0
  45. openfactsheet-0.1.0a1/docs/interpretation/downside_deviation.md +100 -0
  46. openfactsheet-0.1.0a1/docs/interpretation/downside_potential.md +88 -0
  47. openfactsheet-0.1.0a1/docs/interpretation/drawdown_at_risk_95.md +90 -0
  48. openfactsheet-0.1.0a1/docs/interpretation/drawdown_count.md +89 -0
  49. openfactsheet-0.1.0a1/docs/interpretation/edar_95.md +92 -0
  50. openfactsheet-0.1.0a1/docs/interpretation/evar_95.md +89 -0
  51. openfactsheet-0.1.0a1/docs/interpretation/excess_kurtosis.md +91 -0
  52. openfactsheet-0.1.0a1/docs/interpretation/expected_shortfall_historical_95.md +92 -0
  53. openfactsheet-0.1.0a1/docs/interpretation/factor_alpha.md +112 -0
  54. openfactsheet-0.1.0a1/docs/interpretation/factor_alpha_t_statistic.md +104 -0
  55. openfactsheet-0.1.0a1/docs/interpretation/factor_r_squared.md +99 -0
  56. openfactsheet-0.1.0a1/docs/interpretation/factor_residual_volatility.md +102 -0
  57. openfactsheet-0.1.0a1/docs/interpretation/gain_to_pain_ratio.md +89 -0
  58. openfactsheet-0.1.0a1/docs/interpretation/gaussian_var_95.md +93 -0
  59. openfactsheet-0.1.0a1/docs/interpretation/geometric_mean_return.md +89 -0
  60. openfactsheet-0.1.0a1/docs/interpretation/gini_mean_difference.md +94 -0
  61. openfactsheet-0.1.0a1/docs/interpretation/information_ratio.md +105 -0
  62. openfactsheet-0.1.0a1/docs/interpretation/interquartile_range.md +92 -0
  63. openfactsheet-0.1.0a1/docs/interpretation/jarque_bera_pvalue.md +88 -0
  64. openfactsheet-0.1.0a1/docs/interpretation/kappa_3_ratio.md +93 -0
  65. openfactsheet-0.1.0a1/docs/interpretation/ljung_box_pvalue.md +88 -0
  66. openfactsheet-0.1.0a1/docs/interpretation/longest_drawdown_duration.md +90 -0
  67. openfactsheet-0.1.0a1/docs/interpretation/longest_losing_streak.md +87 -0
  68. openfactsheet-0.1.0a1/docs/interpretation/longest_winning_streak.md +87 -0
  69. openfactsheet-0.1.0a1/docs/interpretation/m_squared.md +107 -0
  70. openfactsheet-0.1.0a1/docs/interpretation/martin_ratio.md +96 -0
  71. openfactsheet-0.1.0a1/docs/interpretation/max_drawdown.md +94 -0
  72. openfactsheet-0.1.0a1/docs/interpretation/max_peak_to_trough_duration.md +90 -0
  73. openfactsheet-0.1.0a1/docs/interpretation/mean_absolute_deviation.md +91 -0
  74. openfactsheet-0.1.0a1/docs/interpretation/mean_return_standard_error.md +92 -0
  75. openfactsheet-0.1.0a1/docs/interpretation/median_drawdown.md +90 -0
  76. openfactsheet-0.1.0a1/docs/interpretation/median_return.md +87 -0
  77. openfactsheet-0.1.0a1/docs/interpretation/minimum_track_record_length.md +95 -0
  78. openfactsheet-0.1.0a1/docs/interpretation/modified_es_95.md +91 -0
  79. openfactsheet-0.1.0a1/docs/interpretation/modified_var_95.md +93 -0
  80. openfactsheet-0.1.0a1/docs/interpretation/negative_period_pct.md +85 -0
  81. openfactsheet-0.1.0a1/docs/interpretation/omega_ratio.md +92 -0
  82. openfactsheet-0.1.0a1/docs/interpretation/pain_index.md +89 -0
  83. openfactsheet-0.1.0a1/docs/interpretation/pain_ratio.md +95 -0
  84. openfactsheet-0.1.0a1/docs/interpretation/payoff_ratio.md +89 -0
  85. openfactsheet-0.1.0a1/docs/interpretation/positive_calendar_years_pct.md +93 -0
  86. openfactsheet-0.1.0a1/docs/interpretation/positive_period_pct.md +87 -0
  87. openfactsheet-0.1.0a1/docs/interpretation/positive_rolling_year_pct.md +94 -0
  88. openfactsheet-0.1.0a1/docs/interpretation/probabilistic_sharpe_ratio.md +97 -0
  89. openfactsheet-0.1.0a1/docs/interpretation/profit_factor.md +90 -0
  90. openfactsheet-0.1.0a1/docs/interpretation/r_squared.md +93 -0
  91. openfactsheet-0.1.0a1/docs/interpretation/recovery_factor.md +91 -0
  92. openfactsheet-0.1.0a1/docs/interpretation/relative_mean_difference.md +92 -0
  93. openfactsheet-0.1.0a1/docs/interpretation/residual_volatility.md +105 -0
  94. openfactsheet-0.1.0a1/docs/interpretation/semi_deviation.md +96 -0
  95. openfactsheet-0.1.0a1/docs/interpretation/sharpe_ratio.md +107 -0
  96. openfactsheet-0.1.0a1/docs/interpretation/sharpe_ratio_autocorrelation_adjusted.md +99 -0
  97. openfactsheet-0.1.0a1/docs/interpretation/sharpe_ratio_standard_error.md +103 -0
  98. openfactsheet-0.1.0a1/docs/interpretation/skewness.md +91 -0
  99. openfactsheet-0.1.0a1/docs/interpretation/skewness_kurtosis_ratio.md +91 -0
  100. openfactsheet-0.1.0a1/docs/interpretation/sortino_ratio.md +102 -0
  101. openfactsheet-0.1.0a1/docs/interpretation/sterling_ratio.md +98 -0
  102. openfactsheet-0.1.0a1/docs/interpretation/tail_ratio.md +89 -0
  103. openfactsheet-0.1.0a1/docs/interpretation/time_underwater_pct.md +87 -0
  104. openfactsheet-0.1.0a1/docs/interpretation/timing_ratio.md +98 -0
  105. openfactsheet-0.1.0a1/docs/interpretation/tracking_error.md +103 -0
  106. openfactsheet-0.1.0a1/docs/interpretation/treynor_ratio.md +103 -0
  107. openfactsheet-0.1.0a1/docs/interpretation/ulcer_index.md +91 -0
  108. openfactsheet-0.1.0a1/docs/interpretation/upside_capture.md +100 -0
  109. openfactsheet-0.1.0a1/docs/interpretation/upside_potential_ratio.md +93 -0
  110. openfactsheet-0.1.0a1/docs/interpretation/var_historical_95.md +91 -0
  111. openfactsheet-0.1.0a1/docs/interpretation/variance_ratio_1y.md +94 -0
  112. openfactsheet-0.1.0a1/docs/interpretation/volatility.md +92 -0
  113. openfactsheet-0.1.0a1/docs/interpretation/volatility_skewness.md +93 -0
  114. openfactsheet-0.1.0a1/docs/interpretation/worst_calendar_year.md +93 -0
  115. openfactsheet-0.1.0a1/docs/interpretation/worst_period.md +87 -0
  116. openfactsheet-0.1.0a1/docs/interpretation/worst_rolling_year.md +94 -0
  117. openfactsheet-0.1.0a1/docs/interpretation/zero_return_pct.md +85 -0
  118. openfactsheet-0.1.0a1/docs/legal/disclaimers.md +19 -0
  119. openfactsheet-0.1.0a1/docs/manual/README.md +64 -0
  120. openfactsheet-0.1.0a1/docs/manual/data/api.json +1032 -0
  121. openfactsheet-0.1.0a1/docs/manual/data/bibliography.json +717 -0
  122. openfactsheet-0.1.0a1/docs/manual/data/documents.json +328 -0
  123. openfactsheet-0.1.0a1/docs/manual/data/methodology.json +341 -0
  124. openfactsheet-0.1.0a1/docs/manual/data/metrics.json +7601 -0
  125. openfactsheet-0.1.0a1/docs/manual/data/package.json +66 -0
  126. openfactsheet-0.1.0a1/docs/manual/lib/style.typ +172 -0
  127. openfactsheet-0.1.0a1/docs/manual/lib/topics.typ +184 -0
  128. openfactsheet-0.1.0a1/docs/manual/openfactsheet-manual.pdf +0 -0
  129. openfactsheet-0.1.0a1/docs/manual/openfactsheet-manual.typ +131 -0
  130. openfactsheet-0.1.0a1/docs/manual/packages/preview/cmarker/0.1.10/LICENSE +7 -0
  131. openfactsheet-0.1.0a1/docs/manual/packages/preview/cmarker/0.1.10/README.md +900 -0
  132. openfactsheet-0.1.0a1/docs/manual/packages/preview/cmarker/0.1.10/lib.typ +462 -0
  133. openfactsheet-0.1.0a1/docs/manual/packages/preview/cmarker/0.1.10/plugin.wasm +0 -0
  134. openfactsheet-0.1.0a1/docs/manual/packages/preview/cmarker/0.1.10/typst.toml +11 -0
  135. openfactsheet-0.1.0a1/docs/manual/packages/preview/mitex/0.2.7/CHANGELOG.md +69 -0
  136. openfactsheet-0.1.0a1/docs/manual/packages/preview/mitex/0.2.7/LICENSE +176 -0
  137. openfactsheet-0.1.0a1/docs/manual/packages/preview/mitex/0.2.7/README.md +154 -0
  138. openfactsheet-0.1.0a1/docs/manual/packages/preview/mitex/0.2.7/lib.typ +1 -0
  139. openfactsheet-0.1.0a1/docs/manual/packages/preview/mitex/0.2.7/mitex.typ +45 -0
  140. openfactsheet-0.1.0a1/docs/manual/packages/preview/mitex/0.2.7/mitex.wasm +0 -0
  141. openfactsheet-0.1.0a1/docs/manual/packages/preview/mitex/0.2.7/specs/README.md +250 -0
  142. openfactsheet-0.1.0a1/docs/manual/packages/preview/mitex/0.2.7/specs/latex/standard.typ +1187 -0
  143. openfactsheet-0.1.0a1/docs/manual/packages/preview/mitex/0.2.7/specs/mod.typ +12 -0
  144. openfactsheet-0.1.0a1/docs/manual/packages/preview/mitex/0.2.7/specs/prelude.typ +230 -0
  145. openfactsheet-0.1.0a1/docs/manual/packages/preview/mitex/0.2.7/typst.toml +12 -0
  146. openfactsheet-0.1.0a1/docs/methodology/decisions/0001-return-type.md +64 -0
  147. openfactsheet-0.1.0a1/docs/methodology/decisions/0002-annualization-and-frequency.md +80 -0
  148. openfactsheet-0.1.0a1/docs/methodology/decisions/0003-standard-deviation.md +55 -0
  149. openfactsheet-0.1.0a1/docs/methodology/decisions/0004-annual-return.md +66 -0
  150. openfactsheet-0.1.0a1/docs/methodology/decisions/0005-risk-free-rate.md +59 -0
  151. openfactsheet-0.1.0a1/docs/methodology/decisions/0006-sortino-downside-deviation.md +61 -0
  152. openfactsheet-0.1.0a1/docs/methodology/decisions/0007-drawdown-conventions.md +78 -0
  153. openfactsheet-0.1.0a1/docs/methodology/decisions/0008-sharpe-ratio.md +69 -0
  154. openfactsheet-0.1.0a1/docs/methodology/decisions/0009-calmar-full-history.md +62 -0
  155. openfactsheet-0.1.0a1/docs/methodology/decisions/0010-var-es-quantiles.md +77 -0
  156. openfactsheet-0.1.0a1/docs/methodology/decisions/0011-skewness-kurtosis.md +65 -0
  157. openfactsheet-0.1.0a1/docs/methodology/decisions/0012-benchmark-alignment-and-relative-metrics.md +97 -0
  158. openfactsheet-0.1.0a1/docs/methodology/decisions/0013-return-scale-detection.md +70 -0
  159. openfactsheet-0.1.0a1/docs/methodology/decisions/0014-smoothing-risk.md +77 -0
  160. openfactsheet-0.1.0a1/docs/methodology/decisions/0015-minimum-data-policy.md +78 -0
  161. openfactsheet-0.1.0a1/docs/methodology/decisions/0016-lower-partial-moment-ratios.md +95 -0
  162. openfactsheet-0.1.0a1/docs/methodology/decisions/0017-drawdown-ratios-burke-sterling-pain.md +83 -0
  163. openfactsheet-0.1.0a1/docs/methodology/decisions/0018-parametric-var.md +82 -0
  164. openfactsheet-0.1.0a1/docs/methodology/decisions/0019-sharpe-ratio-inference.md +98 -0
  165. openfactsheet-0.1.0a1/docs/methodology/decisions/0020-mean-inference-and-normality.md +80 -0
  166. openfactsheet-0.1.0a1/docs/methodology/decisions/0021-drawdown-tail-and-entropic-measures.md +95 -0
  167. openfactsheet-0.1.0a1/docs/methodology/decisions/0022-modified-expected-shortfall.md +71 -0
  168. openfactsheet-0.1.0a1/docs/methodology/decisions/0023-calendar-year-statistics.md +82 -0
  169. openfactsheet-0.1.0a1/docs/methodology/decisions/0024-rolling-one-year-windows.md +66 -0
  170. openfactsheet-0.1.0a1/docs/methodology/decisions/0025-episode-durations-and-path-summaries.md +77 -0
  171. openfactsheet-0.1.0a1/docs/methodology/decisions/0026-canonical-charts.md +131 -0
  172. openfactsheet-0.1.0a1/docs/methodology/decisions/0027-benchmark-relative-additions.md +128 -0
  173. openfactsheet-0.1.0a1/docs/methodology/decisions/0028-factor-models.md +128 -0
  174. openfactsheet-0.1.0a1/docs/methodology/decisions/0029-serial-correlation-and-annualization.md +102 -0
  175. openfactsheet-0.1.0a1/docs/methodology/decisions/0030-pdf-ingestion.md +97 -0
  176. openfactsheet-0.1.0a1/docs/methodology/decisions/0031-ocr-ingestion.md +91 -0
  177. openfactsheet-0.1.0a1/docs/methodology/decisions/0032-identifiers-and-fund-profile.md +102 -0
  178. openfactsheet-0.1.0a1/docs/methodology/decisions/0033-share-classes-and-table-roles.md +96 -0
  179. openfactsheet-0.1.0a1/docs/methodology/decisions/0034-reference-manual.md +123 -0
  180. openfactsheet-0.1.0a1/docs/methodology/decisions/0035-linking-results-to-the-manual.md +98 -0
  181. openfactsheet-0.1.0a1/docs/methodology/decisions/0036-bacon-wave1-monthly-measures.md +187 -0
  182. openfactsheet-0.1.0a1/docs/methodology/decisions/README.md +85 -0
  183. openfactsheet-0.1.0a1/docs/methodology.md +138 -0
  184. openfactsheet-0.1.0a1/docs/metric_catalog.md +164 -0
  185. openfactsheet-0.1.0a1/docs/reference/criteria.md +806 -0
  186. openfactsheet-0.1.0a1/docs/reference/formulas.md +757 -0
  187. openfactsheet-0.1.0a1/docs/reference/notation.md +107 -0
  188. openfactsheet-0.1.0a1/docs/reference/policies.md +424 -0
  189. openfactsheet-0.1.0a1/docs/reference/report_schema.md +415 -0
  190. openfactsheet-0.1.0a1/docs/validation/reference_implementations.md +293 -0
  191. openfactsheet-0.1.0a1/pyproject.toml +172 -0
  192. openfactsheet-0.1.0a1/src/openfactsheet/__init__.py +47 -0
  193. openfactsheet-0.1.0a1/src/openfactsheet/api.py +304 -0
  194. openfactsheet-0.1.0a1/src/openfactsheet/compare/__init__.py +1 -0
  195. openfactsheet-0.1.0a1/src/openfactsheet/compare/alignment.py +240 -0
  196. openfactsheet-0.1.0a1/src/openfactsheet/compare/comparison.py +297 -0
  197. openfactsheet-0.1.0a1/src/openfactsheet/diagnostics/__init__.py +1 -0
  198. openfactsheet-0.1.0a1/src/openfactsheet/diagnostics/autocorrelation.py +70 -0
  199. openfactsheet-0.1.0a1/src/openfactsheet/diagnostics/data_quality.py +188 -0
  200. openfactsheet-0.1.0a1/src/openfactsheet/diagnostics/missingness.py +46 -0
  201. openfactsheet-0.1.0a1/src/openfactsheet/diagnostics/outliers.py +23 -0
  202. openfactsheet-0.1.0a1/src/openfactsheet/diagnostics/smoothing.py +41 -0
  203. openfactsheet-0.1.0a1/src/openfactsheet/diagnostics/stale_returns.py +23 -0
  204. openfactsheet-0.1.0a1/src/openfactsheet/documents/__init__.py +8 -0
  205. openfactsheet-0.1.0a1/src/openfactsheet/documents/identifiers.py +136 -0
  206. openfactsheet-0.1.0a1/src/openfactsheet/documents/labels.py +91 -0
  207. openfactsheet-0.1.0a1/src/openfactsheet/documents/layout.py +72 -0
  208. openfactsheet-0.1.0a1/src/openfactsheet/documents/ocr/__init__.py +32 -0
  209. openfactsheet-0.1.0a1/src/openfactsheet/documents/ocr/base.py +93 -0
  210. openfactsheet-0.1.0a1/src/openfactsheet/documents/ocr/rapid.py +89 -0
  211. openfactsheet-0.1.0a1/src/openfactsheet/documents/ocr/tesseract.py +75 -0
  212. openfactsheet-0.1.0a1/src/openfactsheet/documents/profile.py +401 -0
  213. openfactsheet-0.1.0a1/src/openfactsheet/documents/raster.py +48 -0
  214. openfactsheet-0.1.0a1/src/openfactsheet/documents/share_classes.py +226 -0
  215. openfactsheet-0.1.0a1/src/openfactsheet/documents/tables.py +632 -0
  216. openfactsheet-0.1.0a1/src/openfactsheet/documents/text_pdf.py +66 -0
  217. openfactsheet-0.1.0a1/src/openfactsheet/exceptions.py +69 -0
  218. openfactsheet-0.1.0a1/src/openfactsheet/factors/__init__.py +9 -0
  219. openfactsheet-0.1.0a1/src/openfactsheet/factors/data.py +133 -0
  220. openfactsheet-0.1.0a1/src/openfactsheet/factors/models.py +260 -0
  221. openfactsheet-0.1.0a1/src/openfactsheet/factors/regressions.py +353 -0
  222. openfactsheet-0.1.0a1/src/openfactsheet/input/__init__.py +1 -0
  223. openfactsheet-0.1.0a1/src/openfactsheet/input/arrays.py +36 -0
  224. openfactsheet-0.1.0a1/src/openfactsheet/input/clipboard.py +52 -0
  225. openfactsheet-0.1.0a1/src/openfactsheet/input/csv.py +21 -0
  226. openfactsheet-0.1.0a1/src/openfactsheet/input/dispatcher.py +88 -0
  227. openfactsheet-0.1.0a1/src/openfactsheet/input/excel.py +30 -0
  228. openfactsheet-0.1.0a1/src/openfactsheet/input/image.py +73 -0
  229. openfactsheet-0.1.0a1/src/openfactsheet/input/limits.py +112 -0
  230. openfactsheet-0.1.0a1/src/openfactsheet/input/monthly_table.py +104 -0
  231. openfactsheet-0.1.0a1/src/openfactsheet/input/pandas_input.py +116 -0
  232. openfactsheet-0.1.0a1/src/openfactsheet/input/pdf.py +113 -0
  233. openfactsheet-0.1.0a1/src/openfactsheet/input/values.py +66 -0
  234. openfactsheet-0.1.0a1/src/openfactsheet/interpretation/__init__.py +1 -0
  235. openfactsheet-0.1.0a1/src/openfactsheet/interpretation/engine.py +40 -0
  236. openfactsheet-0.1.0a1/src/openfactsheet/interpretation/glossary.py +36 -0
  237. openfactsheet-0.1.0a1/src/openfactsheet/interpretation/templates.py +178 -0
  238. openfactsheet-0.1.0a1/src/openfactsheet/manual/__init__.py +53 -0
  239. openfactsheet-0.1.0a1/src/openfactsheet/manual/build.py +251 -0
  240. openfactsheet-0.1.0a1/src/openfactsheet/manual/export.py +520 -0
  241. openfactsheet-0.1.0a1/src/openfactsheet/manual/links.py +138 -0
  242. openfactsheet-0.1.0a1/src/openfactsheet/metrics/__init__.py +1 -0
  243. openfactsheet-0.1.0a1/src/openfactsheet/metrics/attribution.py +538 -0
  244. openfactsheet-0.1.0a1/src/openfactsheet/metrics/benchmark.py +1057 -0
  245. openfactsheet-0.1.0a1/src/openfactsheet/metrics/catalog_docs.py +687 -0
  246. openfactsheet-0.1.0a1/src/openfactsheet/metrics/consistency.py +446 -0
  247. openfactsheet-0.1.0a1/src/openfactsheet/metrics/context.py +336 -0
  248. openfactsheet-0.1.0a1/src/openfactsheet/metrics/dependence.py +248 -0
  249. openfactsheet-0.1.0a1/src/openfactsheet/metrics/distribution.py +347 -0
  250. openfactsheet-0.1.0a1/src/openfactsheet/metrics/downside.py +125 -0
  251. openfactsheet-0.1.0a1/src/openfactsheet/metrics/drawdown.py +742 -0
  252. openfactsheet-0.1.0a1/src/openfactsheet/metrics/engine.py +114 -0
  253. openfactsheet-0.1.0a1/src/openfactsheet/metrics/factors.py +278 -0
  254. openfactsheet-0.1.0a1/src/openfactsheet/metrics/path.py +120 -0
  255. openfactsheet-0.1.0a1/src/openfactsheet/metrics/references.py +231 -0
  256. openfactsheet-0.1.0a1/src/openfactsheet/metrics/registry.py +149 -0
  257. openfactsheet-0.1.0a1/src/openfactsheet/metrics/returns.py +441 -0
  258. openfactsheet-0.1.0a1/src/openfactsheet/metrics/risk_adjusted.py +639 -0
  259. openfactsheet-0.1.0a1/src/openfactsheet/metrics/statistical.py +343 -0
  260. openfactsheet-0.1.0a1/src/openfactsheet/metrics/tail.py +400 -0
  261. openfactsheet-0.1.0a1/src/openfactsheet/metrics/volatility.py +261 -0
  262. openfactsheet-0.1.0a1/src/openfactsheet/models/__init__.py +1 -0
  263. openfactsheet-0.1.0a1/src/openfactsheet/models/assumptions.py +81 -0
  264. openfactsheet-0.1.0a1/src/openfactsheet/models/diagnostics.py +118 -0
  265. openfactsheet-0.1.0a1/src/openfactsheet/models/input.py +234 -0
  266. openfactsheet-0.1.0a1/src/openfactsheet/models/metric.py +346 -0
  267. openfactsheet-0.1.0a1/src/openfactsheet/models/report.py +288 -0
  268. openfactsheet-0.1.0a1/src/openfactsheet/normalization/__init__.py +1 -0
  269. openfactsheet-0.1.0a1/src/openfactsheet/normalization/dates.py +46 -0
  270. openfactsheet-0.1.0a1/src/openfactsheet/normalization/frequency.py +201 -0
  271. openfactsheet-0.1.0a1/src/openfactsheet/normalization/returns.py +209 -0
  272. openfactsheet-0.1.0a1/src/openfactsheet/normalization/scaling.py +120 -0
  273. openfactsheet-0.1.0a1/src/openfactsheet/normalization/validation.py +36 -0
  274. openfactsheet-0.1.0a1/src/openfactsheet/policy/__init__.py +1 -0
  275. openfactsheet-0.1.0a1/src/openfactsheet/policy/annualization.py +43 -0
  276. openfactsheet-0.1.0a1/src/openfactsheet/policy/applicability.py +77 -0
  277. openfactsheet-0.1.0a1/src/openfactsheet/policy/confidence.py +251 -0
  278. openfactsheet-0.1.0a1/src/openfactsheet/policy/defaults.py +289 -0
  279. openfactsheet-0.1.0a1/src/openfactsheet/policy/methodology_version.py +9 -0
  280. openfactsheet-0.1.0a1/src/openfactsheet/policy/risk_free.py +22 -0
  281. openfactsheet-0.1.0a1/src/openfactsheet/policy/thresholds.py +223 -0
  282. openfactsheet-0.1.0a1/src/openfactsheet/py.typed +0 -0
  283. openfactsheet-0.1.0a1/src/openfactsheet/report/__init__.py +1 -0
  284. openfactsheet-0.1.0a1/src/openfactsheet/report/builder.py +134 -0
  285. openfactsheet-0.1.0a1/src/openfactsheet/report/charts.py +889 -0
  286. openfactsheet-0.1.0a1/src/openfactsheet/report/html.py +432 -0
  287. openfactsheet-0.1.0a1/src/openfactsheet/report/json.py +84 -0
  288. openfactsheet-0.1.0a1/src/openfactsheet/report/markdown.py +207 -0
  289. openfactsheet-0.1.0a1/src/openfactsheet/report/tables.py +284 -0
  290. openfactsheet-0.1.0a1/src/openfactsheet/report/terminal.py +248 -0
  291. openfactsheet-0.1.0a1/src/openfactsheet/utils/__init__.py +1 -0
  292. openfactsheet-0.1.0a1/src/openfactsheet/utils/math.py +47 -0
  293. openfactsheet-0.1.0a1/src/openfactsheet/version.py +3 -0
  294. openfactsheet-0.1.0a1/tests/__init__.py +0 -0
  295. openfactsheet-0.1.0a1/tests/conftest.py +43 -0
  296. openfactsheet-0.1.0a1/tests/cross_library/__init__.py +0 -0
  297. openfactsheet-0.1.0a1/tests/cross_library/test_factor_models.py +62 -0
  298. openfactsheet-0.1.0a1/tests/cross_library/test_performanceanalytics.py +290 -0
  299. openfactsheet-0.1.0a1/tests/cross_library/test_python_references.py +194 -0
  300. openfactsheet-0.1.0a1/tests/fixtures/benchmark_case_benchmark.csv +103 -0
  301. openfactsheet-0.1.0a1/tests/fixtures/benchmark_case_fund.csv +103 -0
  302. openfactsheet-0.1.0a1/tests/fixtures/factor_case_factors.csv +133 -0
  303. openfactsheet-0.1.0a1/tests/fixtures/factor_case_fund.csv +109 -0
  304. openfactsheet-0.1.0a1/tests/fixtures/monthly_fund_10y.csv +121 -0
  305. openfactsheet-0.1.0a1/tests/fixtures/negative_fund.csv +61 -0
  306. openfactsheet-0.1.0a1/tests/fixtures/ocr_fake.py +61 -0
  307. openfactsheet-0.1.0a1/tests/fixtures/pdf_writer.py +104 -0
  308. openfactsheet-0.1.0a1/tests/fixtures/reference/factor_models.json +29 -0
  309. openfactsheet-0.1.0a1/tests/fixtures/reference/performanceanalytics.json +254 -0
  310. openfactsheet-0.1.0a1/tests/fixtures/smoothed_hedge_fund.csv +97 -0
  311. openfactsheet-0.1.0a1/tests/golden/__init__.py +0 -0
  312. openfactsheet-0.1.0a1/tests/golden/benchmark_case.json +4133 -0
  313. openfactsheet-0.1.0a1/tests/golden/cases.py +36 -0
  314. openfactsheet-0.1.0a1/tests/golden/factor_case.json +4154 -0
  315. openfactsheet-0.1.0a1/tests/golden/monthly_fund_10y.json +4006 -0
  316. openfactsheet-0.1.0a1/tests/golden/negative_fund.json +3598 -0
  317. openfactsheet-0.1.0a1/tests/golden/smoothed_hedge_fund.json +3876 -0
  318. openfactsheet-0.1.0a1/tests/golden/test_golden.py +47 -0
  319. openfactsheet-0.1.0a1/tests/integration/__init__.py +0 -0
  320. openfactsheet-0.1.0a1/tests/integration/test_acceptance.py +131 -0
  321. openfactsheet-0.1.0a1/tests/integration/test_charts.py +255 -0
  322. openfactsheet-0.1.0a1/tests/integration/test_ocr_engines.py +112 -0
  323. openfactsheet-0.1.0a1/tests/integration/test_reports.py +163 -0
  324. openfactsheet-0.1.0a1/tests/property/__init__.py +0 -0
  325. openfactsheet-0.1.0a1/tests/property/test_identities.py +79 -0
  326. openfactsheet-0.1.0a1/tests/unit/__init__.py +0 -0
  327. openfactsheet-0.1.0a1/tests/unit/diagnostics/__init__.py +0 -0
  328. openfactsheet-0.1.0a1/tests/unit/diagnostics/test_diagnostics.py +65 -0
  329. openfactsheet-0.1.0a1/tests/unit/documents/__init__.py +0 -0
  330. openfactsheet-0.1.0a1/tests/unit/documents/test_identifiers.py +89 -0
  331. openfactsheet-0.1.0a1/tests/unit/documents/test_ocr_rules.py +164 -0
  332. openfactsheet-0.1.0a1/tests/unit/documents/test_profile.py +168 -0
  333. openfactsheet-0.1.0a1/tests/unit/documents/test_share_classes.py +219 -0
  334. openfactsheet-0.1.0a1/tests/unit/documents/test_tables.py +76 -0
  335. openfactsheet-0.1.0a1/tests/unit/factors/__init__.py +0 -0
  336. openfactsheet-0.1.0a1/tests/unit/factors/test_factors.py +259 -0
  337. openfactsheet-0.1.0a1/tests/unit/input/__init__.py +0 -0
  338. openfactsheet-0.1.0a1/tests/unit/input/test_input.py +148 -0
  339. openfactsheet-0.1.0a1/tests/unit/input/test_pdf.py +194 -0
  340. openfactsheet-0.1.0a1/tests/unit/metrics/__init__.py +0 -0
  341. openfactsheet-0.1.0a1/tests/unit/metrics/test_bacon_wave1.py +279 -0
  342. openfactsheet-0.1.0a1/tests/unit/metrics/test_benchmark_additions.py +204 -0
  343. openfactsheet-0.1.0a1/tests/unit/metrics/test_direction_labels.py +112 -0
  344. openfactsheet-0.1.0a1/tests/unit/metrics/test_edge_cases.py +121 -0
  345. openfactsheet-0.1.0a1/tests/unit/metrics/test_formulas.py +203 -0
  346. openfactsheet-0.1.0a1/tests/unit/metrics/test_path.py +54 -0
  347. openfactsheet-0.1.0a1/tests/unit/metrics/test_phase2b.py +168 -0
  348. openfactsheet-0.1.0a1/tests/unit/metrics/test_serial_correlation.py +129 -0
  349. openfactsheet-0.1.0a1/tests/unit/normalization/__init__.py +0 -0
  350. openfactsheet-0.1.0a1/tests/unit/normalization/test_frequency.py +70 -0
  351. openfactsheet-0.1.0a1/tests/unit/normalization/test_normalize.py +125 -0
  352. openfactsheet-0.1.0a1/tests/unit/normalization/test_scaling.py +71 -0
  353. openfactsheet-0.1.0a1/tests/unit/policy/__init__.py +0 -0
  354. openfactsheet-0.1.0a1/tests/unit/policy/test_policy.py +81 -0
  355. openfactsheet-0.1.0a1/tests/unit/test_criteria_docs.py +36 -0
  356. openfactsheet-0.1.0a1/tests/unit/test_disclaimer.py +146 -0
  357. openfactsheet-0.1.0a1/tests/unit/test_generated_docs.py +40 -0
  358. openfactsheet-0.1.0a1/tests/unit/test_links.py +165 -0
  359. openfactsheet-0.1.0a1/tests/unit/test_manual.py +234 -0
  360. openfactsheet-0.1.0a1/tests/unit/test_registry.py +77 -0
  361. openfactsheet-0.1.0a1/tests/unit/test_security.py +184 -0
@@ -0,0 +1,87 @@
1
+ # ---------------------------------------------------------------------------
2
+ # Secrets and credentials — never commit these.
3
+ # ---------------------------------------------------------------------------
4
+ .env
5
+ .env.*
6
+ !.env.example
7
+ *.pem
8
+ *.key
9
+ *.p12
10
+ *.pfx
11
+ *.jks
12
+ *.keystore
13
+ id_rsa*
14
+ id_ed25519*
15
+ credentials*.json
16
+ service-account*.json
17
+ secrets.*
18
+ *.secret
19
+ *.secrets
20
+ .netrc
21
+ .pypirc
22
+ token.txt
23
+ *.token
24
+
25
+ # Local Claude Code settings (may contain machine-specific permissions)
26
+ .claude/settings.local.json
27
+
28
+ # Private / proprietary return data — keep outside the repository.
29
+ data/private/
30
+ private/
31
+ *.private.csv
32
+ *.private.xlsx
33
+
34
+ # ---------------------------------------------------------------------------
35
+ # Python
36
+ # ---------------------------------------------------------------------------
37
+ __pycache__/
38
+ *.py[cod]
39
+ *$py.class
40
+ *.so
41
+ build/
42
+ dist/
43
+ *.egg-info/
44
+ .eggs/
45
+ pip-wheel-metadata/
46
+ .venv/
47
+ venv/
48
+ env/
49
+
50
+ # Tooling caches
51
+ .pytest_cache/
52
+ .mypy_cache/
53
+ .ruff_cache/
54
+ .hypothesis/
55
+ .coverage
56
+ .coverage.*
57
+ coverage.xml
58
+ htmlcov/
59
+ .tox/
60
+ .nox/
61
+
62
+ # Notebooks
63
+ .ipynb_checkpoints/
64
+
65
+ # R
66
+ .Rhistory
67
+ .RData
68
+ .Rproj.user/
69
+
70
+ # Full-resolution logo artwork (1.2 MB) kept locally; the web-optimized copy used
71
+ # by the README is committed as docs/assets/openfactsheet_logo.png.
72
+ /OpenFactsheet_logo.png
73
+
74
+ # Generated reports from local experiments
75
+ /factsheet*.html
76
+ /factsheet*.json
77
+ examples/factsheet_example.*
78
+ *.log
79
+
80
+ # OS / editor
81
+ .DS_Store
82
+ Thumbs.db
83
+ desktop.ini
84
+ .idea/
85
+ .vscode/
86
+ *.swp
87
+ *~
@@ -0,0 +1,309 @@
1
+ # Changelog
2
+
3
+ All notable changes are recorded here. OpenFactsheet versions the **package**
4
+ and the **methodology** separately: a methodology version change means reported
5
+ numbers, statuses or conventions changed.
6
+
7
+ ## [0.1.0a1] — 2026-10-16
8
+
9
+ Package 0.1.0a1 (public alpha) · Methodology 0.1.0
10
+
11
+ ### Added
12
+ - Canonical pipeline: input → normalization → data-quality diagnostics →
13
+ metrics → applicability/confidence policy → interpretation → reports.
14
+ - Inputs: lists, tuples, NumPy arrays, pandas Series/DataFrames, CSV, Excel
15
+ (optional extra), wide monthly-return tables, pasted table text.
16
+ - Deterministic percent/decimal classifier; calendar-based frequency inference.
17
+ - 48 canonical metrics (returns, volatility, drawdowns, risk-adjusted, tail,
18
+ distribution, consistency, serial dependence, benchmark-relative) with full
19
+ registry documentation and generated per-metric pages.
20
+ - Data-quality diagnostics: missing values/periods, stale and repeated returns,
21
+ outliers, impossible returns, serial correlation, smoothing risk.
22
+ - Reports: terminal, Markdown, HTML, deterministic JSON; `ofs.compare()` with
23
+ common-period analysis and no ranking.
24
+ - Every result links to the reference-manual topic that defines it:
25
+ `MetricResult.documentation` and `FactsheetReport.documentation`, a
26
+ `documentation` key on every metric in the JSON and a top-level
27
+ `documentation` block, linked metric names in the Markdown and HTML reports.
28
+ The links are pinned to the version that produced the result (decision 0035).
29
+ - Tests: unit, property-based, golden reports, CLAUDE.md acceptance tests 1–3,
30
+ cross-library validation against PerformanceAnalytics, empyrical, QuantStats.
31
+
32
+ ### Added — Public-alpha status, creator credit, disclaimer and attribution
33
+ - README states **Public alpha** · Methodology 0.1.0 with a caution to validate
34
+ results, and a Creator section (Prof. Andrés A. Bagnasco, with LinkedIn link);
35
+ `CITATION.cff` and `pyproject.toml` credit him alongside the contributors.
36
+ - `DISCLAIMER.md` is the single source of the disclosure (proposed text, counsel
37
+ review pending). Its short notice (`interpretation.glossary.SHORT_DISCLAIMER`)
38
+ appears, with a link to the full text, at the top and end of the terminal,
39
+ Markdown and HTML reports, in `ofs.compare(...).summary()` and on the manual's
40
+ title page; the manual includes the full text. The JSON schema is unchanged.
41
+ - `docs/ATTRIBUTION.md`, generated from the registry and
42
+ `metrics/attribution.py`, credits each metric's originator(s) and seminal
43
+ work with an uncertainty flag (Bacon as a secondary reference); a test requires
44
+ an entry for every registered metric.
45
+ - `THIRD_PARTY_NOTICES.md` (dependency and vendored-component licenses) and
46
+ `docs/audits/regulatory_disclosure_review.md` (regulatory questions for
47
+ counsel; no compliance claim).
48
+
49
+ ### Added — Bacon Wave 1: monthly-return measures (5 metrics; 102 in total)
50
+ - `gini_mean_difference`: Gini's mean difference over the n(n − 1) ordered
51
+ pairs (Bacon eq. 2.8), per period, computed in O(n log n) from the sorted
52
+ returns; agrees with skfolio `gini_mean_difference`.
53
+ - `relative_mean_difference`: mean difference over the **signed** mean
54
+ (Bacon eq. 2.9); undefined when the mean is zero, negative for losing
55
+ histories (documented).
56
+ - `skewness_kurtosis_ratio`: Watanabe's ratio G1 / (G2 + 3) from the canonical
57
+ bias-corrected estimators (Bacon eq. 3.7); undefined when G2 + 3 <= 0.
58
+ PerformanceAnalytics' population-moment g1 / b2 is a pinned known difference.
59
+ - `bias_ratio`: Abdulali's bias ratio (Bacon eq. 10.17) with the sample
60
+ standard deviation and closed intervals, a zero return counted on both
61
+ sides; a neutral shape diagnostic, explicitly not a fraud detector.
62
+ - `volatility_skewness`: UPM2 / LPM2 at the 0% target (Bacon eq. 6.32);
63
+ agrees with PerformanceAnalytics `VolatilitySkewness`. Variability skewness
64
+ (its square root) is not registered.
65
+ - None is annualized. No existing metric value, status or convention changes;
66
+ methodology stays 0.1.0. Gap audit in
67
+ `docs/audits/bacon_wave1_monthly_gap_audit.md`; decision 0036.
68
+
69
+ ### Added — Share classes, table roles and document benchmarks (decision 0033)
70
+ - Tables with a fund row and a benchmark row per year (and optional relative
71
+ rows) are read as separate series with roles (fund / benchmark / relative /
72
+ unknown); a benchmark table is also recognized by its caption.
73
+ - `ofs.load(document)` returns the benchmark returns as a separate series;
74
+ `ofs.analyze(document)` uses the fund series and says the benchmark returns
75
+ were not used. A benchmark-only document is not analyzed as the fund.
76
+ - Share classes are detected (class tables or class-and-ISIN lines) and the
77
+ returns table is attributed to one by fixed evidence rules (caption/footnote,
78
+ performance heading, single class, currency); otherwise the report says it is
79
+ ambiguous and lists the candidates.
80
+
81
+ ### Added — Reference manual (decision 0034)
82
+ - A CRAN-style PDF reference manual generated from the code: title page,
83
+ contents, one topic per public function and class (from docstrings), one topic
84
+ per metric (formula, usage, whether annualized, interpretation, assumptions,
85
+ when it misleads, minimum data, calculation and confidence criteria, reference
86
+ implementations, references, related decisions), the methodology documents,
87
+ every decision note, validation, a bibliography with back-links and an index.
88
+ - Every topic has a stable PDF named destination (`metric-<id>`, `api-<name>`,
89
+ `decision-<nnnn>`, ...).
90
+ - Built offline and reproducibly with Typst (`pip install openfactsheet[docs]`,
91
+ `python scripts/build_manual.py`); vendored MiTeX and cmarker; PDF/A-2b. CI
92
+ builds it on every change and fails on any formula or link that does not compile.
93
+ - The manual's data (`docs/manual/data/*.json`) is generated by
94
+ `scripts/generate_docs.py`, from the same per-metric record as the Markdown pages.
95
+ - Complete Google-style docstrings for the public API; a test requires every
96
+ argument to be documented.
97
+
98
+ ### Security (pre-release review, 2026-10-16)
99
+ - Security review of the public alpha: `docs/audits/security_alpha_review.md`
100
+ (automated scans plus manual review; not a third-party audit). No metric
101
+ value, status or methodology convention changed.
102
+ - Explicit resource limits on untrusted inputs, defined in
103
+ `openfactsheet.input.limits`: file size, Excel uncompressed size, image and
104
+ rendered-page pixels, PDF pages, Tesseract run time. Oversized inputs are
105
+ refused with `InputError` / `OCRExtractionError`.
106
+ - Markdown reports write `<`/`>` in names as entities and fence document text
107
+ with a fence it cannot close; terminal reports replace control characters.
108
+ - Dependency floors raised past known advisories: `pypdf>=6.19`,
109
+ `Pillow>=12.3`; `defusedxml` added to the `excel` extra.
110
+ - CI: GitHub Actions pinned to commit SHAs, least-privilege workflow
111
+ permissions, `persist-credentials: false`, Dependabot for pip and Actions.
112
+
113
+ ### Changed (pre-release)
114
+ - The reference manual can be downloaded as one file from the `manual-latest`
115
+ pre-release (updated by `.github/workflows/manual.yml` whenever the PDF on
116
+ `main` changes); published releases get the manual of their version attached.
117
+ - The reference manual PDF is committed (`docs/manual/openfactsheet-manual.pdf`).
118
+ It records a digest of its sources, and the test suite and CI fail when it is
119
+ stale. Its date is the version's CHANGELOG release date ("unreleased" before
120
+ release). Typst is pinned exactly, and the file is packed with pikepdf
121
+ (2.4 MB instead of 6.5 MB).
122
+ - Documentation of the 16 metrics that state a loss as a negative number (drawdowns,
123
+ VaR, expected shortfall, worst period/calendar year/rolling year) now says
124
+ "smaller loss is better (−10% beats −25%)" instead of "higher is better", which
125
+ read as "a bigger drawdown is better". The machine field `direction` is unchanged
126
+ (`higher_is_better` on the signed value); the metrics are flagged `signed_loss`
127
+ in the registry and `ofs.metric_catalog()`, and registration rejects an unflagged
128
+ drawdown or tail return.
129
+ - `factor_alpha_t_statistic` formula written with `\left\lfloor`/`\right\rfloor`
130
+ (display only) so every formula compiles in the manual.
131
+ - A PDF with a fund table and a benchmark table no longer raises in `analyze()`;
132
+ it analyzes the fund table (decision 0033).
133
+
134
+ ### Added — Fund profile from documents (decision 0032)
135
+ - PDF and image inputs yield a `DocumentProfile` (`report.document`, JSON
136
+ `document`): fund name, objective, benchmark name(s), currency, launch date
137
+ and identifiers, each with evidence (page, line, snippet, rule) and a
138
+ confidence. Shown in section 1 of every renderer.
139
+ - Identifier validation by check digit (ISIN, CUSIP, SEDOL, LEI, FIGI; never
140
+ corrected), label-only codes (WKN, Valor, Bloomberg ticker, RIC), and links
141
+ to the national code embedded in an ISIN (DE/WKN, US/CA/CUSIP, GB/IE/SEDOL,
142
+ CH/LI/Valor). Labels in English, German, French, Spanish and Italian.
143
+ - A benchmark named in the document is shown with a note that its returns were
144
+ not supplied; it is never used as benchmark returns.
145
+
146
+ ### Added — OCR of screenshots and scanned PDFs
147
+ - `ofs.analyze("table.png")` and scanned (image-only) PDF pages are recognized
148
+ by a local OCR engine: RapidOCR by default with the models bundled in its
149
+ wheel (never downloaded; the model hashes are recorded), Tesseract as an
150
+ alternative (`ofs.load(path, ocr_engine="tesseract")`). Extras `ocr` and
151
+ `tesseract` (decision 0031).
152
+ - Recognized tables use the same position-based reconstruction as PDF text
153
+ (new `openfactsheet.documents` layer) with stricter acceptance: cells below
154
+ 0.90 confidence, a missing total column or any unreconciled year refuse the
155
+ table; documented character repairs and up to three unreadable month headers
156
+ are allowed but recorded and lower the confidence to moderate.
157
+ - Every renderer now shows document extractions in section 1: engine,
158
+ confidence, checks (with the reconciliation tolerance) and the table exactly
159
+ as read.
160
+ - `ocr` pytest marker and CI job; engine-independent rule tests use a fake
161
+ engine.
162
+
163
+ ### Fixed (pre-release, comparison)
164
+ - `ofs.compare(..., benchmark=...)`: the common-period re-analysis re-read the
165
+ benchmark with a decimal declaration, so a benchmark supplied in percent was
166
+ taken 100 times too large (e.g. beta 0.0013 instead of 0.13). The benchmark is
167
+ now normalized once, exactly as for the full-history reports, and the
168
+ common-period reports keep each fund's original scale evidence.
169
+
170
+ ### Added — Phase 6: PDF factsheets (embedded text)
171
+ - `ofs.load("factsheet.pdf")` / `ofs.analyze(...)` read monthly-return tables from
172
+ PDFs with embedded text (optional extra `openfactsheet[pdf]`, pypdf). Values are
173
+ assigned to month columns by their position under the header (a row of a fund
174
+ launched in April is never shifted to January), each year is reconciled with
175
+ its YTD cell, and any inconsistency refuses the table with the reconstructed
176
+ table in the error (decision 0030). Scanned PDFs are refused (no OCR yet).
177
+ - Extraction confidence (high / moderate) and its reasons are shown in the input
178
+ warnings; `provenance.extraction` records the engine and version, the file's
179
+ SHA-256, the page, the checks and the reconstructed table.
180
+ - `RawReturns.warnings` carries parser warnings into `InputDiagnostics`.
181
+
182
+ ### Added — Phase 2, fourth increment (3 metrics; 97 in total)
183
+ - `variance_ratio_1y` (supplementary): variance ratio at the one-year horizon
184
+ from the sample autocorrelations, with i.i.d. standard error, z and p-value —
185
+ a direct test of square-root-of-time annualization.
186
+ - `sharpe_ratio_autocorrelation_adjusted`: Lo (2002) annualization of the
187
+ Sharpe ratio, `SR_per_period × sqrt(q / VR(q))`; for the smoothed hedge-fund
188
+ fixture it is 1.57 against a conventional 2.38. The conventional Sharpe ratio
189
+ is unchanged; an interpretation note states both.
190
+ - `profit_factor`: gross gains / gross losses (validated against QuantStats).
191
+ - Both serial-correlation statistics need two years of data; confidence policy
192
+ `long_horizon_dependence` (low below 5 years, moderate below 10). Decision 0029.
193
+
194
+ ### Added — Phase 7: factor models (4 metrics; 94 in total)
195
+ - `ofs.analyze(returns, factors=...)` and `ofs.compare(..., factors=...)` accept
196
+ caller-supplied factor returns (DataFrame, CSV/Excel path or table text; one
197
+ column per factor). A column named `RF` is the risk-free rate and is subtracted
198
+ from fund returns. Factor data are never downloaded.
199
+ - One return scale is detected jointly for all factor columns (so a small RF
200
+ column in percent is never read as decimals); periods missing for the fund or
201
+ any factor are dropped, never filled; frequency mismatches raise the new
202
+ `FactorAlignmentError`.
203
+ - OLS with Newey-West (HAC) standard errors, fixed lag `floor(4 (m/100)^(2/9))`,
204
+ no prewhitening, small-sample factor and Student t inference (decision 0028).
205
+ Known factor sets are labelled (CAPM, Fama-French 3/5, Carhart).
206
+ - New `factors` category: factor-model alpha (annualized), its t-statistic,
207
+ R-squared and residual volatility. Report section 11 now shows the model,
208
+ alignment and every loading with standard error, t, p and 95% interval; JSON
209
+ gains `factor_analysis`, provenance gains `factor_names` and `factors_sha256`.
210
+ - Confidence: policy `factor_regression`; factor overlap below 90% caps at
211
+ moderate; smoothed returns lower confidence (they bias loadings toward zero and
212
+ alpha upward). Collinear factors and serially correlated residuals are flagged.
213
+ - Validated against R `lm` + `sandwich::NeweyWest` + `lmtest::coeftest` to 1e-8
214
+ (`validation/r/factor_reference.R`); new golden report `factor_case`.
215
+
216
+ ### Fixed (pre-release, factor-model increment)
217
+ - The outlier diagnostic emitted a floating-point overflow warning when the median
218
+ absolute deviation was subnormal (found by property-based testing); the
219
+ overflowing robust z-score is now counted as an outlier without a warning.
220
+
221
+ ### Added — Phase 4: canonical charts
222
+ - The HTML report now contains eight canonical charts rendered as static,
223
+ self-contained SVG (no external resources): growth of 1, calendar-year returns,
224
+ monthly heatmap, rolling one-year volatility, underwater chart, return
225
+ distribution, rolling one-year return and growth over the benchmark overlap.
226
+ Each has a caption and a data table; light and dark themes.
227
+ - Presentation rules fixed by the methodology (decision 0026, `charts.*`
228
+ conventions): full history, linear scales, zero baselines for bars, symmetric
229
+ heatmap scale, partial years outlined and labelled, benchmark on the aligned
230
+ overlap only, every return counted in the histogram.
231
+ - Drawdown-episode table (the 10 deepest episodes, deepest first) in terminal,
232
+ Markdown and HTML reports.
233
+ - `FactsheetReport.charts()` returns the SVG strings keyed by chart id;
234
+ `FactsheetReport.benchmark_returns` keeps the supplied benchmark series.
235
+
236
+ ### Added — Phase 2, third increment (8 metrics; 90 in total)
237
+ - Benchmark-relative: capture ratio (upside / downside capture), batting average
238
+ (with up- and down-market components), residual (specific) volatility,
239
+ appraisal ratio, M-squared, bull- and bear-market beta, timing ratio.
240
+ - Validated against PerformanceAnalytics (`CAPM.beta.bull` / `.bear`,
241
+ `TimingRatio`, `Modigliani`, `UpDownRatios(method = "Percent")`, R `lm`) and
242
+ empyrical (`up_down_capture`); documented differences from `SpecificRisk` and
243
+ `AppraisalRatio` pinned by tests. Decision note 0027.
244
+
245
+ ### Fixed (pre-release, third increment)
246
+ - A constant fund against a varying benchmark produced rounding-noise betas
247
+ (e.g. 1e-17) and therefore absurd Treynor ratios (about -8.6e15). The
248
+ single-index regression is now solved exactly for a constant fund (beta 0,
249
+ zero residuals), so ratios dividing by beta or residual risk are
250
+ `not_applicable` with a reason.
251
+ - R-squared for a constant fund was reported with status `error` (NaN); it is now
252
+ `not_applicable` (no variance to explain).
253
+
254
+ ### Added — Phase 2, second increment (18 metrics; 82 in total)
255
+ - Drawdown tail: Drawdown-at-Risk, Conditional Drawdown-at-Risk, Entropic
256
+ Drawdown-at-Risk (95%); entropic VaR of returns; modified (Cornish-Fisher)
257
+ Expected Shortfall.
258
+ - Episode summaries: median drawdown, average drawdown duration, longest
259
+ peak-to-trough decline, average recovery time; recovery factor.
260
+ - Complete-calendar-year statistics (best, worst, share positive; partial years
261
+ excluded and disclosed) and rolling one-year windows over every start date
262
+ (best, worst, share positive).
263
+ - Geometric mean return per period; interquartile range.
264
+ - Validated against PerformanceAnalytics (episode table, calendar years,
265
+ rolling windows, modified ES, geometric mean), R `IQR`, skfolio 1.0.6
266
+ (DaR/CDaR/EDaR/EVaR; added to the `validation` extra) and QuantStats.
267
+
268
+ ### Changed (pre-release, second increment)
269
+ - A metric result of plus or minus infinity (a denominator below floating-point
270
+ resolution) is reported as `not_applicable` with an explanation; NaN remains
271
+ `error`. Found by property-based testing.
272
+ - Shape statistics are undefined for numerically constant returns (variance
273
+ below floating-point resolution), instead of returning rounding noise.
274
+
275
+ ### Added — Phase 2, first increment (16 metrics; 64 in total)
276
+ - Risk-adjusted: Kappa 3, upside potential ratio, Burke, Sterling, Pain ratio.
277
+ - Returns / dispersion: payoff ratio, semi-deviation, downside potential (LPM 1),
278
+ mean absolute deviation.
279
+ - Tail (supplementary, model-dependent): Gaussian and Cornish-Fisher VaR.
280
+ - Distribution (supplementary): Jarque-Bera p-value.
281
+ - New **Statistical confidence** category, rendered in report section 12:
282
+ Probabilistic Sharpe Ratio, Sharpe standard error with 95% interval, Minimum
283
+ Track Record Length, standard error of the mean with t-interval and t-test.
284
+ - Two interpretation rules state whether the Sharpe ratio is statistically
285
+ distinguishable from zero and whether the track record is long enough.
286
+ - Every new metric cross-validated against PerformanceAnalytics, R `t.test`,
287
+ SciPy or QuantStats; decision notes 0016–0020.
288
+
289
+ ### Documentation
290
+ - Complete specification under `docs/reference/`: exact LaTeX formulas for every
291
+ metric (stored in the registry), notation, every decision criterion in
292
+ evaluation order, all thresholds and constants (generated from the code), and
293
+ the JSON report schema. Metric pages include calculation criteria
294
+ (applicability, undefined conditions, confidence rules, recorded assumptions).
295
+ - Tests fail if a metric lacks an exact formula, if a runtime "undefined"
296
+ condition is undocumented, or if a diagnostic finding or interpretation rule
297
+ is missing from the criteria reference.
298
+
299
+ ### Changed (pre-release)
300
+ - `InputDiagnostics.duplicate_dates` renamed `duplicate_periods` (it counts
301
+ observations sharing a calendar period).
302
+ - A declared frequency is accepted for a single dated observation.
303
+ - Numeric (integer or float) indexes are treated as positions, never dates.
304
+ - `max_drawdown` warns when the deepest drawdown has not recovered.
305
+ - Benchmark-coverage and short-annualization confidence thresholds moved into
306
+ the canonical methodology (`confidence.*`); values unchanged.
307
+
308
+ ### Methodology 0.1.0
309
+ - Initial canonical conventions; see `docs/methodology/decisions/0001`–`0015`.
@@ -0,0 +1,56 @@
1
+ # Important information and disclaimers
2
+
3
+ This file is the single, version-controlled source of OpenFactsheet's
4
+ English-language disclosure. The README, the documentation, the reference
5
+ manual, the generated reports and the website reuse or link to this text rather
6
+ than keeping their own copies. A test (`tests/unit/test_disclaimer.py`) fails if
7
+ the short notice below drifts from the copy used in the README and the reports.
8
+
9
+ > **Status of this text.** This is proposed public-facing copy prepared for the
10
+ > public alpha. It is not legal advice and has not yet been reviewed by legal
11
+ > counsel; counsel review is pending (see
12
+ > [the regulatory disclosure review](docs/audits/regulatory_disclosure_review.md)).
13
+ > A disclaimer is not a regulatory safe harbor and does not, by itself,
14
+ > establish compliance with, exemption from, or registration under any
15
+ > regulatory regime.
16
+
17
+ ## Full disclosure
18
+
19
+ **Important information — educational analytics only; not financial advice.** OpenFactsheet and OpenFactsheet.org provide general-purpose, informational and educational software and investment performance analytics. The content, calculations, comparisons, examples, reports, and other outputs are not personalized investment, financial, legal, tax, or accounting advice; they are not a recommendation, solicitation, endorsement, or offer to buy, sell, or hold any security, commodity interest, fund, or other financial product. OpenFactsheet does not evaluate your individual financial circumstances, objectives, risk tolerance, or suitability. Consult an appropriately qualified and, where applicable, licensed financial adviser before making investment decisions.
20
+
21
+ **Investing involves risk, including possible loss of principal. Past performance is not indicative of future results.** Historical returns, statistical measures, rankings, comparisons and risk-adjusted performance figures do not predict future outcomes. Backtested, simulated, modeled or hypothetical results are not actual trading records and may differ materially from actual results. Results depend on the quality, completeness, timing, methodology, assumptions, benchmarks, fees, taxes, currencies, and other characteristics of the supplied data. Neither accuracy nor completeness is guaranteed; independently verify all inputs and outputs.
22
+
23
+ **Use at your own risk.** The software and website are provided on an **“as is” and “as available”** basis, without warranties to the extent permitted by applicable law. Users are responsible for their use and interpretation of the software and results. Nothing in this notice excludes or restricts liability that cannot lawfully be excluded, or overrides the applicable open-source license or consumer-protection law.
24
+
25
+ **References and attribution.** OpenFactsheet seeks to identify and appropriately credit the originators of financial metrics and methodologies, academic papers, books, data sources, and third-party libraries used or referenced. Attribution is not an endorsement, affiliation, license grant, or permission to reproduce protected content. If you believe an attribution, copyright notice, license, or reference is incomplete or incorrect, please contact the project using its published contact channel so the issue can be reviewed and corrected.
26
+
27
+ ## Short notice
28
+
29
+ Where the full disclosure would be disruptive (report headers, comparison
30
+ output, small screens), OpenFactsheet uses this short notice, always with a link
31
+ to this page:
32
+
33
+ > For information and education only — not investment advice. Investing involves risk; past performance does not predict future results. Verify results and consult a qualified financial adviser.
34
+
35
+ The short notice does not replace context-specific warnings: every report also
36
+ carries its data-quality findings, confidence labels, assumptions and the
37
+ reasons a metric is unavailable.
38
+
39
+ ## Related documents
40
+
41
+ - **License.** OpenFactsheet's source code is licensed under the
42
+ [Apache License 2.0](LICENSE). The license governs use and redistribution of
43
+ the software; it is not an investment-advice disclaimer, and this page does
44
+ not modify it.
45
+ - **Attribution and corrections.** [docs/ATTRIBUTION.md](docs/ATTRIBUTION.md)
46
+ credits the originators of each metric. Report an incorrect or incomplete
47
+ attribution, copyright notice, license or reference by opening an issue at
48
+ <https://github.com/bagnascotrader/openfactsheet/issues>.
49
+ - **Security.** Report vulnerabilities privately as described in
50
+ [SECURITY.md](SECURITY.md), never in a public issue.
51
+ - **Third-party software.** [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md)
52
+ lists the licenses of the libraries OpenFactsheet uses.
53
+ - **Your data.** OpenFactsheet runs locally and does not upload the returns
54
+ you analyze. You are responsible for having the right to use any data,
55
+ factsheet or document you analyze; analyzing it with OpenFactsheet does not
56
+ make it freely redistributable.
@@ -0,0 +1,202 @@
1
+
2
+ Apache License
3
+ Version 2.0, January 2004
4
+ http://www.apache.org/licenses/
5
+
6
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7
+
8
+ 1. Definitions.
9
+
10
+ "License" shall mean the terms and conditions for use, reproduction,
11
+ and distribution as defined by Sections 1 through 9 of this document.
12
+
13
+ "Licensor" shall mean the copyright owner or entity authorized by
14
+ the copyright owner that is granting the License.
15
+
16
+ "Legal Entity" shall mean the union of the acting entity and all
17
+ other entities that control, are controlled by, or are under common
18
+ control with that entity. For the purposes of this definition,
19
+ "control" means (i) the power, direct or indirect, to cause the
20
+ direction or management of such entity, whether by contract or
21
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
22
+ outstanding shares, or (iii) beneficial ownership of such entity.
23
+
24
+ "You" (or "Your") shall mean an individual or Legal Entity
25
+ exercising permissions granted by this License.
26
+
27
+ "Source" form shall mean the preferred form for making modifications,
28
+ including but not limited to software source code, documentation
29
+ source, and configuration files.
30
+
31
+ "Object" form shall mean any form resulting from mechanical
32
+ transformation or translation of a Source form, including but
33
+ not limited to compiled object code, generated documentation,
34
+ and conversions to other media types.
35
+
36
+ "Work" shall mean the work of authorship, whether in Source or
37
+ Object form, made available under the License, as indicated by a
38
+ copyright notice that is included in or attached to the work
39
+ (an example is provided in the Appendix below).
40
+
41
+ "Derivative Works" shall mean any work, whether in Source or Object
42
+ form, that is based on (or derived from) the Work and for which the
43
+ editorial revisions, annotations, elaborations, or other modifications
44
+ represent, as a whole, an original work of authorship. For the purposes
45
+ of this License, Derivative Works shall not include works that remain
46
+ separable from, or merely link (or bind by name) to the interfaces of,
47
+ the Work and Derivative Works thereof.
48
+
49
+ "Contribution" shall mean any work of authorship, including
50
+ the original version of the Work and any modifications or additions
51
+ to that Work or Derivative Works thereof, that is intentionally
52
+ submitted to Licensor for inclusion in the Work by the copyright owner
53
+ or by an individual or Legal Entity authorized to submit on behalf of
54
+ the copyright owner. For the purposes of this definition, "submitted"
55
+ means any form of electronic, verbal, or written communication sent
56
+ to the Licensor or its representatives, including but not limited to
57
+ communication on electronic mailing lists, source code control systems,
58
+ and issue tracking systems that are managed by, or on behalf of, the
59
+ Licensor for the purpose of discussing and improving the Work, but
60
+ excluding communication that is conspicuously marked or otherwise
61
+ designated in writing by the copyright owner as "Not a Contribution."
62
+
63
+ "Contributor" shall mean Licensor and any individual or Legal Entity
64
+ on behalf of whom a Contribution has been received by Licensor and
65
+ subsequently incorporated within the Work.
66
+
67
+ 2. Grant of Copyright License. Subject to the terms and conditions of
68
+ this License, each Contributor hereby grants to You a perpetual,
69
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70
+ copyright license to reproduce, prepare Derivative Works of,
71
+ publicly display, publicly perform, sublicense, and distribute the
72
+ Work and such Derivative Works in Source or Object form.
73
+
74
+ 3. Grant of Patent License. Subject to the terms and conditions of
75
+ this License, each Contributor hereby grants to You a perpetual,
76
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77
+ (except as stated in this section) patent license to make, have made,
78
+ use, offer to sell, sell, import, and otherwise transfer the Work,
79
+ where such license applies only to those patent claims licensable
80
+ by such Contributor that are necessarily infringed by their
81
+ Contribution(s) alone or by combination of their Contribution(s)
82
+ with the Work to which such Contribution(s) was submitted. If You
83
+ institute patent litigation against any entity (including a
84
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
85
+ or a Contribution incorporated within the Work constitutes direct
86
+ or contributory patent infringement, then any patent licenses
87
+ granted to You under this License for that Work shall terminate
88
+ as of the date such litigation is filed.
89
+
90
+ 4. Redistribution. You may reproduce and distribute copies of the
91
+ Work or Derivative Works thereof in any medium, with or without
92
+ modifications, and in Source or Object form, provided that You
93
+ meet the following conditions:
94
+
95
+ (a) You must give any other recipients of the Work or
96
+ Derivative Works a copy of this License; and
97
+
98
+ (b) You must cause any modified files to carry prominent notices
99
+ stating that You changed the files; and
100
+
101
+ (c) You must retain, in the Source form of any Derivative Works
102
+ that You distribute, all copyright, patent, trademark, and
103
+ attribution notices from the Source form of the Work,
104
+ excluding those notices that do not pertain to any part of
105
+ the Derivative Works; and
106
+
107
+ (d) If the Work includes a "NOTICE" text file as part of its
108
+ distribution, then any Derivative Works that You distribute must
109
+ include a readable copy of the attribution notices contained
110
+ within such NOTICE file, excluding those notices that do not
111
+ pertain to any part of the Derivative Works, in at least one
112
+ of the following places: within a NOTICE text file distributed
113
+ as part of the Derivative Works; within the Source form or
114
+ documentation, if provided along with the Derivative Works; or,
115
+ within a display generated by the Derivative Works, if and
116
+ wherever such third-party notices normally appear. The contents
117
+ of the NOTICE file are for informational purposes only and
118
+ do not modify the License. You may add Your own attribution
119
+ notices within Derivative Works that You distribute, alongside
120
+ or as an addendum to the NOTICE text from the Work, provided
121
+ that such additional attribution notices cannot be construed
122
+ as modifying the License.
123
+
124
+ You may add Your own copyright statement to Your modifications and
125
+ may provide additional or different license terms and conditions
126
+ for use, reproduction, or distribution of Your modifications, or
127
+ for any such Derivative Works as a whole, provided Your use,
128
+ reproduction, and distribution of the Work otherwise complies with
129
+ the conditions stated in this License.
130
+
131
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
132
+ any Contribution intentionally submitted for inclusion in the Work
133
+ by You to the Licensor shall be under the terms and conditions of
134
+ this License, without any additional terms or conditions.
135
+ Notwithstanding the above, nothing herein shall supersede or modify
136
+ the terms of any separate license agreement you may have executed
137
+ with Licensor regarding such Contributions.
138
+
139
+ 6. Trademarks. This License does not grant permission to use the trade
140
+ names, trademarks, service marks, or product names of the Licensor,
141
+ except as required for reasonable and customary use in describing the
142
+ origin of the Work and reproducing the content of the NOTICE file.
143
+
144
+ 7. Disclaimer of Warranty. Unless required by applicable law or
145
+ agreed to in writing, Licensor provides the Work (and each
146
+ Contributor provides its Contributions) on an "AS IS" BASIS,
147
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148
+ implied, including, without limitation, any warranties or conditions
149
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150
+ PARTICULAR PURPOSE. You are solely responsible for determining the
151
+ appropriateness of using or redistributing the Work and assume any
152
+ risks associated with Your exercise of permissions under this License.
153
+
154
+ 8. Limitation of Liability. In no event and under no legal theory,
155
+ whether in tort (including negligence), contract, or otherwise,
156
+ unless required by applicable law (such as deliberate and grossly
157
+ negligent acts) or agreed to in writing, shall any Contributor be
158
+ liable to You for damages, including any direct, indirect, special,
159
+ incidental, or consequential damages of any character arising as a
160
+ result of this License or out of the use or inability to use the
161
+ Work (including but not limited to damages for loss of goodwill,
162
+ work stoppage, computer failure or malfunction, or any and all
163
+ other commercial damages or losses), even if such Contributor
164
+ has been advised of the possibility of such damages.
165
+
166
+ 9. Accepting Warranty or Additional Liability. While redistributing
167
+ the Work or Derivative Works thereof, You may choose to offer,
168
+ and charge a fee for, acceptance of support, warranty, indemnity,
169
+ or other liability obligations and/or rights consistent with this
170
+ License. However, in accepting such obligations, You may act only
171
+ on Your own behalf and on Your sole responsibility, not on behalf
172
+ of any other Contributor, and only if You agree to indemnify,
173
+ defend, and hold each Contributor harmless for any liability
174
+ incurred by, or claims asserted against, such Contributor by reason
175
+ of your accepting any such warranty or additional liability.
176
+
177
+ END OF TERMS AND CONDITIONS
178
+
179
+ APPENDIX: How to apply the Apache License to your work.
180
+
181
+ To apply the Apache License to your work, attach the following
182
+ boilerplate notice, with the fields enclosed by brackets "[]"
183
+ replaced with your own identifying information. (Don't include
184
+ the brackets!) The text should be enclosed in the appropriate
185
+ comment syntax for the file format. We also recommend that a
186
+ file or class name and description of purpose be included on the
187
+ same "printed page" as the copyright notice for easier
188
+ identification within third-party archives.
189
+
190
+ Copyright [yyyy] [name of copyright owner]
191
+
192
+ Licensed under the Apache License, Version 2.0 (the "License");
193
+ you may not use this file except in compliance with the License.
194
+ You may obtain a copy of the License at
195
+
196
+ http://www.apache.org/licenses/LICENSE-2.0
197
+
198
+ Unless required by applicable law or agreed to in writing, software
199
+ distributed under the License is distributed on an "AS IS" BASIS,
200
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201
+ See the License for the specific language governing permissions and
202
+ limitations under the License.