mergeron 2024.738963.0__py3-none-any.whl → 2024.738972.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/__init__.py +2 -2
- mergeron/core/guidelines_boundaries.py +16 -13
- mergeron/core/guidelines_boundaries_specialized_functions.py +11 -6
- mergeron/gen/__init__.py +21 -29
- mergeron/gen/{_data_generation_functions_nonpublic.py → _data_generation_functions.py} +77 -19
- mergeron/gen/data_generation.py +17 -14
- mergeron/gen/market_sample.py +79 -0
- mergeron/gen/upp_tests.py +99 -66
- {mergeron-2024.738963.0.dist-info → mergeron-2024.738972.0.dist-info}/METADATA +1 -1
- {mergeron-2024.738963.0.dist-info → mergeron-2024.738972.0.dist-info}/RECORD +11 -10
- {mergeron-2024.738963.0.dist-info → mergeron-2024.738972.0.dist-info}/WHEEL +0 -0
mergeron/core/__init__.py
CHANGED
|
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from importlib.metadata import version
|
|
4
4
|
|
|
5
|
-
from attrs import Attribute,
|
|
5
|
+
from attrs import Attribute, field, frozen, validators
|
|
6
6
|
|
|
7
7
|
from .. import _PKG_NAME, RECConstants, UPPAggrSelector # noqa: TID252
|
|
8
8
|
|
|
@@ -38,7 +38,7 @@ def _rec_spec_validator(
|
|
|
38
38
|
)
|
|
39
39
|
|
|
40
40
|
|
|
41
|
-
@
|
|
41
|
+
@frozen
|
|
42
42
|
class UPPBoundarySpec:
|
|
43
43
|
share_ratio: float = field(
|
|
44
44
|
kw_only=False,
|
|
@@ -5,13 +5,12 @@ with a canvas on which to draw boundaries for Guidelines standards.
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
import decimal
|
|
8
|
-
from collections.abc import Callable
|
|
9
8
|
from dataclasses import dataclass
|
|
10
9
|
from importlib.metadata import version
|
|
11
10
|
from typing import Any, Literal, TypeAlias
|
|
12
11
|
|
|
13
12
|
import numpy as np
|
|
14
|
-
from attrs import
|
|
13
|
+
from attrs import field, frozen
|
|
15
14
|
from mpmath import mp, mpf # type: ignore
|
|
16
15
|
from numpy.typing import NDArray
|
|
17
16
|
|
|
@@ -24,7 +23,7 @@ __version__ = version(_PKG_NAME)
|
|
|
24
23
|
mp.prec = 80
|
|
25
24
|
mp.trap_complex = True
|
|
26
25
|
|
|
27
|
-
HMGPubYear: TypeAlias = Literal[1992, 2010, 2023]
|
|
26
|
+
HMGPubYear: TypeAlias = Literal[1992, 2004, 2010, 2023]
|
|
28
27
|
|
|
29
28
|
|
|
30
29
|
@dataclass(slots=True, frozen=True)
|
|
@@ -43,25 +42,28 @@ class GuidelinesBoundary:
|
|
|
43
42
|
area: float
|
|
44
43
|
|
|
45
44
|
|
|
46
|
-
@
|
|
47
|
-
class GuidelinesBoundaryCallable:
|
|
48
|
-
boundary_function: Callable[[NDArray[np.float64]], NDArray[np.float64]]
|
|
49
|
-
area: float
|
|
50
|
-
s_naught: float = 0
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
@define(slots=True, frozen=True)
|
|
45
|
+
@frozen
|
|
54
46
|
class GuidelinesThresholds:
|
|
55
47
|
"""
|
|
56
48
|
Guidelines threholds by Guidelines publication year
|
|
57
49
|
|
|
58
50
|
ΔHHI, Recapture Rate, GUPPI, Diversion ratio, CMCR, and IPR thresholds
|
|
59
|
-
constructed from concentration standards
|
|
51
|
+
constructed from concentration standards in Guidelines published in
|
|
52
|
+
1992, 2004, 2010, and 2023.
|
|
53
|
+
|
|
54
|
+
The 2004 Guidelines refernced here are the EU Commission
|
|
55
|
+
guidelines on assessment of horizontal mergers. These
|
|
56
|
+
guidelines also define a presumption for mergers with
|
|
57
|
+
post-merger HHI in [1000, 2000) and ΔHHI >= 250 points,
|
|
58
|
+
whi is not modeled here.
|
|
59
|
+
|
|
60
|
+
All other Guidelines modeled here are U.S. merger guidelines.
|
|
61
|
+
|
|
60
62
|
"""
|
|
61
63
|
|
|
62
64
|
pub_year: HMGPubYear
|
|
63
65
|
"""
|
|
64
|
-
Year of publication of the
|
|
66
|
+
Year of publication of the Guidelines
|
|
65
67
|
"""
|
|
66
68
|
|
|
67
69
|
safeharbor: HMGThresholds = field(kw_only=True, default=None)
|
|
@@ -99,6 +101,7 @@ class GuidelinesThresholds:
|
|
|
99
101
|
_hhi_p, _dh_s, _dh_p = {
|
|
100
102
|
1992: (0.18, 0.005, 0.01),
|
|
101
103
|
2010: (0.25, 0.01, 0.02),
|
|
104
|
+
2004: (0.20, 0.015, 0.015),
|
|
102
105
|
2023: (0.18, 0.01, 0.01),
|
|
103
106
|
}[self.pub_year]
|
|
104
107
|
|
|
@@ -6,21 +6,19 @@ to have poor performance
|
|
|
6
6
|
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
|
+
from collections.abc import Callable
|
|
10
|
+
from dataclasses import dataclass
|
|
9
11
|
from importlib.metadata import version
|
|
10
12
|
from typing import Literal
|
|
11
13
|
|
|
12
14
|
import numpy as np
|
|
13
15
|
from mpmath import mp, mpf # type: ignore
|
|
16
|
+
from numpy.typing import NDArray
|
|
14
17
|
from scipy.spatial.distance import minkowski as distance_function # type: ignore
|
|
15
18
|
from sympy import lambdify, simplify, solve, symbols
|
|
16
19
|
|
|
17
20
|
from .. import _PKG_NAME # noqa: TID252
|
|
18
|
-
from .guidelines_boundaries import
|
|
19
|
-
GuidelinesBoundary,
|
|
20
|
-
GuidelinesBoundaryCallable,
|
|
21
|
-
_shrratio_boundary_intcpt,
|
|
22
|
-
lerp,
|
|
23
|
-
)
|
|
21
|
+
from .guidelines_boundaries import GuidelinesBoundary, _shrratio_boundary_intcpt, lerp
|
|
24
22
|
|
|
25
23
|
__version__ = version(_PKG_NAME)
|
|
26
24
|
|
|
@@ -29,6 +27,13 @@ mp.prec = 80
|
|
|
29
27
|
mp.trap_complex = True
|
|
30
28
|
|
|
31
29
|
|
|
30
|
+
@dataclass(slots=True, frozen=True)
|
|
31
|
+
class GuidelinesBoundaryCallable:
|
|
32
|
+
boundary_function: Callable[[NDArray[np.float64]], NDArray[np.float64]]
|
|
33
|
+
area: float
|
|
34
|
+
s_naught: float = 0
|
|
35
|
+
|
|
36
|
+
|
|
32
37
|
def delta_hhi_boundary_qdtr(_dh_val: float = 0.01, /) -> GuidelinesBoundaryCallable:
|
|
33
38
|
"""
|
|
34
39
|
Generate the list of share combination on the ΔHHI boundary.
|
mergeron/gen/__init__.py
CHANGED
|
@@ -5,23 +5,21 @@ Defines constants and containers for industry data generation and testing
|
|
|
5
5
|
|
|
6
6
|
from __future__ import annotations
|
|
7
7
|
|
|
8
|
-
from importlib.metadata import version
|
|
9
|
-
|
|
10
|
-
from .. import _PKG_NAME, RECConstants, UPPAggrSelector # noqa: TID252
|
|
11
|
-
|
|
12
|
-
__version__ = version(_PKG_NAME)
|
|
13
|
-
|
|
14
|
-
|
|
15
8
|
import enum
|
|
16
9
|
from dataclasses import dataclass
|
|
17
|
-
from
|
|
10
|
+
from importlib.metadata import version
|
|
11
|
+
from typing import ClassVar, Protocol, TypeVar
|
|
18
12
|
|
|
19
13
|
import numpy as np
|
|
20
|
-
from attrs import Attribute, define, field, validators
|
|
14
|
+
from attrs import Attribute, define, field, frozen, validators
|
|
21
15
|
from numpy.typing import NBitBase, NDArray
|
|
22
16
|
|
|
17
|
+
from .. import _PKG_NAME, RECConstants, UPPAggrSelector # noqa: TID252
|
|
23
18
|
from ..core.pseudorandom_numbers import DIST_PARMS_DEFAULT # noqa: TID252
|
|
24
19
|
|
|
20
|
+
__version__ = version(_PKG_NAME)
|
|
21
|
+
|
|
22
|
+
|
|
25
23
|
EMPTY_ARRAY_DEFAULT = np.zeros(2)
|
|
26
24
|
FCOUNT_WTS_DEFAULT = ((_nr := np.arange(1, 6)[::-1]) / _nr.sum()).astype(np.float64)
|
|
27
25
|
|
|
@@ -74,7 +72,7 @@ class SHRConstants(enum.StrEnum):
|
|
|
74
72
|
"""
|
|
75
73
|
|
|
76
74
|
|
|
77
|
-
@
|
|
75
|
+
@frozen
|
|
78
76
|
class ShareSpec:
|
|
79
77
|
"""Market share specification
|
|
80
78
|
|
|
@@ -152,7 +150,7 @@ class FM2Constants(enum.StrEnum):
|
|
|
152
150
|
SYM = "symmetric"
|
|
153
151
|
|
|
154
152
|
|
|
155
|
-
@
|
|
153
|
+
@frozen
|
|
156
154
|
class PCMSpec:
|
|
157
155
|
"""Price-cost margin (PCM) specification
|
|
158
156
|
|
|
@@ -224,9 +222,9 @@ class SSZConstants(float, enum.ReprEnum):
|
|
|
224
222
|
"""When initial set of draws is not restricted in any way."""
|
|
225
223
|
|
|
226
224
|
|
|
227
|
-
# Validators for selected attributes of
|
|
225
|
+
# Validators for selected attributes of MarketSpec
|
|
228
226
|
def _sample_size_validator(
|
|
229
|
-
_object:
|
|
227
|
+
_object: MarketSpec, _attribute: Attribute[int], _value: int, /
|
|
230
228
|
) -> None:
|
|
231
229
|
if _value < 10**6:
|
|
232
230
|
raise ValueError(
|
|
@@ -235,7 +233,7 @@ def _sample_size_validator(
|
|
|
235
233
|
|
|
236
234
|
|
|
237
235
|
def _share_spec_validator(
|
|
238
|
-
_instance:
|
|
236
|
+
_instance: MarketSpec, _attribute: Attribute[ShareSpec], _value: ShareSpec, /
|
|
239
237
|
) -> None:
|
|
240
238
|
_r_bar = _value.recapture_rate
|
|
241
239
|
if _r_bar and not (0 < _r_bar <= 1):
|
|
@@ -274,7 +272,7 @@ def _share_spec_validator(
|
|
|
274
272
|
|
|
275
273
|
|
|
276
274
|
def _pcm_spec_validator(
|
|
277
|
-
_instance:
|
|
275
|
+
_instance: MarketSpec, _attribute: Attribute[PCMSpec], _value: PCMSpec, /
|
|
278
276
|
) -> None:
|
|
279
277
|
if (
|
|
280
278
|
_instance.share_spec.recapture_form == RECConstants.FIXED
|
|
@@ -308,15 +306,10 @@ def _pcm_spec_validator(
|
|
|
308
306
|
)
|
|
309
307
|
|
|
310
308
|
|
|
311
|
-
@define(slots=
|
|
312
|
-
class
|
|
309
|
+
@define(slots=False)
|
|
310
|
+
class MarketSpec:
|
|
313
311
|
"""Parameter specification for market data generation."""
|
|
314
312
|
|
|
315
|
-
sample_size: int = field(
|
|
316
|
-
default=10**6, validator=(validators.instance_of(int), _sample_size_validator)
|
|
317
|
-
)
|
|
318
|
-
"""sample size generated"""
|
|
319
|
-
|
|
320
313
|
share_spec: ShareSpec = field(
|
|
321
314
|
kw_only=True,
|
|
322
315
|
default=ShareSpec(RECConstants.INOUT, 0.855, SHRConstants.UNI, None, None),
|
|
@@ -353,17 +346,16 @@ class INVResolution(enum.StrEnum):
|
|
|
353
346
|
BOTH = "both"
|
|
354
347
|
|
|
355
348
|
|
|
356
|
-
@
|
|
349
|
+
@frozen
|
|
357
350
|
class UPPTestRegime:
|
|
358
351
|
resolution: INVResolution = field(
|
|
359
352
|
default=INVResolution.ENFT, validator=validators.instance_of(INVResolution)
|
|
360
353
|
)
|
|
361
354
|
guppi_aggregator: UPPAggrSelector = field(
|
|
362
|
-
default=UPPAggrSelector.
|
|
355
|
+
default=UPPAggrSelector.MIN, validator=validators.instance_of(UPPAggrSelector)
|
|
363
356
|
)
|
|
364
357
|
divr_aggregator: UPPAggrSelector | None = field(
|
|
365
|
-
default=
|
|
366
|
-
validator=validators.instance_of((UPPAggrSelector, type(None))),
|
|
358
|
+
default=None, validator=validators.instance_of((UPPAggrSelector, type(None)))
|
|
367
359
|
)
|
|
368
360
|
|
|
369
361
|
|
|
@@ -469,7 +461,7 @@ class MarginDataSample:
|
|
|
469
461
|
|
|
470
462
|
@dataclass(slots=True, frozen=True)
|
|
471
463
|
class UPPTestsRaw:
|
|
472
|
-
"""arrays marking test failures and successes
|
|
464
|
+
"""Container for arrays marking test failures and successes
|
|
473
465
|
|
|
474
466
|
A test success is a draw ("market") that meeets the
|
|
475
467
|
specified test criterion, and a test failure is
|
|
@@ -494,9 +486,9 @@ class UPPTestsRaw:
|
|
|
494
486
|
|
|
495
487
|
@dataclass(slots=True, frozen=True)
|
|
496
488
|
class UPPTestsCounts:
|
|
497
|
-
"""
|
|
489
|
+
"""Counts of markets resolved as specified
|
|
498
490
|
|
|
499
|
-
Resolution
|
|
491
|
+
Resolution may be either "enforcement" or "clearance".
|
|
500
492
|
"""
|
|
501
493
|
|
|
502
494
|
by_firm_count: NDArray[np.int64]
|
|
@@ -19,11 +19,12 @@ from ..core.pseudorandom_numbers import ( # noqa: TID252
|
|
|
19
19
|
prng,
|
|
20
20
|
)
|
|
21
21
|
from . import (
|
|
22
|
+
EMPTY_ARRAY_DEFAULT,
|
|
22
23
|
FCOUNT_WTS_DEFAULT,
|
|
23
24
|
TF,
|
|
24
25
|
FM2Constants,
|
|
25
26
|
MarginDataSample,
|
|
26
|
-
|
|
27
|
+
MarketSpec,
|
|
27
28
|
PCMConstants,
|
|
28
29
|
PriceDataSample,
|
|
29
30
|
PRIConstants,
|
|
@@ -36,7 +37,8 @@ __version__ = version(_PKG_NAME)
|
|
|
36
37
|
|
|
37
38
|
|
|
38
39
|
def _gen_share_data(
|
|
39
|
-
|
|
40
|
+
_sample_size: int,
|
|
41
|
+
_mkt_sample_spec: MarketSpec,
|
|
40
42
|
_fcount_rng_seed_seq: SeedSequence | None,
|
|
41
43
|
_mktshr_rng_seed_seq: SeedSequence,
|
|
42
44
|
_nthreads: int = 16,
|
|
@@ -66,7 +68,7 @@ def _gen_share_data(
|
|
|
66
68
|
for _f in ("recapture_form", "dist_type", "dist_parms", "firm_counts_weights")
|
|
67
69
|
)
|
|
68
70
|
|
|
69
|
-
_ssz =
|
|
71
|
+
_ssz = _sample_size
|
|
70
72
|
|
|
71
73
|
match _dist_type_mktshr:
|
|
72
74
|
case SHRConstants.UNI:
|
|
@@ -396,24 +398,22 @@ def _gen_market_shares_dirichlet(
|
|
|
396
398
|
def _gen_price_data(
|
|
397
399
|
_frmshr_array: NDArray[np.float64],
|
|
398
400
|
_nth_firm_share: NDArray[np.float64],
|
|
399
|
-
_mkt_sample_spec:
|
|
401
|
+
_mkt_sample_spec: MarketSpec,
|
|
400
402
|
_seed_seq: SeedSequence | None = None,
|
|
401
403
|
/,
|
|
402
404
|
) -> PriceDataSample:
|
|
403
|
-
_ssz = len(_frmshr_array)
|
|
404
|
-
|
|
405
405
|
_hsr_filing_test_type = _mkt_sample_spec.hsr_filing_test_type
|
|
406
406
|
|
|
407
407
|
_price_array, _price_ratio_array, _hsr_filing_test = (
|
|
408
408
|
np.ones_like(_frmshr_array, np.float64),
|
|
409
409
|
np.empty_like(_frmshr_array, np.float64),
|
|
410
|
-
np.empty(
|
|
410
|
+
np.empty(len(_frmshr_array), bool),
|
|
411
411
|
)
|
|
412
412
|
|
|
413
413
|
_pr_max_ratio = 5.0
|
|
414
414
|
match _mkt_sample_spec.price_spec:
|
|
415
415
|
case PRIConstants.SYM:
|
|
416
|
-
_nth_firm_price = np.ones((
|
|
416
|
+
_nth_firm_price = np.ones((len(_frmshr_array), 1))
|
|
417
417
|
case PRIConstants.POS:
|
|
418
418
|
_price_array, _nth_firm_price = (
|
|
419
419
|
np.ceil(_p * _pr_max_ratio) for _p in (_frmshr_array, _nth_firm_share)
|
|
@@ -477,14 +477,14 @@ def _gen_price_data(
|
|
|
477
477
|
# del _nth_firm_rev, _rev_ratio_to_nth
|
|
478
478
|
case _:
|
|
479
479
|
# Otherwise, all draws meet the filing test
|
|
480
|
-
_hsr_filing_test = np.ones(
|
|
480
|
+
_hsr_filing_test = np.ones(len(_frmshr_array), dtype=bool)
|
|
481
481
|
|
|
482
482
|
return PriceDataSample(_price_array, _hsr_filing_test)
|
|
483
483
|
|
|
484
484
|
|
|
485
485
|
def _gen_pcm_data(
|
|
486
486
|
_frmshr_array: NDArray[np.floating[TF]],
|
|
487
|
-
_mkt_sample_spec:
|
|
487
|
+
_mkt_sample_spec: MarketSpec,
|
|
488
488
|
_price_array: NDArray[np.floating[TF]],
|
|
489
489
|
_aggregate_purchase_prob: NDArray[np.floating[TF]],
|
|
490
490
|
_pcm_rng_seed_seq: SeedSequence,
|
|
@@ -504,27 +504,25 @@ def _gen_pcm_data(
|
|
|
504
504
|
_mnl_test_array = np.empty((len(_frmshr_array), 2), dtype=int)
|
|
505
505
|
|
|
506
506
|
_beta_min, _beta_max = [None] * 2 # placeholder
|
|
507
|
-
_dist_parms = np.ones(2, np.float64)
|
|
508
507
|
if _dist_type_pcm == PCMConstants.EMPR:
|
|
509
508
|
_pcm_array = resample_mgn_data(
|
|
510
509
|
_pcm_array.shape, # type: ignore
|
|
511
510
|
seed_sequence=_pcm_rng_seed_seq,
|
|
512
511
|
)
|
|
513
512
|
else:
|
|
514
|
-
if _dist_type_pcm == PCMConstants.
|
|
515
|
-
_dist_parms = (
|
|
516
|
-
DIST_PARMS_DEFAULT if _dist_parms_pcm is None else _dist_parms_pcm
|
|
517
|
-
)
|
|
518
|
-
elif _dist_type_pcm == PCMConstants.BETA:
|
|
519
|
-
# Error-checking (could move to validators in definition of MarketSampleSpec)
|
|
520
|
-
|
|
513
|
+
if _dist_type_pcm == PCMConstants.BETA:
|
|
521
514
|
if _dist_parms_pcm is None:
|
|
522
|
-
_dist_parms_pcm =
|
|
515
|
+
_dist_parms_pcm = np.ones(2, np.float64)
|
|
523
516
|
|
|
524
517
|
elif _dist_type_pcm == PCMConstants.BETA_BND: # Bounded beta
|
|
525
518
|
if _dist_parms_pcm is None:
|
|
526
519
|
_dist_parms_pcm = np.array([0, 1, 0, 1], np.float64)
|
|
527
520
|
_dist_parms = beta_located_bound(_dist_parms_pcm)
|
|
521
|
+
else:
|
|
522
|
+
# _dist_type_pcm == PCMConstants.UNI
|
|
523
|
+
_dist_parms = (
|
|
524
|
+
DIST_PARMS_DEFAULT if _dist_parms_pcm is None else _dist_parms_pcm
|
|
525
|
+
)
|
|
528
526
|
|
|
529
527
|
_pcm_rng = MultithreadedRNG(
|
|
530
528
|
_pcm_array,
|
|
@@ -564,6 +562,66 @@ def _gen_pcm_data(
|
|
|
564
562
|
return MarginDataSample(_pcm_array, _mnl_test_array)
|
|
565
563
|
|
|
566
564
|
|
|
565
|
+
def _gen_divr_array(
|
|
566
|
+
_recapture_form: RECConstants,
|
|
567
|
+
_recapture_rate: float | None,
|
|
568
|
+
_frmshr_array: NDArray[np.float64],
|
|
569
|
+
_aggregate_purchase_prob: NDArray[np.float64] = EMPTY_ARRAY_DEFAULT,
|
|
570
|
+
/,
|
|
571
|
+
) -> NDArray[np.float64]:
|
|
572
|
+
"""
|
|
573
|
+
Given merging-firm shares and related parameters, return diverion ratios.
|
|
574
|
+
|
|
575
|
+
If recapture is specified as "Outside-in" (RECConstants.OUTIN), then the
|
|
576
|
+
choice-probability for the outside good must be supplied.
|
|
577
|
+
|
|
578
|
+
Parameters
|
|
579
|
+
----------
|
|
580
|
+
_recapture_form
|
|
581
|
+
Enum specifying Fixed (proportional), Inside-out, or Outside-in
|
|
582
|
+
|
|
583
|
+
_recapture_rate
|
|
584
|
+
If recapture is proportional or inside-out, the recapture rate
|
|
585
|
+
for the firm with the smaller share.
|
|
586
|
+
|
|
587
|
+
_frmshr_array
|
|
588
|
+
Merging-firm shares.
|
|
589
|
+
|
|
590
|
+
_aggregate_purchase_prob
|
|
591
|
+
1 minus probability that the outside good is chosen; converts
|
|
592
|
+
market shares to choice probabilities by multiplication.
|
|
593
|
+
|
|
594
|
+
Returns
|
|
595
|
+
-------
|
|
596
|
+
Merging-firm diversion ratios for mergers in the sample.
|
|
597
|
+
|
|
598
|
+
"""
|
|
599
|
+
|
|
600
|
+
_divr_array: NDArray[np.float64]
|
|
601
|
+
if _recapture_form == RECConstants.FIXED:
|
|
602
|
+
_divr_array = _recapture_rate * _frmshr_array[:, ::-1] / (1 - _frmshr_array) # type: ignore
|
|
603
|
+
|
|
604
|
+
else:
|
|
605
|
+
_purchprob_array = _aggregate_purchase_prob * _frmshr_array
|
|
606
|
+
_divr_array = _purchprob_array[:, ::-1] / (1 - _purchprob_array)
|
|
607
|
+
|
|
608
|
+
_divr_assert_test = (
|
|
609
|
+
(np.round(np.einsum("ij->i", _frmshr_array), 15) == 1)
|
|
610
|
+
| (np.argmin(_frmshr_array, axis=1) == np.argmax(_divr_array, axis=1))
|
|
611
|
+
)[:, None]
|
|
612
|
+
if not all(_divr_assert_test):
|
|
613
|
+
raise ValueError(
|
|
614
|
+
"{} {} {} {}".format(
|
|
615
|
+
"Data construction fails tests:",
|
|
616
|
+
"the index of min(s_1, s_2) must equal",
|
|
617
|
+
"the index of max(d_12, d_21), for all draws.",
|
|
618
|
+
"unless frmshr_array sums to 1.00.",
|
|
619
|
+
)
|
|
620
|
+
)
|
|
621
|
+
|
|
622
|
+
return _divr_array
|
|
623
|
+
|
|
624
|
+
|
|
567
625
|
def _beta_located(
|
|
568
626
|
_mu: float | NDArray[np.float64], _sigma: float | NDArray[np.float64], /
|
|
569
627
|
) -> NDArray[np.float64]:
|
mergeron/gen/data_generation.py
CHANGED
|
@@ -7,7 +7,6 @@ from __future__ import annotations
|
|
|
7
7
|
|
|
8
8
|
from importlib.metadata import version
|
|
9
9
|
|
|
10
|
-
import attrs
|
|
11
10
|
import numpy as np
|
|
12
11
|
from numpy.random import SeedSequence
|
|
13
12
|
from numpy.typing import NDArray
|
|
@@ -17,12 +16,12 @@ from . import (
|
|
|
17
16
|
EMPTY_ARRAY_DEFAULT,
|
|
18
17
|
FM2Constants,
|
|
19
18
|
MarketDataSample,
|
|
20
|
-
|
|
19
|
+
MarketSpec,
|
|
21
20
|
PRIConstants,
|
|
22
21
|
SHRConstants,
|
|
23
22
|
SSZConstants,
|
|
24
23
|
)
|
|
25
|
-
from .
|
|
24
|
+
from ._data_generation_functions import (
|
|
26
25
|
_gen_market_shares_dirichlet, # noqa: F401 easter-egg for external modules
|
|
27
26
|
_gen_market_shares_uniform, # noqa: F401 easter-egg for external modules
|
|
28
27
|
_gen_pcm_data,
|
|
@@ -34,9 +33,10 @@ __version__ = version(_PKG_NAME)
|
|
|
34
33
|
|
|
35
34
|
|
|
36
35
|
def gen_market_sample(
|
|
37
|
-
_mkt_sample_spec:
|
|
36
|
+
_mkt_sample_spec: MarketSpec,
|
|
38
37
|
/,
|
|
39
38
|
*,
|
|
39
|
+
sample_size: int = 10**6,
|
|
40
40
|
seed_seq_list: list[SeedSequence] | None = None,
|
|
41
41
|
nthreads: int = 16,
|
|
42
42
|
) -> MarketDataSample:
|
|
@@ -59,6 +59,8 @@ def gen_market_sample(
|
|
|
59
59
|
----------
|
|
60
60
|
_mkt_sample_spec
|
|
61
61
|
class specifying parameters for data generation
|
|
62
|
+
sample_size
|
|
63
|
+
number of draws to generate
|
|
62
64
|
seed_seq_list
|
|
63
65
|
tuple of SeedSequences to ensure replicable data generation with
|
|
64
66
|
appropriately independent random streams
|
|
@@ -72,7 +74,7 @@ def gen_market_sample(
|
|
|
72
74
|
|
|
73
75
|
"""
|
|
74
76
|
|
|
75
|
-
_mkt_sample_spec = _mkt_sample_spec or
|
|
77
|
+
_mkt_sample_spec = _mkt_sample_spec or MarketSpec()
|
|
76
78
|
|
|
77
79
|
_recapture_form = _mkt_sample_spec.share_spec.recapture_form
|
|
78
80
|
_recapture_rate = _mkt_sample_spec.share_spec.recapture_rate
|
|
@@ -89,19 +91,20 @@ def gen_market_sample(
|
|
|
89
91
|
seed_seq_list, _dist_type_mktshr, _mkt_sample_spec.price_spec
|
|
90
92
|
)
|
|
91
93
|
|
|
92
|
-
_shr_sample_size = 1.0 *
|
|
94
|
+
_shr_sample_size = 1.0 * sample_size
|
|
93
95
|
# Scale up sample size to offset discards based on specified criteria
|
|
94
96
|
_shr_sample_size *= _hsr_filing_test_type
|
|
95
97
|
if _dist_firm2_pcm == FM2Constants.MNL:
|
|
96
98
|
_shr_sample_size *= SSZConstants.MNL_DEP
|
|
97
|
-
|
|
98
|
-
_mkt_sample_spec, sample_size=int(_shr_sample_size)
|
|
99
|
-
)
|
|
100
|
-
del _shr_sample_size
|
|
99
|
+
_shr_sample_size = int(_shr_sample_size)
|
|
101
100
|
|
|
102
101
|
# Generate share data
|
|
103
102
|
_mktshr_data = _gen_share_data(
|
|
104
|
-
|
|
103
|
+
_shr_sample_size,
|
|
104
|
+
_mkt_sample_spec,
|
|
105
|
+
_fcount_rng_seed_seq,
|
|
106
|
+
_mktshr_rng_seed_seq,
|
|
107
|
+
nthreads,
|
|
105
108
|
)
|
|
106
109
|
|
|
107
110
|
_mktshr_array, _fcounts, _aggregate_purchase_prob, _nth_firm_share = (
|
|
@@ -116,7 +119,7 @@ def gen_market_sample(
|
|
|
116
119
|
|
|
117
120
|
# Generate merging-firm price data
|
|
118
121
|
_price_data = _gen_price_data(
|
|
119
|
-
_mktshr_array[:, :2], _nth_firm_share,
|
|
122
|
+
_mktshr_array[:, :2], _nth_firm_share, _mkt_sample_spec, _pr_rng_seed_seq
|
|
120
123
|
)
|
|
121
124
|
|
|
122
125
|
_price_array, _hsr_filing_test = (
|
|
@@ -138,7 +141,7 @@ def gen_market_sample(
|
|
|
138
141
|
# Generate margin data
|
|
139
142
|
_pcm_data = _gen_pcm_data(
|
|
140
143
|
_mktshr_array[:, :2],
|
|
141
|
-
|
|
144
|
+
_mkt_sample_spec,
|
|
142
145
|
_price_array,
|
|
143
146
|
_aggregate_purchase_prob,
|
|
144
147
|
_pcm_rng_seed_seq,
|
|
@@ -148,7 +151,7 @@ def gen_market_sample(
|
|
|
148
151
|
getattr(_pcm_data, _f) for _f in ("pcm_array", "mnl_test_array")
|
|
149
152
|
)
|
|
150
153
|
|
|
151
|
-
_s_size =
|
|
154
|
+
_s_size = sample_size # originally-specified sample size
|
|
152
155
|
if _dist_firm2_pcm == FM2Constants.MNL:
|
|
153
156
|
_mktshr_array = _mktshr_array[_mnl_test_rows][:_s_size]
|
|
154
157
|
_pcm_array = _pcm_array[_mnl_test_rows][:_s_size]
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Methods to generate data for analyzing merger enforcement policy.
|
|
3
|
+
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
from importlib.metadata import version
|
|
9
|
+
|
|
10
|
+
from attrs import define
|
|
11
|
+
from numpy.random import SeedSequence
|
|
12
|
+
|
|
13
|
+
from .. import _PKG_NAME # noqa: TID252
|
|
14
|
+
from ..core import guidelines_boundaries as gbl # noqa: TID252
|
|
15
|
+
from . import MarketSpec, UPPTestRegime
|
|
16
|
+
from .data_generation import gen_market_sample
|
|
17
|
+
from .upp_tests import SaveData, invres_cnts, save_data_to_hdf5, sim_invres_cnts_ll
|
|
18
|
+
|
|
19
|
+
__version__ = version(_PKG_NAME)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@define(slots=False)
|
|
23
|
+
class MarketSample(MarketSpec):
|
|
24
|
+
def generate_sample(
|
|
25
|
+
self,
|
|
26
|
+
/,
|
|
27
|
+
*,
|
|
28
|
+
sample_size: int = 10**6,
|
|
29
|
+
seed_seq_list: list[SeedSequence] | None,
|
|
30
|
+
nthreads: int,
|
|
31
|
+
save_data_to_file: SaveData = False,
|
|
32
|
+
) -> None:
|
|
33
|
+
self.data = gen_market_sample(
|
|
34
|
+
self,
|
|
35
|
+
sample_size=sample_size,
|
|
36
|
+
seed_seq_list=seed_seq_list,
|
|
37
|
+
nthreads=nthreads,
|
|
38
|
+
)
|
|
39
|
+
_invalid_array_names = (
|
|
40
|
+
("fcounts", "choice_prob_outgd", "nth_firm_share", "hhi_post")
|
|
41
|
+
if self.share_spec.dist_type == "Uniform"
|
|
42
|
+
else ()
|
|
43
|
+
)
|
|
44
|
+
if save_data_to_file:
|
|
45
|
+
save_data_to_hdf5(
|
|
46
|
+
self.data,
|
|
47
|
+
excluded_attrs=_invalid_array_names,
|
|
48
|
+
save_data_to_file=save_data_to_file,
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
def estimate_invres_counts(
|
|
52
|
+
self,
|
|
53
|
+
_invres_parm_vec: gbl.HMGThresholds,
|
|
54
|
+
_upp_test_regime: UPPTestRegime,
|
|
55
|
+
/,
|
|
56
|
+
*,
|
|
57
|
+
sample_size: int = 10**6,
|
|
58
|
+
seed_seq_list: list[SeedSequence] | None,
|
|
59
|
+
nthreads: int,
|
|
60
|
+
save_data_to_file: SaveData = False,
|
|
61
|
+
) -> None:
|
|
62
|
+
if getattr(self, "market_data_sample", None) is None:
|
|
63
|
+
self.invres_counts = sim_invres_cnts_ll(
|
|
64
|
+
self,
|
|
65
|
+
_invres_parm_vec,
|
|
66
|
+
_upp_test_regime,
|
|
67
|
+
save_data_to_file=save_data_to_file,
|
|
68
|
+
sample_size=sample_size,
|
|
69
|
+
seed_seq_list=seed_seq_list,
|
|
70
|
+
nthreads=nthreads,
|
|
71
|
+
)
|
|
72
|
+
else:
|
|
73
|
+
self.invres_counts = invres_cnts(
|
|
74
|
+
self.data, _invres_parm_vec, _upp_test_regime
|
|
75
|
+
)
|
|
76
|
+
if save_data_to_file:
|
|
77
|
+
save_data_to_hdf5(
|
|
78
|
+
self.invres_counts, save_data_to_file=save_data_to_file
|
|
79
|
+
)
|
mergeron/gen/upp_tests.py
CHANGED
|
@@ -12,7 +12,6 @@ from typing import Literal, TypeAlias, TypedDict
|
|
|
12
12
|
|
|
13
13
|
import numpy as np
|
|
14
14
|
import tables as ptb # type: ignore
|
|
15
|
-
from attrs import evolve
|
|
16
15
|
from joblib import Parallel, cpu_count, delayed # type: ignore
|
|
17
16
|
from numpy.random import SeedSequence
|
|
18
17
|
from numpy.typing import NDArray
|
|
@@ -26,7 +25,7 @@ from . import (
|
|
|
26
25
|
DataclassInstance,
|
|
27
26
|
INVResolution,
|
|
28
27
|
MarketDataSample,
|
|
29
|
-
|
|
28
|
+
MarketSpec,
|
|
30
29
|
UPPTestRegime,
|
|
31
30
|
UPPTestsCounts,
|
|
32
31
|
UPPTestsRaw,
|
|
@@ -43,21 +42,27 @@ ptb.parameters.MAX_BLOSC_THREADS = 4
|
|
|
43
42
|
SaveData: TypeAlias = Literal[False] | tuple[Literal[True], ptb.File, ptb.Group]
|
|
44
43
|
|
|
45
44
|
|
|
46
|
-
class
|
|
45
|
+
class INVRESCntsArgs(TypedDict, total=False):
|
|
47
46
|
"Keyword arguments of function, :code:`sim_invres_cnts`"
|
|
48
47
|
|
|
49
|
-
sim_test_regime: UPPTestRegime
|
|
50
48
|
saved_array_name_suffix: str
|
|
51
49
|
save_data_to_file: SaveData
|
|
52
|
-
|
|
50
|
+
sample_size: int
|
|
51
|
+
seed_seq_list: list[SeedSequence] | None
|
|
53
52
|
nthreads: int
|
|
54
53
|
|
|
55
54
|
|
|
56
55
|
def sim_invres_cnts_ll(
|
|
57
|
-
_mkt_sample_spec:
|
|
56
|
+
_mkt_sample_spec: MarketSpec,
|
|
58
57
|
_invres_parm_vec: gbl.HMGThresholds,
|
|
59
|
-
|
|
58
|
+
_sim_test_regime: UPPTestRegime,
|
|
60
59
|
/,
|
|
60
|
+
*,
|
|
61
|
+
saved_array_name_suffix: str = "",
|
|
62
|
+
save_data_to_file: SaveData = False,
|
|
63
|
+
sample_size: int = 10**6,
|
|
64
|
+
seed_seq_list: list[SeedSequence] | None = None,
|
|
65
|
+
nthreads: int = 16,
|
|
61
66
|
) -> UPPTestsCounts:
|
|
62
67
|
"""A function to parallelize data-generation and testing
|
|
63
68
|
|
|
@@ -78,22 +83,34 @@ def sim_invres_cnts_ll(
|
|
|
78
83
|
_mkt_sample_spec
|
|
79
84
|
Configuration to use for generating sample data to test
|
|
80
85
|
|
|
81
|
-
|
|
82
|
-
|
|
86
|
+
_sim_test_regime
|
|
87
|
+
Configuration to use for testing
|
|
88
|
+
|
|
89
|
+
saved_array_name_suffix
|
|
90
|
+
Suffix to add to the array names in the HDF5 file
|
|
91
|
+
|
|
92
|
+
save_data_to_file
|
|
93
|
+
Whether to save data to an HDF5 file, and where to save it
|
|
94
|
+
|
|
95
|
+
sample_size
|
|
96
|
+
Number of draws to simulate
|
|
97
|
+
|
|
98
|
+
seed_seq_list
|
|
99
|
+
List of seed sequences, to assure independent samples in each thread
|
|
100
|
+
|
|
101
|
+
nthreads
|
|
102
|
+
Number of parallel processes to use
|
|
83
103
|
|
|
84
104
|
Returns
|
|
85
105
|
-------
|
|
86
106
|
Arrays of UPPTestCounts
|
|
87
107
|
|
|
88
108
|
"""
|
|
89
|
-
_sample_sz =
|
|
109
|
+
_sample_sz = sample_size
|
|
90
110
|
_subsample_sz = 10**6
|
|
91
111
|
_iter_count = int(_sample_sz / _subsample_sz) if _subsample_sz < _sample_sz else 1
|
|
92
112
|
_thread_count = cpu_count()
|
|
93
113
|
|
|
94
|
-
# Crate a copy, to avoid side effects in the outer scope
|
|
95
|
-
_mkt_sample_spec_here = evolve(_mkt_sample_spec, sample_size=_subsample_sz)
|
|
96
|
-
|
|
97
114
|
if (
|
|
98
115
|
_mkt_sample_spec.share_spec.recapture_form != RECConstants.OUTIN
|
|
99
116
|
and _mkt_sample_spec.share_spec.recapture_rate != _invres_parm_vec.rec
|
|
@@ -107,26 +124,24 @@ def sim_invres_cnts_ll(
|
|
|
107
124
|
)
|
|
108
125
|
|
|
109
126
|
_rng_seed_seq_list = [None] * _iter_count
|
|
110
|
-
if
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
)
|
|
127
|
+
if seed_seq_list:
|
|
128
|
+
_rng_seed_seq_list = list(
|
|
129
|
+
zip(*[g.spawn(_iter_count) for g in seed_seq_list], strict=True) # type: ignore
|
|
130
|
+
)
|
|
115
131
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
else:
|
|
122
|
-
_sim_invres_cnts_kwargs = {}
|
|
132
|
+
_sim_invres_cnts_kwargs: INVRESCntsArgs = INVRESCntsArgs({
|
|
133
|
+
"sample_size": _subsample_sz,
|
|
134
|
+
"save_data_to_file": save_data_to_file,
|
|
135
|
+
"nthreads": nthreads,
|
|
136
|
+
})
|
|
123
137
|
|
|
124
138
|
_res_list = Parallel(n_jobs=_thread_count, prefer="threads")(
|
|
125
139
|
delayed(sim_invres_cnts)(
|
|
126
|
-
|
|
140
|
+
_mkt_sample_spec,
|
|
127
141
|
_invres_parm_vec,
|
|
142
|
+
_sim_test_regime,
|
|
128
143
|
**_sim_invres_cnts_kwargs,
|
|
129
|
-
saved_array_name_suffix=f"{_iter_id:0{2 + int(np.ceil(np.log10(_iter_count)))}d}",
|
|
144
|
+
saved_array_name_suffix=f"{saved_array_name_suffix}_{_iter_id:0{2 + int(np.ceil(np.log10(_iter_count)))}d}",
|
|
130
145
|
seed_seq_list=_rng_seed_seq_list_ch,
|
|
131
146
|
)
|
|
132
147
|
for _iter_id, _rng_seed_seq_list_ch in enumerate(_rng_seed_seq_list)
|
|
@@ -151,19 +166,23 @@ def sim_invres_cnts_ll(
|
|
|
151
166
|
|
|
152
167
|
|
|
153
168
|
def sim_invres_cnts(
|
|
154
|
-
_mkt_sample_spec:
|
|
169
|
+
_mkt_sample_spec: MarketSpec,
|
|
155
170
|
_upp_test_parms: gbl.HMGThresholds,
|
|
171
|
+
_sim_test_regime: UPPTestRegime,
|
|
156
172
|
/,
|
|
157
173
|
*,
|
|
158
|
-
sim_test_regime: UPPTestRegime,
|
|
159
174
|
saved_array_name_suffix: str = "",
|
|
160
175
|
save_data_to_file: SaveData = False,
|
|
176
|
+
sample_size: int = 10**6,
|
|
161
177
|
seed_seq_list: list[SeedSequence] | None = None,
|
|
162
178
|
nthreads: int = 16,
|
|
163
179
|
) -> UPPTestsCounts:
|
|
164
180
|
# Generate market data
|
|
165
|
-
|
|
166
|
-
_mkt_sample_spec,
|
|
181
|
+
_market_data_sample = dgl.gen_market_sample(
|
|
182
|
+
_mkt_sample_spec,
|
|
183
|
+
sample_size=sample_size,
|
|
184
|
+
seed_seq_list=seed_seq_list,
|
|
185
|
+
nthreads=nthreads,
|
|
167
186
|
)
|
|
168
187
|
|
|
169
188
|
_invalid_array_names = (
|
|
@@ -173,28 +192,42 @@ def sim_invres_cnts(
|
|
|
173
192
|
)
|
|
174
193
|
|
|
175
194
|
save_data_to_hdf5(
|
|
176
|
-
|
|
177
|
-
saved_array_name_suffix,
|
|
178
|
-
_invalid_array_names,
|
|
195
|
+
_market_data_sample,
|
|
196
|
+
saved_array_name_suffix=saved_array_name_suffix,
|
|
197
|
+
excluded_attrs=_invalid_array_names,
|
|
179
198
|
save_data_to_file=save_data_to_file,
|
|
180
199
|
)
|
|
181
200
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
201
|
+
_upp_test_arrays = invres_cnts(
|
|
202
|
+
_market_data_sample, _upp_test_parms, _sim_test_regime
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
save_data_to_hdf5(
|
|
206
|
+
_upp_test_arrays,
|
|
186
207
|
saved_array_name_suffix=saved_array_name_suffix,
|
|
187
208
|
save_data_to_file=save_data_to_file,
|
|
188
209
|
)
|
|
189
210
|
|
|
211
|
+
return _upp_test_arrays
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def invres_cnts(
|
|
215
|
+
_market_data_sample: MarketDataSample,
|
|
216
|
+
_upp_test_parms: gbl.HMGThresholds,
|
|
217
|
+
_upp_test_regime: UPPTestRegime,
|
|
218
|
+
/,
|
|
219
|
+
) -> UPPTestsCounts:
|
|
220
|
+
_upp_test_arrays = gen_upp_test_arrays(
|
|
221
|
+
_market_data_sample, _upp_test_parms, _upp_test_regime
|
|
222
|
+
)
|
|
223
|
+
|
|
190
224
|
_fcounts, _hhi_delta, _hhi_post = (
|
|
191
|
-
getattr(
|
|
225
|
+
getattr(_market_data_sample, _g) for _g in ("fcounts", "hhi_delta", "hhi_post")
|
|
192
226
|
)
|
|
193
|
-
del _market_data
|
|
194
227
|
|
|
195
228
|
_stats_rowlen = 6
|
|
196
229
|
# Clearance/enforcement counts --- by firm count
|
|
197
|
-
_firm_counts_weights =
|
|
230
|
+
_firm_counts_weights = np.unique(_fcounts)
|
|
198
231
|
if _firm_counts_weights is not None and np.all(_firm_counts_weights >= 0):
|
|
199
232
|
_max_firm_count = len(_firm_counts_weights)
|
|
200
233
|
|
|
@@ -210,9 +243,9 @@ def sim_invres_cnts(
|
|
|
210
243
|
*[
|
|
211
244
|
np.einsum(
|
|
212
245
|
"ij->",
|
|
213
|
-
1 * (_firm_count_test & getattr(
|
|
246
|
+
1 * (_firm_count_test & getattr(_upp_test_arrays, _f)),
|
|
214
247
|
)
|
|
215
|
-
for _f in
|
|
248
|
+
for _f in _upp_test_arrays.__dataclass_fields__
|
|
216
249
|
],
|
|
217
250
|
]),
|
|
218
251
|
))
|
|
@@ -236,9 +269,9 @@ def sim_invres_cnts(
|
|
|
236
269
|
np.einsum("ij->", 1 * _hhi_delta_test),
|
|
237
270
|
*[
|
|
238
271
|
np.einsum(
|
|
239
|
-
"ij->", 1 * (_hhi_delta_test & getattr(
|
|
272
|
+
"ij->", 1 * (_hhi_delta_test & getattr(_upp_test_arrays, _f))
|
|
240
273
|
)
|
|
241
|
-
for _f in
|
|
274
|
+
for _f in _upp_test_arrays.__dataclass_fields__
|
|
242
275
|
],
|
|
243
276
|
]),
|
|
244
277
|
))
|
|
@@ -273,9 +306,9 @@ def sim_invres_cnts(
|
|
|
273
306
|
np.einsum("ij->", 1 * _conc_test),
|
|
274
307
|
*[
|
|
275
308
|
np.einsum(
|
|
276
|
-
"ij->", 1 * (_conc_test & getattr(
|
|
309
|
+
"ij->", 1 * (_conc_test & getattr(_upp_test_arrays, _f))
|
|
277
310
|
)
|
|
278
|
-
for _f in
|
|
311
|
+
for _f in _upp_test_arrays.__dataclass_fields__
|
|
279
312
|
],
|
|
280
313
|
]),
|
|
281
314
|
))
|
|
@@ -293,19 +326,26 @@ def sim_invres_cnts(
|
|
|
293
326
|
)
|
|
294
327
|
|
|
295
328
|
|
|
296
|
-
def
|
|
329
|
+
def gen_upp_test_arrays(
|
|
297
330
|
_market_data: MarketDataSample,
|
|
298
331
|
_upp_test_parms: gbl.HMGThresholds,
|
|
299
332
|
_sim_test_regime: UPPTestRegime,
|
|
300
333
|
/,
|
|
301
|
-
*,
|
|
302
|
-
saved_array_name_suffix: str = "",
|
|
303
|
-
save_data_to_file: SaveData = False,
|
|
304
334
|
) -> UPPTestsRaw:
|
|
305
335
|
"""
|
|
306
336
|
Generate UPP tests arrays for given configuration and market sample
|
|
307
337
|
|
|
308
338
|
Given a standards vector, market
|
|
339
|
+
|
|
340
|
+
Parameters
|
|
341
|
+
----------
|
|
342
|
+
_market_data
|
|
343
|
+
market data sample
|
|
344
|
+
_upp_test_parms
|
|
345
|
+
guidelines thresholds for testing UPP and related statistics
|
|
346
|
+
_sim_test_regime
|
|
347
|
+
configuration to use for generating UPP tests
|
|
348
|
+
|
|
309
349
|
"""
|
|
310
350
|
_g_bar, _divr_bar, _cmcr_bar, _ipr_bar = (
|
|
311
351
|
getattr(_upp_test_parms, _f) for _f in ("guppi", "divr", "cmcr", "ipr")
|
|
@@ -407,29 +447,21 @@ def gen_upp_arrays(
|
|
|
407
447
|
_divr_test_vector = _market_data.divr_array.max(axis=1, keepdims=True)
|
|
408
448
|
|
|
409
449
|
if _invres_resolution == INVResolution.ENFT:
|
|
410
|
-
|
|
450
|
+
_upp_test_arrays = UPPTestsRaw(
|
|
411
451
|
_guppi_test_vector >= _g_bar,
|
|
412
452
|
(_guppi_test_vector >= _g_bar) | (_divr_test_vector >= _divr_bar),
|
|
413
453
|
_cmcr_test_vector >= _cmcr_bar,
|
|
414
454
|
_ipr_test_vector >= _ipr_bar,
|
|
415
455
|
)
|
|
416
456
|
else:
|
|
417
|
-
|
|
457
|
+
_upp_test_arrays = UPPTestsRaw(
|
|
418
458
|
_guppi_test_vector < _g_bar,
|
|
419
459
|
(_guppi_test_vector < _g_bar) & (_divr_test_vector < _divr_bar),
|
|
420
460
|
_cmcr_test_vector < _cmcr_bar,
|
|
421
461
|
_ipr_test_vector < _ipr_bar,
|
|
422
462
|
)
|
|
423
|
-
del _guppi_test_vector, _divr_test_vector, _cmcr_test_vector, _ipr_test_vector
|
|
424
|
-
|
|
425
|
-
save_data_to_hdf5(
|
|
426
|
-
_upp_tests_data,
|
|
427
|
-
saved_array_name_suffix,
|
|
428
|
-
(),
|
|
429
|
-
save_data_to_file=save_data_to_file,
|
|
430
|
-
)
|
|
431
463
|
|
|
432
|
-
return
|
|
464
|
+
return _upp_test_arrays
|
|
433
465
|
|
|
434
466
|
|
|
435
467
|
def initialize_hd5(
|
|
@@ -449,24 +481,25 @@ def initialize_hd5(
|
|
|
449
481
|
|
|
450
482
|
def save_data_to_hdf5(
|
|
451
483
|
_dclass: DataclassInstance,
|
|
452
|
-
_saved_array_name_suffix: str = "",
|
|
453
|
-
_excl_attrs: Sequence[str] = (),
|
|
454
484
|
/,
|
|
455
485
|
*,
|
|
486
|
+
saved_array_name_suffix: str | None = "",
|
|
487
|
+
excluded_attrs: Sequence[str] | None = (),
|
|
456
488
|
save_data_to_file: SaveData = False,
|
|
457
489
|
) -> None:
|
|
458
490
|
if save_data_to_file:
|
|
459
491
|
_, _h5_file, _h5_group = save_data_to_file
|
|
460
492
|
# Save market data arrays
|
|
493
|
+
excluded_attrs = excluded_attrs or ()
|
|
461
494
|
for _array_name in _dclass.__dataclass_fields__:
|
|
462
|
-
if _array_name in
|
|
495
|
+
if _array_name in excluded_attrs:
|
|
463
496
|
continue
|
|
464
497
|
save_array_to_hdf5(
|
|
465
498
|
getattr(_dclass, _array_name),
|
|
466
499
|
_array_name,
|
|
467
500
|
_h5_group,
|
|
468
501
|
_h5_file,
|
|
469
|
-
saved_array_name_suffix=
|
|
502
|
+
saved_array_name_suffix=saved_array_name_suffix,
|
|
470
503
|
)
|
|
471
504
|
|
|
472
505
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: mergeron
|
|
3
|
-
Version: 2024.
|
|
3
|
+
Version: 2024.738972.0
|
|
4
4
|
Summary: Analysis of standards defined in Horizontal Merger Guidelines
|
|
5
5
|
License: MIT
|
|
6
6
|
Keywords: merger policy analysis,merger guidelines,merger screening,policy presumptions,concentration standards,upward pricing pressure,GUPPI
|
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
mergeron/License.txt,sha256=7iX-y0EyjkbVJKJLS4ZKzuuE1wd0lryfsD_IytLG8lQ,1246
|
|
2
2
|
mergeron/__init__.py,sha256=_0Bt2k2P8MPlF_WagQKGspaSODn-pkqib0uvSd4gys4,1019
|
|
3
3
|
mergeron/core/InCommon RSA Server CA cert chain.pem,sha256=W8TqydgY8jphQ4fr6WMdT6jLwqFjHLpx8fFr3LXub4s,4292
|
|
4
|
-
mergeron/core/__init__.py,sha256=
|
|
4
|
+
mergeron/core/__init__.py,sha256=NWalI-uDifb8Y8bDN4BFNH2IoCAx3C60_Dz3bwbxveY,2085
|
|
5
5
|
mergeron/core/damodaran_margin_data.py,sha256=DHTQdFjuZ5Yl3Dbq0db0QR4FHUqJpZj4yi5zdUncLtg,8166
|
|
6
6
|
mergeron/core/excel_helper.py,sha256=XfdKNOEdB5zNJl8LguVyAcDjr5y2wapKDbNgAx6r-es,7831
|
|
7
7
|
mergeron/core/ftc_invdata.msgpack,sha256=WBFHgi7Ld4R-h2zL2Zc3TOIlKqVrbVFMH1LoI4-T-M0,264664
|
|
8
8
|
mergeron/core/ftc_merger_investigations_data.py,sha256=wHF1dKAqWlh1hMvaQv2uOCAKAHnuPvCGnmaOB3CJO9I,26929
|
|
9
|
-
mergeron/core/guidelines_boundaries.py,sha256=
|
|
10
|
-
mergeron/core/guidelines_boundaries_specialized_functions.py,sha256=
|
|
9
|
+
mergeron/core/guidelines_boundaries.py,sha256=h--dAO449VyhhVJ-GjzQ56L-Bq_Zz-PXonBHKRsBQmE,37554
|
|
10
|
+
mergeron/core/guidelines_boundaries_specialized_functions.py,sha256=OiTu_MIvw_f93ESpTpMBL6rVqTLPyqE-fhf62mgGNxA,10620
|
|
11
11
|
mergeron/core/proportions_tests.py,sha256=tCrbya1el5u1OFOXphODP6yWOGywuNY6z9LBTsNRKzM,15320
|
|
12
12
|
mergeron/core/pseudorandom_numbers.py,sha256=uBK_fnhkOSkqnK4gEU8b3r_9B6r-vKmXZ64HViraTK8,9446
|
|
13
13
|
mergeron/ext/__init__.py,sha256=iyfxkX3-SoMS4ZQZKHKPn8JEMN536vpty9oSZf0LHv8,115
|
|
14
14
|
mergeron/ext/tol_colors.py,sha256=wFOHZXWZonbp9mhmSGu9mVujBYhdTsvx9_WikMpoCmo,22229
|
|
15
|
-
mergeron/gen/__init__.py,sha256=
|
|
16
|
-
mergeron/gen/
|
|
17
|
-
mergeron/gen/data_generation.py,sha256=
|
|
15
|
+
mergeron/gen/__init__.py,sha256=GSFduoVwk0dOqogqX-YdWMtlxSM6G3tyFqf6U43okV4,16268
|
|
16
|
+
mergeron/gen/_data_generation_functions.py,sha256=QLxeS35D3bqQjjDabq1QncqwptMaHBrtmZ-_JUo6SG4,23202
|
|
17
|
+
mergeron/gen/data_generation.py,sha256=7teP8OKgKp08riX2Yu7flMEvN6a_eNXJllv_Hdkt7W8,8842
|
|
18
18
|
mergeron/gen/investigations_stats.py,sha256=4-AY_zhqKSlGE8sQciuYxzg2U4efQs2014dydmWUFz4,22802
|
|
19
|
-
mergeron/gen/
|
|
19
|
+
mergeron/gen/market_sample.py,sha256=HQbdmzAEub9vZDXjwPzZOZrTRHDLwn5fDhcTgeOwSlQ,2399
|
|
20
|
+
mergeron/gen/upp_tests.py,sha256=OaEEo1ARSza2-PFsZaFArC2bOdo2qKG3k1jubhg-ccQ,17217
|
|
20
21
|
mergeron/jinja_LaTex_templates/clrrate_cis_summary_table_template.tex.jinja2,sha256=ae4JiciU-pt8YAM8mRbsmt4W6ePuN1y1NPCWD95oXIo,4833
|
|
21
22
|
mergeron/jinja_LaTex_templates/ftcinvdata_byhhianddelta_table_template.tex.jinja2,sha256=ODEurkC0UHuWpjRUiQpeW85njSeUEUJYRdYg8gqoEq0,3642
|
|
22
23
|
mergeron/jinja_LaTex_templates/ftcinvdata_summary_table_template.tex.jinja2,sha256=h8_DEE0iskT9tnga5lZtxcoevN7pY4iKF-maErt4UU4,2906
|
|
@@ -25,6 +26,6 @@ mergeron/jinja_LaTex_templates/mergeron.cls,sha256=AV2mk4-uERvAuMkE95Ka7el6LZsb0
|
|
|
25
26
|
mergeron/jinja_LaTex_templates/mergeron_table_collection_template.tex.jinja2,sha256=nr6xUI0_2KHG4Sz9k1JFVQjs2h9qS9BGt1MeE6Tygs8,2429
|
|
26
27
|
mergeron/jinja_LaTex_templates/setup_tikz_tables.tex.jinja2,sha256=WKVxtp3eoMchfGliQAJMj4w2FtBkWG5z2V3-hBYUYUQ,3292
|
|
27
28
|
mergeron/py.typed,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
|
|
28
|
-
mergeron-2024.
|
|
29
|
-
mergeron-2024.
|
|
30
|
-
mergeron-2024.
|
|
29
|
+
mergeron-2024.738972.0.dist-info/METADATA,sha256=qJ2QkDvJJZ5L6ETVxFB7KX_uB0FktsbTovnSj7GSiMQ,6925
|
|
30
|
+
mergeron-2024.738972.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
31
|
+
mergeron-2024.738972.0.dist-info/RECORD,,
|
|
File without changes
|