financetoolkit 2.3.0__tar.gz → 2.3.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (231) hide show
  1. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/PKG-INFO +5 -2
  2. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/cache/cache_controller.py +64 -14
  3. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/cache/policy_model.py +3 -3
  4. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/cache/sqlite_model.py +96 -13
  5. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/currencies_model.py +15 -3
  6. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/discovery/discovery_controller.py +39 -29
  7. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/discovery/discovery_model.py +164 -32
  8. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/econometrics/cointegration_model.py +19 -1
  9. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/econometrics/diagnostics_model.py +3 -2
  10. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/econometrics/econometrics_controller.py +102 -52
  11. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/econometrics/regression_model.py +100 -4
  12. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/econometrics/state_space_model.py +7 -0
  13. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/econometrics/unitroot_model.py +12 -0
  14. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/economics/economics_controller.py +84 -83
  15. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/economics/helpers.py +8 -3
  16. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/economics/imf_model.py +13 -1
  17. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/etf/etf_controller.py +93 -57
  18. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/fixedincome/bond_model.py +46 -6
  19. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/fixedincome/derivative_model.py +34 -17
  20. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/fixedincome/fixedincome_controller.py +13 -6
  21. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/fixedincome/fred_model.py +5 -1
  22. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/fixedincome/short_rate_model.py +10 -0
  23. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/fmp_model.py +148 -29
  24. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/fundamentals_model.py +50 -35
  25. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/helpers.py +127 -0
  26. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/historical_model.py +113 -41
  27. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/mcp_server/analytics_model.py +122 -19
  28. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/mcp_server/auth_model.py +344 -90
  29. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/mcp_server/coercion_model.py +37 -0
  30. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/mcp_server/config.yaml +25 -11
  31. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/mcp_server/diagnostics_model.py +17 -3
  32. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/mcp_server/formatting_model.py +16 -1
  33. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/mcp_server/inspection_controller.py +60 -29
  34. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/mcp_server/mcp_controller.py +16 -2
  35. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/mcp_server/mcpb/manifest.json +10 -6
  36. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/mcp_server/mcpb/pyproject.toml +3 -3
  37. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/mcp_server/provider_model.py +174 -9
  38. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/mcp_server/registry_controller.py +391 -19
  39. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/mcp_server/series_model.py +15 -3
  40. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/mcp_server/setup_model.py +78 -35
  41. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/mcp_server/tools_model.py +16 -4
  42. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/models/models_controller.py +144 -63
  43. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/models/wacc_model.py +6 -6
  44. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/normalization/statistics.csv +2 -4
  45. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/normalization_model.py +171 -62
  46. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/options/binomial_trees_model.py +15 -4
  47. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/options/black_scholes_model.py +26 -4
  48. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/options/exotics_model.py +6 -2
  49. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/options/greeks_model.py +3 -1
  50. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/options/helpers.py +3 -3
  51. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/options/options_controller.py +103 -60
  52. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/options/options_model.py +30 -10
  53. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/performance/performance_controller.py +76 -35
  54. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/performance/performance_model.py +50 -13
  55. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/portfolio/attribution_model.py +23 -3
  56. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/portfolio/config.yaml +4 -0
  57. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/portfolio/construction_controller.py +76 -21
  58. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/portfolio/helpers.py +53 -6
  59. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/portfolio/optimization_model.py +84 -10
  60. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/portfolio/overview_model.py +84 -17
  61. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/portfolio/portfolio_controller.py +241 -37
  62. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/portfolio/portfolio_model.py +63 -29
  63. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/ratios/helpers.py +7 -6
  64. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/ratios/ratios_controller.py +250 -117
  65. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/risk/cvar_model.py +8 -6
  66. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/risk/garch_model.py +29 -1
  67. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/risk/risk_controller.py +77 -36
  68. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/risk/risk_model.py +116 -31
  69. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/risk/var_model.py +3 -1
  70. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/technicals/breadth_model.py +64 -28
  71. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/technicals/momentum_model.py +23 -7
  72. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/technicals/overlap_model.py +23 -11
  73. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/technicals/technicals_controller.py +219 -238
  74. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/technicals/volatility_model.py +6 -3
  75. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/toolkit_controller.py +411 -107
  76. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/utilities/error_model.py +18 -5
  77. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/utilities/statistics_model.py +88 -23
  78. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/utilities/validation_model.py +22 -10
  79. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/yfinance_model.py +4 -4
  80. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/pyproject.toml +9 -4
  81. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/.gitignore +0 -0
  82. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/LICENSE.txt +0 -0
  83. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/README.md +0 -0
  84. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/__init__.py +0 -0
  85. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/cache/__init__.py +0 -0
  86. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/cache/coverage_model.py +0 -0
  87. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/cache/frame_model.py +0 -0
  88. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/cache/request_model.py +0 -0
  89. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/cache/serialization_model.py +0 -0
  90. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/cache/ticker_model.py +0 -0
  91. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/discovery/__init__.py +0 -0
  92. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/econometrics/__init__.py +0 -0
  93. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/econometrics/causal_inference_model.py +0 -0
  94. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/econometrics/causality_model.py +0 -0
  95. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/econometrics/data_model.py +0 -0
  96. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/econometrics/event_study_model.py +0 -0
  97. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/econometrics/fama_macbeth_model.py +0 -0
  98. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/econometrics/forecast_evaluation_model.py +0 -0
  99. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/econometrics/hypothesis_testing_model.py +0 -0
  100. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/econometrics/pairs_trading_model.py +0 -0
  101. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/econometrics/panel_data_model.py +0 -0
  102. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/econometrics/regime_model.py +0 -0
  103. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/econometrics/specification_tests_model.py +0 -0
  104. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/econometrics/time_series_model.py +0 -0
  105. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/economics/__init__.py +0 -0
  106. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/economics/bis_model.py +0 -0
  107. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/economics/bls_model.py +0 -0
  108. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/economics/boe_model.py +0 -0
  109. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/economics/boj_model.py +0 -0
  110. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/economics/cboe_model.py +0 -0
  111. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/economics/dnb_model.py +0 -0
  112. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/economics/ecb_model.py +0 -0
  113. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/economics/eex_model.py +0 -0
  114. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/economics/esrb_model.py +0 -0
  115. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/economics/eurostat_model.py +0 -0
  116. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/economics/fmp_model.py +0 -0
  117. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/economics/frb_model.py +0 -0
  118. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/economics/fred_model.py +0 -0
  119. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/economics/freddie_mac_model.py +0 -0
  120. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/economics/gmdb_model.py +0 -0
  121. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/economics/ibge_model.py +0 -0
  122. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/economics/macrohistory_model.py +0 -0
  123. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/economics/mof_model.py +0 -0
  124. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/economics/nber_model.py +0 -0
  125. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/economics/ngfs_model.py +0 -0
  126. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/economics/oecd_model.py +0 -0
  127. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/economics/ons_model.py +0 -0
  128. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/economics/sbj_model.py +0 -0
  129. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/economics/shiller_model.py +0 -0
  130. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/economics/stoxx_model.py +0 -0
  131. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/economics/treasury_model.py +0 -0
  132. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/economics/yfinance_model.py +0 -0
  133. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/etf/__init__.py +0 -0
  134. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/etf/etf_model.py +0 -0
  135. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/fixedincome/__init__.py +0 -0
  136. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/fixedincome/boc_model.py +0 -0
  137. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/fixedincome/bundesbank_model.py +0 -0
  138. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/fixedincome/curve_model.py +0 -0
  139. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/fixedincome/ecb_model.py +0 -0
  140. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/fixedincome/eiopa_model.py +0 -0
  141. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/fixedincome/esma_model.py +0 -0
  142. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/fixedincome/euribor_model.py +0 -0
  143. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/fixedincome/fed_model.py +0 -0
  144. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/fixedincome/fiscaldata_model.py +0 -0
  145. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/fixedincome/fmp_model.py +0 -0
  146. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/fixedincome/helpers.py +0 -0
  147. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/fixedincome/norgesbank_model.py +0 -0
  148. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/fixedincome/rba_model.py +0 -0
  149. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/fixedincome/riksbank_model.py +0 -0
  150. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/fixedincome/yieldcurve_model.py +0 -0
  151. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/mcp_server/__init__.py +0 -0
  152. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/mcp_server/__main__.py +0 -0
  153. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/mcp_server/mcpb/.mcpbignore +0 -0
  154. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/mcp_server/mcpb/LICENSE +0 -0
  155. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/mcp_server/mcpb/README.md +0 -0
  156. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/mcp_server/mcpb/build-mcpb.sh +0 -0
  157. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/mcp_server/mcpb/finance_toolkit_icon.png +0 -0
  158. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/mcp_server/static/apple-touch-icon.png +0 -0
  159. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/mcp_server/static/favicon-32.png +0 -0
  160. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/mcp_server/static/favicon.ico +0 -0
  161. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/mcp_server/stats_page_model.py +0 -0
  162. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/models/__init__.py +0 -0
  163. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/models/altman_model.py +0 -0
  164. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/models/beneish_model.py +0 -0
  165. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/models/credit_model.py +0 -0
  166. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/models/damodaran_model.py +0 -0
  167. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/models/dupont_model.py +0 -0
  168. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/models/enterprise_model.py +0 -0
  169. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/models/eva_model.py +0 -0
  170. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/models/fulmer_model.py +0 -0
  171. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/models/grover_model.py +0 -0
  172. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/models/growth_model.py +0 -0
  173. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/models/helpers.py +0 -0
  174. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/models/intrinsic_model.py +0 -0
  175. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/models/ohlson_model.py +0 -0
  176. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/models/peers_model.py +0 -0
  177. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/models/piotroski_model.py +0 -0
  178. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/models/quality_model.py +0 -0
  179. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/models/springate_model.py +0 -0
  180. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/models/zmijewski_model.py +0 -0
  181. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/normalization/balance.csv +0 -0
  182. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/normalization/balance_yf.csv +0 -0
  183. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/normalization/cash.csv +0 -0
  184. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/normalization/cash_yf.csv +0 -0
  185. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/normalization/income.csv +0 -0
  186. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/normalization/income_yf.csv +0 -0
  187. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/normalization/statistics_yf.csv +0 -0
  188. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/options/__init__.py +0 -0
  189. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/options/market_metrics_model.py +0 -0
  190. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/options/risk_neutral_density_model.py +0 -0
  191. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/options/svi_model.py +0 -0
  192. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/performance/__init__.py +0 -0
  193. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/performance/helpers.py +0 -0
  194. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/portfolio/__init__.py +0 -0
  195. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/portfolio/definition_model.py +0 -0
  196. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/portfolio/example_datasets/example_portfolio.csv +0 -0
  197. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/portfolio/example_datasets/example_portfolio.xlsx +0 -0
  198. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/portfolio/presets/all_weather.yaml +0 -0
  199. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/portfolio/presets/balanced_60_40.yaml +0 -0
  200. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/portfolio/presets/barbell.yaml +0 -0
  201. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/portfolio/presets/bogleheads_three_fund.yaml +0 -0
  202. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/portfolio/presets/buffett_90_10.yaml +0 -0
  203. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/portfolio/presets/conservative_income.yaml +0 -0
  204. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/portfolio/presets/global_60_40.yaml +0 -0
  205. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/portfolio/presets/global_equity_growth.yaml +0 -0
  206. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/portfolio/presets/golden_butterfly.yaml +0 -0
  207. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/portfolio/presets/permanent_portfolio.yaml +0 -0
  208. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/portfolio/presets/small_cap_value_tilt.yaml +0 -0
  209. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/portfolio/presets/target_date_glidepath.yaml +0 -0
  210. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/portfolio/presets/us_equity_sectors.yaml +0 -0
  211. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/py.typed +0 -0
  212. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/ratios/__init__.py +0 -0
  213. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/ratios/efficiency_model.py +0 -0
  214. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/ratios/liquidity_model.py +0 -0
  215. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/ratios/profitability_model.py +0 -0
  216. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/ratios/solvency_model.py +0 -0
  217. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/ratios/valuation_model.py +0 -0
  218. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/risk/__init__.py +0 -0
  219. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/risk/backtesting_model.py +0 -0
  220. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/risk/copula_model.py +0 -0
  221. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/risk/covar_model.py +0 -0
  222. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/risk/evar_model.py +0 -0
  223. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/risk/helpers.py +0 -0
  224. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/risk/market_liquidity_model.py +0 -0
  225. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/risk/realized_volatility_model.py +0 -0
  226. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/technicals/__init__.py +0 -0
  227. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/technicals/seasonality_model.py +0 -0
  228. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/utilities/dataframe_model.py +0 -0
  229. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/utilities/excel_model.py +0 -0
  230. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/utilities/logger_model.py +0 -0
  231. {financetoolkit-2.3.0 → financetoolkit-2.3.1}/financetoolkit/utilities/requests_model.py +0 -0
