mergeron 2024.738953.0__py3-none-any.whl → 2024.738953.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-2024.738953.0.dist-info → mergeron-2024.738953.1.dist-info}/METADATA +1 -1
- {mergeron-2024.738953.0.dist-info → mergeron-2024.738953.1.dist-info}/RECORD +3 -17
- mergeron/examples/__init__.py +0 -5
- mergeron/examples/concentration_as_diversion.py +0 -625
- mergeron/examples/enforcement_boundaries_for_mergers_with_asymmetric_shares.py +0 -493
- mergeron/examples/enforcement_boundaries_for_symmetric_firm_mergers.py +0 -206
- mergeron/examples/example_parameterizations.py +0 -143
- mergeron/examples/guidelines_enforcement_patterns.py +0 -74
- mergeron/examples/investigations_stats_obs_tables.py +0 -481
- mergeron/examples/investigations_stats_sim_tables.py +0 -425
- mergeron/examples/plotSafeHarbs_symbolically.py +0 -53
- mergeron/examples/sound_guppi_safeharbor.py +0 -181
- mergeron/examples/summarize_ftc_investigations_data.py +0 -44
- mergeron/examples/testIntrinsicClearanceRates.py +0 -135
- mergeron/examples/visualize_empirical_margin_distribution.py +0 -100
- mergeron/examples/visualize_guidelines_tests.py +0 -298
- {mergeron-2024.738953.0.dist-info → mergeron-2024.738953.1.dist-info}/WHEEL +0 -0
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
|
|
3
|
-
Estimation of intrinsic clearance rates for ΔHHI safeharbor and GUPPI safeharbor
|
|
4
|
-
Demonstrates MC integration with closed-form integrand and indicator-function
|
|
5
|
-
integrand (Tested with Python 3.8 and 3.9; NumPy module is required.)
|
|
6
|
-
|
|
7
|
-
S. Murthy Kambhampaty, © 2019. This work is licensed under a CC BY-NC-SA 4.0 License
|
|
8
|
-
https://creativecommons.org/licenses/by-nc-sa/4.0/
|
|
9
|
-
|
|
10
|
-
"""
|
|
11
|
-
|
|
12
|
-
from datetime import datetime
|
|
13
|
-
|
|
14
|
-
import numpy as np
|
|
15
|
-
from numpy.random import PCG64DXSM, Generator
|
|
16
|
-
from numpy.typing import NDArray
|
|
17
|
-
|
|
18
|
-
rng = Generator(PCG64DXSM())
|
|
19
|
-
|
|
20
|
-
dh_bar = 0.01
|
|
21
|
-
g_bar = 0.06
|
|
22
|
-
r_bar = 0.80
|
|
23
|
-
d_bar = 0.2 # 0.2 # r_bar # g_bar # 0.8 * 0.125 / (1 - 0.125)
|
|
24
|
-
sample_sz = 10**8
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
def icr_gsh_sym(_ssz: int = sample_sz) -> NDArray[np.float64]:
|
|
28
|
-
"""With symmetric shares, margins, and prices; closed-form integrand."""
|
|
29
|
-
_m_lim = g_bar / d_bar
|
|
30
|
-
_m_star = _m_lim + (1.0 - _m_lim) * rng.uniform(size=(_ssz, 1))
|
|
31
|
-
_d_star = g_bar / (r_bar * _m_star)
|
|
32
|
-
_divr_limit_prob = 2 * g_bar / (r_bar + d_bar)
|
|
33
|
-
_guppi_bound_prob = 2 * (1 - _m_lim) * (_d_star / (1 + _d_star)).mean()
|
|
34
|
-
return np.array([_ssz, _divr_limit_prob + _guppi_bound_prob, np.nan, np.nan])
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def icr_gsh_asymmshr(_ssz: int = sample_sz) -> NDArray[np.float64]:
|
|
38
|
-
"""With symmetric margins and prices, unequal shares; closed-form integrand."""
|
|
39
|
-
_m_lim = g_bar / d_bar
|
|
40
|
-
_m_star = _m_lim + (1.0 - _m_lim) * rng.random(size=(_ssz, 1))
|
|
41
|
-
|
|
42
|
-
_d_star = g_bar / (r_bar * _m_star)
|
|
43
|
-
_divr_limit_prob = 2 * (g_bar / r_bar) * d_bar / (r_bar + d_bar)
|
|
44
|
-
_guppi_bound_prob = 2 * (1 - _m_lim) * (_d_star**2 / (1 + _d_star)).mean()
|
|
45
|
-
return np.array([_ssz, _divr_limit_prob + _guppi_bound_prob, np.nan, np.nan])
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
def gen_qtyshr(_ssz: int = sample_sz, *, sym_flag: bool = False) -> NDArray[np.float64]:
|
|
49
|
-
"""Unequal shares and margins, and symmetric prices; indicator-function integrand."""
|
|
50
|
-
if sym_flag:
|
|
51
|
-
# for symmetric shares
|
|
52
|
-
_mktshr_array = 0.5 * rng.uniform(size=(_ssz, 1))
|
|
53
|
-
_mktshr_array = _mktshr_array[:, [0, 0]]
|
|
54
|
-
else:
|
|
55
|
-
_mktshr_array = np.sort(rng.random(size=(_ssz, 2)))
|
|
56
|
-
_mktshr_array = np.column_stack((_mktshr_array[:, [0]], np.diff(_mktshr_array)))
|
|
57
|
-
return _mktshr_array
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
def icr_gsh_asymmshrmgn(_ssz: int = sample_sz) -> NDArray[np.float64]:
|
|
61
|
-
"""With symmetric prices, unequal shares and margins; indicator-function integrand."""
|
|
62
|
-
|
|
63
|
-
_shr_sym_flag = False
|
|
64
|
-
_mktshr_array = gen_qtyshr(_ssz, sym_flag=_shr_sym_flag)
|
|
65
|
-
_hhi_delta = np.einsum("ij,ij->i", _mktshr_array, _mktshr_array[:, ::-1])
|
|
66
|
-
_divr_array = r_bar * _mktshr_array[:, ::-1] / (1 - _mktshr_array)
|
|
67
|
-
_delta_test = _hhi_delta < dh_bar
|
|
68
|
-
del _hhi_delta
|
|
69
|
-
|
|
70
|
-
_pcm_array = rng.uniform(size=_divr_array.shape)
|
|
71
|
-
_pcm_sym_flag = False
|
|
72
|
-
if _pcm_sym_flag:
|
|
73
|
-
_pcm_array = _pcm_array[:, [0, 0]]
|
|
74
|
-
|
|
75
|
-
_pr_sym_flag = True
|
|
76
|
-
_pr_corr_sign = None
|
|
77
|
-
if _pr_corr_sign not in (_pcvs := (None, "positive", "negative")):
|
|
78
|
-
raise ValueError(f"Price correlation must be one of {_pcvs!r}")
|
|
79
|
-
if _pr_sym_flag:
|
|
80
|
-
_pr_ratio_array = np.ones(_pcm_array.shape)
|
|
81
|
-
else:
|
|
82
|
-
_pr_max_ratio = 5
|
|
83
|
-
if _pr_corr_sign == "positive":
|
|
84
|
-
_pr_array = 1 + np.floor(_pr_max_ratio * _mktshr_array)
|
|
85
|
-
elif _pr_corr_sign == "negative":
|
|
86
|
-
_pr_array = _pr_max_ratio - np.floor(_pr_max_ratio * _mktshr_array)
|
|
87
|
-
else:
|
|
88
|
-
_pr_array = rng.choice(
|
|
89
|
-
1.00 + np.arange(_pr_max_ratio), size=_pcm_array.shape
|
|
90
|
-
)
|
|
91
|
-
_pr_ratio_array = np.divide(_pr_array, _pr_array[:, ::-1])
|
|
92
|
-
del _pr_max_ratio, _pr_array
|
|
93
|
-
|
|
94
|
-
_guppi_array = np.einsum(
|
|
95
|
-
"ij,ij,ij->ij", _divr_array, _pcm_array[:, ::-1], _pr_ratio_array[:, ::-1]
|
|
96
|
-
)
|
|
97
|
-
_gbd_test = _guppi_array.max(axis=1) < g_bar
|
|
98
|
-
_divr_test = _divr_array.max(axis=1) < d_bar
|
|
99
|
-
_pcm_min_test = _pcm_array.min(axis=1) >= (g_bar / d_bar)
|
|
100
|
-
_divr_limit_test = _gbd_test & _divr_test & np.logical_not(_pcm_min_test)
|
|
101
|
-
_gbd_not_in_deltah = np.logical_not(_delta_test) & _gbd_test & _divr_test
|
|
102
|
-
|
|
103
|
-
_scount = len(_gbd_test)
|
|
104
|
-
_gbd_prob = len(_gbd_test[_gbd_test & _divr_test]) / _scount
|
|
105
|
-
_deltah_prob = len(_gbd_test[_delta_test]) / _scount
|
|
106
|
-
_cum_clr_prob = len(_gbd_test[_delta_test | _gbd_not_in_deltah]) / _scount
|
|
107
|
-
|
|
108
|
-
del _guppi_array, _divr_array, _pcm_array
|
|
109
|
-
del _gbd_test, _divr_test, _pcm_min_test, _divr_limit_test
|
|
110
|
-
|
|
111
|
-
return np.array([_scount, _gbd_prob, _deltah_prob, _cum_clr_prob])
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
if __name__ == "__main__":
|
|
115
|
-
for run_func in (icr_gsh_sym, icr_gsh_asymmshr, icr_gsh_asymmshrmgn):
|
|
116
|
-
resv = np.array([0.0, 0.0, 0.0, 0.0])
|
|
117
|
-
icount = 1000
|
|
118
|
-
stime = datetime.now()
|
|
119
|
-
for _ in range(icount):
|
|
120
|
-
tmpv = run_func(sample_sz // icount)
|
|
121
|
-
resv += tmpv[0] * tmpv
|
|
122
|
-
resv = np.round(resv / (icount * np.sqrt(resv[0] / icount)), 4)
|
|
123
|
-
|
|
124
|
-
# In the printed output,
|
|
125
|
-
# first column reports the intrinsic clearance rate for
|
|
126
|
-
# the GUPPI safeharbor Where reported,
|
|
127
|
-
# second column reports the intrinsic clearance rate for the ΔHHI safeharbor
|
|
128
|
-
# third column reports the intrinsic clearance rate for cumulative application
|
|
129
|
-
# of the ΔHHI safeharbor and the GUPPI safeharbor
|
|
130
|
-
print(
|
|
131
|
-
np.sum(resv[1]),
|
|
132
|
-
resv[-2],
|
|
133
|
-
resv[-1],
|
|
134
|
-
f"; duration {(datetime.now() - stime).total_seconds()} secs.",
|
|
135
|
-
)
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Plot the empirical distribution of margin data downloaded from
|
|
3
|
-
Prof. Damodaran's website at NYU.
|
|
4
|
-
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
import warnings
|
|
8
|
-
from pathlib import Path
|
|
9
|
-
|
|
10
|
-
import numpy as np
|
|
11
|
-
from matplotlib.ticker import StrMethodFormatter
|
|
12
|
-
from numpy.typing import NDArray
|
|
13
|
-
from scipy import stats # type: ignore
|
|
14
|
-
|
|
15
|
-
import mergeron.core.damodaran_margin_data as dmgn
|
|
16
|
-
from mergeron import DATA_DIR
|
|
17
|
-
from mergeron.core.guidelines_boundaries import boundary_plot
|
|
18
|
-
|
|
19
|
-
PROG_PATH = Path(__file__)
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
def _get_margin_data() -> (
|
|
23
|
-
tuple[NDArray[np.float64], NDArray[np.float64], NDArray[np.float64]]
|
|
24
|
-
):
|
|
25
|
-
return dmgn.mgn_data_builder()
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
if __name__ == "__main__":
|
|
29
|
-
mgn_data_obs, mgn_data_wts, mgn_data_stats = _get_margin_data()
|
|
30
|
-
print(repr(mgn_data_obs))
|
|
31
|
-
print(repr(mgn_data_stats))
|
|
32
|
-
|
|
33
|
-
plt, mgn_fig, mgn_ax, set_axis_def = boundary_plot(mktshares_plot_flag=False)
|
|
34
|
-
mgn_fig.set_figheight(6.5)
|
|
35
|
-
mgn_fig.set_figwidth(9.0)
|
|
36
|
-
|
|
37
|
-
bin_count = 25
|
|
38
|
-
_, mgn_bins, _ = mgn_ax.hist(
|
|
39
|
-
x=mgn_data_obs,
|
|
40
|
-
weights=mgn_data_wts,
|
|
41
|
-
bins=bin_count,
|
|
42
|
-
alpha=0.4,
|
|
43
|
-
density=True,
|
|
44
|
-
label="Downloaded data",
|
|
45
|
-
color="#004488", # Paul Tol's High Contrast Blue
|
|
46
|
-
)
|
|
47
|
-
mgn_ax_yticklabels = mgn_ax.get_yticklabels()
|
|
48
|
-
with warnings.catch_warnings():
|
|
49
|
-
warnings.filterwarnings("ignore", category=UserWarning)
|
|
50
|
-
# Don't warn regarding the below; ticklabels have been fixed before this point
|
|
51
|
-
mgn_ax.set_yticklabels([
|
|
52
|
-
f"{float(_g.get_text()) * np.diff(mgn_bins)[-1]:.0%}"
|
|
53
|
-
for _g in mgn_ax_yticklabels
|
|
54
|
-
])
|
|
55
|
-
|
|
56
|
-
# Add KDE plot
|
|
57
|
-
# https://stackoverflow.com/questions/33323432
|
|
58
|
-
mgn_kde = stats.gaussian_kde(mgn_data_obs, weights=mgn_data_wts)
|
|
59
|
-
print(
|
|
60
|
-
f"Approximately {mgn_kde.integrate_box_1d(0, 1):.2%} of the estimated mass",
|
|
61
|
-
"of the empirical distribution under the Gaussian KDE",
|
|
62
|
-
"estimated using selected margin data falls in the interval [0, 1].",
|
|
63
|
-
)
|
|
64
|
-
mgn_xx = np.linspace(0, bin_count, 10**5)
|
|
65
|
-
mgn_ax.plot(
|
|
66
|
-
mgn_xx,
|
|
67
|
-
mgn_kde(mgn_xx),
|
|
68
|
-
color="#004488",
|
|
69
|
-
rasterized=True,
|
|
70
|
-
label="Estimated Density",
|
|
71
|
-
)
|
|
72
|
-
|
|
73
|
-
sample_size = 10**6
|
|
74
|
-
mgn_ax.hist(
|
|
75
|
-
x=dmgn.resample_mgn_data(sample_size),
|
|
76
|
-
color="#DDAA33", # Paul Tol's High Contrast Yellow
|
|
77
|
-
alpha=0.6,
|
|
78
|
-
bins=bin_count,
|
|
79
|
-
density=True,
|
|
80
|
-
label="Generated data",
|
|
81
|
-
)
|
|
82
|
-
|
|
83
|
-
mgn_ax.legend(
|
|
84
|
-
loc="best",
|
|
85
|
-
fancybox=False,
|
|
86
|
-
shadow=False,
|
|
87
|
-
frameon=True,
|
|
88
|
-
facecolor="white",
|
|
89
|
-
edgecolor="white",
|
|
90
|
-
framealpha=1,
|
|
91
|
-
fontsize="small",
|
|
92
|
-
)
|
|
93
|
-
|
|
94
|
-
mgn_ax.set_xlim(0.0, 1.0)
|
|
95
|
-
mgn_ax.xaxis.set_major_formatter(StrMethodFormatter("{x:>3.0%}"))
|
|
96
|
-
mgn_ax.set_xlabel("Price Cost Margin", fontsize=10)
|
|
97
|
-
mgn_ax.set_ylabel("Relative Frequency", fontsize=10)
|
|
98
|
-
|
|
99
|
-
mgn_fig.tight_layout()
|
|
100
|
-
plt.savefig(DATA_DIR / PROG_PATH.with_suffix(".pdf").name)
|
|
@@ -1,298 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Defining the merging firm with the larger share as buyer under a
|
|
3
|
-
GUPPI safeharbor bound of 6%, and the merging firm with the
|
|
4
|
-
*smaller* share as the buyer under a GUPPI safeharbor bound of 5%,
|
|
5
|
-
and incrementing shares and margins by 5%, plot mergers that
|
|
6
|
-
clear the safeharbor threshold, color-coded by margin of the firm
|
|
7
|
-
with the larger GUPPI estimate.
|
|
8
|
-
|
|
9
|
-
"""
|
|
10
|
-
|
|
11
|
-
from __future__ import annotations
|
|
12
|
-
|
|
13
|
-
import gc
|
|
14
|
-
from dataclasses import fields
|
|
15
|
-
from pathlib import Path
|
|
16
|
-
from typing import Final
|
|
17
|
-
|
|
18
|
-
import numpy as np
|
|
19
|
-
from matplotlib import cm, colors
|
|
20
|
-
from matplotlib.ticker import StrMethodFormatter
|
|
21
|
-
from numpy.typing import NDArray
|
|
22
|
-
|
|
23
|
-
import mergeron.core.guidelines_boundaries as gbl
|
|
24
|
-
import mergeron.gen.data_generation as dgl
|
|
25
|
-
import mergeron.gen.upp_tests as utl
|
|
26
|
-
from mergeron import DATA_DIR, RECConstants, UPPAggrSelector
|
|
27
|
-
from mergeron.core.pseudorandom_numbers import DIST_PARMS_DEFAULT
|
|
28
|
-
from mergeron.gen import (
|
|
29
|
-
INVResolution,
|
|
30
|
-
MarketDataSample,
|
|
31
|
-
MarketSampleSpec,
|
|
32
|
-
ShareSpec,
|
|
33
|
-
SHRConstants,
|
|
34
|
-
UPPTestRegime,
|
|
35
|
-
)
|
|
36
|
-
|
|
37
|
-
PROG_PATH = Path(__file__)
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
def gen_plot_data(
|
|
41
|
-
_market_data: MarketDataSample,
|
|
42
|
-
_std_vec: gbl.HMGThresholds,
|
|
43
|
-
_pcm_firm2_star: float,
|
|
44
|
-
_test_regime: UPPTestRegime,
|
|
45
|
-
/,
|
|
46
|
-
*,
|
|
47
|
-
save_data_to_file: utl.SaveData = False,
|
|
48
|
-
) -> tuple[NDArray[np.float64], NDArray[np.float64], NDArray[np.float64]]:
|
|
49
|
-
if save_data_to_file:
|
|
50
|
-
_, _h5_file, _h5_hier = save_data_to_file
|
|
51
|
-
_h5_hier = _h5_file.create_group(
|
|
52
|
-
_h5_hier,
|
|
53
|
-
"plotData_mstar{}PCT".format(
|
|
54
|
-
f"{_pcm_firm2_star * 100:03.1f}".replace(".", "dot")
|
|
55
|
-
),
|
|
56
|
-
title=f"Firm 2 margin = {_pcm_firm2_star * 100:03.1f}%",
|
|
57
|
-
)
|
|
58
|
-
save_data_to_file = (True, _h5_file, _h5_hier)
|
|
59
|
-
|
|
60
|
-
_pcm_array = np.column_stack((
|
|
61
|
-
_m1 := _market_data.pcm_array[:, [0]],
|
|
62
|
-
_pcm_firm2_star * np.ones_like(_m1),
|
|
63
|
-
))
|
|
64
|
-
del _m1
|
|
65
|
-
|
|
66
|
-
_upp_test_raw = utl.gen_upp_arrays(
|
|
67
|
-
_std_vec,
|
|
68
|
-
MarketDataSample(*[ # type: ignore
|
|
69
|
-
_pcm_array if _f.name == "pcm_array" else getattr(_market_data, _f.name)
|
|
70
|
-
for _f in fields(_market_data)
|
|
71
|
-
]),
|
|
72
|
-
_test_regime,
|
|
73
|
-
)
|
|
74
|
-
|
|
75
|
-
_gbd_test_rows = np.where(_upp_test_raw.guppi_test_simple)[0]
|
|
76
|
-
del _upp_test_raw
|
|
77
|
-
|
|
78
|
-
_qtyshr_firm1_inv, _qtyshr_firm2_inv = (
|
|
79
|
-
_market_data.frmshr_array[_gbd_test_rows][:, [0]],
|
|
80
|
-
_market_data.frmshr_array[_gbd_test_rows][:, [1]],
|
|
81
|
-
)
|
|
82
|
-
_pcm_firm1_inv, _pcm_firm2_inv = (
|
|
83
|
-
_pcm_array[_gbd_test_rows][:, [0]],
|
|
84
|
-
_pcm_array[_gbd_test_rows][:, [1]],
|
|
85
|
-
)
|
|
86
|
-
del _gbd_test_rows
|
|
87
|
-
|
|
88
|
-
_pcm_plotter = _pcm_firm1_inv
|
|
89
|
-
|
|
90
|
-
if save_data_to_file:
|
|
91
|
-
print("Save data to tables")
|
|
92
|
-
for _array_name in (
|
|
93
|
-
"qtyshr_firm1_inv",
|
|
94
|
-
"qtyshr_firm2_inv",
|
|
95
|
-
"pcm_firm1_inv",
|
|
96
|
-
"pcm_firm2_inv",
|
|
97
|
-
):
|
|
98
|
-
_array_obj: NDArray[any] = locals().get(f"_{_array_name}") # type: ignore
|
|
99
|
-
if np.any(_array_obj):
|
|
100
|
-
utl.save_array_to_hdf5(
|
|
101
|
-
_array_obj, _array_name, save_data_to_file[-1], save_data_to_file[1]
|
|
102
|
-
)
|
|
103
|
-
|
|
104
|
-
_pcm_sorter = np.argsort(_pcm_plotter, axis=0)
|
|
105
|
-
if test_regime.resolution != INVResolution.CLRN:
|
|
106
|
-
_pcm_sorter = _pcm_sorter[::-1, :]
|
|
107
|
-
_qtyshr_firm1_plotter = _qtyshr_firm1_inv[_pcm_sorter]
|
|
108
|
-
_qtyshr_firm2_plotter = _qtyshr_firm2_inv[_pcm_sorter]
|
|
109
|
-
_pcm_plotter = _pcm_plotter[_pcm_sorter]
|
|
110
|
-
|
|
111
|
-
del (
|
|
112
|
-
_qtyshr_firm1_inv,
|
|
113
|
-
_qtyshr_firm2_inv,
|
|
114
|
-
_pcm_firm1_inv,
|
|
115
|
-
_pcm_firm2_inv,
|
|
116
|
-
_pcm_sorter,
|
|
117
|
-
)
|
|
118
|
-
|
|
119
|
-
return _qtyshr_firm1_plotter, _qtyshr_firm2_plotter, _pcm_plotter
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
# Generate market data
|
|
123
|
-
def _main(
|
|
124
|
-
_hmg_pub_year: gbl.HMGPubYear,
|
|
125
|
-
_market_sample_spec: MarketSampleSpec,
|
|
126
|
-
_test_regime: UPPTestRegime,
|
|
127
|
-
save_data_to_file: utl.SaveData,
|
|
128
|
-
) -> None:
|
|
129
|
-
guidelins_std_vec = getattr(
|
|
130
|
-
gbl.GuidelinesThresholds(_hmg_pub_year),
|
|
131
|
-
"safeharbor" if test_regime.resolution == INVResolution.ENFT else "presumption",
|
|
132
|
-
)
|
|
133
|
-
|
|
134
|
-
_r_bar, _g_bar, _divr_bar = (
|
|
135
|
-
getattr(guidelins_std_vec, _f) for _f in ("rec", "guppi", "divr")
|
|
136
|
-
)
|
|
137
|
-
|
|
138
|
-
market_data = dgl.gen_market_sample(_market_sample_spec, seed_seq_list=None)
|
|
139
|
-
|
|
140
|
-
# Set up a plot grid to fill in the various scatterplots
|
|
141
|
-
print(
|
|
142
|
-
"Construct panel of scatter plots of cleared mergers by Firm 2 margin",
|
|
143
|
-
"with each plot color-coded by Firm 1 margin",
|
|
144
|
-
sep=", ",
|
|
145
|
-
)
|
|
146
|
-
_fig_norm = colors.Normalize(0.0, 1.0)
|
|
147
|
-
_cmap_kwargs = {"cmap": "cividis", "norm": _fig_norm}
|
|
148
|
-
_plt, _, _, _set_axis_def = gbl.boundary_plot()
|
|
149
|
-
|
|
150
|
-
_fig_2dsg = _plt.figure(figsize=(8.5, 9.5), dpi=600)
|
|
151
|
-
|
|
152
|
-
_fig_grid = _fig_2dsg.add_gridspec(
|
|
153
|
-
nrows=1, ncols=2, figure=_fig_2dsg, width_ratios=[6, 0.125], wspace=0.0
|
|
154
|
-
)
|
|
155
|
-
_fig_grid_gbd = _fig_grid[0, 0].subgridspec(
|
|
156
|
-
nrows=3, ncols=1, wspace=0, hspace=0.125
|
|
157
|
-
)
|
|
158
|
-
|
|
159
|
-
for _ax_row, _pcm_firm2_star in enumerate((
|
|
160
|
-
1.00,
|
|
161
|
-
_g_bar / _divr_bar,
|
|
162
|
-
_g_bar / _r_bar,
|
|
163
|
-
)):
|
|
164
|
-
_ax_now = _fig_2dsg.add_subplot(_fig_grid_gbd[_ax_row, 0])
|
|
165
|
-
_ax_now = _set_axis_def(_ax_now, mktshares_plot_flag=True)
|
|
166
|
-
_ax_now.set_xlabel(None)
|
|
167
|
-
_ax_now.set_ylabel(None)
|
|
168
|
-
_plt.setp(_ax_now.get_xticklabels()[1::2], visible=False)
|
|
169
|
-
_plt.setp(_ax_now.get_yticklabels()[1::2], visible=False)
|
|
170
|
-
|
|
171
|
-
_ax_now.text(
|
|
172
|
-
0.81,
|
|
173
|
-
0.72,
|
|
174
|
-
"\n".join((
|
|
175
|
-
R"$m_2 = m^* = {0:.{1}f}\%$".format(
|
|
176
|
-
(_pcmv := _pcm_firm2_star * 100), 1 * (_pcmv % 1 > 0)
|
|
177
|
-
),
|
|
178
|
-
R"$m_1 \neq m_2$",
|
|
179
|
-
)),
|
|
180
|
-
rotation=0,
|
|
181
|
-
ha="right",
|
|
182
|
-
va="top",
|
|
183
|
-
fontsize=10,
|
|
184
|
-
zorder=5,
|
|
185
|
-
)
|
|
186
|
-
if _ax_row == 0:
|
|
187
|
-
# Set y-axis label
|
|
188
|
-
_ax_now.yaxis.set_label_coords(-0.20, 1.0)
|
|
189
|
-
_ax_now.set_ylabel(
|
|
190
|
-
"Firm 2 Market Share, $s_2$",
|
|
191
|
-
rotation=90,
|
|
192
|
-
ha="right",
|
|
193
|
-
va="top",
|
|
194
|
-
fontsize=10,
|
|
195
|
-
)
|
|
196
|
-
elif _ax_row == 2:
|
|
197
|
-
_ax_now.xaxis.set_label_coords(1.0, -0.15)
|
|
198
|
-
_ax_now.set_xlabel(
|
|
199
|
-
"\n".join(["Firm 1 Market Share, $s_1$"]), ha="right", fontsize=10
|
|
200
|
-
)
|
|
201
|
-
|
|
202
|
-
_qtyshr_firm1_plotter, _qtyshr_firm2_plotter, _pcm_plotter = gen_plot_data(
|
|
203
|
-
market_data,
|
|
204
|
-
guidelins_std_vec,
|
|
205
|
-
_pcm_firm2_star,
|
|
206
|
-
_test_regime,
|
|
207
|
-
save_data_to_file=save_data_to_file,
|
|
208
|
-
)
|
|
209
|
-
|
|
210
|
-
_ax_now.scatter(
|
|
211
|
-
_qtyshr_firm1_plotter,
|
|
212
|
-
_qtyshr_firm2_plotter,
|
|
213
|
-
marker=".",
|
|
214
|
-
s=(0.1 * 72.0 / _fig_2dsg.dpi) ** 2,
|
|
215
|
-
c=_pcm_plotter,
|
|
216
|
-
**_cmap_kwargs,
|
|
217
|
-
rasterized=True,
|
|
218
|
-
)
|
|
219
|
-
_ax_now.set_aspect(1.0)
|
|
220
|
-
|
|
221
|
-
gc.collect()
|
|
222
|
-
|
|
223
|
-
# Colorbar
|
|
224
|
-
_ax_cm = _fig_2dsg.add_subplot(_fig_grid[-1, -1], frameon=False)
|
|
225
|
-
_ax_cm.axis("off")
|
|
226
|
-
_cm_plot = _fig_2dsg.colorbar(
|
|
227
|
-
cm.ScalarMappable(**_cmap_kwargs), # type: ignore
|
|
228
|
-
use_gridspec=True,
|
|
229
|
-
ax=_ax_cm,
|
|
230
|
-
orientation="vertical",
|
|
231
|
-
fraction=3.0,
|
|
232
|
-
ticks=np.arange(0, 1.2, 0.2),
|
|
233
|
-
format=StrMethodFormatter("{x:>3.0%}"),
|
|
234
|
-
)
|
|
235
|
-
_cm_plot.set_label(label="Firm 1 Price-Cost Margin, $m_1$", fontsize=10)
|
|
236
|
-
_cm_plot.ax.tick_params(length=5, width=0.5, labelsize=6)
|
|
237
|
-
_plt.setp(
|
|
238
|
-
_cm_plot.ax.yaxis.get_majorticklabels(), horizontalalignment="left", fontsize=6
|
|
239
|
-
)
|
|
240
|
-
|
|
241
|
-
_cm_plot.outline.set_visible(False)
|
|
242
|
-
|
|
243
|
-
_base_name = DATA_DIR / "{}_{}Rate_{}gbar{}PCT_{}Recapture".format(
|
|
244
|
-
PROG_PATH.stem,
|
|
245
|
-
f"{test_regime.resolution}".capitalize(),
|
|
246
|
-
_hmg_pub_year,
|
|
247
|
-
f"{_g_bar * 100:02.0f}",
|
|
248
|
-
market_sample_spec.share_spec.recapture_spec,
|
|
249
|
-
)
|
|
250
|
-
_my_fig_2dsg_savepath = DATA_DIR / f"{_base_name}_2DScatterGrid.pdf"
|
|
251
|
-
print(f"Save 2D plot to, {f'"{_my_fig_2dsg_savepath}"'}")
|
|
252
|
-
_fig_2dsg.savefig(_my_fig_2dsg_savepath, dpi=600)
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
if __name__ == "__main__":
|
|
256
|
-
# Get Guidelines parameter values
|
|
257
|
-
hmg_pub_year: Final = 2023
|
|
258
|
-
|
|
259
|
-
test_regime: UPPTestRegime = UPPTestRegime(
|
|
260
|
-
INVResolution.ENFT, UPPAggrSelector.MIN, UPPAggrSelector.MIN
|
|
261
|
-
)
|
|
262
|
-
|
|
263
|
-
r_bar = getattr(
|
|
264
|
-
gbl.GuidelinesThresholds(hmg_pub_year),
|
|
265
|
-
"presumption" if test_regime.resolution == INVResolution.ENFT else "safeharbor",
|
|
266
|
-
).rec
|
|
267
|
-
|
|
268
|
-
sample_sz = 10**7
|
|
269
|
-
|
|
270
|
-
market_sample_spec = MarketSampleSpec(
|
|
271
|
-
sample_sz,
|
|
272
|
-
r_bar,
|
|
273
|
-
share_spec=ShareSpec(
|
|
274
|
-
RECConstants.INOUT, SHRConstants.UNI, DIST_PARMS_DEFAULT, None
|
|
275
|
-
),
|
|
276
|
-
)
|
|
277
|
-
|
|
278
|
-
save_data_to_file_flag = True
|
|
279
|
-
if save_data_to_file_flag:
|
|
280
|
-
h5_path = DATA_DIR / PROG_PATH.with_suffix(".h5").name
|
|
281
|
-
(_, h5_file, h5_group), h5_subgroup_name = utl.initialize_hd5( # type: ignore
|
|
282
|
-
h5_path, hmg_pub_year, test_regime
|
|
283
|
-
)
|
|
284
|
-
|
|
285
|
-
h5_subgroup = h5_file.create_group(
|
|
286
|
-
h5_group,
|
|
287
|
-
h5_subgroup_name,
|
|
288
|
-
title=f"Market sample specifications: {market_sample_spec}",
|
|
289
|
-
)
|
|
290
|
-
save_data_to_file: utl.SaveData = (True, h5_file, h5_subgroup)
|
|
291
|
-
else:
|
|
292
|
-
save_data_to_file = False
|
|
293
|
-
|
|
294
|
-
_main(hmg_pub_year, market_sample_spec, test_regime, save_data_to_file)
|
|
295
|
-
|
|
296
|
-
if save_data_to_file_flag:
|
|
297
|
-
save_data_to_file[1].flush() # type: ignore
|
|
298
|
-
save_data_to_file[1].close() # type: ignore
|
|
File without changes
|