mergeron 2024.739145.3__tar.gz → 2024.739145.4__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.

Potentially problematic release.


This version of mergeron might be problematic. Click here for more details.

Files changed (24) hide show
  1. {mergeron-2024.739145.3 → mergeron-2024.739145.4}/PKG-INFO +1 -1
  2. {mergeron-2024.739145.3 → mergeron-2024.739145.4}/pyproject.toml +1 -1
  3. {mergeron-2024.739145.3 → mergeron-2024.739145.4}/src/mergeron/__init__.py +1 -1
  4. {mergeron-2024.739145.3 → mergeron-2024.739145.4}/src/mergeron/core/guidelines_boundaries.py +24 -36
  5. {mergeron-2024.739145.3 → mergeron-2024.739145.4}/src/mergeron/core/guidelines_boundary_functions.py +12 -15
  6. {mergeron-2024.739145.3 → mergeron-2024.739145.4}/README.rst +0 -0
  7. {mergeron-2024.739145.3 → mergeron-2024.739145.4}/src/mergeron/License.txt +0 -0
  8. {mergeron-2024.739145.3 → mergeron-2024.739145.4}/src/mergeron/core/__init__.py +0 -0
  9. {mergeron-2024.739145.3 → mergeron-2024.739145.4}/src/mergeron/core/empirical_margin_distribution.py +0 -0
  10. {mergeron-2024.739145.3 → mergeron-2024.739145.4}/src/mergeron/core/ftc_merger_investigations_data.py +0 -0
  11. {mergeron-2024.739145.3 → mergeron-2024.739145.4}/src/mergeron/core/guidelines_boundary_functions_extra.py +0 -0
  12. {mergeron-2024.739145.3 → mergeron-2024.739145.4}/src/mergeron/core/pseudorandom_numbers.py +0 -0
  13. {mergeron-2024.739145.3 → mergeron-2024.739145.4}/src/mergeron/data/__init__.py +0 -0
  14. {mergeron-2024.739145.3 → mergeron-2024.739145.4}/src/mergeron/data/damodaran_margin_data.xls +0 -0
  15. {mergeron-2024.739145.3 → mergeron-2024.739145.4}/src/mergeron/data/damodaran_margin_data_dict.msgpack +0 -0
  16. {mergeron-2024.739145.3 → mergeron-2024.739145.4}/src/mergeron/data/ftc_invdata.msgpack +0 -0
  17. {mergeron-2024.739145.3 → mergeron-2024.739145.4}/src/mergeron/demo/__init__.py +0 -0
  18. {mergeron-2024.739145.3 → mergeron-2024.739145.4}/src/mergeron/demo/visualize_empirical_margin_distribution.py +0 -0
  19. {mergeron-2024.739145.3 → mergeron-2024.739145.4}/src/mergeron/gen/__init__.py +0 -0
  20. {mergeron-2024.739145.3 → mergeron-2024.739145.4}/src/mergeron/gen/data_generation.py +0 -0
  21. {mergeron-2024.739145.3 → mergeron-2024.739145.4}/src/mergeron/gen/data_generation_functions.py +0 -0
  22. {mergeron-2024.739145.3 → mergeron-2024.739145.4}/src/mergeron/gen/enforcement_stats.py +0 -0
  23. {mergeron-2024.739145.3 → mergeron-2024.739145.4}/src/mergeron/gen/upp_tests.py +0 -0
  24. {mergeron-2024.739145.3 → mergeron-2024.739145.4}/src/mergeron/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mergeron
3
- Version: 2024.739145.3
3
+ Version: 2024.739145.4
4
4
  Summary: Merger Policy Analysis using Python
5
5
  License: MIT
6
6
  Keywords: merger policy analysis,merger guidelines,merger screening,policy presumptions,concentration standards,upward pricing pressure,GUPPI
@@ -13,7 +13,7 @@ keywords = [
13
13
  "upward pricing pressure",
14
14
  "GUPPI",
15
15
  ]
16
- version = "2024.739145.3"
16
+ version = "2024.739145.4"
17
17
 
18
18
  # Classifiers list: https://pypi.org/classifiers/