@@ -1,7 +1,11 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: financetoolkit
3
- Version: 2.3.0
3
+ Version: 2.3.1
4
4
  Summary: Transparent and Efficient Financial Analysis
5
+ Project-URL: Homepage, https://www.jeroenbouma.com/projects/financetoolkit
6
+ Project-URL: Documentation, https://www.jeroenbouma.com/projects/financetoolkit/docs
7
+ Project-URL: Repository, https://github.com/JerBouma/FinanceToolkit
8
+ Project-URL: Issues, https://github.com/JerBouma/FinanceToolkit/issues
5
9
  Author: Jeroen Bouma
6
10
  License: MIT
7
11
  License-File: LICENSE.txt
@@ -36,7 +40,6 @@ Requires-Dist: mcp[cli]<2,>=1.27.0; extra == 'mcp'
36
40
  Requires-Dist: python-dotenv>=1.0; extra == 'mcp'
37
41
  Requires-Dist: rich>=13.0; extra == 'mcp'
38
42
  Requires-Dist: statsmodels>=0.14; extra == 'mcp'
39
- Requires-Dist: tabulate>=0.9.0; extra == 'mcp'
40
43
  Description-Content-Type: text/markdown
41
44
 
42
45
  <!-- mcp-name: io.github.JerBouma/financetoolkit -->
