pyRVtest 0.3.2__tar.gz → 0.4.0b2__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 (181) hide show
  1. pyrvtest-0.4.0b2/PKG-INFO +243 -0
  2. pyrvtest-0.4.0b2/README.rst +207 -0
  3. pyrvtest-0.4.0b2/docs/advanced_features.rst +646 -0
  4. pyrvtest-0.4.0b2/docs/agent_guide.rst +837 -0
  5. pyrvtest-0.4.0b2/docs/api.rst +371 -0
  6. {pyrvtest-0.3.2 → pyrvtest-0.4.0b2}/docs/conf.py +8 -0
  7. pyrvtest-0.4.0b2/docs/custom_demand.rst +273 -0
  8. pyrvtest-0.4.0b2/docs/faq.rst +331 -0
  9. pyrvtest-0.4.0b2/docs/in_package_demand.rst +258 -0
  10. {pyrvtest-0.3.2 → pyrvtest-0.4.0b2}/docs/index.rst +14 -1
  11. pyrvtest-0.4.0b2/docs/installation.rst +35 -0
  12. pyrvtest-0.4.0b2/docs/introduction.rst +159 -0
  13. pyrvtest-0.4.0b2/docs/math.rst +531 -0
  14. pyrvtest-0.4.0b2/docs/migrating_to_v0.4.rst +568 -0
  15. pyrvtest-0.4.0b2/docs/notebooks/dmqsw_dmqss_diagnostic_workflow.py +257 -0
  16. {pyrvtest-0.3.2 → pyrvtest-0.4.0b2}/docs/notebooks/model_library.ipynb +212 -100
  17. pyrvtest-0.4.0b2/docs/notebooks/monte_carlo_example.py +369 -0
  18. pyrvtest-0.4.0b2/docs/notebooks/replication_CarRV.py +90 -0
  19. pyrvtest-0.4.0b2/docs/notebooks/replication_RVpaper.py +170 -0
  20. pyrvtest-0.4.0b2/docs/notebooks/speed_benchmark.py +113 -0
  21. pyrvtest-0.4.0b2/docs/notebooks/testing_firm_conduct.ipynb +1536 -0
  22. pyrvtest-0.4.0b2/docs/pyRVtest_performance_at_scale.md +319 -0
  23. {pyrvtest-0.3.2 → pyrvtest-0.4.0b2}/docs/references.rst +21 -5
  24. pyrvtest-0.4.0b2/docs/tutorial.rst +283 -0
  25. pyrvtest-0.4.0b2/pyRVtest/__init__.py +97 -0
  26. pyrvtest-0.4.0b2/pyRVtest/_agent_guide.py +102 -0
  27. pyrvtest-0.4.0b2/pyRVtest/_parallel.py +105 -0
  28. pyrvtest-0.4.0b2/pyRVtest/backends/__init__.py +38 -0
  29. pyrvtest-0.4.0b2/pyRVtest/backends/base.py +196 -0
  30. pyrvtest-0.4.0b2/pyRVtest/backends/labor/__init__.py +20 -0
  31. pyrvtest-0.4.0b2/pyRVtest/backends/labor/nested_logit_labor.py +204 -0
  32. pyrvtest-0.4.0b2/pyRVtest/backends/logit.py +874 -0
  33. pyrvtest-0.4.0b2/pyRVtest/backends/nested_logit.py +157 -0
  34. pyrvtest-0.4.0b2/pyRVtest/backends/pyblp.py +388 -0
  35. pyrvtest-0.4.0b2/pyRVtest/backends/user.py +170 -0
  36. pyrvtest-0.4.0b2/pyRVtest/data/__init__.py +205 -0
  37. pyrvtest-0.4.0b2/pyRVtest/data/example_synthetic.csv +6001 -0
  38. pyrvtest-0.4.0b2/pyRVtest/estimators/__init__.py +15 -0
  39. pyrvtest-0.4.0b2/pyRVtest/estimators/_base.py +198 -0
  40. pyrvtest-0.4.0b2/pyRVtest/estimators/_within_share.py +54 -0
  41. pyrvtest-0.4.0b2/pyRVtest/estimators/logit.py +261 -0
  42. pyrvtest-0.4.0b2/pyRVtest/estimators/nested_logit.py +332 -0
  43. pyrvtest-0.4.0b2/pyRVtest/exceptions.py +104 -0
  44. pyrvtest-0.4.0b2/pyRVtest/formulation.py +473 -0
  45. pyrvtest-0.4.0b2/pyRVtest/instruments/__init__.py +41 -0
  46. pyrvtest-0.4.0b2/pyRVtest/instruments/labor.py +205 -0
  47. pyrvtest-0.4.0b2/pyRVtest/instruments/product.py +283 -0
  48. pyrvtest-0.4.0b2/pyRVtest/markups.py +687 -0
  49. pyrvtest-0.4.0b2/pyRVtest/models/__init__.py +95 -0
  50. pyrvtest-0.4.0b2/pyRVtest/models/_adapter.py +222 -0
  51. pyrvtest-0.4.0b2/pyRVtest/models/base.py +336 -0
  52. pyrvtest-0.4.0b2/pyRVtest/models/collusion.py +73 -0
  53. pyrvtest-0.4.0b2/pyRVtest/models/constant.py +278 -0
  54. pyrvtest-0.4.0b2/pyRVtest/models/custom.py +144 -0
  55. pyrvtest-0.4.0b2/pyRVtest/models/labor.py +295 -0
  56. pyrvtest-0.4.0b2/pyRVtest/models/mixed.py +179 -0
  57. pyrvtest-0.4.0b2/pyRVtest/models/standard.py +173 -0
  58. pyrvtest-0.4.0b2/pyRVtest/models/user_supplied.py +133 -0
  59. pyrvtest-0.4.0b2/pyRVtest/models/vertical.py +213 -0
  60. {pyrvtest-0.3.2 → pyrvtest-0.4.0b2}/pyRVtest/options.py +92 -12
  61. pyrvtest-0.4.0b2/pyRVtest/output.py +153 -0
  62. pyrvtest-0.4.0b2/pyRVtest/problem.py +2735 -0
  63. pyrvtest-0.4.0b2/pyRVtest/products.py +337 -0
  64. pyrvtest-0.4.0b2/pyRVtest/results/__init__.py +26 -0
  65. pyrvtest-0.4.0b2/pyRVtest/results/_format.py +73 -0
  66. pyrvtest-0.4.0b2/pyRVtest/results/panel.py +476 -0
  67. pyrvtest-0.4.0b2/pyRVtest/results/results.py +1263 -0
  68. pyrvtest-0.4.0b2/pyRVtest/solve/__init__.py +29 -0
  69. pyrvtest-0.4.0b2/pyRVtest/solve/demand_adjustment.py +590 -0
  70. pyrvtest-0.4.0b2/pyRVtest/solve/endogenous_cost.py +127 -0
  71. pyrvtest-0.4.0b2/pyRVtest/solve/markups.py +79 -0
  72. pyrvtest-0.4.0b2/pyRVtest/solve/orthogonalize.py +157 -0
  73. pyrvtest-0.4.0b2/pyRVtest/solve/passthrough.py +2128 -0
  74. pyrvtest-0.4.0b2/pyRVtest/solve/test_engine.py +991 -0
  75. pyrvtest-0.4.0b2/pyRVtest/version.py +12 -0
  76. pyrvtest-0.4.0b2/pyRVtest.egg-info/PKG-INFO +243 -0
  77. pyrvtest-0.4.0b2/pyRVtest.egg-info/SOURCES.txt +150 -0
  78. {pyrvtest-0.3.2 → pyrvtest-0.4.0b2}/pyRVtest.egg-info/requires.txt +2 -0
  79. {pyrvtest-0.3.2 → pyrvtest-0.4.0b2}/pyRVtest.egg-info/top_level.txt +1 -0
  80. pyrvtest-0.4.0b2/pyproject.toml +8 -0
  81. pyrvtest-0.4.0b2/requirements.txt +22 -0
  82. {pyrvtest-0.3.2 → pyrvtest-0.4.0b2}/setup.py +9 -4
  83. pyrvtest-0.4.0b2/tests/__init__.py +0 -0
  84. pyrvtest-0.4.0b2/tests/_snapshot_helpers.py +192 -0
  85. pyrvtest-0.4.0b2/tests/conftest.py +51 -0
  86. pyrvtest-0.4.0b2/tests/fixtures/__init__.py +0 -0
  87. pyrvtest-0.4.0b2/tests/fixtures/tiny_synthetic.py +74 -0
  88. pyrvtest-0.4.0b2/tests/regressions/__init__.py +0 -0
  89. pyrvtest-0.4.0b2/tests/regressions/test_memo1_section43_gradient_no_fes.py +140 -0
  90. pyrvtest-0.4.0b2/tests/replication/__init__.py +0 -0
  91. pyrvtest-0.4.0b2/tests/replication/test_dmss_yogurt.py +172 -0
  92. pyrvtest-0.4.0b2/tests/test_adapter_user_supplied_markups.py +302 -0
  93. pyrvtest-0.4.0b2/tests/test_agent_guide.py +170 -0
  94. pyrvtest-0.4.0b2/tests/test_analytical.py +1065 -0
  95. pyrvtest-0.4.0b2/tests/test_backends.py +796 -0
  96. pyrvtest-0.4.0b2/tests/test_clustering_equivalence.py +82 -0
  97. pyrvtest-0.4.0b2/tests/test_compute_markups_direct.py +556 -0
  98. pyrvtest-0.4.0b2/tests/test_custom_demand_example.py +346 -0
  99. pyrvtest-0.4.0b2/tests/test_dearing_models.py +495 -0
  100. pyrvtest-0.4.0b2/tests/test_demand_adjustment.py +1187 -0
  101. pyrvtest-0.4.0b2/tests/test_demand_params.py +291 -0
  102. pyrvtest-0.4.0b2/tests/test_demand_params_integration.py +413 -0
  103. pyrvtest-0.4.0b2/tests/test_demand_params_rho_alias.py +193 -0
  104. pyrvtest-0.4.0b2/tests/test_doctest_gate.py +42 -0
  105. pyrvtest-0.4.0b2/tests/test_error_messages.py +215 -0
  106. pyrvtest-0.4.0b2/tests/test_f_reliability.py +823 -0
  107. pyrvtest-0.4.0b2/tests/test_first_stage_correction.py +481 -0
  108. pyrvtest-0.4.0b2/tests/test_formulation.py +72 -0
  109. pyrvtest-0.4.0b2/tests/test_import_roundtrip.py +220 -0
  110. pyrvtest-0.4.0b2/tests/test_instrument_channels.py +364 -0
  111. pyrvtest-0.4.0b2/tests/test_instruments.py +277 -0
  112. pyrvtest-0.4.0b2/tests/test_k_gt_30_warning.py +285 -0
  113. pyrvtest-0.4.0b2/tests/test_known_coefficients.py +297 -0
  114. pyrvtest-0.4.0b2/tests/test_labor_mode.py +730 -0
  115. pyrvtest-0.4.0b2/tests/test_logging.py +271 -0
  116. pyrvtest-0.4.0b2/tests/test_logit_estimator.py +508 -0
  117. pyrvtest-0.4.0b2/tests/test_market_scan_scaling.py +192 -0
  118. pyrvtest-0.4.0b2/tests/test_model_formulation_deprecation.py +92 -0
  119. pyrvtest-0.4.0b2/tests/test_models.py +320 -0
  120. pyrvtest-0.4.0b2/tests/test_models_integration.py +391 -0
  121. pyrvtest-0.4.0b2/tests/test_models_step_0_parity.py +260 -0
  122. pyrvtest-0.4.0b2/tests/test_mypy_strict.py +53 -0
  123. pyrvtest-0.4.0b2/tests/test_nested_logit_estimator.py +418 -0
  124. pyrvtest-0.4.0b2/tests/test_nested_logit_hessian_validation.py +281 -0
  125. pyrvtest-0.4.0b2/tests/test_options.py +107 -0
  126. pyrvtest-0.4.0b2/tests/test_panel_results.py +411 -0
  127. pyrvtest-0.4.0b2/tests/test_parallel.py +169 -0
  128. pyrvtest-0.4.0b2/tests/test_passthrough.py +172 -0
  129. pyrvtest-0.4.0b2/tests/test_passthrough_numerical.py +409 -0
  130. pyrvtest-0.4.0b2/tests/test_passthrough_reliability.py +407 -0
  131. pyrvtest-0.4.0b2/tests/test_passthrough_summary.py +374 -0
  132. pyrvtest-0.4.0b2/tests/test_problem_level_taxes.py +604 -0
  133. pyrvtest-0.4.0b2/tests/test_problem_state_isolation.py +130 -0
  134. pyrvtest-0.4.0b2/tests/test_properties.py +1275 -0
  135. pyrvtest-0.4.0b2/tests/test_public_api_pin.py +179 -0
  136. pyrvtest-0.4.0b2/tests/test_results_exports.py +338 -0
  137. pyrvtest-0.4.0b2/tests/test_size_power.py +191 -0
  138. pyrvtest-0.4.0b2/tests/test_snapshots.py +329 -0
  139. pyrvtest-0.3.2/PKG-INFO +0 -98
  140. pyrvtest-0.3.2/README.rst +0 -66
  141. pyrvtest-0.3.2/docs/.DS_Store +0 -0
  142. pyrvtest-0.3.2/docs/Makefile +0 -20
  143. pyrvtest-0.3.2/docs/api.rst +0 -74
  144. pyrvtest-0.3.2/docs/introduction.rst +0 -9
  145. pyrvtest-0.3.2/docs/make.bat +0 -35
  146. pyrvtest-0.3.2/docs/notebooks/.DS_Store +0 -0
  147. pyrvtest-0.3.2/docs/notebooks/my_demand_estimates +0 -0
  148. pyrvtest-0.3.2/docs/notebooks/my_testing_results +0 -0
  149. pyrvtest-0.3.2/docs/tutorial.rst +0 -13
  150. pyrvtest-0.3.2/pyRVtest/__init__.py +0 -17
  151. pyrvtest-0.3.2/pyRVtest/configurations/__init__.py +0 -1
  152. pyrvtest-0.3.2/pyRVtest/configurations/formulation.py +0 -492
  153. pyrvtest-0.3.2/pyRVtest/construction.py +0 -344
  154. pyrvtest-0.3.2/pyRVtest/data/__init__.py +0 -20
  155. pyrvtest-0.3.2/pyRVtest/data/__pycache__/__init__.cpython-39.pyc~Stashed changes +0 -0
  156. pyrvtest-0.3.2/pyRVtest/economies/__init__.py +0 -1
  157. pyrvtest-0.3.2/pyRVtest/economies/economy.py +0 -140
  158. pyrvtest-0.3.2/pyRVtest/economies/problem.py +0 -897
  159. pyrvtest-0.3.2/pyRVtest/primitives.py +0 -414
  160. pyrvtest-0.3.2/pyRVtest/results/__init__.py +0 -1
  161. pyrvtest-0.3.2/pyRVtest/results/problem_results.py +0 -152
  162. pyrvtest-0.3.2/pyRVtest/results/results.py +0 -32
  163. pyrvtest-0.3.2/pyRVtest/utilities/__init__.py +0 -1
  164. pyrvtest-0.3.2/pyRVtest/utilities/basics.py +0 -94
  165. pyrvtest-0.3.2/pyRVtest/version.py +0 -3
  166. pyrvtest-0.3.2/pyRVtest.egg-info/PKG-INFO +0 -98
  167. pyrvtest-0.3.2/pyRVtest.egg-info/SOURCES.txt +0 -50
  168. pyrvtest-0.3.2/requirements.txt +0 -6
  169. {pyrvtest-0.3.2 → pyrvtest-0.4.0b2}/LICENSE.txt +0 -0
  170. {pyrvtest-0.3.2 → pyrvtest-0.4.0b2}/MANIFEST.in +0 -0
  171. {pyrvtest-0.3.2 → pyrvtest-0.4.0b2}/docs/legal.rst +0 -0
  172. /pyrvtest-0.3.2/docs/notebooks/testing_firm_conduct.ipynb → /pyrvtest-0.4.0b2/docs/notebooks/.ipynb_checkpoints/testing_firm_conduct-checkpoint.ipynb +0 -0
  173. {pyrvtest-0.3.2 → pyrvtest-0.4.0b2}/docs/templates/class_with_signature.rst +0 -0
  174. {pyrvtest-0.3.2 → pyrvtest-0.4.0b2}/docs/templates/class_without_methods.rst +0 -0
  175. {pyrvtest-0.3.2 → pyrvtest-0.4.0b2}/docs/templates/class_without_signature.rst +0 -0
  176. {pyrvtest-0.3.2 → pyrvtest-0.4.0b2}/docs/templates/nbsphinx_epilog.rst +0 -0
  177. {pyrvtest-0.3.2 → pyrvtest-0.4.0b2}/docs/templates/nbsphinx_prolog.rst +0 -0
  178. {pyrvtest-0.3.2 → pyrvtest-0.4.0b2}/pyRVtest/data/f_critical_values_power_rho.csv +0 -0
  179. {pyrvtest-0.3.2 → pyrvtest-0.4.0b2}/pyRVtest/data/f_critical_values_size_rho.csv +0 -0
  180. {pyrvtest-0.3.2 → pyrvtest-0.4.0b2}/pyRVtest.egg-info/dependency_links.txt +0 -0
  181. {pyrvtest-0.3.2 → pyrvtest-0.4.0b2}/setup.cfg +0 -0
