mergeron 2025.739355.18__py3-none-any.whl → 2025.739413.1__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/__init__.py +39 -1
- mergeron/core/empirical_margin_distribution.py +6 -5
- mergeron/core/ftc_merger_investigations_data.py +4 -3
- mergeron/core/guidelines_boundaries.py +12 -10
- mergeron/core/guidelines_boundary_functions.py +4 -4
- mergeron/data/__init__.py +1 -1
- mergeron/gen/__init__.py +2 -1
- mergeron/gen/data_generation_functions.py +2 -2
- {mergeron-2025.739355.18.dist-info → mergeron-2025.739413.1.dist-info}/METADATA +1 -1
- mergeron-2025.739413.1.dist-info/RECORD +20 -0
- mergeron-2025.739355.18.dist-info/RECORD +0 -20
- {mergeron-2025.739355.18.dist-info → mergeron-2025.739413.1.dist-info}/WHEEL +0 -0
mergeron/__init__.py
CHANGED
|
@@ -15,7 +15,7 @@ from ruamel import yaml
|
|
|
15
15
|
|
|
16
16
|
_PKG_NAME: str = Path(__file__).parent.name
|
|
17
17
|
|
|
18
|
-
VERSION = "2025.
|
|
18
|
+
VERSION = "2025.739413.1"
|
|
19
19
|
|
|
20
20
|
__version__ = VERSION
|
|
21
21
|
|
|
@@ -51,6 +51,44 @@ type ArrayDouble = NDArray[np.float64]
|
|
|
51
51
|
type ArrayBIGINT = NDArray[np.int64]
|
|
52
52
|
|
|
53
53
|
|
|
54
|
+
def allclose(
|
|
55
|
+
_a: ArrayFloat | ArrayINT | float | int,
|
|
56
|
+
_b: ArrayFloat | ArrayINT | float | int,
|
|
57
|
+
/,
|
|
58
|
+
*,
|
|
59
|
+
rtol: float = 1e-14,
|
|
60
|
+
atol: float = 1e-15,
|
|
61
|
+
equal_nan: bool = True,
|
|
62
|
+
) -> bool:
|
|
63
|
+
"""Redefine native numpy function with updated default tolerances."""
|
|
64
|
+
return np.allclose(_a, _b, atol=atol, rtol=rtol, equal_nan=equal_nan)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def assert_allclose( # noqa: PLR0913
|
|
68
|
+
_a: ArrayFloat | ArrayINT | float | int,
|
|
69
|
+
_b: ArrayFloat | ArrayINT | float | int,
|
|
70
|
+
/,
|
|
71
|
+
*,
|
|
72
|
+
rtol: float = 1e-14,
|
|
73
|
+
atol: float = 1e-15,
|
|
74
|
+
equal_nan: bool = True,
|
|
75
|
+
err_msg: str = "",
|
|
76
|
+
verbose: bool = False,
|
|
77
|
+
strict: bool = True,
|
|
78
|
+
) -> None:
|
|
79
|
+
"""Redefine native numpy function with updated default tolerances, type-enforcing."""
|
|
80
|
+
return np.testing.assert_allclose(
|
|
81
|
+
_a,
|
|
82
|
+
_b,
|
|
83
|
+
atol=1e-15,
|
|
84
|
+
rtol=1e-14,
|
|
85
|
+
equal_nan=equal_nan,
|
|
86
|
+
err_msg=err_msg,
|
|
87
|
+
verbose=verbose,
|
|
88
|
+
strict=True,
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
|
|
54
92
|
this_yaml = yaml.YAML(typ="rt")
|
|
55
93
|
this_yaml.indent(mapping=2, sequence=4, offset=2)
|
|
56
94
|
|
|
@@ -221,22 +221,23 @@ def margin_data_getter(
|
|
|
221
221
|
elif data_download_flag or not list(data_archive_path.glob("margin*.xls")):
|
|
222
222
|
margin_data_downloader()
|
|
223
223
|
|
|
224
|
-
# Whitespace cleanup
|
|
225
|
-
ws_pat = re.compile(r"\s+")
|
|
226
|
-
|
|
227
224
|
# Parse workbooks and save margin data dictionary
|
|
228
225
|
margin_data_: dict[str, dict[str, MappingProxyType[str, float]]] = {}
|
|
229
226
|
for _p in (WORK_DIR / "damodaran_margin_data_archive").iterdir():
|
|
230
227
|
xl_wbk = CalamineWorkbook.from_path(_p)
|
|
231
228
|
xl_wks = xl_wbk.get_sheet_by_index(
|
|
232
|
-
0
|
|
229
|
+
0
|
|
230
|
+
if (_p.stem.startswith("margin") and _p.stem[-2:] in {"17", "18", "19"})
|
|
231
|
+
else 1
|
|
233
232
|
).to_python()
|
|
234
233
|
if xl_wks[8][2] != "Gross Margin":
|
|
235
234
|
raise ValueError("Worksheet does not match expected layout.")
|
|
236
235
|
row_keys: list[str] = [_c.upper() for _c in xl_wks[8][1:]] # type: ignore
|
|
237
236
|
|
|
238
237
|
_u = xl_wks[0][1]
|
|
239
|
-
if not isinstance(_u, datetime.
|
|
238
|
+
if not isinstance(_u, datetime.date):
|
|
239
|
+
print(_u)
|
|
240
|
+
print(xl_wks[:8])
|
|
240
241
|
raise ValueError("Worksheet does not match expected layout.")
|
|
241
242
|
update: str = _u.isoformat()[:10]
|
|
242
243
|
|
|
@@ -434,7 +434,7 @@ def _parse_invdata() -> INVData:
|
|
|
434
434
|
" the source code as well as to install an additional package"
|
|
435
435
|
" not distributed with this package or identified as a requirement."
|
|
436
436
|
)
|
|
437
|
-
import pymupdf # type: ignore
|
|
437
|
+
import pymupdf # type: ignore
|
|
438
438
|
|
|
439
439
|
invdata_docnames = _download_invdata(FID_WORK_DIR)
|
|
440
440
|
|
|
@@ -656,9 +656,10 @@ def _process_table_blks_conc_type(
|
|
|
656
656
|
# Check column totals
|
|
657
657
|
for _col_tot in col_totals:
|
|
658
658
|
assert_array_equal(
|
|
659
|
-
_col_tot[2:],
|
|
659
|
+
_col_tot[2:], # type: ignore
|
|
660
660
|
np.einsum(
|
|
661
|
-
"ij->j",
|
|
661
|
+
"ij->j",
|
|
662
|
+
invdata_array[invdata_array[:, 1] == _col_tot[1]][:, 2:], # type: ignore
|
|
662
663
|
),
|
|
663
664
|
)
|
|
664
665
|
|
|
@@ -327,23 +327,25 @@ class DiversionRatioBoundary:
|
|
|
327
327
|
share_ratio = critical_share_ratio(
|
|
328
328
|
self.diversion_ratio, r_bar=self.recapture_ratio
|
|
329
329
|
)
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
330
|
+
|
|
331
|
+
upp_agg_kwargs: gbfn.ShareRatioBoundaryKeywords = {"dps": self.precision}
|
|
332
|
+
if self.agg_method != UPPAggrSelector.MAX:
|
|
333
|
+
upp_agg_kwargs |= {
|
|
334
|
+
"recapture_form": getattr(self.recapture_form, "value", "inside-out")
|
|
335
|
+
}
|
|
334
336
|
|
|
335
337
|
match self.agg_method:
|
|
336
338
|
case UPPAggrSelector.DIS:
|
|
337
339
|
upp_agg_fn = gbfn.diversion_share_boundary_wtd_avg
|
|
338
340
|
upp_agg_kwargs |= {"agg_method": "distance", "weighting": None}
|
|
339
341
|
case UPPAggrSelector.AVG:
|
|
340
|
-
upp_agg_fn = gbfn.diversion_share_boundary_xact_avg
|
|
342
|
+
upp_agg_fn = gbfn.diversion_share_boundary_xact_avg
|
|
341
343
|
case UPPAggrSelector.MAX:
|
|
342
|
-
upp_agg_fn = gbfn.diversion_share_boundary_max
|
|
343
|
-
upp_agg_kwargs
|
|
344
|
+
upp_agg_fn = gbfn.diversion_share_boundary_max
|
|
345
|
+
upp_agg_kwargs |= {"dps": 10}
|
|
344
346
|
case UPPAggrSelector.MIN:
|
|
345
|
-
upp_agg_fn = gbfn.diversion_share_boundary_min
|
|
346
|
-
upp_agg_kwargs |= {"dps": 10}
|
|
347
|
+
upp_agg_fn = gbfn.diversion_share_boundary_min
|
|
348
|
+
upp_agg_kwargs |= {"dps": 10}
|
|
347
349
|
case _:
|
|
348
350
|
upp_agg_fn = gbfn.diversion_share_boundary_wtd_avg
|
|
349
351
|
|
|
@@ -365,7 +367,7 @@ class DiversionRatioBoundary:
|
|
|
365
367
|
|
|
366
368
|
upp_agg_kwargs |= {"agg_method": aggregator_, "weighting": wgt_type}
|
|
367
369
|
|
|
368
|
-
boundary_ = upp_agg_fn(share_ratio, self.recapture_ratio, **upp_agg_kwargs)
|
|
370
|
+
boundary_ = upp_agg_fn(share_ratio, self.recapture_ratio, **upp_agg_kwargs) # type: ignore
|
|
369
371
|
object.__setattr__(self, "area", boundary_.area)
|
|
370
372
|
object.__setattr__(self, "coordinates", boundary_.coordinates)
|
|
371
373
|
|
|
@@ -481,7 +481,7 @@ def diversion_share_boundary_xact_avg(
|
|
|
481
481
|
_bdry_start = np.array([(_s_mid, _s_mid)])
|
|
482
482
|
_s_1 = np.arange(_s_mid - _step_size, 0, -_step_size)
|
|
483
483
|
if recapture_form == "inside-out":
|
|
484
|
-
_s_intcpt
|
|
484
|
+
_s_intcpt = (
|
|
485
485
|
2 * _delta_star * _r_val + 1 - np.abs(2 * _delta_star * _r_val - 1)
|
|
486
486
|
) / (2 * _r_val)
|
|
487
487
|
nr_t1: ArrayDouble = (
|
|
@@ -523,11 +523,11 @@ def diversion_share_boundary_xact_avg(
|
|
|
523
523
|
f"with recapture spec, {f'"{recapture_form}"'} is incorrect."
|
|
524
524
|
)
|
|
525
525
|
|
|
526
|
-
s_2
|
|
526
|
+
s_2 = (nr_t1 - nr_t2_s1**0.5) / (2 * _r_val)
|
|
527
527
|
|
|
528
528
|
else:
|
|
529
|
-
_s_intcpt
|
|
530
|
-
s_2
|
|
529
|
+
_s_intcpt = _delta_star + 1 / 2 - np.abs(_delta_star - 1 / 2)
|
|
530
|
+
s_2 = (
|
|
531
531
|
0.5
|
|
532
532
|
+ _delta_star
|
|
533
533
|
- _delta_star * _s_1
|
mergeron/data/__init__.py
CHANGED
|
@@ -23,7 +23,7 @@ Use for replication/testing.
|
|
|
23
23
|
NOTES
|
|
24
24
|
-----
|
|
25
25
|
Source data are from Prof. Aswath Damodaran, Stern School of Business, NYU; available online
|
|
26
|
-
at https://pages.stern.nyu.edu/~adamodar/pc/datasets/margin.xls
|
|
26
|
+
at https://pages.stern.nyu.edu/~adamodar/pc/datasets/margin.xls
|
|
27
27
|
and https://pages.stern.nyu.edu/~adamodar/pc/archives/margin*.xls.
|
|
28
28
|
|
|
29
29
|
Gross margins are reported in 2017 data and later.
|
mergeron/gen/__init__.py
CHANGED
|
@@ -25,6 +25,7 @@ from .. import ( # noqa: TID252
|
|
|
25
25
|
Enameled,
|
|
26
26
|
RECForm,
|
|
27
27
|
UPPAggrSelector,
|
|
28
|
+
allclose,
|
|
28
29
|
this_yaml,
|
|
29
30
|
yamelize_attrs,
|
|
30
31
|
)
|
|
@@ -350,7 +351,7 @@ class PCMSpec:
|
|
|
350
351
|
|
|
351
352
|
dist_parms: ArrayFloat = field(
|
|
352
353
|
kw_only=True,
|
|
353
|
-
eq=cmp_using(eq=
|
|
354
|
+
eq=cmp_using(eq=allclose),
|
|
354
355
|
converter=Converter(_pcm_dp_conv, takes_self=True), # type: ignore
|
|
355
356
|
)
|
|
356
357
|
"""Parameter specification for tailoring PCM distribution
|
|
@@ -4,7 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
from typing import Literal
|
|
6
6
|
|
|
7
|
-
import numexpr as ne
|
|
7
|
+
import numexpr as ne # type: ignore
|
|
8
8
|
import numpy as np
|
|
9
9
|
from attrs import evolve
|
|
10
10
|
from numpy.random import SeedSequence
|
|
@@ -386,7 +386,7 @@ def gen_market_shares_dirichlet(
|
|
|
386
386
|
aggregate_purchase_prob_ = np.empty((_s_size, 1), float)
|
|
387
387
|
aggregate_purchase_prob_.fill(np.nan)
|
|
388
388
|
if _recapture_form == RECForm.OUTIN:
|
|
389
|
-
aggregate_purchase_prob_ = 1 - mktshr_array[:, [-1]]
|
|
389
|
+
aggregate_purchase_prob_ = 1 - mktshr_array[:, [-1]]
|
|
390
390
|
mktshr_array = mktshr_array[:, :-1] / aggregate_purchase_prob_
|
|
391
391
|
|
|
392
392
|
return ShareSampleData(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: mergeron
|
|
3
|
-
Version: 2025.
|
|
3
|
+
Version: 2025.739413.1
|
|
4
4
|
Summary: Python for analyzing merger enforcement policy
|
|
5
5
|
License: MIT
|
|
6
6
|
Keywords: merger enforcement policy,merger guidelines,merger screening,enforcement presumptions,concentration standards,diversion ratio,upward pricing pressure,GUPPI
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
mergeron/__init__.py,sha256=O0n3Kq1YKJ30YvSWu9URdLXvKl6YQG9tizw1e1fj9cY,6751
|
|
2
|
+
mergeron/core/__init__.py,sha256=4Y_q-Qu7gXENVKHS-lNebn5mPZDy9oPHFwUV7fAW9Nw,3269
|
|
3
|
+
mergeron/core/empirical_margin_distribution.py,sha256=mlxlxab0JOzme7OTI-JoJOM6qQpztkUiB96GXE-zKU4,11647
|
|
4
|
+
mergeron/core/ftc_merger_investigations_data.py,sha256=oM4cs2PnyeSwyV1LOE_EYCUEzCKPm7lnCGxLIc6JQY8,28820
|
|
5
|
+
mergeron/core/guidelines_boundaries.py,sha256=N9rsGvm_HSlwX4ZRARC4Fgr90s7OVdnKalxfMbaUvV0,15602
|
|
6
|
+
mergeron/core/guidelines_boundary_functions.py,sha256=xXScuMaC56B6LjYJGEq8D8QzyIAlvJzjOCapdevCVGY,30300
|
|
7
|
+
mergeron/core/guidelines_boundary_functions_extra.py,sha256=hRhROaLJoRtTrtd-dNkpAGPOEeY1w_qXQHKIxfALaG4,22070
|
|
8
|
+
mergeron/core/pseudorandom_numbers.py,sha256=-mPveXjJJ446NrBMAmWIa2jI6j0Px0xcCJTGEEsn3bo,10149
|
|
9
|
+
mergeron/data/__init__.py,sha256=SAFkR23RBM0zwGam2TeWmw08oHAKmU2YF-Nygj73ies,1845
|
|
10
|
+
mergeron/data/damodaran_margin_data_serialized.zip,sha256=Wc1v9buSrYTWWAravG8W9nPbgsU07zMtSAR2RvMQU5s,623482
|
|
11
|
+
mergeron/data/ftc_merger_investigations_data.zip,sha256=tiB2TLFyS9LMSFIv8DBA_oEEx12DU4MyjHni4NlsRMU,24002
|
|
12
|
+
mergeron/gen/__init__.py,sha256=xMnzIqxuWaNZ9HQE-C6kCwLfvwdFOEmlpNRUJsObQFg,23866
|
|
13
|
+
mergeron/gen/data_generation.py,sha256=L44YNtxso-Ya50YT71rnG-el4_PgGn4vtoA7rFDD194,17487
|
|
14
|
+
mergeron/gen/data_generation_functions.py,sha256=hXUq5D2CIUkM4_NdGXiOb4XATYwIUeUcCGadzQGDqLw,26126
|
|
15
|
+
mergeron/gen/enforcement_stats.py,sha256=etTax-sBSn8DveF-IxuBJDdX0XSBD6oFU9vaZe6cYks,14387
|
|
16
|
+
mergeron/gen/upp_tests.py,sha256=gRJISQ2jGmIDmFOvaTIkvYooI4mK-QbgkfgL46RrRio,7445
|
|
17
|
+
mergeron/py.typed,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
|
|
18
|
+
mergeron-2025.739413.1.dist-info/METADATA,sha256=R-wKIGeC_v9iDoZL7aEaAcGSH6MK259QnM0tM-Ue0GY,4065
|
|
19
|
+
mergeron-2025.739413.1.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
20
|
+
mergeron-2025.739413.1.dist-info/RECORD,,
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
mergeron/__init__.py,sha256=v1CyRWh0ScaCpTfO-R7eCmGEg0a84G7N7_FY4MKJvjk,5788
|
|
2
|
-
mergeron/core/__init__.py,sha256=4Y_q-Qu7gXENVKHS-lNebn5mPZDy9oPHFwUV7fAW9Nw,3269
|
|
3
|
-
mergeron/core/empirical_margin_distribution.py,sha256=aqQ7JYpliHSjHpzyPRkYW9LhJfp-aAlSifRxYx3Dmbo,11623
|
|
4
|
-
mergeron/core/ftc_merger_investigations_data.py,sha256=ccPN81wE6Z-jUguXtAr01JUJVovWzP8Vxlha9g3r8yI,28788
|
|
5
|
-
mergeron/core/guidelines_boundaries.py,sha256=noacM3NmhzqPKLPGm7HEvLKX2UlRI1DCw1kxDa2cFXk,15586
|
|
6
|
-
mergeron/core/guidelines_boundary_functions.py,sha256=c9QwiogtcelqBFSGgXgKH2ecIr6UEhn_Z8rjriLbPRQ,30340
|
|
7
|
-
mergeron/core/guidelines_boundary_functions_extra.py,sha256=hRhROaLJoRtTrtd-dNkpAGPOEeY1w_qXQHKIxfALaG4,22070
|
|
8
|
-
mergeron/core/pseudorandom_numbers.py,sha256=-mPveXjJJ446NrBMAmWIa2jI6j0Px0xcCJTGEEsn3bo,10149
|
|
9
|
-
mergeron/data/__init__.py,sha256=CbqheFSkXEe7NOfuAV-NLaaEiNzl9pVCndGjtUUOj9g,1846
|
|
10
|
-
mergeron/data/damodaran_margin_data_serialized.zip,sha256=Wc1v9buSrYTWWAravG8W9nPbgsU07zMtSAR2RvMQU5s,623482
|
|
11
|
-
mergeron/data/ftc_merger_investigations_data.zip,sha256=tiB2TLFyS9LMSFIv8DBA_oEEx12DU4MyjHni4NlsRMU,24002
|
|
12
|
-
mergeron/gen/__init__.py,sha256=769XK4nxsDHDddCBV46WR01mWuO2y--jGl22rV3rc3k,23858
|
|
13
|
-
mergeron/gen/data_generation.py,sha256=L44YNtxso-Ya50YT71rnG-el4_PgGn4vtoA7rFDD194,17487
|
|
14
|
-
mergeron/gen/data_generation_functions.py,sha256=GQaeIzdiBXrYWMb9-kO2QPBY7YAVtUxaz1o1bqgnbw0,26126
|
|
15
|
-
mergeron/gen/enforcement_stats.py,sha256=etTax-sBSn8DveF-IxuBJDdX0XSBD6oFU9vaZe6cYks,14387
|
|
16
|
-
mergeron/gen/upp_tests.py,sha256=gRJISQ2jGmIDmFOvaTIkvYooI4mK-QbgkfgL46RrRio,7445
|
|
17
|
-
mergeron/py.typed,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
|
|
18
|
-
mergeron-2025.739355.18.dist-info/METADATA,sha256=N-lFBLvpe58ggpZLDo2nIIyRtNkTezqAR3Aj1s4-y80,4066
|
|
19
|
-
mergeron-2025.739355.18.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
20
|
-
mergeron-2025.739355.18.dist-info/RECORD,,
|
|
File without changes
|