@@ -29,6 +29,13 @@ DATABASE_FILE_NAME = "financetoolkit_cache.db"
29
29
  # Compacted into merged intervals past this many rows, to bound table growth.
30
30
  COVERAGE_COMPACTION_THRESHOLD = 16
31
31
 
32
+ # Point-in-time entries are kept at least this long after they were written, also past their
33
+ # time-to-live, since an expired entry still answers when its source cannot be reached.
34
+ STALE_ENTRY_RETENTION_SECONDS = 90 * policy_model.DAY
35
+
36
+ # How often the entries nobody asks for any more are removed.
37
+ EVICTION_INTERVAL_SECONDS = policy_model.DAY
38
+
32
39
  _CACHE_REGISTRY: dict[str, "Cache"] = {}
33
40
  _REGISTRY_LOCK = Lock()
34
41
 
@@ -103,7 +110,7 @@ def get_default_cache_location() -> Path:
103
110
  override = os.environ.get("FINANCE_TOOLKIT_CACHE_DB")
104
111
 
105
112
  if override:
106
- return Path(override).expanduser()
113
+ return Path(override).expanduser().absolute()
107
114
 
108
115
  if platform.system() == "Windows":
109
116
  base = Path(
@@ -113,7 +120,7 @@ def get_default_cache_location() -> Path:
113
120
  xdg_config_home = os.environ.get("XDG_CONFIG_HOME")
114
121
  base = Path(xdg_config_home) if xdg_config_home else Path.home() / ".config"
115
122
 
116
- return base / "financetoolkit" / DATABASE_FILE_NAME
123
+ return (base / "financetoolkit" / DATABASE_FILE_NAME).absolute()
117
124
 
118
125
 
119
126
  def resolve_cache_location(location: str | Path | None) -> Path:
@@ -133,7 +140,9 @@ def resolve_cache_location(location: str | Path | None) -> Path:
133
140
  if location is None:
134
141
  return get_default_cache_location()
135
142
 
136
- path = Path(location).expanduser()
143
+ # Absolute, so a relative folder keeps pointing at the same database after a change of
144
+ # working directory and caches opened from different directories are told apart.
145
+ path = Path(location).expanduser().absolute()
137
146
 
138
147
  if path.suffix in (".db", ".sqlite", ".sqlite3"):
139
148
  return path
@@ -283,6 +292,38 @@ class Cache:
283
292
  )
