Metadata-Version: 2.1
Name: acquisitionuniverse
Version: 1.0.0
Summary: Toolkit for acquisition target screening: write a thesis brief, rank screened companies with a weighted composite that zeroes out group-owned targets, and measure signal coverage across the 15 common signals.
Home-page: https://www.acquisitionuniverse.com
Author: Alpha Quantum
Author-email: info@alpha-quantum.com
License: MIT
Project-URL: Homepage, https://www.acquisitionuniverse.com
Project-URL: Documentation, https://www.acquisitionuniverse.com/method.php
Project-URL: Source, https://github.com/explainableaixai/acquisitionuniverse
Project-URL: Mirror, https://gitlab.com/url-classifications/acquisitionuniverse
Project-URL: Tracker, https://www.acquisitionuniverse.com/contact.php
Project-URL: Pilot, https://www.acquisitionuniverse.com/free-pilot.php
Keywords: acquisition target,target screening,m&a,search fund,private equity,deal sourcing,thesis,add-on acquisition,buy-side,independent sponsor,corporate development,long list
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Office/Business :: Financial
Requires-Python: >=3.7
Description-Content-Type: text/markdown

# acquisitionuniverse (Python)

Utilities for search funds, independent sponsors and corporate development teams who work from screened company lists. Score records, rank them, measure evidence gaps and generate a clean thesis brief.

Pure Python, standard library only, offline.

```bash
pip install acquisitionuniverse
```

## Where it fits

A full-web screen hands you a long ranked file. Before you call anyone you want to answer three questions: what exactly did we ask for, which companies come first, and how much is the file really telling us?

This package answers those with small functions that work on dictionaries and DataFrame rows alike. The method behind the screens is described on the [search fund target lists](https://www.acquisitionuniverse.com/use-cases/search-fund-target-lists.php) page.

## 1. Write the brief

```python
from acquisitionuniverse import ThesisBrief

brief = ThesisBrief(
    name="Calibration labs, Midwest",
    vertical="Calibration and metrology",
    regions=["Ohio", "Michigan", "Indiana"],
    employees_min=8,
    employees_max=60,
    must_have=["ISO/IEC 17025 accreditation"],
    exclusions=["group-owned", "single-person shops"],
)

assert brief.validate() == []
print(brief.to_text())
```

`to_json()` gives the same content as a string for a ticket or a shared drive.

## 2. Rank the file

```python
from acquisitionuniverse import rank

companies = [
    {"id": "C-01", "mandate_fit": 92, "outreach_suitability": 75, "transition_context": 60},
    {"id": "C-02", "mandate_fit": 97, "outreach_suitability": 90, "transition_context": 80, "group_owned": True},
    {"id": "C-03", "mandate_fit": 84, "outreach_suitability": 88, "transition_context": 40},
]

for c in rank(companies):
    print(c["id"], c["composite"])
```

C-02 has the best fit but belongs to a group, so its outreach component is zero and it falls behind C-01. That ordering is the point: you should call the independent first.

Custom weights:

```python
rank(companies, weights={"mandate_fit": 0.6, "outreach_suitability": 0.3, "transition_context": 0.1})
```

## 3. Count the evidence

```python
from acquisitionuniverse import SIGNALS, signal_coverage

record = {SIGNALS[0]: "founder led", SIGNALS[3]: "service company", SIGNALS[10]: None}
print(signal_coverage(record))   # {'visible': 2, 'checked': 3, 'ratio': 0.666...}
```

A value of `None` or the string `"not visible"` counts as silent. You see at a glance whether a high score rests on much evidence or little.

## With pandas

```python
import pandas as pd
from acquisitionuniverse import composite

df = pd.read_csv("screen.csv")
df["composite"] = df.apply(
    lambda r: composite({
        "mandate_fit": r.mandate_fit,
        "outreach_suitability": r.outreach_suitability,
        "transition_context": r.transition_context,
        "group_owned": r.group_owned == "yes",
    }),
    axis=1,
)
df.sort_values("composite", ascending=False).head(25).to_csv("call_list.csv", index=False)
```

## Reference

| Name | Kind | Notes |
|---|---|---|
| `ThesisBrief` | dataclass | `validate`, `to_dict`, `to_json`, `to_text` |
| `composite(company, weights=None)` | function | 0 to 100, one decimal |
| `rank(companies, weights=None)` | function | returns copies with `composite` |
| `signal_coverage(map)` | function | visible, checked, ratio |
| `SIGNALS` | tuple | 15 names |
| `DEFAULT_WEIGHTS` | dict | 0.7, 0.2, 0.1 |
| `PILOT_URL` | str | pilot request page |

## Related products

Alpha Quantum also publishes an [audience segmentation API](https://www.cookielessaudiences.com/api.php) for advertisers and a [CV parser](https://www.resumereaderapi.com/api-v2.php) for hiring teams. Neither is needed here.

## Questions

**Is a database included?** No. Bring your own screened records.

**Why dictionaries?** They match JSON, CSV rows and pandas without a conversion step.

**Python versions?** 3.7 and up. MIT license. info@alpha-quantum.com


