History: short company names
Browse files- app.py +12 -1
- tests/test_qt3_space.py +7 -0
app.py
CHANGED
|
@@ -130,6 +130,17 @@ async def orders():
|
|
| 130 |
_names: dict = {}
|
| 131 |
|
| 132 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 133 |
@app.get("/api/history")
|
| 134 |
async def get_history():
|
| 135 |
def load():
|
|
@@ -143,7 +154,7 @@ async def get_history():
|
|
| 143 |
missing = sorted(s for s in syms if s not in _names and not rk.get(s))
|
| 144 |
if missing: # company names from Alpaca, once per symbol
|
| 145 |
try:
|
| 146 |
-
_names.update({s: v.get("name") for s, v in a.assets(missing).items()})
|
| 147 |
except BrokerError:
|
| 148 |
pass
|
| 149 |
return history.build(orders, pos, flows, {s: rk.get(s) or _names.get(s) for s in syms})
|
|
|
|
| 130 |
_names: dict = {}
|
| 131 |
|
| 132 |
|
| 133 |
+
def _short_name(n: str | None) -> str | None:
|
| 134 |
+
"""Alpaca's listing name without the share-class tail ("Micron Technology, Inc. Common Stock" → "Micron Technology, Inc.")."""
|
| 135 |
+
if not n:
|
| 136 |
+
return n
|
| 137 |
+
for tail in (" Common Stock", " Class A", " Class B", " Class C", " Ordinary Shares", " American Depositary", " Common Shares"):
|
| 138 |
+
i = n.find(tail)
|
| 139 |
+
if i > 0:
|
| 140 |
+
n = n[:i]
|
| 141 |
+
return n.strip()
|
| 142 |
+
|
| 143 |
+
|
| 144 |
@app.get("/api/history")
|
| 145 |
async def get_history():
|
| 146 |
def load():
|
|
|
|
| 154 |
missing = sorted(s for s in syms if s not in _names and not rk.get(s))
|
| 155 |
if missing: # company names from Alpaca, once per symbol
|
| 156 |
try:
|
| 157 |
+
_names.update({s: _short_name(v.get("name")) for s, v in a.assets(missing).items()})
|
| 158 |
except BrokerError:
|
| 159 |
pass
|
| 160 |
return history.build(orders, pos, flows, {s: rk.get(s) or _names.get(s) for s in syms})
|
tests/test_qt3_space.py
CHANGED
|
@@ -328,3 +328,10 @@ def test_history_replays_rebalances_from_orders():
|
|
| 328 |
assert op["A"]["return"] == pytest.approx(120 / 105 - 1) and op["B"]["return"] == pytest.approx(93 / 100 - 1)
|
| 329 |
s = h["summary"]
|
| 330 |
assert s["rebalances"] == 2 and s["swaps_per_rebalance"] == 1 and s["closed"] == 1 and s["win_rate"] == 1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 328 |
assert op["A"]["return"] == pytest.approx(120 / 105 - 1) and op["B"]["return"] == pytest.approx(93 / 100 - 1)
|
| 329 |
s = h["summary"]
|
| 330 |
assert s["rebalances"] == 2 and s["swaps_per_rebalance"] == 1 and s["closed"] == 1 and s["win_rate"] == 1
|
| 331 |
+
|
| 332 |
+
|
| 333 |
+
def test_short_company_names():
|
| 334 |
+
import app as space
|
| 335 |
+
assert space._short_name("Micron Technology, Inc. Common Stock") == "Micron Technology, Inc."
|
| 336 |
+
assert space._short_name("Alphabet Inc. Class A Common Stock") == "Alphabet Inc."
|
| 337 |
+
assert space._short_name("HF Sinclair Corporation") == "HF Sinclair Corporation" and space._short_name(None) is None
|