284
293
 
285
294
  self._warn_on_schema_mismatch()
295
+ self._remove_stale_entries()
296
+
297
+ def _remove_stale_entries(self) -> None:
298
+ """
299
+ Remove the point-in-time entries of every source that have not been refreshed for
300
+ longer than their time-to-live and the retention for unreachable sources, at most
301
+ once a day. The MCP server's responses are left to the server, which evicts them
302
+ on its own time-to-live.
303
+ """
304
+ try:
305
+ # A database of another schema version is left exactly as it is.
306
+ if (
307
+ self._backend is None
308
+ or self._backend.get_schema_version() != SCHEMA_VERSION
309
+ ):
310
+ return
311
+
312
+ evicted = self._backend.remove_stale_blobs(
313
+ lambda source, dataset: max(
314
+ policy_model.get_policy(source, dataset).ttl_seconds,
315
+ STALE_ENTRY_RETENTION_SECONDS,
316
+ ),
317
+ EVICTION_INTERVAL_SECONDS,
318
+ excluded_sources=frozenset({policy_model.MCP}),
319
+ )
320
+ except Exception as error: # pylint: disable=broad-except
321
+ # Eviction is housekeeping, so a failure here is not surfaced.
322
+ logger.debug("Could not evict stale cache entries: %s", error)
323
+ return
324
+
325
+ if evicted:
326
+ logger.debug("Removed %s stale cache entries.", evicted)
286
327
 
287
328
  def _warn_on_schema_mismatch(self) -> None:
288
329
  """
@@ -388,9 +429,9 @@ class Cache:
388
429
  start (str | date | None): Inclusive start of the requested range.
389
430
  end (str | date | None): Inclusive end of the requested range.
390
431
  parameters (dict[str, Any] | None): Parameters that change the data.
391
- date_axis (int): 0 when the index holds the dates, 1 when the columns do.
432
+ date_axis (int): 0 when the index holds the dates, 1 when the columns do. Defaults to 0.
392
433
  reference_date (date | None): The date the revision window is measured
393
- back from when the requested range has no end. Defaults to today;
434
+ back from when the requested range has no end or ends after it. Defaults to today;
394
435
  mainly useful for testing.
395
436
 
396
437
  Returns:
@@ -405,6 +446,10 @@ class Cache:
405
446
  coverage_model.normalize_date(start) if start else date(1900, 1, 1)
406
447
  )
407
448
  requested_end = coverage_model.normalize_date(end) if end else reference
449
+ # Nothing after today has been published yet, so a range that runs into the future is
450
+ # covered up to today and its revision window ends today, as an open range's does.
451
+ if requested_start <= reference < requested_end:
452
+ requested_end = reference
408
453
 
409
454
  if not self.serves(source):
410
455
  plan.missing = {
@@ -507,7 +552,7 @@ class Cache:
507
552
  start (str | date | None): Inclusive start of the range that was requested.
508
553
  end (str | date | None): Inclusive end of the range that was requested.
509
554
  parameters (dict[str, Any] | None): Parameters that change the data.
510
- date_axis (int): 0 when the index holds the dates, 1 when the columns do.
555
+ date_axis (int): 0 when the index holds the dates, 1 when the columns do. Defaults to 0.
511
556
  """