@@ -0,0 +1,243 @@
1
+ Metadata-Version: 2.4
2
+ Name: pyRVtest
3
+ Version: 0.4.0b2
4
+ Summary: Code to perform econometric test of firm conduct
5
+ Home-page: https://github.com/anyatarascina/pyRVtest
6
+ Author: Marco Duarte, Lorenzo Magnolfi, Mikkel Solvsten, Christopher Sullivan, Anya Tarascina
7
+ Author-email: chris.sullivan.econ@gmail.com
8
+ License: MIT
9
+ Requires-Python: >=3.9
10
+ Description-Content-Type: text/x-rst
11
+ License-File: LICENSE.txt
12
+ Requires-Dist: numpy>=1.17.0
13
+ Requires-Dist: patsy>=0.5.1
14
+ Requires-Dist: scipy>=1.2.0
15
+ Requires-Dist: sympy>=1.1.0
16
+ Requires-Dist: statsmodels>=0.12.2
17
+ Requires-Dist: pyblp>=1.0.0
18
+ Requires-Dist: jinja2>=3.0
19
+ Requires-Dist: typing_extensions>=4.0
20
+ Provides-Extra: docs
21
+ Requires-Dist: sphinx==5.0.2; extra == "docs"
22
+ Requires-Dist: pandas; extra == "docs"
23
+ Requires-Dist: ipython; extra == "docs"
24
+ Requires-Dist: astunparse; extra == "docs"
25
+ Requires-Dist: sphinx-rtd-theme==1.1.1; extra == "docs"
26
+ Requires-Dist: nbsphinx==0.8.11; extra == "docs"
27
+ Requires-Dist: jinja2==3.0.3; extra == "docs"
28
+ Requires-Dist: docutils==0.17.1; extra == "docs"
29
+ Requires-Dist: numpydoc; extra == "docs"
30
+ Dynamic: author
31
+ Dynamic: author-email
32
+ Dynamic: description
33
+ Dynamic: description-content-type
34
+ Dynamic: home-page
35
+ Dynamic: license
36
+ Dynamic: license-file
37
+ Dynamic: provides-extra
38
+ Dynamic: requires-dist
39
+ Dynamic: requires-python
40
+ Dynamic: summary
41
+
42
+ This code was written to perform the procedure for testing firm conduct developed in `"Testing Firm Conduct" <https://onlinelibrary.wiley.com/doi/10.3982/QE2319>`_ by Marco Duarte, Lorenzo Magnolfi, Mikkel Sølvsten, and Christopher Sullivan (*Quantitative Economics* 15(3), 2024). It builds on the PyBLP source code (see `Conlon and Gortmaker (2020) <https://onlinelibrary.wiley.com/doi/full/10.1111/1756-2171.12352>`_) - to do so.
43
+
44
+ The code implements the following features:
45
+
46
+ * Computes `Rivers and Vuong (2002) <https://onlinelibrary.wiley.com/doi/full/10.1111/1368-423X.t01-1-00071>`_ (RV) test statistics to test a menu of two or more models of firm conduct allowing for the possibility that firms or consumers face per-unit or ad-valorem taxes.
47
+ * Implements the RV test using the variance estimator of `Duarte, Magnolfi, Sølvsten, and Sullivan (2024) <https://onlinelibrary.wiley.com/doi/10.3982/QE2319>`_, including options to adjust for demand estimation error and clustering.
48
+ * Computes the effective F-statistic proposed in `Duarte, Magnolfi, Sølvsten, and Sullivan (2024) <https://onlinelibrary.wiley.com/doi/10.3982/QE2319>`_ to diagnose instrument strength with respect to worst-case size and best-case power of the test, and reports appropriate critical values.
49
+ * Reports `Hansen, Lunde, and Nason (2011) <https://www.jstor.org/stable/41057463?seq=1#metadata_info_tab_contents>`_ MCS p-values for testing more than two models.
50
+ * Ships a class-based ``ConductModel`` API: standard oligopoly (``Bertrand``, ``Cournot``, ``Monopoly``, ``PerfectCompetition``, ``MixCournotBertrand``), generalizations (``PartialCollusion``, ``Vertical``), Dearing, Magnolfi, Quint, Sullivan, and Waldfogel (2024) simple-markup models (``RuleOfThumb(phi)``, ``ConstantMarkup(markup)``), and customization escape hatches (``UserSuppliedMarkups`` for precomputed markup columns, ``CustomConductModel`` for arbitrary markup callables).
51
+ * Ships the full Dearing, Magnolfi, Quint, Sullivan, and Waldfogel (2024) pass-through framework as a diagnostic suite on ``Problem`` and ``ProblemResults``: ``passthrough_summary`` (pre-solve γ-free pair-by-pair structural-feature distances against four DMQSW-keyed metrics), ``passthrough_matrix`` (raw per-candidate pass-through matrix, computed numerically for every conduct class with analytical fast paths for ``Vertical`` and trivial conducts), and ``instrument_channels`` (post-solve channel decomposition for one chosen IV column). Under non-constant marginal cost (``endogenous_cost_component`` set), ``instrument_channels`` automatically applies DMQSS Appendix B's z^e residualization, producing a single unified diagnostic that collapses the Dearing condition and the DMQSS Appendix A.4 distinctness check.
52
+ * Supports ``endogenous_cost_component`` as either a single column name (single endogenous cost variable, the original v0.4 case) or a list of column names (multi-endogenous variables — quadratic cost ``['q', 'q_sq']``, scale + scope ``['log_q', 'log_Q_minus']``, etc., per DMQSS Appendix A.4). Combinable with ``demand_adjustment=True`` and ``costs_type='log'``.
53
+ * **Experimental** — Supports labor-side conduct testing via ``Problem(market_side='labor')`` with ``Monopsony``, ``BertrandWages``, and ``CournotEmployment`` model classes. The labor API is considered experimental in v0.4: the sign convention, column-name defaults, and validation behavior may adjust based on coauthor review (``pyRVtest/models/labor.py`` is flagged for a labor-market-conduct-manuscript sign check). ``NashBargaining`` raises ``NotImplementedError`` and the full ``LaborSupplyBackend`` math (Jacobian, Hessian, demand-adjustment participation) is deferred to v0.5.
54
+ * Provides instrument construction helpers (``pyRVtest.instruments.product``: BLP, differentiation IVs, rival sums; ``pyRVtest.instruments.labor``: Hausman, Bartik).
55
+ * Compatible with PyBLP `Conlon and Gortmaker (2020) <https://onlinelibrary.wiley.com/doi/full/10.1111/1756-2171.12352>`_, so that demand can be estimated with PyBLP, and the estimates are an input to the test for conduct. A ``DemandBackend`` protocol also supports user-supplied demand systems; see ``docs/custom_demand.rst``.
56
+
57
+ For a full list of references, see the references in `Duarte, Magnolfi, Sølvsten, and Sullivan (2024) <https://onlinelibrary.wiley.com/doi/10.3982/QE2319>`_.
58
+
59
+
60
+ Install
61
+ _______
62
+
63
+ First, you will need to download and install python, which you can do from this `link <https://www.python.org/>`_.
64
+ pyRVtest v0.4 requires Python ``>=3.9``.
65
+
66
+ You will also need to make sure that you have all package dependencies installed.
67
+
68
+ **Release candidate (v0.4):** PyPI still serves the older v0.3 line; the v0.4 release candidate is installed from the GitHub tag:
69
+
70
+ .. code-block::
71
+
72
+ pip install git+https://github.com/anyatarascina/pyRVtest@v0.4.0rc15
73
+
74
+ The v0.4 series will be uploaded to PyPI once it leaves release-candidate status.
75
+
76
+ **Older v0.3 release:** still available from PyPI for users on the
77
+ prior public API:
78
+
79
+ .. code-block::
80
+
81
+ pip install pyRVtest
82
+
83
+ To update to a newer version of the package use:
84
+
85
+
86
+ .. code-block::
87
+
88
+ pip install --upgrade pyRVtest
89
+
90
+ Dependencies (auto-installed): ``numpy``, ``pandas``, ``statsmodels``,
91
+ ``pyblp``, ``patsy``, ``scipy``, ``sympy``, ``jinja2``. Note: ``numpy
92
+ >= 2`` requires ``pyblp >= 1.2``; pyRVtest enforces this at import
93
+ time with a clean ``ImportError`` if the resolved combination is
94
+ inconsistent.
95
+
96
+
97
+ Quick start
98
+ ___________
99
+
100
+ A complete pyRVtest run on a synthetic dataset shipped with the package
101
+ (2 single-product firms × 3000 markets, simulated under perfect
102
+ competition with logit demand). Tests four candidate conduct models
103
+ (Bertrand, Cournot, Monopoly, Perfect Competition) using rival cost
104
+ shifters as testing instruments per Dearing, Magnolfi, Quint, Sullivan, and Waldfogel (2024).
105
+
106
+ .. code-block:: python
107
+
108
+ import pyRVtest
109
+
110
+ data = pyRVtest.data.load_example()
111
+ results = pyRVtest.Problem(
112
+ cost_formulation=pyRVtest.Formulation('1 + z1 + z2'),
113
+ instrument_formulation=pyRVtest.Formulation('0 + rival_z1 + rival_z2'),
114
+ models=[
115
+ pyRVtest.Bertrand(ownership='firm_ids'),
116
+ pyRVtest.Cournot(ownership='firm_ids'),
117
+ pyRVtest.Monopoly(),
118
+ pyRVtest.PerfectCompetition(),
119
+ ],
120
+ product_data=data,
121
+ demand_params={'estimate': 'logit',
122
+ 'formulation_X': pyRVtest.Formulation('1 + x1'),
123
+ 'formulation_Z': pyRVtest.Formulation('0 + z1')},
124
+ ).solve(demand_adjustment=False)
125
+ print(results)
126
+
127
+ Output::
128
+
129
+ Testing Results - Instruments z0:
130
+ ===============================================================================================================
131
+ TRV: | F-stats: | MCS:
132
+ -------- --- ----- ------- ------ | ---------- --- ------- ------- ------- | -------- ------------
133
+ models 0 1 2 3 | models 0 1 2 3 | models MCS p-values
134
+ -------- --- ----- ------- ------ | ---------- --- ------- ------- ------- | -------- ------------
135
+ 0 nan 6.894 -9.103 6.771 | 0 nan 92.8 170.2 2.6 | 0 0.0
136
+ *** *** *** | ††† ^^^ ††† ^^^ ††† ^^^ |
137
+ 1 nan nan -10.555 0.419 | 1 nan nan 178.4 0.0 | 1 0.675
138
+ *** | ††† ^^^ ††† |
139
+ 2 nan nan nan 10.593 | 2 nan nan nan 1.4 | 2 0.0
140
+ *** | ††† ^^^ |
141
+ 3 nan nan nan nan | 3 nan nan nan nan | 3 1.0
142
+ ===============================================================================================================
143
+
144
+ Models 0/1/2/3 correspond to Bertrand / Cournot / Monopoly / Perfect
145
+ Competition (in the order passed to ``models=``). Each block has rows
146
+ and columns indexed by model number; cell ``[i, j]`` shows the pairwise
147
+ statistic for model ``i`` vs. model ``j``. The diagonal is ``nan`` (a
148
+ model is not compared to itself); off-diagonals carry significance
149
+ markers (``*`` 10%, ``**`` 5%, ``***`` 1% for TRV; ``†``/``^`` for
150
+ F-stat size/power thresholds). The MCS column is per-model.
151
+
152
+ The truth in this dataset is Perfect Competition. Reading the output:
153
+
154
+ * **Bertrand** (model 0) and **Monopoly** (model 2) are cleanly
155
+ rejected: their MCS p-values are both 0.0, and every pairwise TRV
156
+ involving them is significant at 1% (``***``).
157
+ * **Perfect Competition** (model 3) has the highest MCS p-value (1.0).
158
+ * **Cournot** (model 1) has MCS p-value 0.675 — surviving the
159
+ confidence set despite not being the truth. The TRV(Cournot, PC) cell
160
+ is the only insignificant comparison (0.419), and its F-stat is
161
+ effectively zero. This is the Dearing et al. (2024) degeneracy
162
+ result: under logit demand, both Cournot and PC have diagonal
163
+ pass-through matrices (zero off-diagonal pass-through of rival
164
+ costs), so rival cost shifters cannot distinguish them. To falsify
165
+ Cournot in favor of PC here, the researcher would need a different
166
+ instrument such as own or rival product characteristics.
167
+
168
+ Reader's guide
169
+ ______________
170
+
171
+ Where to go next, by audience:
172
+
173
+ * **End users** running the test on their own data — `Tutorial <https://pyrvtest.readthedocs.io/en/stable/tutorial.html>`_ (worked notebooks).
174
+ * **Migrating from v0.3** — ``docs/migrating_to_v0.4.rst``. The class-based ``ConductModel`` API, ``demand_params=dict(rho=...)``, and Problem-level ``unit_tax`` / ``advalorem_tax`` kwargs are all new in v0.4; the legacy per-model ``ModelFormulation``, ``sigma`` alias, and per-model tax kwargs continue to work for one or two releases with ``DeprecationWarning``.
175
+ * **Custom demand backend** — ``docs/custom_demand.rst`` covers the ``DemandBackend`` protocol.
176
+ * **AI coding assistants and contributors** — ``AGENTS.md`` at the repo root is the living contract for code state, layout, and conventions. ``docs/agent_guide.rst`` is the longer architecture walkthrough (also surfaced via ``pyRVtest.show_agent_guide()``). ``CONTRIBUTING.md`` covers dev environment setup, running tests / lint / docs locally, and the conventions for adding new conduct models or demand backends.
177
+
178
+
179
+ Citing the package
180
+ __________________
181
+
182
+ When using ``pyRVtest`` in research, please cite the package itself plus the methodology papers your usage exercises.
183
+
184
+ **Package:**
185
+
186
+ Duarte, M., L. Magnolfi, M. Sølvsten, C. Sullivan, and A. Tarascina (2023): “pyRVtest: A Python package for testing firm conduct,” https://github.com/anyatarascina/pyRVtest.
187
+
188
+ **Methodology papers:**
189
+
190
+ * For the Rivers-Vuong test, F-statistic, MCS p-values, and demand-adjustment correction:
191
+
192
+ Duarte, M., L. Magnolfi, M. Sølvsten, and C. Sullivan (2024): `“Testing Firm Conduct,” <https://onlinelibrary.wiley.com/doi/10.3982/QE2319>`_ *Quantitative Economics*, 15(3), 571-606.
193
+
194
+ * For pass-through diagnostics, simple-markup models (``RuleOfThumb``, ``ConstantMarkup``), and the instrument-relevance / falsification framework:
195
+
196
+ Dearing, A., L. Magnolfi, D. Quint, C. Sullivan, and S. Waldfogel (2024): `“Learning Firm Conduct: Pass-Through as a Foundation for Instrument Relevance,” <https://www.nber.org/papers/w32863>`_ NBER Working Paper No. 32863, August 2024.
197
+
198
+ * For the endogenous-cost-component first-stage correction (non-linear cost):
199
+
200
+ Duarte, M., L. Magnolfi, D. Quint, M. Sølvsten, and C. Sullivan (2026): “Conduct and Scale Economies: Evaluating Tariffs in the US Automobile Market,” Working paper.
201
+
202
+ BibTeX:
203
+
204
+ .. code-block:: bibtex
205
+
206
+ @misc{pyrvtest,
207
+ author={Marco Duarte and Lorenzo Magnolfi and Mikkel S{\o}lvsten and Christopher Sullivan and Anya Tarascina},
208
+ title={\texttt{pyRVtest}: A Python package for testing firm conduct},
209
+ howpublished={\url{https://github.com/anyatarascina/pyRVtest}},
210
+ year={2023}
211
+ }
212
+
213
+ @article{dmss2024,
214
+ author={Marco Duarte and Lorenzo Magnolfi and Mikkel S{\o}lvsten and Christopher Sullivan},
215
+ title={Testing Firm Conduct},
216
+ journal={Quantitative Economics},
217
+ volume={15},
218
+ number={3},
219
+ pages={571--606},
220
+ year={2024},
221
+ doi={10.3982/QE2319}
222
+ }
223
+
224
+ @techreport{dmqsw2024,
225
+ author={Adam Dearing and Lorenzo Magnolfi and Daniel Quint and Christopher Sullivan and Sarah Waldfogel},
226
+ title={Learning Firm Conduct: Pass-Through as a Foundation for Instrument Relevance},
227
+ institution={National Bureau of Economic Research},
228
+ type={NBER Working Paper},
229
+ number={32863},
230
+ month={August},
231
+ year={2024}
232
+ }
233
+
234
+ @article{dmqss2026,
235
+ author={Marco Duarte and Lorenzo Magnolfi and Daniel Quint and Mikkel S{\o}lvsten and Christopher Sullivan},
236
+ title={Conduct and Scale Economies: Evaluating Tariffs in the US Automobile Market},
237
+ year={2026}
238
+ }
239
+
240
+ Bugs and Requests
241
+ _________________
242
+
243
+ Please use the `GitHub issue tracker <https://github.com/anyatarascina/pyRVtest/issues>`_ to submit bugs or to request features.
@@ -0,0 +1,207 @@
1
+ pyRVtest
2
+ ========
3
+
4
+ .. docs-start
5
+
6
+ This code was written to perform the procedure for testing firm conduct developed in `"Testing Firm Conduct" <https://onlinelibrary.wiley.com/doi/10.3982/QE2319>`_ by Marco Duarte, Lorenzo Magnolfi, Mikkel Sølvsten, and Christopher Sullivan (*Quantitative Economics* 15(3), 2024). It builds on the PyBLP source code (see `Conlon and Gortmaker (2020) <https://onlinelibrary.wiley.com/doi/full/10.1111/1756-2171.12352>`_) - to do so.
7
+
8
+ The code implements the following features:
9
+
10
+ * Computes `Rivers and Vuong (2002) <https://onlinelibrary.wiley.com/doi/full/10.1111/1368-423X.t01-1-00071>`_ (RV) test statistics to test a menu of two or more models of firm conduct allowing for the possibility that firms or consumers face per-unit or ad-valorem taxes.
11
+ * Implements the RV test using the variance estimator of `Duarte, Magnolfi, Sølvsten, and Sullivan (2024) <https://onlinelibrary.wiley.com/doi/10.3982/QE2319>`_, including options to adjust for demand estimation error and clustering.
12
+ * Computes the effective F-statistic proposed in `Duarte, Magnolfi, Sølvsten, and Sullivan (2024) <https://onlinelibrary.wiley.com/doi/10.3982/QE2319>`_ to diagnose instrument strength with respect to worst-case size and best-case power of the test, and reports appropriate critical values.
13
+ * Reports `Hansen, Lunde, and Nason (2011) <https://www.jstor.org/stable/41057463?seq=1#metadata_info_tab_contents>`_ MCS p-values for testing more than two models.
14
+ * Ships a class-based ``ConductModel`` API: standard oligopoly (``Bertrand``, ``Cournot``, ``Monopoly``, ``PerfectCompetition``, ``MixCournotBertrand``), generalizations (``PartialCollusion``, ``Vertical``), Dearing, Magnolfi, Quint, Sullivan, and Waldfogel (2024) simple-markup models (``RuleOfThumb(phi)``, ``ConstantMarkup(markup)``), and customization escape hatches (``UserSuppliedMarkups`` for precomputed markup columns, ``CustomConductModel`` for arbitrary markup callables).
15
+ * Ships the full Dearing, Magnolfi, Quint, Sullivan, and Waldfogel (2024) pass-through framework as a diagnostic suite on ``Problem`` and ``ProblemResults``: ``passthrough_summary`` (pre-solve γ-free pair-by-pair structural-feature distances against four DMQSW-keyed metrics), ``passthrough_matrix`` (raw per-candidate pass-through matrix, computed numerically for every conduct class with analytical fast paths for ``Vertical`` and trivial conducts), and ``instrument_channels`` (post-solve channel decomposition for one chosen IV column). Under non-constant marginal cost (``endogenous_cost_component`` set), ``instrument_channels`` automatically applies DMQSS Appendix B's z^e residualization, producing a single unified diagnostic that collapses the Dearing condition and the DMQSS Appendix A.4 distinctness check.
16
+ * Supports ``endogenous_cost_component`` as either a single column name (single endogenous cost variable, the original v0.4 case) or a list of column names (multi-endogenous variables — quadratic cost ``['q', 'q_sq']``, scale + scope ``['log_q', 'log_Q_minus']``, etc., per DMQSS Appendix A.4). Combinable with ``demand_adjustment=True`` and ``costs_type='log'``.
17
+ * **Experimental** — Supports labor-side conduct testing via ``Problem(market_side='labor')`` with ``Monopsony``, ``BertrandWages``, and ``CournotEmployment`` model classes. The labor API is considered experimental in v0.4: the sign convention, column-name defaults, and validation behavior may adjust based on coauthor review (``pyRVtest/models/labor.py`` is flagged for a labor-market-conduct-manuscript sign check). ``NashBargaining`` raises ``NotImplementedError`` and the full ``LaborSupplyBackend`` math (Jacobian, Hessian, demand-adjustment participation) is deferred to v0.5.
18
+ * Provides instrument construction helpers (``pyRVtest.instruments.product``: BLP, differentiation IVs, rival sums; ``pyRVtest.instruments.labor``: Hausman, Bartik).
19
+ * Compatible with PyBLP `Conlon and Gortmaker (2020) <https://onlinelibrary.wiley.com/doi/full/10.1111/1756-2171.12352>`_, so that demand can be estimated with PyBLP, and the estimates are an input to the test for conduct. A ``DemandBackend`` protocol also supports user-supplied demand systems; see ``docs/custom_demand.rst``.
20
+
21
+ For a full list of references, see the references in `Duarte, Magnolfi, Sølvsten, and Sullivan (2024) <https://onlinelibrary.wiley.com/doi/10.3982/QE2319>`_.
22
+
23
+
24
+ Install
25
+ _______
26
+
27
+ First, you will need to download and install python, which you can do from this `link <https://www.python.org/>`_.
28
+ pyRVtest v0.4 requires Python ``>=3.9``.
29
+
30
+ You will also need to make sure that you have all package dependencies installed.
31
+
32
+ **Release candidate (v0.4):** PyPI still serves the older v0.3 line; the v0.4 release candidate is installed from the GitHub tag:
33
+
34
+ .. code-block::
35
+
36
+ pip install git+https://github.com/anyatarascina/pyRVtest@v0.4.0rc15
37
+
38
+ The v0.4 series will be uploaded to PyPI once it leaves release-candidate status.
39
+
40
+ **Older v0.3 release:** still available from PyPI for users on the
41
+ prior public API:
42
+
43
+ .. code-block::
44
+
45
+ pip install pyRVtest
46
+
47
+ To update to a newer version of the package use:
48
+
49
+
50
+ .. code-block::
51
+
52
+ pip install --upgrade pyRVtest
53
+
54
+ Dependencies (auto-installed): ``numpy``, ``pandas``, ``statsmodels``,
55
+ ``pyblp``, ``patsy``, ``scipy``, ``sympy``, ``jinja2``. Note: ``numpy
56
+ >= 2`` requires ``pyblp >= 1.2``; pyRVtest enforces this at import
57
+ time with a clean ``ImportError`` if the resolved combination is
58
+ inconsistent.
59
+
60
+
61
+ Quick start
62
+ ___________
63
+
64
+ A complete pyRVtest run on a synthetic dataset shipped with the package
65
+ (2 single-product firms × 3000 markets, simulated under perfect
66
+ competition with logit demand). Tests four candidate conduct models
67
+ (Bertrand, Cournot, Monopoly, Perfect Competition) using rival cost
68
+ shifters as testing instruments per Dearing, Magnolfi, Quint, Sullivan, and Waldfogel (2024).
69
+
70
+ .. code-block:: python
71
+
72
+ import pyRVtest
73
+
74
+ data = pyRVtest.data.load_example()
75
+ results = pyRVtest.Problem(
76
+ cost_formulation=pyRVtest.Formulation('1 + z1 + z2'),
77
+ instrument_formulation=pyRVtest.Formulation('0 + rival_z1 + rival_z2'),
78
+ models=[
79
+ pyRVtest.Bertrand(ownership='firm_ids'),
80
+ pyRVtest.Cournot(ownership='firm_ids'),
81
+ pyRVtest.Monopoly(),
82
+ pyRVtest.PerfectCompetition(),
83
+ ],
84
+ product_data=data,
85
+ demand_params={'estimate': 'logit',
86
+ 'formulation_X': pyRVtest.Formulation('1 + x1'),
87
+ 'formulation_Z': pyRVtest.Formulation('0 + z1')},
88
+ ).solve(demand_adjustment=False)
89
+ print(results)
90
+
91
+ Output::
92
+
93
+ Testing Results - Instruments z0:
94
+ ===============================================================================================================
95
+ TRV: | F-stats: | MCS:
96
+ -------- --- ----- ------- ------ | ---------- --- ------- ------- ------- | -------- ------------
97
+ models 0 1 2 3 | models 0 1 2 3 | models MCS p-values
98
+ -------- --- ----- ------- ------ | ---------- --- ------- ------- ------- | -------- ------------
99
+ 0 nan 6.894 -9.103 6.771 | 0 nan 92.8 170.2 2.6 | 0 0.0
100
+ *** *** *** | ††† ^^^ ††† ^^^ ††† ^^^ |
101
+ 1 nan nan -10.555 0.419 | 1 nan nan 178.4 0.0 | 1 0.675
102
+ *** | ††† ^^^ ††† |
103
+ 2 nan nan nan 10.593 | 2 nan nan nan 1.4 | 2 0.0
104
+ *** | ††† ^^^ |
105
+ 3 nan nan nan nan | 3 nan nan nan nan | 3 1.0
106
+ ===============================================================================================================
107
+
108
+ Models 0/1/2/3 correspond to Bertrand / Cournot / Monopoly / Perfect
109
+ Competition (in the order passed to ``models=``). Each block has rows
110
+ and columns indexed by model number; cell ``[i, j]`` shows the pairwise
111
+ statistic for model ``i`` vs. model ``j``. The diagonal is ``nan`` (a
112
+ model is not compared to itself); off-diagonals carry significance
113
+ markers (``*`` 10%, ``**`` 5%, ``***`` 1% for TRV; ``†``/``^`` for
114
+ F-stat size/power thresholds). The MCS column is per-model.
115
+
116
+ The truth in this dataset is Perfect Competition. Reading the output:
117
+
118
+ * **Bertrand** (model 0) and **Monopoly** (model 2) are cleanly
119
+ rejected: their MCS p-values are both 0.0, and every pairwise TRV
120
+ involving them is significant at 1% (``***``).
121
+ * **Perfect Competition** (model 3) has the highest MCS p-value (1.0).
122
+ * **Cournot** (model 1) has MCS p-value 0.675 — surviving the
123
+ confidence set despite not being the truth. The TRV(Cournot, PC) cell
124
+ is the only insignificant comparison (0.419), and its F-stat is
125
+ effectively zero. This is the Dearing et al. (2024) degeneracy
126
+ result: under logit demand, both Cournot and PC have diagonal
127
+ pass-through matrices (zero off-diagonal pass-through of rival
128
+ costs), so rival cost shifters cannot distinguish them. To falsify
129
+ Cournot in favor of PC here, the researcher would need a different
130
+ instrument such as own or rival product characteristics.
131
+
132
+ Reader's guide
133
+ ______________
134
+
135
+ Where to go next, by audience:
136
+
137
+ * **End users** running the test on their own data — `Tutorial <https://pyrvtest.readthedocs.io/en/stable/tutorial.html>`_ (worked notebooks).
138
+ * **Migrating from v0.3** — ``docs/migrating_to_v0.4.rst``. The class-based ``ConductModel`` API, ``demand_params=dict(rho=...)``, and Problem-level ``unit_tax`` / ``advalorem_tax`` kwargs are all new in v0.4; the legacy per-model ``ModelFormulation``, ``sigma`` alias, and per-model tax kwargs continue to work for one or two releases with ``DeprecationWarning``.
139
+ * **Custom demand backend** — ``docs/custom_demand.rst`` covers the ``DemandBackend`` protocol.
140
+ * **AI coding assistants and contributors** — ``AGENTS.md`` at the repo root is the living contract for code state, layout, and conventions. ``docs/agent_guide.rst`` is the longer architecture walkthrough (also surfaced via ``pyRVtest.show_agent_guide()``). ``CONTRIBUTING.md`` covers dev environment setup, running tests / lint / docs locally, and the conventions for adding new conduct models or demand backends.
141
+
142
+
143
+ Citing the package
144
+ __________________
145
+
146
+ When using ``pyRVtest`` in research, please cite the package itself plus the methodology papers your usage exercises.
147
+
148
+ **Package:**
149
+
150
+ Duarte, M., L. Magnolfi, M. Sølvsten, C. Sullivan, and A. Tarascina (2023): “pyRVtest: A Python package for testing firm conduct,” https://github.com/anyatarascina/pyRVtest.
151
+
152
+ **Methodology papers:**
153
+
154
+ * For the Rivers-Vuong test, F-statistic, MCS p-values, and demand-adjustment correction:
155
+
156
+ Duarte, M., L. Magnolfi, M. Sølvsten, and C. Sullivan (2024): `“Testing Firm Conduct,” <https://onlinelibrary.wiley.com/doi/10.3982/QE2319>`_ *Quantitative Economics*, 15(3), 571-606.
157
+
158
+ * For pass-through diagnostics, simple-markup models (``RuleOfThumb``, ``ConstantMarkup``), and the instrument-relevance / falsification framework:
159
+
160
+ Dearing, A., L. Magnolfi, D. Quint, C. Sullivan, and S. Waldfogel (2024): `“Learning Firm Conduct: Pass-Through as a Foundation for Instrument Relevance,” <https://www.nber.org/papers/w32863>`_ NBER Working Paper No. 32863, August 2024.
161
+
162
+ * For the endogenous-cost-component first-stage correction (non-linear cost):
163
+
164
+ Duarte, M., L. Magnolfi, D. Quint, M. Sølvsten, and C. Sullivan (2026): “Conduct and Scale Economies: Evaluating Tariffs in the US Automobile Market,” Working paper.
165
+
166
+ BibTeX:
167
+
168
+ .. code-block:: bibtex
169
+
170
+ @misc{pyrvtest,
171
+ author={Marco Duarte and Lorenzo Magnolfi and Mikkel S{\o}lvsten and Christopher Sullivan and Anya Tarascina},
172
+ title={\texttt{pyRVtest}: A Python package for testing firm conduct},
173
+ howpublished={\url{https://github.com/anyatarascina/pyRVtest}},
174
+ year={2023}
175
+ }
176
+
177
+ @article{dmss2024,
178
+ author={Marco Duarte and Lorenzo Magnolfi and Mikkel S{\o}lvsten and Christopher Sullivan},
179
+ title={Testing Firm Conduct},
180
+ journal={Quantitative Economics},
181
+ volume={15},
182
+ number={3},
183
+ pages={571--606},
184
+ year={2024},
185
+ doi={10.3982/QE2319}
186
+ }
187
+
188
+ @techreport{dmqsw2024,
189
+ author={Adam Dearing and Lorenzo Magnolfi and Daniel Quint and Christopher Sullivan and Sarah Waldfogel},
190
+ title={Learning Firm Conduct: Pass-Through as a Foundation for Instrument Relevance},
191
+ institution={National Bureau of Economic Research},
192
+ type={NBER Working Paper},
193
+ number={32863},
194
+ month={August},
195
+ year={2024}
196
+ }
197
+
198
+ @article{dmqss2026,
199
+ author={Marco Duarte and Lorenzo Magnolfi and Daniel Quint and Mikkel S{\o}lvsten and Christopher Sullivan},
200
+ title={Conduct and Scale Economies: Evaluating Tariffs in the US Automobile Market},
201
+ year={2026}
202
+ }
203
+
204
+ Bugs and Requests
205
+ _________________
206
+
207
+ Please use the `GitHub issue tracker <https://github.com/anyatarascina/pyRVtest/issues>`_ to submit bugs or to request features.