mergeron 2024.738940.0__py3-none-any.whl → 2024.738949.0__py3-none-any.whl
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.
Potentially problematic release.
This version of mergeron might be problematic. Click here for more details.
- mergeron/core/excel_helper.py +38 -25
- mergeron/core/ftc_merger_investigations_data.py +33 -30
- mergeron/core/{guidelines_standards.py → guidelines_boundaries.py} +35 -29
- mergeron/core/proportions_tests.py +12 -10
- mergeron/examples/concentration_as_diversion.py +30 -26
- mergeron/examples/{safeharbor_boundaries_for_mergers_with_asymmetric_shares.py → enforcement_boundaries_for_mergers_with_asymmetric_shares.py} +84 -90
- mergeron/examples/{safeharbor_boundaries_for_symmetric_firm_mergers.py → enforcement_boundaries_for_symmetric_firm_mergers.py} +3 -3
- mergeron/examples/guidelines_enforcement_patterns.py +18 -16
- mergeron/examples/investigations_stats_obs_tables.py +15 -14
- mergeron/examples/investigations_stats_sim_tables.py +49 -54
- mergeron/examples/plotSafeHarbs_symbolically.py +1 -1
- mergeron/examples/sound_guppi_safeharbor.py +59 -54
- mergeron/examples/summarize_ftc_investigations_data.py +4 -4
- mergeron/examples/visualize_empirical_margin_distribution.py +2 -2
- mergeron/examples/visualize_guidelines_tests.py +67 -65
- mergeron/gen/__init__.py +104 -42
- mergeron/gen/_data_generation_functions_nonpublic.py +6 -6
- mergeron/gen/data_generation.py +1 -4
- mergeron/gen/investigations_stats.py +21 -27
- mergeron/gen/{guidelines_tests.py → upp_tests.py} +98 -102
- {mergeron-2024.738940.0.dist-info → mergeron-2024.738949.0.dist-info}/METADATA +2 -5
- mergeron-2024.738949.0.dist-info/RECORD +42 -0
- {mergeron-2024.738940.0.dist-info → mergeron-2024.738949.0.dist-info}/WHEEL +1 -1
- mergeron-2024.738940.0.dist-info/RECORD +0 -42
|
@@ -14,6 +14,7 @@ from numpy import einsum, row_stack, unique
|
|
|
14
14
|
import mergeron.core.ftc_merger_investigations_data as fid
|
|
15
15
|
import mergeron.gen.investigations_stats as isl
|
|
16
16
|
from mergeron import DATA_DIR
|
|
17
|
+
from mergeron.gen import INVResolution
|
|
17
18
|
|
|
18
19
|
if not sys.warnoptions:
|
|
19
20
|
warnings.simplefilter("ignore")
|
|
@@ -144,7 +145,7 @@ def invres_stats_odds_ratio_byhhianddelta(
|
|
|
144
145
|
_invres_rate_table_content.invdata_byhhianddelta = _odds_ratio_data_str
|
|
145
146
|
|
|
146
147
|
_output_dottex_path = DATA_DIR / INVDATA_DOTTEX_FORMAT_STR.format(
|
|
147
|
-
f"{_stats_group}_{_data_period_1}_{_merger_class.replace(
|
|
148
|
+
f"{_stats_group}_{_data_period_1}_{_merger_class.replace(" ", "")}"
|
|
148
149
|
)
|
|
149
150
|
with _output_dottex_path.open(
|
|
150
151
|
"w", encoding="utf8"
|
|
@@ -168,13 +169,13 @@ def invres_stats_obs_setup(
|
|
|
168
169
|
_data_array_dict: Mapping,
|
|
169
170
|
_data_periods: tuple[str, str],
|
|
170
171
|
_merger_classes: Sequence[isl.INDGRPConstants | isl.EVIDENConstants],
|
|
171
|
-
|
|
172
|
+
_invres_spec: INVResolution = INVResolution.CLRN,
|
|
172
173
|
/,
|
|
173
174
|
) -> tuple[str, ...]:
|
|
174
175
|
_notes_str_base = " ".join((
|
|
175
176
|
"NOTES:",
|
|
176
177
|
isl.LTX_ARRAY_LINEEND,
|
|
177
|
-
Rf"\(\cdot\) Data for period, {_data_periods[1].replace(
|
|
178
|
+
Rf"\(\cdot\) Data for period, {_data_periods[1].replace("-", "--")}",
|
|
178
179
|
"calculated by subtracting reported figures for 1996--{}".format(
|
|
179
180
|
int(_data_periods[1].split("-")[0]) - 1
|
|
180
181
|
),
|
|
@@ -182,7 +183,7 @@ def invres_stats_obs_setup(
|
|
|
182
183
|
))
|
|
183
184
|
_stats_group_dict = {
|
|
184
185
|
isl.StatsGrpSelector.FC: {
|
|
185
|
-
"desc": f"{
|
|
186
|
+
"desc": f"{_invres_spec.capitalize()} rates by Firm Count",
|
|
186
187
|
"title_str": "By Number of Significant Competitors",
|
|
187
188
|
"hval": "Firm Count",
|
|
188
189
|
"hcol_width": 54,
|
|
@@ -195,7 +196,7 @@ def invres_stats_obs_setup(
|
|
|
195
196
|
)),
|
|
196
197
|
},
|
|
197
198
|
isl.StatsGrpSelector.DL: {
|
|
198
|
-
"desc": Rf"{
|
|
199
|
+
"desc": Rf"{_invres_spec.capitalize()} rates by range of \(\Delta HHI\)",
|
|
199
200
|
"title_str": R"By Change in Concentration (\Deltah{})",
|
|
200
201
|
"hval": R"$\Delta HHI$",
|
|
201
202
|
"hval_plus": R"{ $[\Delta_L, \Delta_H)$ pts.}",
|
|
@@ -217,7 +218,7 @@ def invres_stats_obs_setup(
|
|
|
217
218
|
)),
|
|
218
219
|
},
|
|
219
220
|
isl.StatsGrpSelector.ZN: {
|
|
220
|
-
"desc": f"{
|
|
221
|
+
"desc": f"{_invres_spec.capitalize()} rates by Approximate Presumption Zone",
|
|
221
222
|
"title_str": R"By Approximate \textit{2010 Guidelines} Concentration-Based Standards",
|
|
222
223
|
"hval": "Approximate Standard",
|
|
223
224
|
"hcol_width": 190,
|
|
@@ -238,7 +239,7 @@ def invres_stats_obs_setup(
|
|
|
238
239
|
_merger_classes,
|
|
239
240
|
_stats_group_key,
|
|
240
241
|
_stats_group_dict[_stats_group_key],
|
|
241
|
-
|
|
242
|
+
_invres_spec,
|
|
242
243
|
)
|
|
243
244
|
_output_dottex_pathlist += (_output_dottex_path,)
|
|
244
245
|
|
|
@@ -251,7 +252,7 @@ def _invres_stats_obs_render(
|
|
|
251
252
|
_merger_classes: Sequence[isl.INDGRPConstants | isl.EVIDENConstants],
|
|
252
253
|
_stats_group: isl.StatsGrpSelector,
|
|
253
254
|
_stats_group_dict: Mapping,
|
|
254
|
-
|
|
255
|
+
_invres_spec: isl.INVResolution = isl.INVResolution.CLRN,
|
|
255
256
|
/,
|
|
256
257
|
) -> str:
|
|
257
258
|
_invres_rate_table_content = isl.StatsContainer()
|
|
@@ -262,7 +263,7 @@ def _invres_stats_obs_render(
|
|
|
262
263
|
print(
|
|
263
264
|
f'{_stats_group_dict["desc"]}:', ", ".join([f'"{g}"' for g in _merger_classes])
|
|
264
265
|
)
|
|
265
|
-
_invres_rate_table_content.test_regime =
|
|
266
|
+
_invres_rate_table_content.test_regime = _invres_spec.capitalize()
|
|
266
267
|
_invres_rate_table_content.obs_summary_type = f"{_stats_group}"
|
|
267
268
|
_invres_rate_table_content.obs_summary_type_title = _stats_group_dict.get(
|
|
268
269
|
"title_str"
|
|
@@ -290,7 +291,7 @@ def _invres_stats_obs_render(
|
|
|
290
291
|
_invres_rate_table_content.obs_merger_class_0 = f"{_merger_classes[0]}"
|
|
291
292
|
_invres_rate_table_content.obs_merger_class_1 = f"{_merger_classes[1]}"
|
|
292
293
|
_invres_rate_table_content.obs_periods_str = (
|
|
293
|
-
Rf"{
|
|
294
|
+
Rf"{" & ".join(_data_periods)} \\".replace("-", "--")
|
|
294
295
|
)
|
|
295
296
|
|
|
296
297
|
_invres_rate_table_content.invdata_notewidth = _stats_group_dict["notewidth"]
|
|
@@ -349,7 +350,7 @@ def _invres_stats_obs_render(
|
|
|
349
350
|
_table_ind_group,
|
|
350
351
|
_table_evid_cond,
|
|
351
352
|
_stats_group,
|
|
352
|
-
|
|
353
|
+
_invres_spec,
|
|
353
354
|
return_type_sel=isl.StatsReturnSelector.CNT,
|
|
354
355
|
print_to_screen=False,
|
|
355
356
|
)[1][-1][0]
|
|
@@ -361,7 +362,7 @@ def _invres_stats_obs_render(
|
|
|
361
362
|
_table_ind_group,
|
|
362
363
|
_table_evid_cond,
|
|
363
364
|
_stats_group,
|
|
364
|
-
|
|
365
|
+
_invres_spec,
|
|
365
366
|
return_type_sel=isl.StatsReturnSelector.RPT,
|
|
366
367
|
sort_order=_sort_order,
|
|
367
368
|
print_to_screen=False,
|
|
@@ -384,7 +385,7 @@ def _invres_stats_obs_render(
|
|
|
384
385
|
])
|
|
385
386
|
|
|
386
387
|
_invdata_datstr = "".join([
|
|
387
|
-
f"{
|
|
388
|
+
f"{" & ".join(_invdata_dat_list[g])} {isl.LTX_ARRAY_LINEEND}"
|
|
388
389
|
for g in range(len(_invdata_dat_list))
|
|
389
390
|
])
|
|
390
391
|
|
|
@@ -459,7 +460,7 @@ if __name__ == "__main__":
|
|
|
459
460
|
isl.EVIDENConstants.ED,
|
|
460
461
|
) # clstl.INDGRPConstants.IID)
|
|
461
462
|
data_periods = ("1996-2003", "2004-2011")
|
|
462
|
-
test_regime = isl.
|
|
463
|
+
test_regime = isl.INVResolution.ENFT
|
|
463
464
|
|
|
464
465
|
# Now generate the various tables summarizing merger investigations data
|
|
465
466
|
invres_stats_byhhianddelta_pathlist = invres_stats_odds_ratio_byhhianddelta(
|
|
@@ -8,25 +8,32 @@ Format output as LaTeX tables (using TikZ).
|
|
|
8
8
|
import sys
|
|
9
9
|
import warnings
|
|
10
10
|
from collections.abc import Mapping, Sequence
|
|
11
|
+
from dataclasses import fields
|
|
11
12
|
from datetime import datetime, timedelta
|
|
12
13
|
from io import TextIOWrapper
|
|
13
|
-
from pathlib import Path
|
|
14
14
|
from typing import Any
|
|
15
15
|
|
|
16
16
|
import numpy as np
|
|
17
|
-
import re2 as re # type: ignore
|
|
18
|
-
import tables as ptb # type: ignore
|
|
19
17
|
from attrs import evolve
|
|
20
18
|
|
|
21
19
|
import mergeron.core.ftc_merger_investigations_data as fid
|
|
22
|
-
import mergeron.core.
|
|
20
|
+
import mergeron.core.guidelines_boundaries as gbl
|
|
23
21
|
import mergeron.gen.data_generation as dgl
|
|
24
|
-
import mergeron.gen.guidelines_tests as gtl
|
|
25
22
|
import mergeron.gen.investigations_stats as isl
|
|
23
|
+
import mergeron.gen.upp_tests as utl
|
|
26
24
|
from mergeron import DATA_DIR
|
|
27
|
-
from mergeron.core.guidelines_standards import GuidelinesStandards
|
|
28
25
|
from mergeron.core.proportions_tests import propn_ci
|
|
29
|
-
from mergeron.gen import
|
|
26
|
+
from mergeron.gen import (
|
|
27
|
+
INVResolution,
|
|
28
|
+
MarketSampleSpec,
|
|
29
|
+
PCMConstants,
|
|
30
|
+
PCMSpec,
|
|
31
|
+
RECConstants,
|
|
32
|
+
ShareSpec,
|
|
33
|
+
SHRConstants,
|
|
34
|
+
UPPAggrSelector,
|
|
35
|
+
UPPTestRegime,
|
|
36
|
+
)
|
|
30
37
|
|
|
31
38
|
if not sys.warnoptions:
|
|
32
39
|
warnings.simplefilter("ignore") # , category="RuntimeWarning")
|
|
@@ -42,9 +49,9 @@ def invres_stats_sim_setup(
|
|
|
42
49
|
_invdata: fid.INVData,
|
|
43
50
|
_data_period: str,
|
|
44
51
|
_merger_class: isl.INDGRPConstants | isl.EVIDENConstants,
|
|
45
|
-
_invres_parm_vec:
|
|
46
|
-
_sample_spec:
|
|
47
|
-
_invres_stats_kwargs:
|
|
52
|
+
_invres_parm_vec: gbl.HMGThresholds,
|
|
53
|
+
_sample_spec: MarketSampleSpec,
|
|
54
|
+
_invres_stats_kwargs: utl.IVNRESCntsArgs | None = None,
|
|
48
55
|
/,
|
|
49
56
|
) -> str:
|
|
50
57
|
_table_ind_group = (
|
|
@@ -59,10 +66,14 @@ def invres_stats_sim_setup(
|
|
|
59
66
|
)
|
|
60
67
|
|
|
61
68
|
_invres_stats_kwargs = _invres_stats_kwargs or {
|
|
62
|
-
"sim_test_regime":
|
|
69
|
+
"sim_test_regime": UPPTestRegime(INVResolution.ENFT, UPPAggrSelector.MAX, None)
|
|
63
70
|
}
|
|
64
|
-
_sim_test_regime = _invres_stats_kwargs
|
|
65
|
-
|
|
71
|
+
_sim_test_regime = _invres_stats_kwargs.get("sim_test_regime")
|
|
72
|
+
|
|
73
|
+
_invres_spec, _guppi_wgtng_policy, _divr_wgtng_policy = (
|
|
74
|
+
getattr(_sim_test_regime, _f.name)
|
|
75
|
+
for _f in fields(_sim_test_regime) # type: ignore
|
|
76
|
+
)
|
|
66
77
|
|
|
67
78
|
# Get observed rates
|
|
68
79
|
(
|
|
@@ -76,7 +87,7 @@ def invres_stats_sim_setup(
|
|
|
76
87
|
_table_ind_group,
|
|
77
88
|
_table_evid_cond,
|
|
78
89
|
_grp,
|
|
79
|
-
|
|
90
|
+
_invres_spec,
|
|
80
91
|
)
|
|
81
92
|
for _grp in (
|
|
82
93
|
isl.StatsGrpSelector.FC,
|
|
@@ -97,7 +108,7 @@ def invres_stats_sim_setup(
|
|
|
97
108
|
|
|
98
109
|
# Generate simulated rates
|
|
99
110
|
_start_time = datetime.now()
|
|
100
|
-
_upp_tests_counts =
|
|
111
|
+
_upp_tests_counts = utl.sim_invres_cnts_ll(
|
|
101
112
|
_invres_parm_vec, _sample_spec_here, _invres_stats_kwargs
|
|
102
113
|
)
|
|
103
114
|
_total_duration = datetime.now() - _start_time
|
|
@@ -109,7 +120,7 @@ def invres_stats_sim_setup(
|
|
|
109
120
|
# Prepare and write/print output tables
|
|
110
121
|
_stats_group_dict = {
|
|
111
122
|
isl.StatsGrpSelector.FC: {
|
|
112
|
-
"desc": f"{
|
|
123
|
+
"desc": f"{_invres_spec.capitalize()} rates by firm count",
|
|
113
124
|
"title_str": "By Number of Significant Competitors",
|
|
114
125
|
"hval": "Firm Count",
|
|
115
126
|
"hcol_width": 54,
|
|
@@ -118,7 +129,7 @@ def invres_stats_sim_setup(
|
|
|
118
129
|
"sim_array": _upp_tests_counts.by_firm_count,
|
|
119
130
|
},
|
|
120
131
|
isl.StatsGrpSelector.DL: {
|
|
121
|
-
"desc": Rf"{
|
|
132
|
+
"desc": Rf"{_invres_spec.capitalize()} rates by range of $\Delta HHI$",
|
|
122
133
|
"title_str": R"By Change in Concentration (\Deltah{})",
|
|
123
134
|
"hval": R"$\Delta HHI$",
|
|
124
135
|
"hval_plus": R"{ $[\Delta_L, \Delta_H)$ }",
|
|
@@ -137,7 +148,7 @@ def invres_stats_sim_setup(
|
|
|
137
148
|
"sim_array": _upp_tests_counts.by_delta,
|
|
138
149
|
},
|
|
139
150
|
isl.StatsGrpSelector.ZN: {
|
|
140
|
-
"desc": f"{
|
|
151
|
+
"desc": f"{_invres_spec.capitalize()} rates by Approximate Presumption Zone",
|
|
141
152
|
"title_str": "{} {}".format(
|
|
142
153
|
R"By Approximate \textit{2010 Guidelines}",
|
|
143
154
|
"Concentration-Based Standards",
|
|
@@ -151,7 +162,7 @@ def invres_stats_sim_setup(
|
|
|
151
162
|
}
|
|
152
163
|
|
|
153
164
|
_stats_table_name = dottex_format_str.format(
|
|
154
|
-
|
|
165
|
+
_invres_spec.capitalize(),
|
|
155
166
|
_merger_class.replace(" ", ""),
|
|
156
167
|
_data_period.split("-")[1],
|
|
157
168
|
)
|
|
@@ -177,8 +188,8 @@ def invres_stats_sim_render(
|
|
|
177
188
|
_merger_class: isl.INDGRPConstants | isl.EVIDENConstants,
|
|
178
189
|
_stats_group: isl.StatsGrpSelector,
|
|
179
190
|
_stats_group_dict_sub: Mapping[str, Any],
|
|
180
|
-
_invres_parm_vec:
|
|
181
|
-
_sim_test_regime:
|
|
191
|
+
_invres_parm_vec: gbl.HMGThresholds,
|
|
192
|
+
_sim_test_regime: UPPTestRegime,
|
|
182
193
|
_stats_table_file: TextIOWrapper,
|
|
183
194
|
/,
|
|
184
195
|
) -> None:
|
|
@@ -203,7 +214,13 @@ def invres_stats_sim_render(
|
|
|
203
214
|
_stats_table_content.dbar,
|
|
204
215
|
_stats_table_content.cmcr_bound,
|
|
205
216
|
_stats_table_content.ipr_bound,
|
|
206
|
-
) = (
|
|
217
|
+
) = (
|
|
218
|
+
rf"{_s * 100:.1f}\%"
|
|
219
|
+
for _s in (
|
|
220
|
+
getattr(_invres_parm_vec, _f)
|
|
221
|
+
for _f in ("rec", "guppi", "divr", "cmcr", "ipr")
|
|
222
|
+
)
|
|
223
|
+
)
|
|
207
224
|
|
|
208
225
|
# Prepare and write/print output tables
|
|
209
226
|
_stats_cis_wilson_notestr = " ".join((
|
|
@@ -216,9 +233,9 @@ def invres_stats_sim_render(
|
|
|
216
233
|
isl.LTX_ARRAY_LINEEND,
|
|
217
234
|
))
|
|
218
235
|
|
|
219
|
-
_eg_count = (_relfreq_eg := 0.01) * _sim_sample_sz
|
|
236
|
+
_eg_count = int(_relfreq_eg := 0.01) * _sim_sample_sz
|
|
220
237
|
_stats_sim_ci_eg = 100 * np.array(
|
|
221
|
-
propn_ci(0.50 * _eg_count, _eg_count, method="Exact")
|
|
238
|
+
propn_ci(int(0.50 * _eg_count), _eg_count, method="Exact")
|
|
222
239
|
)
|
|
223
240
|
_stats_sim_notestr = " ".join((
|
|
224
241
|
Rf"\(\cdot\) Simulated {_stats_table_content.test_res} rates are estimated by",
|
|
@@ -250,7 +267,7 @@ def invres_stats_sim_render(
|
|
|
250
267
|
_stats_table_content.stats_cis_notewidth = _stats_group_dict_sub["notewidth"]
|
|
251
268
|
_stats_cis_numobs_notestr = " ".join((
|
|
252
269
|
R"\(\cdot\) Estimates for Proportion {} are based on".format(
|
|
253
|
-
"Enforced" if _invres_select ==
|
|
270
|
+
"Enforced" if _invres_select == INVResolution.ENFT else "Cleared"
|
|
254
271
|
),
|
|
255
272
|
f"{_obs_sample_sz:,d} total observations (investigated mergers).",
|
|
256
273
|
))
|
|
@@ -361,22 +378,9 @@ if __name__ == "__main__":
|
|
|
361
378
|
sample_sz_base = 10**7
|
|
362
379
|
pcm_dist_type, pcm_dist_parms = PCMConstants.EMPR, None
|
|
363
380
|
|
|
364
|
-
save_data_to_file_flag = False
|
|
365
|
-
save_data_to_file: gtl.SaveData = False
|
|
366
|
-
if save_data_to_file_flag:
|
|
367
|
-
h5path = DATA_DIR / Path(__file__).with_suffix(".h5").name
|
|
368
|
-
blosc_filters = ptb.Filters(complevel=3, complib="blosc:lz4", fletcher32=True)
|
|
369
|
-
h5datafile = ptb.open_file(
|
|
370
|
-
str(h5path),
|
|
371
|
-
mode="w",
|
|
372
|
-
title="Datasets, Sound GUPPI Safeharbor",
|
|
373
|
-
filters=blosc_filters,
|
|
374
|
-
)
|
|
375
|
-
save_data_to_file = (True, h5datafile, "/")
|
|
376
|
-
|
|
377
381
|
sim_test_regime = (
|
|
378
|
-
(
|
|
379
|
-
(
|
|
382
|
+
UPPTestRegime(INVResolution.CLRN, utl.UPPAggrSelector.MAX, None),
|
|
383
|
+
UPPTestRegime(INVResolution.ENFT, utl.UPPAggrSelector.OSD, None),
|
|
380
384
|
)[1]
|
|
381
385
|
invres_stats_kwargs = {"sim_test_regime": sim_test_regime}
|
|
382
386
|
|
|
@@ -387,16 +391,16 @@ if __name__ == "__main__":
|
|
|
387
391
|
continue
|
|
388
392
|
|
|
389
393
|
print(
|
|
390
|
-
f"{sim_test_regime
|
|
394
|
+
f"{sim_test_regime.resolution.capitalize()} rates and c.i.s",
|
|
391
395
|
f"for the class of mergers, '{merger_class}',",
|
|
392
396
|
f"for study period, {study_period}:",
|
|
393
397
|
)
|
|
394
398
|
stats_table_content.obs_period = study_period.split("-")
|
|
395
399
|
|
|
396
400
|
invres_parm_vec = (
|
|
397
|
-
|
|
401
|
+
gbl.GuidelinesThresholds(2010).presumption
|
|
398
402
|
if study_period.split("-")[1] == data_periods[1].split("-")[1]
|
|
399
|
-
else
|
|
403
|
+
else gbl.GuidelinesThresholds(1992).presumption
|
|
400
404
|
)
|
|
401
405
|
|
|
402
406
|
mkt_sample_spec = dgl.MarketSampleSpec(
|
|
@@ -406,26 +410,17 @@ if __name__ == "__main__":
|
|
|
406
410
|
hsr_filing_test_type=dgl.SSZConstants.HSR_NTH,
|
|
407
411
|
)
|
|
408
412
|
|
|
409
|
-
# A file to write tables to, and a hierarchy under which to store the data
|
|
410
|
-
if save_data_to_file:
|
|
411
|
-
h5hier_pat = re.compile(r"\W")
|
|
412
|
-
h5hier = f"/{h5hier_pat.sub("_", f"{merger_class} {study_period}")}"
|
|
413
|
-
save_data_to_file = (True, save_data_to_file[1], h5hier)
|
|
414
|
-
|
|
415
413
|
table_dottex_name = invres_stats_sim_setup(
|
|
416
414
|
invdata_array_dict,
|
|
417
415
|
study_period,
|
|
418
416
|
merger_class,
|
|
419
417
|
invres_parm_vec,
|
|
420
418
|
mkt_sample_spec,
|
|
421
|
-
invres_stats_kwargs,
|
|
419
|
+
invres_stats_kwargs, # type: ignore
|
|
422
420
|
)
|
|
423
421
|
table_dottex_namelist += (table_dottex_name,)
|
|
424
422
|
|
|
425
423
|
isl.render_table_pdf(
|
|
426
424
|
table_dottex_namelist,
|
|
427
|
-
dottex_format_str.format(
|
|
425
|
+
dottex_format_str.format(sim_test_regime.resolution.capitalize(), "All", "All"),
|
|
428
426
|
)
|
|
429
|
-
|
|
430
|
-
if save_data_to_file:
|
|
431
|
-
save_data_to_file[1].close()
|
|
@@ -1,43 +1,39 @@
|
|
|
1
|
-
import re
|
|
2
1
|
from datetime import datetime, timedelta
|
|
3
2
|
from itertools import product as iterprod
|
|
4
3
|
from pathlib import Path
|
|
5
4
|
from typing import Literal
|
|
6
5
|
|
|
7
6
|
import numpy as np
|
|
8
|
-
import tables as ptb # type: ignore
|
|
9
7
|
|
|
10
|
-
import mergeron.core.
|
|
8
|
+
import mergeron.core.guidelines_boundaries as gbl
|
|
11
9
|
import mergeron.gen.data_generation as dgl
|
|
12
|
-
import mergeron.gen.guidelines_tests as gtl
|
|
13
10
|
import mergeron.gen.investigations_stats as isl
|
|
11
|
+
import mergeron.gen.upp_tests as utl
|
|
14
12
|
from mergeron import DATA_DIR
|
|
13
|
+
from mergeron.core.pseudorandom_numbers import DIST_PARMS_DEFAULT
|
|
15
14
|
from mergeron.gen import (
|
|
16
|
-
|
|
17
|
-
FCOUNT_WTS_DEFAULT,
|
|
15
|
+
INVResolution,
|
|
18
16
|
MarketSampleSpec,
|
|
19
17
|
PCMConstants,
|
|
20
18
|
PCMSpec,
|
|
21
19
|
ShareSpec,
|
|
22
20
|
SHRConstants,
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
tests_of_interest: tuple[gtl.UPPTestRegime, ...] = (
|
|
26
|
-
gtl.UPPTestRegime(
|
|
27
|
-
isl.PolicySelector.CLRN, gtl.UPPAggrSelector.MAX, gtl.UPPAggrSelector.MAX
|
|
28
|
-
),
|
|
29
|
-
gtl.UPPTestRegime(
|
|
30
|
-
isl.PolicySelector.ENFT, gtl.UPPAggrSelector.MIN, gtl.UPPAggrSelector.MIN
|
|
31
|
-
),
|
|
21
|
+
UPPAggrSelector,
|
|
22
|
+
UPPTestRegime,
|
|
32
23
|
)
|
|
33
24
|
|
|
34
25
|
PROG_PATH = Path(__file__)
|
|
35
26
|
|
|
27
|
+
tests_of_interest: tuple[UPPTestRegime, ...] = (
|
|
28
|
+
UPPTestRegime(INVResolution.CLRN, UPPAggrSelector.MAX, UPPAggrSelector.MAX),
|
|
29
|
+
UPPTestRegime(INVResolution.ENFT, UPPAggrSelector.MIN, UPPAggrSelector.MIN),
|
|
30
|
+
)
|
|
31
|
+
|
|
36
32
|
|
|
37
33
|
def analyze_invres_data(
|
|
38
34
|
_sample_size: int = 10**6,
|
|
39
|
-
|
|
40
|
-
|
|
35
|
+
_hmg_pub_year: Literal[1992, 2010, 2023] = 1992,
|
|
36
|
+
_test_regime: UPPTestRegime = tests_of_interest[1],
|
|
41
37
|
/,
|
|
42
38
|
*,
|
|
43
39
|
save_data_to_file_flag: bool = False,
|
|
@@ -51,39 +47,35 @@ def analyze_invres_data(
|
|
|
51
47
|
_sample_size
|
|
52
48
|
Number of draws (mergers) to analyze
|
|
53
49
|
|
|
54
|
-
|
|
50
|
+
_hmg_pub_year
|
|
55
51
|
Guidelines version for ∆HHI standard
|
|
56
52
|
|
|
57
|
-
|
|
53
|
+
_test_regime
|
|
58
54
|
Specifies analysis of enforcement rates or, alternatively, clearance rates
|
|
59
55
|
|
|
60
56
|
save_data_to_file_flag
|
|
61
57
|
If True, simulated data are save to file (hdf5 format)
|
|
62
58
|
|
|
63
59
|
"""
|
|
64
|
-
_invres_parm_vec =
|
|
60
|
+
_invres_parm_vec = gbl.GuidelinesThresholds(_hmg_pub_year).presumption
|
|
65
61
|
|
|
66
|
-
_save_data_to_file:
|
|
62
|
+
_save_data_to_file: utl.SaveData = False
|
|
67
63
|
if save_data_to_file_flag:
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
)
|
|
72
|
-
_h5_datafile = ptb.open_file(
|
|
73
|
-
DATA_DIR / PROG_PATH.with_suffix(".h5").name,
|
|
74
|
-
mode="w",
|
|
75
|
-
title=f"GUPPI Safeharbor {_test_sel.resolution.capitalize()} Rate Module",
|
|
76
|
-
filters=_blosc_filters,
|
|
77
|
-
)
|
|
78
|
-
_h5_hier = f"/{_h5_hier_pat.sub("_", f"Standards from {_hmg_std_pub_year} Guidelines")}"
|
|
64
|
+
_h5_path = DATA_DIR / PROG_PATH.with_suffix(".h5").name
|
|
65
|
+
(_, _h5_file, _h5_group), _h5_subgroup_name = utl.initialize_hd5(
|
|
66
|
+
_h5_path, _hmg_pub_year, _test_regime
|
|
67
|
+
) # type: ignore
|
|
79
68
|
|
|
80
|
-
|
|
69
|
+
_h5_group = _h5_file.create_group(
|
|
70
|
+
_h5_group, _h5_subgroup_name, f"{_invres_parm_vec}"
|
|
71
|
+
)
|
|
72
|
+
_save_data_to_file = (True, _h5_file, _h5_group)
|
|
81
73
|
|
|
82
74
|
# ##
|
|
83
75
|
# Print summaries of intrinsic clearance/enforcement rates by ∆HHI,
|
|
84
76
|
# with asymmetric margins
|
|
85
77
|
# ##
|
|
86
|
-
for _recapture_spec_test,
|
|
78
|
+
for _recapture_spec_test, _pcm_dist_test, _pcm_dist_firm2_test in iterprod(
|
|
87
79
|
(dgl.RECConstants.INOUT, dgl.RECConstants.FIXED),
|
|
88
80
|
[
|
|
89
81
|
tuple(
|
|
@@ -92,7 +84,7 @@ def analyze_invres_data(
|
|
|
92
84
|
(
|
|
93
85
|
np.array((0, 1), dtype=np.float64),
|
|
94
86
|
np.array((10, 10), dtype=np.float64),
|
|
95
|
-
|
|
87
|
+
None,
|
|
96
88
|
),
|
|
97
89
|
strict=True,
|
|
98
90
|
)
|
|
@@ -102,52 +94,64 @@ def analyze_invres_data(
|
|
|
102
94
|
(dgl.FM2Constants.IID, dgl.FM2Constants.MNL),
|
|
103
95
|
):
|
|
104
96
|
if _recapture_spec_test == "proportional" and (
|
|
105
|
-
|
|
97
|
+
_pcm_dist_test[0] != "Uniform" or _pcm_dist_firm2_test == "MNL-dep"
|
|
106
98
|
):
|
|
99
|
+
continue
|
|
107
100
|
# When margins are specified as symmetric, then
|
|
108
101
|
# recapture_spec must be proportional and
|
|
109
102
|
# margins distributions must be iid;
|
|
110
|
-
continue
|
|
111
103
|
|
|
112
|
-
_pcm_dist_type_test, _pcm_dist_parms_test =
|
|
104
|
+
_pcm_dist_type_test, _pcm_dist_parms_test = _pcm_dist_test
|
|
113
105
|
|
|
114
106
|
print()
|
|
115
107
|
print(
|
|
116
|
-
f"Simulated {
|
|
108
|
+
f"Simulated {_test_regime.resolution.capitalize()} rates by range of ∆HHI",
|
|
117
109
|
f'recapture-rate calibrated, "{_recapture_spec_test}"',
|
|
118
110
|
f'Firm 2 margins, "{_pcm_dist_firm2_test}"',
|
|
119
|
-
f"and margins distributed {_pcm_dist_type_test}{
|
|
111
|
+
f"and margins distributed as, {_pcm_dist_type_test}{
|
|
112
|
+
_pcm_dist_parms_test if _pcm_dist_type_test.name == "BETA" else ""
|
|
113
|
+
}:",
|
|
120
114
|
sep="; ",
|
|
121
115
|
)
|
|
122
116
|
|
|
123
|
-
|
|
117
|
+
_mkt_sample_spec = MarketSampleSpec(
|
|
124
118
|
_sample_size,
|
|
125
119
|
_invres_parm_vec.rec,
|
|
126
120
|
share_spec=ShareSpec(
|
|
127
|
-
_recapture_spec_test,
|
|
128
|
-
SHRConstants.UNI,
|
|
129
|
-
EMPTY_ARRAY_DEFAULT,
|
|
130
|
-
FCOUNT_WTS_DEFAULT,
|
|
121
|
+
_recapture_spec_test, SHRConstants.UNI, DIST_PARMS_DEFAULT, None
|
|
131
122
|
),
|
|
132
123
|
pcm_spec=PCMSpec(
|
|
133
124
|
_pcm_dist_type_test, _pcm_dist_firm2_test, _pcm_dist_parms_test
|
|
134
125
|
),
|
|
135
126
|
)
|
|
136
127
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
128
|
+
if _save_data_to_file:
|
|
129
|
+
_h5_file.flush()
|
|
130
|
+
|
|
131
|
+
_h5_subgrp_name = "invres_rec{}_pcm{}_fm2res{}".format(
|
|
132
|
+
_recapture_spec_test.name,
|
|
133
|
+
_pcm_dist_type_test.name,
|
|
134
|
+
_pcm_dist_firm2_test.name,
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
_h5_subgroup = _h5_file.create_group(
|
|
138
|
+
_h5_group, _h5_subgrp_name, title=f"{_mkt_sample_spec}"
|
|
139
|
+
)
|
|
140
|
+
_save_data_to_file = (True, _h5_file, _h5_subgroup)
|
|
141
|
+
|
|
142
|
+
_invres_cnts_kwargs = utl.IVNRESCntsArgs(
|
|
143
|
+
sim_test_regime=_test_regime, save_data_to_file=_save_data_to_file
|
|
144
|
+
)
|
|
141
145
|
|
|
142
146
|
_start_time = datetime.now()
|
|
143
147
|
|
|
144
|
-
upp_test_counts =
|
|
145
|
-
_invres_parm_vec,
|
|
148
|
+
upp_test_counts = utl.sim_invres_cnts_ll(
|
|
149
|
+
_invres_parm_vec, _mkt_sample_spec, _invres_cnts_kwargs
|
|
146
150
|
)
|
|
147
151
|
_run_duration = datetime.now() - _start_time
|
|
148
152
|
print(
|
|
149
153
|
f"Simulation completed in {_run_duration / timedelta(seconds=1):.6f} secs.",
|
|
150
|
-
f"on {
|
|
154
|
+
f"on {_mkt_sample_spec.sample_size:,d} draws",
|
|
151
155
|
sep=", ",
|
|
152
156
|
)
|
|
153
157
|
|
|
@@ -166,10 +170,11 @@ def analyze_invres_data(
|
|
|
166
170
|
])
|
|
167
171
|
print(_stats_teststr_val)
|
|
168
172
|
del _stats_hdr_list, _stats_dat_list, _stats_teststr_val
|
|
169
|
-
del
|
|
173
|
+
del _pcm_dist_test, _pcm_dist_firm2_test, _recapture_spec_test
|
|
170
174
|
del _pcm_dist_type_test, _pcm_dist_parms_test
|
|
171
175
|
|
|
172
|
-
if
|
|
176
|
+
if _save_data_to_file:
|
|
177
|
+
_h5_file.flush()
|
|
173
178
|
_save_data_to_file[1].close() # type: ignore
|
|
174
179
|
|
|
175
180
|
|
|
@@ -16,13 +16,13 @@ for data_period in invdata:
|
|
|
16
16
|
print(leader_str, table_type, "-->")
|
|
17
17
|
leader_str += "\t"
|
|
18
18
|
for table_no in (isd11 := isd1[table_type]):
|
|
19
|
-
(
|
|
19
|
+
(invdata_ind_group, invdata_evid_cond, table_data_array) = isd11[table_no]
|
|
20
20
|
print(
|
|
21
21
|
leader_str,
|
|
22
22
|
table_no,
|
|
23
23
|
" \N{EM DASH} ",
|
|
24
|
-
|
|
25
|
-
f", {invdata_evid_cond or
|
|
24
|
+
invdata_ind_group,
|
|
25
|
+
f", {invdata_evid_cond or "N/A"}",
|
|
26
26
|
", ",
|
|
27
27
|
sep="",
|
|
28
28
|
end="",
|
|
@@ -39,6 +39,6 @@ data_period, data_type, table_no = ("2004-2011", "HHI and Delta", "Table 3.3")
|
|
|
39
39
|
print(f"Investigations data, {data_period}, by {data_type}, {table_no}")
|
|
40
40
|
print(
|
|
41
41
|
"{}, {}\n{}".format(
|
|
42
|
-
*invdata[data_period][f"By{data_type.replace(
|
|
42
|
+
*invdata[data_period][f"By{data_type.replace(" ", "")}"][table_no]
|
|
43
43
|
)
|
|
44
44
|
)
|
|
@@ -14,7 +14,7 @@ from scipy import stats # type: ignore
|
|
|
14
14
|
|
|
15
15
|
import mergeron.core.damodaran_margin_data as dmgn
|
|
16
16
|
from mergeron import DATA_DIR
|
|
17
|
-
from mergeron.core.
|
|
17
|
+
from mergeron.core.guidelines_boundaries import boundary_plot
|
|
18
18
|
|
|
19
19
|
PROG_PATH = Path(__file__)
|
|
20
20
|
|
|
@@ -97,4 +97,4 @@ if __name__ == "__main__":
|
|
|
97
97
|
mgn_ax.set_ylabel("Relative Frequency", fontsize=10)
|
|
98
98
|
|
|
99
99
|
mgn_fig.tight_layout()
|
|
100
|
-
plt.savefig(PROG_PATH.with_suffix(".pdf"))
|
|
100
|
+
plt.savefig(DATA_DIR / PROG_PATH.with_suffix(".pdf").name)
|