512
557
  if not self.serves(source):
513
558
  return
@@ -520,8 +565,10 @@ class Cache:
520
565
  if start
521
566
  else (bounds[0] if bounds else None)
522
567
  )
568
+ # A request that runs into the future holds what was published up to today; claiming the
569
+ # future as well would never ask for those days once they have passed.
523
570
  coverage_end = (
524
- coverage_model.normalize_date(end)
571
+ min(coverage_model.normalize_date(end), date.today()) # noqa: DTZ011
525
572
  if end
526
573
  else (bounds[1] if bounds else None)
527
574
  )
@@ -534,7 +581,8 @@ class Cache:
534
581
  coverage_start = min(coverage_start, bounds[0])
535
582
  coverage_end = max(coverage_end, bounds[1])
536
583
 
537
- coverage = (coverage_start, coverage_end)
584
+ if coverage_start <= coverage_end:
585
+ coverage = (coverage_start, coverage_end)
538
586
 
539
587
  def merge_payload(existing_payload: bytes | None) -> bytes:
540
588
  """
@@ -813,7 +861,7 @@ def get_cache(
813
861
  location (str | Path | None): Directory or database file to use. None
814
862
  selects the shared default location.
815
863
  enabled (bool): When False a disabled cache is returned, which misses on
816
- every read and ignores every write.
864
+ every read and ignores every write. Defaults to True.
817
865
  excluded_sources (frozenset[str] | set[str] | None): Sources this cache never
818
866
  reads or writes, see Cache. Defaults to None.
819
867
 
@@ -829,12 +877,14 @@ def get_cache(
829
877
  registry_key = f"{resolved}|{','.join(sorted(excluded))}"
830
878
 
831
879
  with _REGISTRY_LOCK:
832
- if registry_key not in _CACHE_REGISTRY:
833
- _CACHE_REGISTRY[registry_key] = Cache(
834
- location=location, enabled=True, excluded_sources=excluded
835
- )
880
+ cache = _CACHE_REGISTRY.get(registry_key)
881
+ if cache is not None:
882
+ return cache
836
883
 
837
- return _CACHE_REGISTRY[registry_key]
884
+ # Opened outside the lock: opening evicts stale entries once a day, which can wait for another process's write lock, and that would hold up every other caller meanwhile. When two threads open the same location at once, the first instance registered is kept. # noqa: E501
885
+ cache = Cache(location=location, enabled=True, excluded_sources=excluded)
886
+ with _REGISTRY_LOCK:
887
+ return _CACHE_REGISTRY.setdefault(registry_key, cache)
838
888
 
839
889
 
840
890
  def reset_cache_registry() -> None:
@@ -47,9 +47,9 @@ DE_NEDERLANDSCHE_BANK = "DeNederlandscheBank"
47
47
  EUROPEAN_SYSTEMIC_RISK_BOARD = "ESRB"
48
48
  DAMODARAN = "Damodaran"
49
49
 
50
- # The market risk premium is published per country, so it is one cache entry. Its name
51
- # changed when the premiums became decimals (v2.2.2), so an entry cached in percent by an
52
- # earlier version is never read back as decimals.
50
+ # The market risk premium is published per country, so it is one cache entry. The name
51
+ # marks the premiums as decimals, so an entry holding percentages under another name is
52
+ # never read back as decimals.
53
53
  MARKET_RISK_PREMIUM_ENTITY = "global_decimals"
54
54
 
55
55
 
@@ -20,6 +20,10 @@ SCHEMA_VERSION = 1
20
20
  # How long a writer waits for another process to release the write lock.
21
21
  BUSY_TIMEOUT_SECONDS = 30
22
22
 
23
+ # A database up to this size is compacted after an eviction freed most of it; a larger one
24
+ # would hold every other process off the cache for too long while it is rewritten.
25
+ VACUUM_MAXIMUM_BYTES = 256 * 1024 * 1024
26
+
23
27
  # Three tables; source and dataset stay plain columns so clearing can be scoped.
24
28
  SCHEMA_STATEMENTS = (
25
29
  """
@@ -130,10 +134,15 @@ class SQLiteBackend:
130
134
  the block, so that every statement inside it commits or rolls back
131
135
  as one unit. False opens a plain read connection.
132
136
 