19
19
  classifiers = [
@@ -8,7 +8,7 @@ from numpy.typing import NDArray
8
8
 
9
9
  _PKG_NAME: str = Path(__file__).parent.stem
10
10
 
11
- VERSION = "2024.739145.3"
11
+ VERSION = "2024.739145.4"
12
12
 
13
13
  __version__ = VERSION
14
14
 
@@ -6,6 +6,7 @@ with a canvas on which to draw boundaries for Guidelines standards.
6
6
 
7
7
  from __future__ import annotations
8
8
 
9
+ import decimal
9
10
  from dataclasses import dataclass
10
11
  from typing import Literal
11
12
 
@@ -112,52 +113,41 @@ class GuidelinesThresholds:
112
113
  HMGThresholds(
113
114
  _dh_s,
114
115
  _fc := int(np.ceil(1 / _hhi_p)),
115
- _r := gbfn.round_cust(_fc / (_fc + 1), frac=0.05),
116
- _g_s := guppi_from_delta(_dh_s, m_star=1.0, r_bar=_r),
117
- _dr := (1 - _r),
116
+ _r := float(_r_s := gbfn.round_cust(_fc / (_fc + 1), frac=0.05)),
117
+ _g := float(guppi_from_delta(_dh_s, m_star=1.0, r_bar=_r)),
118
+ _dr := float(1 - _r_s),
118
119
  _cmcr := 0.03, # Not strictly a Guidelines standard
119
- _ipr := _g_s, # Not strictly a Guidelines standard
120
+ _ipr := _g, # Not strictly a Guidelines standard
120
121
  ),
121
122
  )
122
123
 
123
124
  object.__setattr__(
124
- self,
125
- "presumption",
126
- HMGThresholds(
127
- _dh_p,
128
- _fc,
129
- _r,
130
- _g_p := guppi_from_delta(_dh_p, m_star=1.0, r_bar=_r),
131
- _dr,
132
- _cmcr,
133
- _ipr := _g_p,
134
- ),
125
+ self, "presumption", HMGThresholds(_dh_p, _fc, _r, _g, _dr, _cmcr, _ipr)
135
126
  )
136
127
 
137
- # imputed_presumption is relevant for 2010 Guidelines
138
- # merger to symmetry in numbers-equivalent of post-merger HHI
128
+ # imputed_presumption is relevant for presumptions implicating
129
+ # mergers *to* symmetry in numbers-equivalent of post-merger HHI
130
+ # as in 2010 U.S.Guidelines and 2004 EU Commission Guidelines
139
131
  object.__setattr__(
140
132
  self,
141
133
  "imputed_presumption",
142
134
  (
143
135
  HMGThresholds(
144
- _dh_i := 2 * (0.5 / _fc) ** 2,
136
+ 2 * (0.5 / _fc) ** 2,
145
137
  _fc,
146
- _r_i := gbfn.round_cust((_fc - 1 / 2) / (_fc + 1 / 2), frac=0.05),
147
- _g_i := guppi_from_delta(_dh_p, m_star=1.0, r_bar=_r_i),
148
- 1 / 2 * (1 - _r_i),
138
+ float(
139
+ _r_i := gbfn.round_cust(
140
+ (_fc - 1 / 2) / (_fc + 1 / 2), frac=0.05
141
+ )
142
+ ),
143
+ _g,
144
+ float((1 - _r_i) / 2),
149
145
  _cmcr,
150
- _g_i,
146
+ _ipr := _g,
151
147
  )
152
148
  if self.pub_year in (2004, 2010)
153
149
  else HMGThresholds(
154
- _dh_i := 2 * (1 / (_fc + 1)) ** 2,
155
- _fc,
156
- _r,
157
- _g_i := guppi_from_delta(_dh_p, m_star=1.0, r_bar=_r),
158
- _dr,
159
- _cmcr,
160
- _g_i,
150
+ 2 * (1 / (_fc + 1)) ** 2, _fc, _r, _g, _dr, _cmcr, _ipr
161
151
  )
162
152
  ),
163
153
  )
@@ -169,10 +159,7 @@ class ConcentrationBoundary:
169
159
 
170
160
  measure_name: Literal[
171
161
  "ΔHHI", "Combined share", "Pre-merger HHI", "Post-merger HHI"
172
- ] = field(
173
- kw_only=False,
174
- default="ΔHHI", # pyright: ignore
175
- )
162
+ ] = field(kw_only=False, default="ΔHHI")
176
163
 
177
164
  @measure_name.validator # pyright: ignore
178
165
  def __mnv(
@@ -193,7 +180,7 @@ class ConcentrationBoundary:
193
180
  _instance: ConcentrationBoundary, _attribute: Attribute[float], _value: float, /
194
181
  ) -> None:
195
182
  if not 0 <= _value <= 1:
196
- raise ValueError("Concentration threshold must lie between 0 and 1.") # pyright: ignore
183
+ raise ValueError("Concentration threshold must lie between 0 and 1.")
197
184
 
198
185
  precision: int = field(
199
186
  kw_only=False, default=5, validator=validators.instance_of(int)
@@ -337,6 +324,7 @@ class DiversionRatioBoundary:
337
324
  "recapture_form": getattr(self.recapture_form, "value", "inside-out"),
338
325
  "dps": self.precision,
339
326
  }
327
+
340
328
  match self.agg_method:
341
329
  case UPPAggrSelector.DIS:
342
330
  _upp_agg_fn = gbfn.shrratio_boundary_wtd_avg