137
+ Only writers take the instance lock, so the threads of one process queue for the
138
+ write lock here instead of each waiting out SQLite's busy timeout. Readers never
139
+ take it: under write-ahead logging they read alongside a writer, also while that
140
+ writer waits for another process to release the database.
141
+
133
142
  Yields:
134
- sqlite3.Connection: An open connection guarded by the instance lock.
143
+ sqlite3.Connection: An open connection, guarded by the instance lock when writing.
135
144
  """
136
- with self._lock:
145
+ with self._lock if write else contextlib.nullcontext():
137
146
  connection = sqlite3.connect(
138
147
  self._database_location,
139
148
  timeout=BUSY_TIMEOUT_SECONDS,
@@ -277,8 +286,8 @@ class SQLiteBackend:
277
286
 
278
287
  Reading the coverage and the payload over three separate connections lets
279
288
  a concurrent writer commit in between, so the planner could see coverage
280
- that does not describe the payload it read. A single connection gives one
281
- consistent view of both.
289
+ that does not describe the payload it read. One read transaction on a single
290
+ connection gives one consistent view of both.
282
291
 
283
292
  Args:
284
293
  key (str): The dataset key.
@@ -292,15 +301,20 @@ class SQLiteBackend:
292
301
  stored payload (None when nothing is cached).
293
302
  """
294
303
  with self._connect() as connection:
295
- ever_rows = connection.execute(
296
- "SELECT start_date, end_date, fetched_at FROM coverage "
297
- "WHERE key = ? AND entity = ?",
298
- (key, entity),
299
- ).fetchall()
300
- payload_row = connection.execute(
301
- "SELECT payload FROM series WHERE key = ? AND entity = ?",
302
- (key, entity),
303
- ).fetchone()
304
+ # One read transaction, so both SELECTs see the same snapshot; in autocommit mode each would take its own. # noqa: E501
305
+ connection.execute("BEGIN")
306
+ try:
307
+ ever_rows = connection.execute(
308
+ "SELECT start_date, end_date, fetched_at FROM coverage "
309
+ "WHERE key = ? AND entity = ?",
310
+ (key, entity),
311
+ ).fetchall()
312
+ payload_row = connection.execute(
313
+ "SELECT payload FROM series WHERE key = ? AND entity = ?",
314
+ (key, entity),
315
+ ).fetchone()
316
+ finally:
317
+ connection.execute("COMMIT")
304
318
 
305
319
  ever_covered = [
306
320
  (normalize_date(start), normalize_date(end)) for start, end, _ in ever_rows
@@ -671,6 +685,75 @@ class SQLiteBackend:
671
685
 
672
686
  return deleted
673
687
 
688
+ def remove_stale_blobs(
689
+ self,
690
+ maximum_age: Callable[[str, str], float],
691
+ interval: float,
692
+ excluded_sources: frozenset[str] = frozenset(),
693
+ ) -> int:
694
+ """
695
+ Delete the point-in-time entries of every source that have not been refreshed for
696
+ longer than their dataset allows, at most once per interval.
697
+
698
+ An entry that is read again is refreshed by its next fetch, so only entries nobody
699
+ asks for any more pile up. The time of the last run is kept in the database, so
700
+ every process sharing it runs this once per interval in total. When the deletes
701
+ free more than half of a small database, it is compacted as well.
702
+
703
+ Args:
704
+ maximum_age (Callable[[str, str], float]): The age in seconds after which an
705
+ entry of a source and dataset is removed.
706
+ interval (float): The minimum number of seconds between two runs.
707
+ excluded_sources (frozenset[str]): Sources that evict their own entries.
708
+
709
+ Returns:
710
+ int: The number of entries deleted, 0 when the interval has not passed.
711
+ """
712
+ now = time.time()
713
+ deleted = 0
714
+
715
+ with self._connect(write=True) as connection:
716
+ row = connection.execute(
717
+ "SELECT value FROM meta WHERE name = ?", ("last_blob_eviction",)
718
+ ).fetchone()
719
+
720
+ if row is not None and now - float(row[0]) < interval:
721
+ return 0
722
+
723
+ connection.execute(
724
+ "INSERT OR REPLACE INTO meta (name, value) VALUES (?, ?)",
725
+ ("last_blob_eviction", str(now)),
726
+ )
727
+
728
+ scopes = connection.execute(
729
+ "SELECT DISTINCT source, dataset FROM blobs"
730
+ ).fetchall()
731
+
732
+ for source, dataset in scopes:
733
+ if source in excluded_sources:
734
+ continue
735
+
736
+ deleted += connection.execute(
737
+ "DELETE FROM blobs WHERE source = ? AND dataset = ? AND updated_at < ?",
738
+ (source, dataset, now - maximum_age(source, dataset)),
739
+ ).rowcount
740
+
741
+ page_count = connection.execute("PRAGMA page_count").fetchone()[0]
742
+ free_pages = connection.execute("PRAGMA freelist_count").fetchone()[0]
743
+
744
+ database_path = Path(self._database_location)
745
+ if (
746
+ deleted
747
+ and free_pages * 2 > page_count
748
+ and database_path.exists()
749
+ and database_path.stat().st_size <= VACUUM_MAXIMUM_BYTES
750
+ ):
751
+ # VACUUM cannot run inside a transaction, so it takes a plain connection.
752
+ with self._lock, self._connect() as connection:
753
+ connection.execute("VACUUM")
754
+
755
+ return deleted
756
+
674
757
  def clear_all(self) -> int:
675
758
  """
676
759
  Remove every cached entry regardless of age.
@@ -190,6 +190,12 @@ CURRENCY_CODES: frozenset[str] = frozenset(
190
190
  ) # codespell:ignore zar
191
191
 
192
192
 
193
+ # How old the last published rate may be on a period end before the period has no rate.
194
+ # Sparse or exotic pairs can go a few weeks without a quote, so only a rate older than a
195
+ # month marks a series that ended before the period did.
196
+ STALE_RATE_DAYS = pd.Timedelta(days=31)
197
+
198
+
193
199
  def is_currency_pair(ticker: str) -> bool:
194
200
  """
195
201
  Returns whether a ticker is a forex pair: six letters, optionally followed by "=X" as
@@ -474,11 +480,17 @@ def get_statement_exchange_rates(
474
480
  ]
475
481
  else:
476
482
  dates = end_dates if rate == "closing" else start_dates
477
- # The last published rate on or before each date.
483
+ # The last published rate on or before each date, unless that rate is more than
484
+ # a month old: a period ending after the rates do has no rate yet.
478
485
  positions = currency_rates.index.searchsorted(dates, side="right") - 1
479
486
  values = [
480
- currency_rates.iloc[position] if position >= 0 else float("nan")
481
- for position in positions
487
+ (
488
+ currency_rates.iloc[position]
489
+ if position >= 0
490
+ and date - currency_rates.index[position] <= STALE_RATE_DAYS
491
+ else float("nan")
492
+ )
493
+ for position, date in zip(positions, dates, strict=True)
482
494
  ]
483
495
 
484
496
  rates[ticker] = pd.Series(values, index=end_dates.index, dtype="float64")
@@ -214,14 +214,14 @@ class Discovery:
214
214
  self,
215
215
  market_cap_higher: int | None = None,
216
216
  market_cap_lower: int | None = None,
217
- price_higher: int | None = None,
218
- price_lower: int | None = None,
219
- beta_higher: int | None = None,
220
- beta_lower: int | None = None,
217
+ price_higher: float | None = None,
218
+ price_lower: float | None = None,
219
+ beta_higher: float | None = None,
220
+ beta_lower: float | None = None,
221
221
  volume_higher: int | None = None,
222
222
  volume_lower: int | None = None,
223
- dividend_higher: int | None = None,
224
- dividend_lower: int | None = None,
223
+ dividend_higher: float | None = None,
224
+ dividend_lower: float | None = None,
225
225
  sector: str | None = None,
226
226
  industry: str | None = None,
227
227
  country: str | None = None,
@@ -250,22 +250,32 @@ class Discovery:
250
250
 
251
251
  Args:
252
252
  market_cap_higher (int): The minimum market capitalization of the stock in US dollars
253
- (not in millions), e.g. 1_000_000_000 for $1 billion.
253
+ (not in millions), e.g. 1_000_000_000 for $1 billion. Defaults to None, which applies no filter.
254
254
  market_cap_lower (int): The maximum market capitalization of the stock in US dollars.
255
- price_higher (int): The minimum price of the stock.
256
- price_lower (int): The maximum price of the stock.
257
- beta_higher (int): The minimum beta of the stock.
258
- beta_lower (int): The maximum beta of the stock.
259
- volume_higher (int): The minimum volume of the stock, in shares traded.
260
- volume_lower (int): The maximum volume of the stock.
261
- dividend_higher (int): The minimum dividend of the stock, as an amount per share
262
- over the last annual period rather than as a yield.
263
- dividend_lower (int): The maximum dividend of the stock.
264
- sector (str | None): The sector to restrict the screen to, e.g. "Energy".
265
- industry (str | None): The industry to restrict the screen to, e.g. "Biotechnology".
266
- country (str | None): The two-letter country code to restrict the screen to, e.g. "US".
267
- exchange (str | None): The exchange code to restrict the screen to, e.g. "NASDAQ".
268
- is_etf (bool | None): Whether to restrict the screen to ETFs or to exclude them.
255
+ The screener returns the largest companies first, so this bound is only sent to it
256
+ when the currency of the listings is known: with an exchange, or with a country and
257
+ primary_only. Otherwise it is applied to the companies returned. Defaults to None,
258
+ which applies no filter.
259
+ price_higher (float | None): The minimum price of the stock. Defaults to None, which applies no filter.
260
+ price_lower (float | None): The maximum price of the stock. Defaults to None, which applies no filter.
261
+ beta_higher (float | None): The minimum beta of the stock. Defaults to None, which applies no filter.
262
+ beta_lower (float | None): The maximum beta of the stock. Defaults to None, which applies no filter.
263
+ volume_higher (int): The minimum volume of the stock, in shares traded. Defaults to None, which applies no
264
+ filter.
265
+ volume_lower (int): The maximum volume of the stock. Defaults to None, which applies no filter.
266
+ dividend_higher (float | None): The minimum dividend of the stock, as an amount per share
267
+ over the last annual period rather than as a yield. Defaults to None, which applies no filter.
268
+ dividend_lower (float | None): The maximum dividend of the stock. Defaults to None, which applies no filter.
269
+ sector (str | None): The sector to restrict the screen to, e.g. "Energy". Defaults to None, which applies no
270
+ filter.
271
+ industry (str | None): The industry to restrict the screen to, e.g. "Biotechnology". Defaults to None, which
272
+ applies no filter.
273
+ country (str | None): The country to restrict the screen to, as a two-letter code ("US")
274
+ or a name ("United States"). Defaults to None, which applies no filter.
275
+ exchange (str | None): The exchange code to restrict the screen to, e.g. "NASDAQ". Defaults to None, which
276
+ applies no filter.
277
+ is_etf (bool | None): Whether to restrict the screen to ETFs or to exclude them. Defaults to None, which
278
+ applies no filter.
269
279
  limit (int): The maximum number of companies to return. Defaults to 1000.
270
280
  primary_only (bool): Whether to keep only the home listing of each company (on an
271
281
  exchange in its own country, the most traded one among several) rather than
@@ -1666,8 +1676,8 @@ class Discovery:
1666
1676
  Also known as: sector performance snapshot, sector performance history, sector trend.
1667
1677
 
1668
1678
  Args:
1669
- date (str, optional): The date to retrieve a snapshot for, e.g. "2024-02-01".
1670
- sector (str, optional): The sector to retrieve the history for, e.g. "Energy".
1679
+ date (str, optional): The date to retrieve a snapshot for, e.g. "2024-02-01". Defaults to None.
1680
+ sector (str, optional): The sector to retrieve the history for, e.g. "Energy". Defaults to None.
1671
1681
  start_date (str, optional): The start of the history of one sector. Defaults to a year
1672
1682
  ago.
1673
1683
  end_date (str, optional): The end of the history of one sector. Defaults to today.
@@ -1735,8 +1745,8 @@ class Discovery:
1735
1745
  Also known as: industry performance snapshot, industry performance history, industry trend.
1736
1746
 
1737
1747
  Args:
1738
- date (str, optional): The date to retrieve a snapshot for, e.g. "2024-02-01".
1739
- industry (str, optional): The industry to retrieve the history for, e.g. "Biotechnology".
1748
+ date (str, optional): The date to retrieve a snapshot for, e.g. "2024-02-01". Defaults to None.
1749
+ industry (str, optional): The industry to retrieve the history for, e.g. "Biotechnology". Defaults to None.
1740
1750
  start_date (str, optional): The start of the history of one industry. Defaults to a year
1741
1751
  ago.
1742
1752
  end_date (str, optional): The end of the history of one industry. Defaults to today.
@@ -1803,8 +1813,8 @@ class Discovery:
1803
1813
  Also known as: sector P/E snapshot, sector P/E history, sector valuation trend.
1804
1814
 
1805
1815
  Args:
1806
- date (str, optional): The date to retrieve a snapshot for, e.g. "2024-02-01".
1807
- sector (str, optional): The sector to retrieve the history for, e.g. "Energy".
1816
+ date (str, optional): The date to retrieve a snapshot for, e.g. "2024-02-01". Defaults to None.
1817
+ sector (str, optional): The sector to retrieve the history for, e.g. "Energy". Defaults to None.
1808
1818
  start_date (str, optional): The start of the history of one sector. Defaults to a year
1809
1819
  ago.
1810
1820
  end_date (str, optional): The end of the history of one sector. Defaults to today.
@@ -1872,8 +1882,8 @@ class Discovery:
1872
1882
  Also known as: industry P/E snapshot, industry P/E history, industry valuation trend.
1873
1883
 
1874
1884
  Args:
1875
- date (str, optional): The date to retrieve a snapshot for, e.g. "2024-02-01".
1876
- industry (str, optional): The industry to retrieve the history for, e.g. "Biotechnology".
1885
+ date (str, optional): The date to retrieve a snapshot for, e.g. "2024-02-01". Defaults to None.
1886
+ industry (str, optional): The industry to retrieve the history for, e.g. "Biotechnology". Defaults to None.
1877
1887
  start_date (str, optional): The start of the history of one industry. Defaults to a year
1878
1888
  ago.
1879
1889
  end_date (str, optional): The end of the history of one industry. Defaults to today.