@@ -381,7 +369,7 @@ def guppi_from_delta(
381
369
  *,
382
370
  m_star: float = 1.00,
383
371
  r_bar: float = DEFAULT_REC_RATE,
384
- ) -> float:
372
+ ) -> decimal.Decimal:
385
373
  """
386
374
  Translate ∆HHI bound to GUPPI bound.
387
375
 
@@ -443,7 +431,7 @@ def share_from_guppi(
443
431
  *,
444
432
  m_star: float = 1.00,
445
433
  r_bar: float = DEFAULT_REC_RATE,
446
- ) -> float:
434
+ ) -> decimal.Decimal:
447
435
  """
448
436
  Symmetric-firm share for given GUPPI, margin, and recapture ratio.
449
437
 
@@ -305,7 +305,7 @@ def shrratio_boundary_wtd_avg(
305
305
  _s_mid = mp.fdiv(_delta_star, 1 + _delta_star)
306
306
 
307
307
  # initial conditions
308
- _gbdry_points: list[tuple[MPFloat, MPFloat]] | ArrayDouble = [(_s_mid, _s_mid)]
308
+ _gbdry_points = [(_s_mid, _s_mid)]
309
309
  _s_1_pre, _s_2_pre = _s_mid, _s_mid
310
310
  _s_2_oddval, _s_2_oddsum, _s_2_evnsum = True, 0.0, 0.0
311
311
 
@@ -401,11 +401,11 @@ def shrratio_boundary_wtd_avg(
401
401
  _gbdry_area_total = float(2 * _gbd_prtlarea - mp.power(_s_mid, "2"))
402
402
 
403
403
  _gbdry_points.append((mpf("0.0"), _s_intcpt))
404
- _gbdry_points = np.array(_gbdry_points).astype(np.float64)
404
+ _gbdry_array = np.array(_gbdry_points).astype(np.float64)
405
405
 
406
406
  # Points defining boundary to point-of-symmetry
407
407
  return GuidelinesBoundary(
408
- np.vstack((_gbdry_points[::-1], _gbdry_points[1:, ::-1])),
408
+ np.vstack((_gbdry_array[::-1], _gbdry_array[1:, ::-1])),
409
409
  round(float(_gbdry_area_total), dps),
410
410
  )
411
411
 
@@ -851,7 +851,9 @@ def _shrratio_boundary_intcpt(
851
851
  ),
852
852
  2 * mpf(f"{_r_val}"),
853
853
  )
854
- case None if agg_method == "arithmetic mean" and recapture_form == "proportional":
854
+ case None if (
855
+ agg_method == "arithmetic mean" and recapture_form == "proportional"
856
+ ):
855
857
  _s_intcpt = mp.fsub(_delta_star + 1 / 2, mp.fabs(_delta_star - 1 / 2))
856
858
  case _:
857
859
  _s_intcpt = _s_2_pre
@@ -859,12 +861,9 @@ def _shrratio_boundary_intcpt(
859
861
  return _s_intcpt
860
862
 
861
863
 
862
- def lerp(
863
- _x1: int | float | MPFloat | ArrayDouble | ArrayBIGINT = 3,
864
- _x2: int | float | MPFloat | ArrayDouble | ArrayBIGINT = 1,
865
- _r: float | MPFloat = 0.25,
866
- /,
867
- ) -> float | MPFloat | ArrayDouble:
864
+ def lerp[LerpT: (float, MPFloat, ArrayDouble, ArrayBIGINT)](
865
+ _x1: LerpT, _x2: LerpT, _r: float = 0.25, /
866
+ ) -> LerpT:
868
867
  """
869
868
  From the function of the same name in the C++ standard [2]_
870
869
 
@@ -901,10 +900,8 @@ def lerp(
901
900
  return _x1
902
901
  elif _r == 1:
903
902
  return _x2
904
- elif _r == 0.5:
905
- return 1 / 2 * (_x1 + _x2)
906
903
  else:
907
- return _r * _x2 + (1 - _r) * _x1
904
+ return _r * _x2 + (1 - _r) * _x1 # pyright: ignore
908
905
 
909
906
 
910
907
  def round_cust(
@@ -913,7 +910,7 @@ def round_cust(
913
910
  *,
914
911
  frac: float = 0.005,
915
912
  rounding_mode: str = "ROUND_HALF_UP",
916
- ) -> float:
913
+ ) -> decimal.Decimal:
917
914
  """
918
915
  Custom rounding, to the nearest 0.5% by default.
919
916
 
@@ -960,7 +957,7 @@ def round_cust(
960
957
 
961
958
  _n, _f, _e = (decimal.Decimal(f"{_g}") for _g in [_num, frac, 1])
962
959
 
963
- return float(_f * (_n / _f).quantize(_e, rounding=rounding_mode))
960
+ return _f * (_n / _f).quantize(_e, rounding=rounding_mode)
964
961
 
965
962
 
966
963
  def boundary_plot(*, mktshares_plot_flag: bool = True) -> tuple[Any, ...]: