Compare commits
10 Commits
6f6d6b8047
...
9263283995
| Author | SHA1 | Date | |
|---|---|---|---|
| 9263283995 | |||
| 6536c9903e | |||
| 02aa750a06 | |||
| 2bbe4e58ec | |||
| d2ff607c79 | |||
| e28f8fcf85 | |||
| 3fbf332b31 | |||
| 328855a926 | |||
| 89674c24dd | |||
| 9f666538c3 |
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -9,3 +9,4 @@ fundlab/nport_cache/raw/
|
|||
fundlab/universe_cache/
|
||||
fundlab/xcheck_run.log
|
||||
fundlab/streamlit.log
|
||||
reports/report_data_adhoc.json
|
||||
|
|
|
|||
251
app.py
251
app.py
|
|
@ -403,6 +403,17 @@ def rng(s):
|
|||
"""Clip a price/return series (or frame) to the display range."""
|
||||
return s[(s.index >= lo) & (s.index <= hi)]
|
||||
|
||||
# standalone symbols in the Symbol box (not portfolio components) get a
|
||||
# full per-fund report, built on demand - point the user at it
|
||||
_standalone = [s for w in items if len(w) == 1 for s in w]
|
||||
if _standalone:
|
||||
st.info(
|
||||
f"Full report(s) generated for: "
|
||||
f"{', '.join(s.upper() for s in _standalone)} — see the "
|
||||
f"**Fund Lab** tab, top of the Summary section. (Only symbols "
|
||||
f"that stand alone in the Symbol box get a report; portfolio "
|
||||
f"components do not.)")
|
||||
|
||||
tab_stats, tab_equity, tab_alloc, tab_tax, tab_corr, tab_fundlab = st.tabs(
|
||||
["Statistics", "Equity curves", "Allocation", "Tax detail",
|
||||
"Correlation", "Fund Lab"])
|
||||
|
|
@ -576,6 +587,110 @@ with tab_corr:
|
|||
|
||||
# ---------------------------------------------------------------- fund lab
|
||||
# per-fund report mockup from N-PORT schedules of investments (fundlab)
|
||||
|
||||
def render_fund_report(_f: dict) -> None:
|
||||
"""Render one per-fund report entry (narrative, re-basing equity
|
||||
chart, period table, drivers, reference mix, tax, cluster peers).
|
||||
Used by the Summary section for both the pre-built 24 and the
|
||||
on-demand reports generated for standalone Symbol-box funds."""
|
||||
_m, _st = _f["meta"], _f.get("stats", {})
|
||||
_grp = {"candidate": "C", "shortlist": "S"}.get(_m["group"], "A")
|
||||
# ad-hoc entries carry negative sort orders (they sort first) - show
|
||||
# the absolute number; and skip the name when it just repeats the
|
||||
# ticker (ETFs have no fund name on file)
|
||||
_num = abs(int(_m["order"]))
|
||||
_nm = _m["name"] if _m["name"].upper() != _m["sym"].upper() else None
|
||||
_title = (f"{_grp}{_num:02d} · {_m['sym'].upper()}"
|
||||
+ (f" — {_nm}" if _nm else ""))
|
||||
if _m.get("verdict"):
|
||||
_title += f" [{_m['verdict'][:44]}]"
|
||||
with st.expander(_title):
|
||||
if _f.get("narrative"):
|
||||
st.markdown("\n\n".join(_f["narrative"]))
|
||||
# same re-basing-on-zoom widget as the Equity curves tab: every
|
||||
# visible window re-bases each line to 1.0 at its left edge, so
|
||||
# fund/reference/index are comparable no matter where you zoom
|
||||
_c = _f.get("chart", {})
|
||||
if _c.get("dates"):
|
||||
from chart_widget import equity_chart_html
|
||||
_ds = pd.to_datetime(_c["dates"])
|
||||
_series = {_m["sym"].upper(): pd.Series(_c["fund"], _ds)}
|
||||
if _c.get("ref"):
|
||||
_series["fitted reference"] = pd.Series(
|
||||
_c["ref"], pd.to_datetime(_c["ref_dates"]))
|
||||
if _c.get("ivv"):
|
||||
_series["S&P 500 (IVV)"] = pd.Series(
|
||||
_c["ivv"], pd.to_datetime(_c["ivv_dates"]))
|
||||
st.iframe(equity_chart_html(
|
||||
{k: s / s.iloc[0] for k, s in _series.items()},
|
||||
_ds, height=460, ytitle="growth (1.0 = start)",
|
||||
styles={
|
||||
_m["sym"].upper(): {"width": 2},
|
||||
"fitted reference": {"width": 1, "dash": "dash",
|
||||
"opacity": 0.8},
|
||||
"S&P 500 (IVV)": {"width": 1, "dash": "dot",
|
||||
"opacity": 0.5},
|
||||
}), height=490)
|
||||
if _f.get("perf"):
|
||||
st.dataframe(pd.DataFrame(
|
||||
_f["perf"],
|
||||
columns=["period", "fund", "reference",
|
||||
"S&P 500", "fund − reference"]),
|
||||
width="stretch", hide_index=True)
|
||||
st.caption(
|
||||
"fund − reference = period alpha/timing (the part of "
|
||||
"that period the fitted mix does not explain). For "
|
||||
"cash-anchored funds the reference is the T-bill rate "
|
||||
"itself.")
|
||||
if _f.get("drivers"):
|
||||
st.markdown("\n\n".join(_f["drivers"]))
|
||||
_sty = _f.get("style")
|
||||
if _sty and _sty.get("full"):
|
||||
_f5 = {x["sym"]: x for x in _sty.get("rec5", {}).get("factors", [])}
|
||||
_srows = []
|
||||
for x in _sty["full"]["factors"]:
|
||||
y5 = _f5.get(x["sym"], {})
|
||||
if abs(x["t"]) < 2 and abs(y5.get("t", 0) or 0) < 2:
|
||||
continue
|
||||
_srows.append([
|
||||
x["name"], f"{x['beta']:+.2f}", f"{x['t']:+.1f}",
|
||||
(f"{y5['beta']:+.2f}" if y5 else "—"),
|
||||
(f"{y5['t']:+.1f}" if y5 else "—"),
|
||||
"✓" if x["sym"] in _sty.get("identified", []) else ""])
|
||||
st.markdown("**Style tilts** (22 style/asset sleeves regressed "
|
||||
"on the fund's excess returns; US funds proxy the "
|
||||
"global factors; 'identified' = survived the BIC "
|
||||
"forward-selection gate on the full history)")
|
||||
st.dataframe(pd.DataFrame(
|
||||
_srows,
|
||||
columns=["factor", "β full", "t full", "β 5y", "t 5y",
|
||||
"identified"]),
|
||||
width="stretch", hide_index=True)
|
||||
st.markdown("\n\n".join(_sty.get("commentary", [])))
|
||||
_ref = _f.get("reference")
|
||||
if _ref and _ref.get("rows"):
|
||||
st.markdown(f"**Reference mix** ({_ref['netcash']})")
|
||||
st.dataframe(pd.DataFrame(
|
||||
_ref["rows"],
|
||||
columns=["loading", "what it is",
|
||||
"what it exposes you to"]),
|
||||
width="stretch", hide_index=True)
|
||||
st.caption(_ref["text"])
|
||||
if _f.get("tax"):
|
||||
st.markdown(f"**Tax** — {_f['tax']}")
|
||||
_pe = _f.get("peers")
|
||||
if _pe and _pe.get("rows"):
|
||||
st.markdown(
|
||||
f"**Peers — cluster: {_pe['cluster']}** "
|
||||
f"(n={_pe['n']})")
|
||||
st.dataframe(pd.DataFrame(
|
||||
_pe["rows"],
|
||||
columns=["fund", "5y", "CAGR", "maxDD",
|
||||
"R² 5y", "alpha 5y", "tax"]),
|
||||
width="stretch", hide_index=True)
|
||||
st.caption(_pe["proscons"])
|
||||
|
||||
|
||||
with tab_fundlab:
|
||||
try:
|
||||
_FUNDS = json.loads((Path(__file__).parent / "funds.json").read_text())
|
||||
|
|
@ -595,25 +710,74 @@ with tab_fundlab:
|
|||
_DR = json.loads(_dc.RESULTS.read_text())
|
||||
except Exception:
|
||||
_DR = {}
|
||||
with st.expander(f"Summary — all {len(_FL_LABELS)} funds"):
|
||||
_sum_rows = []
|
||||
for _s in _ORDER:
|
||||
_d = _DR.get(_s, {})
|
||||
_rec = _d.get("recent", {})
|
||||
_comp = ", ".join(f"{c['sym']} {c['beta']:+.2f}"
|
||||
for c in _rec.get("components", [])[:4]) or \
|
||||
", ".join(f"{c['sym']} {c['beta']:+.2f}"
|
||||
for c in _d.get("components", [])[:4])
|
||||
_sum_rows.append({
|
||||
"fund": _FL_LABELS.get(_s, _s),
|
||||
"verdict": _d.get("verdict", "n/a"),
|
||||
"R² 5y": round(_rec["r2"], 3) if "r2" in _rec else None,
|
||||
"alpha 5y": (f"{_rec['alpha_ann']*100:+.1f}% "
|
||||
f"(t={_rec['alpha_t']:+.1f})")
|
||||
if "alpha_ann" in _rec else None,
|
||||
"components": _comp or "—",
|
||||
# --- per-fund report: narrative + performance + drivers + peers ----
|
||||
# static build (fundlab.reportdata) so the page stays fast
|
||||
_RD = Path(__file__).parent / "reports" / "report_data.json"
|
||||
if not _RD.exists():
|
||||
with st.expander("Summary - per-fund reports (not built yet)"):
|
||||
st.info("Run `.venv/bin/python -m fundlab.reportdata` in the "
|
||||
"project root, then refresh.")
|
||||
else:
|
||||
try:
|
||||
_rd = json.loads(_RD.read_text())
|
||||
_rfunds = _rd["funds"]
|
||||
except Exception as _e: # noqa: BLE001
|
||||
st.warning(f"report data unreadable: {_e}")
|
||||
_rfunds = {}
|
||||
# on-demand reports: a symbol that stands ALONE in the Symbol box
|
||||
# (not a component of a comma-joined portfolio) gets a full
|
||||
# report, so any fund can be examined; results are cached on
|
||||
# disk (reports/report_data_adhoc.json) so re-loading is instant
|
||||
from fundlab import reportdata as _rdata
|
||||
_standalone = [s for w in items if len(w) == 1 for s in w]
|
||||
_new = [s for s in _standalone if s not in _rfunds]
|
||||
if _new:
|
||||
with st.spinner(
|
||||
f"Building report(s) for {', '.join(s.upper() for s in _new)}"
|
||||
" (first time for a fresh server: up to ~1 min for the "
|
||||
"driver panel; cached afterwards)"):
|
||||
_built = _rdata.ensure_adhoc(_new)
|
||||
_rfunds = {**_built, **_rfunds} # ad-hoc entries first
|
||||
for _i, (_s, _f) in enumerate(_built.items(), 1):
|
||||
_f["meta"]["order"] = -_i # ad-hoc block sorts first
|
||||
_rorder = sorted(_rfunds,
|
||||
key=lambda s: _rfunds[s]["meta"]["order"])
|
||||
if _rfunds:
|
||||
st.subheader(f"Summary - per-fund reports "
|
||||
f"({len(_rfunds)} funds)")
|
||||
st.caption(
|
||||
f"Generated {_rd['generated']}. Each fund: a narrative "
|
||||
"discussion first (the performance, what drives it, and "
|
||||
"what we do NOT know), then the equity curve, the period "
|
||||
"table (fund vs fitted reference vs S&P 500, with the "
|
||||
"fund-minus-reference gap), the return drivers, the "
|
||||
"reference mix explained sleeve by sleeve, tax placement, "
|
||||
"and the best peers from the same return-driver cluster. "
|
||||
"All alphas are in excess of the 3-mo T-bill rate.")
|
||||
_ag = []
|
||||
for _s in _rorder:
|
||||
_f = _rfunds[_s]
|
||||
_m, _st = _f["meta"], _f.get("stats", {})
|
||||
_ag.append({
|
||||
"fund": (f"{_m['sym'].upper()}"
|
||||
if _m["name"].upper() == _m["sym"].upper()
|
||||
else f"{_m['sym'].upper()} — {_m['name'][:44]}"),
|
||||
"group": _m["group"],
|
||||
"5y": _st.get("t5y", "—"),
|
||||
"CAGR": _st.get("cagr", "—"),
|
||||
"maxDD": _st.get("mdd", "—"),
|
||||
"R² 5y": _st.get("r2_5y", "—"),
|
||||
"alpha 5y": _st.get("alpha_5y", "—"),
|
||||
"cluster": (_f.get("peers") or {}).get("cluster", ""),
|
||||
})
|
||||
st.dataframe(pd.DataFrame(_sum_rows), width="stretch")
|
||||
st.dataframe(pd.DataFrame(_ag), width="stretch",
|
||||
hide_index=True)
|
||||
for _s in _rorder:
|
||||
render_fund_report(_rfunds[_s])
|
||||
st.caption("← the rest of the Fund Lab continues below: "
|
||||
"alpha search, return-driver clusters, N-PORT "
|
||||
"cross-check, drawdown resilience, tax location, "
|
||||
"and the CEF ranking.")
|
||||
|
||||
# --- alpha search: all screened funds (shortlist + longlist + harvest)
|
||||
with st.expander("Alpha search — all screened funds, ranked"):
|
||||
|
|
@ -660,6 +824,7 @@ with tab_fundlab:
|
|||
else "—"),
|
||||
"alpha 5y": (f"{_a5*100:+.1f}% (t={_v['alpha_t_5y']:+.1f})"
|
||||
if isinstance(_a5, (int, float)) else "—"),
|
||||
"reference (5y)": _v.get("ref_5y") or "—",
|
||||
"corr port": (f"{_v['corr_portfolio']:.2f}"
|
||||
if isinstance(_v.get("corr_portfolio"),
|
||||
(int, float)) else "—"),
|
||||
|
|
@ -670,14 +835,18 @@ with tab_fundlab:
|
|||
})
|
||||
st.dataframe(pd.DataFrame(_tbl), width="stretch")
|
||||
st.caption(
|
||||
"Screen: daily total returns vs 21 broad sleeve axes (same "
|
||||
"set for every fund); 'alpha 5y' = OLS intercept over the "
|
||||
"last 5 years (t-stat); 'corr port' = correlation with your "
|
||||
"current qspnx/pmaix portfolio; '6m + %' = share of rolling "
|
||||
"6-month windows where the fund beat its fitted sleeve mix. "
|
||||
"CANDIDATE = R²5y < 0.6 (or < 0.85 with strong residual "
|
||||
"alpha), t5y ≥ 2, t-full ≥ 1.25, ≥ 45% positive windows, "
|
||||
"portfolio correlation < 0.3.")
|
||||
"Screen: daily total returns IN EXCESS OF THE 3-MO T-BILL "
|
||||
"RATE (BIL) vs 21 broad sleeve axes (same set for every "
|
||||
"fund); 'alpha 5y' = OLS intercept of the excess returns "
|
||||
"over the last 5 years (t-stat) — i.e. outperformance vs "
|
||||
"the fund's OWN fitted sleeve mix (the 'reference' column), "
|
||||
"not vs one index; a cash position earns exactly the t-bill "
|
||||
"rate and adds zero alpha. 'corr port' = correlation with "
|
||||
"your current qspnx/pmaix portfolio; '6m + %' = share of "
|
||||
"rolling 6-month windows where the fund beat its fitted "
|
||||
"sleeve mix. CANDIDATE = R²5y < 0.6 (or < 0.85 with strong "
|
||||
"residual alpha), t5y ≥ 2, t-full ≥ 1.25, ≥ 45% positive "
|
||||
"windows, portfolio correlation < 0.3.")
|
||||
|
||||
# --- return-driver clusters: k-means on 35-sleeve loading vectors ---
|
||||
with st.expander(
|
||||
|
|
@ -691,7 +860,11 @@ with tab_fundlab:
|
|||
_syms, _V = _cl.loading_matrix()
|
||||
_fr = json.loads((_dc.RESULTS.parent /
|
||||
"factor_results.json").read_text())
|
||||
_lab = _cl.kmeans(_V, _ck)
|
||||
# distance on the cash-emphasized matrix (a pure cash fund's
|
||||
# level axis is otherwise swallowed by the low-exposure cloud);
|
||||
# labels below use the raw _V values
|
||||
_lab = _cl.kmeans(_cl.emphasized(_V, _fac.AXES.index("cash")),
|
||||
_ck)
|
||||
_sumrows = []
|
||||
for c in range(_ck):
|
||||
idx = [i for i, l in enumerate(_lab) if l == c]
|
||||
|
|
@ -699,7 +872,7 @@ with tab_fundlab:
|
|||
continue
|
||||
med = _np.median(_V[idx], 0)
|
||||
top = _np.argsort(-_np.abs(med))[:4]
|
||||
prof = {_fac.DRIVERS[t]: float(med[t]) for t in top
|
||||
prof = {_fac.AXES[t]: float(med[t]) for t in top
|
||||
if abs(med[t]) >= 0.08}
|
||||
lab = _cl.label(prof)
|
||||
t5s = [_fr[_syms[i]].get("alpha_t_5y") for i in idx]
|
||||
|
|
@ -736,7 +909,7 @@ with tab_fundlab:
|
|||
continue
|
||||
med = _np.median(_V[idx], 0)
|
||||
top = _np.argsort(-_np.abs(med))[:4]
|
||||
prof = {_fac.DRIVERS[t]: float(med[t]) for t in top
|
||||
prof = {_fac.AXES[t]: float(med[t]) for t in top
|
||||
if abs(med[t]) >= 0.08}
|
||||
if _cl.label(prof) == _target:
|
||||
_members = [(i, idx[0]) for i in idx]
|
||||
|
|
@ -767,11 +940,14 @@ with tab_fundlab:
|
|||
r.pop("_t")
|
||||
st.dataframe(pd.DataFrame(_rows), width="stretch")
|
||||
st.caption(
|
||||
"Each fund's daily returns are regressed on 35 sleeve axes "
|
||||
"(equity styles/sizes/intl/EM, the duration ladder, IG/HY/"
|
||||
"muni/MBS/preferred/EM-debt credit, sectors, gold/oil/"
|
||||
"commodities, CTA); the 35-d loading vector is the fund's "
|
||||
"'return-driver signature' and k-means groups similar "
|
||||
"Each fund's daily total returns IN EXCESS OF THE 3-MO "
|
||||
"T-BILL RATE (BIL) are regressed on 34 sleeve axes (equity "
|
||||
"styles/sizes/intl/EM, the duration ladder, IG/HY/muni/MBS/"
|
||||
"preferred/EM-debt credit, sectors, gold/oil/commodities, "
|
||||
"CTA); the loading vector is the fund's 'return-driver "
|
||||
"signature' — the betas are its NET INVESTED mix — plus a "
|
||||
"virtual CASH axis = 1 − Σβ (net cash/T-bill position; 1 = "
|
||||
"fully in cash, < 0 = levered). k-means groups similar "
|
||||
"signatures. 'corr port' is shown for reference only - "
|
||||
"high-corr funds are REPLACEMENTS for current holdings, "
|
||||
"not rejections.")
|
||||
|
|
@ -1092,9 +1268,10 @@ with tab_fundlab:
|
|||
if _dr.get("note"):
|
||||
st.markdown("**Holdings cross-check:** " + _dr["note"])
|
||||
st.caption(
|
||||
"Method: daily total returns; greedy forward selection on BIC "
|
||||
"(add only if ΔBIC ≥ 2 and |t| > 2); candidate sleeves curated per "
|
||||
"fund from the strategy text + N-PORT. β = exposure, not a literal "
|
||||
"Method: daily total returns IN EXCESS OF THE 3-MO T-BILL RATE "
|
||||
"(BIL); greedy forward selection on BIC (add only if ΔBIC ≥ 2 and "
|
||||
"|t| > 2); candidate sleeves curated per fund from the strategy "
|
||||
"text + N-PORT. β = exposure, not a literal "
|
||||
"holding weight; 'drift' = mean |rolling 1y β − full β| relative to "
|
||||
"the full β. High-R² + low drift ≈ static mix; low R² with positive "
|
||||
"alpha ≈ market-neutral/alpha strategy.")
|
||||
|
|
|
|||
148
data.py
148
data.py
|
|
@ -28,6 +28,56 @@ import pandas as pd
|
|||
|
||||
DEFAULT_ROOT = Path("~/prog/fin/stocks").expanduser()
|
||||
CACHE_DIR = Path(__file__).parent / ".cache"
|
||||
# Frozen overrides: stale (Yahoo-empty) tickers whose final series is
|
||||
# snapshotted here by scripts/audit_stale.py. For symbols that have a
|
||||
# frozen copy, the data-root files are ignored so a future goget
|
||||
# re-download can never clobber the last known-good series.
|
||||
FROZEN_DIR = Path(__file__).parent / "overrides" / "frozen"
|
||||
# Corrections: per-symbol distribution fixes confirmed against official
|
||||
# sources (see scripts/verify_official.py). Applied on top of whatever the
|
||||
# data root / frozen dir says, so re-downloads can never clobber them.
|
||||
# Format, one file per symbol in overrides/corrections/:
|
||||
# {"dividends": {"remove": [["2008-12-18", 0.292], ...],
|
||||
# "replace": {"2008-12-18": 0.0},
|
||||
# "add": [["2007-12-18", 0.292], ...]},
|
||||
# "capitalGains": {...same ops...},
|
||||
# "as_of": "2026-08-31", "source": "<filing URL>", "note": "..."}
|
||||
CORRECTIONS_DIR = Path(__file__).parent / "overrides" / "corrections"
|
||||
_corr_cache: dict = {}
|
||||
|
||||
|
||||
def _load_corrections(sym: str) -> dict:
|
||||
f = CORRECTIONS_DIR / f"{sym.upper()}.json"
|
||||
if f.exists():
|
||||
try:
|
||||
if f not in _corr_cache or _corr_cache[f][0] != f.stat().st_mtime_ns:
|
||||
_corr_cache[f] = (f.stat().st_mtime_ns,
|
||||
json.loads(f.read_text()))
|
||||
return _corr_cache[f][1]
|
||||
except Exception:
|
||||
return {}
|
||||
return {}
|
||||
|
||||
|
||||
def _apply_corrections(sym: str, suffix: str, ser: pd.Series) -> pd.Series:
|
||||
key = {"dividend": "dividends", "capitalGain": "capitalGains"}.get(suffix)
|
||||
ops = _load_corrections(sym).get(key) if key else None
|
||||
if not ops:
|
||||
return ser
|
||||
d = {ts: float(v) for ts, v in ser.items()}
|
||||
for r in ops.get("remove", []):
|
||||
ts = pd.Timestamp(r[0])
|
||||
amt = r[1] if len(r) > 1 else None
|
||||
if ts in d and (amt is None or abs(d[ts] - amt) < 1e-9):
|
||||
del d[ts]
|
||||
for ts_s, amt in ops.get("replace", {}).items():
|
||||
d[pd.Timestamp(ts_s)] = float(amt)
|
||||
for r in ops.get("add", []):
|
||||
ts = pd.Timestamp(r[0])
|
||||
d[ts] = d.get(ts, 0.0) + float(r[1])
|
||||
if not d:
|
||||
return pd.Series(dtype=float)
|
||||
return pd.Series(d).sort_index()
|
||||
|
||||
_SUFFIXES = ("history", "dividend", "capitalGain")
|
||||
_PANELS = ("adj", "close", "div", "capg")
|
||||
|
|
@ -50,16 +100,37 @@ def _read_csv_clean(f: Path) -> pd.DataFrame:
|
|||
return df
|
||||
|
||||
|
||||
def frozen_syms() -> set:
|
||||
"""Symbols with a frozen history copy in the overrides dir."""
|
||||
if not FROZEN_DIR.is_dir():
|
||||
return set()
|
||||
return {f.stem[: -len("-history")] for f in FROZEN_DIR.glob("*-history.csv")}
|
||||
|
||||
|
||||
def _panel_paths(root: Path, suffix: str) -> list[tuple[str, Path]]:
|
||||
"""(symbol, path) for every panel file; frozen copies shadow data-root."""
|
||||
frozen = frozen_syms()
|
||||
out = []
|
||||
for f in sorted(root.glob(f"*-{suffix}.csv")):
|
||||
sym = f.name[: -len(f"-{suffix}.csv")]
|
||||
if sym in frozen:
|
||||
continue
|
||||
out.append((sym, f))
|
||||
for f in sorted(FROZEN_DIR.glob(f"*-{suffix}.csv")) if FROZEN_DIR.is_dir() else []:
|
||||
out.append((f.name[: -len(f"-{suffix}.csv")], f))
|
||||
return out
|
||||
|
||||
|
||||
def _read_panel(root: Path, suffix: str, col: str) -> pd.DataFrame:
|
||||
cols, syms = [], []
|
||||
for f in sorted(root.glob(f"*-{suffix}.csv")):
|
||||
for sym, f in _panel_paths(root, suffix):
|
||||
try:
|
||||
df = _read_csv_clean(f)
|
||||
except Exception:
|
||||
continue
|
||||
if col in df.columns:
|
||||
cols.append(df[col])
|
||||
syms.append(f.name[: -len(f"-{suffix}.csv")])
|
||||
cols.append(_apply_corrections(sym, suffix, df[col]))
|
||||
syms.append(sym)
|
||||
if not cols:
|
||||
return pd.DataFrame()
|
||||
out = pd.concat(cols, axis=1)
|
||||
|
|
@ -96,13 +167,26 @@ REFRESH_CADENCE = 30.0 # min seconds between actual cache rebuilds
|
|||
_watchers: dict[tuple, threading.Thread] = {}
|
||||
_gen: dict[tuple, int] = {} # (root, cache) -> bundle generation counter
|
||||
def _scan_files(root: Path) -> dict:
|
||||
"""{filename: (mtime_ns, size)} for every csv/json file in the data root."""
|
||||
"""{filename: (mtime_ns, size)} for every csv/json file in the data root
|
||||
plus the frozen overrides (namespaced under 'frozen/')."""
|
||||
out = {}
|
||||
with os.scandir(root) as it:
|
||||
for e in it:
|
||||
if e.is_file() and e.name.endswith((".csv", ".json")):
|
||||
st = e.stat()
|
||||
out[e.name] = (st.st_mtime_ns, st.st_size)
|
||||
if FROZEN_DIR.is_dir():
|
||||
with os.scandir(FROZEN_DIR) as it:
|
||||
for e in it:
|
||||
if e.is_file() and e.name.endswith((".csv", ".json")):
|
||||
st = e.stat()
|
||||
out["frozen/" + e.name] = (st.st_mtime_ns, st.st_size)
|
||||
if CORRECTIONS_DIR.is_dir():
|
||||
with os.scandir(CORRECTIONS_DIR) as it:
|
||||
for e in it:
|
||||
if e.is_file() and e.name.endswith(".json"):
|
||||
st = e.stat()
|
||||
out["corrections/" + e.name] = (st.st_mtime_ns, st.st_size)
|
||||
return out
|
||||
|
||||
|
||||
|
|
@ -154,14 +238,53 @@ def _apply_changes(root: Path, cache: Path, old: dict, new: dict) -> None:
|
|||
return sfx, fname[: -len(f"-{sfx}.csv")]
|
||||
return None, None
|
||||
|
||||
def _path(fname: str) -> Path:
|
||||
# frozen/ namespaced files live in the overrides dir
|
||||
return FROZEN_DIR / fname[8:] if fname.startswith("frozen/") else root / fname
|
||||
|
||||
updates: dict[str, dict] = {k: {} for k in _PANELS} # panel -> {sym: series}
|
||||
drops: set[str] = set()
|
||||
# data-root files of frozen symbols are ignored: their canonical series
|
||||
# lives in the overrides dir, which is tracked in the same scan
|
||||
frozen = frozen_syms()
|
||||
|
||||
def _recompute_corrected(symfile: str) -> None:
|
||||
"""corrections/{SYM}.json changed: re-derive the symbol's
|
||||
dividend/capital-gain series from the base file + corrections."""
|
||||
for sfx, colname, key in (("dividend", "Dividends", "div"),
|
||||
("capitalGain", "Capital Gains", "capg")):
|
||||
sym = None
|
||||
p = None
|
||||
for case in (symfile[:-5].lower(), symfile[:-5].upper()):
|
||||
for base in (FROZEN_DIR, root):
|
||||
q = base / f"{case}-{sfx}.csv"
|
||||
if q.exists():
|
||||
sym, p = case, q
|
||||
break
|
||||
if sym:
|
||||
break
|
||||
if p is None:
|
||||
continue
|
||||
try:
|
||||
df = _read_csv_clean(p)
|
||||
except Exception:
|
||||
continue
|
||||
if colname not in df.columns:
|
||||
continue
|
||||
updates[key][sym] = _apply_corrections(sym, sfx, df[colname]) \
|
||||
.fillna(0.0)
|
||||
|
||||
for fname in changed:
|
||||
if fname.startswith("corrections/"):
|
||||
_recompute_corrected(fname[12:])
|
||||
continue
|
||||
sfx, sym = _suffix(fname)
|
||||
if sfx is None:
|
||||
continue
|
||||
if not fname.startswith("frozen/") and sym in frozen:
|
||||
continue
|
||||
try:
|
||||
df = _read_csv_clean(root / fname)
|
||||
df = _read_csv_clean(_path(fname))
|
||||
except Exception:
|
||||
continue # e.g. a file mid-download
|
||||
if sfx == "history":
|
||||
|
|
@ -170,11 +293,22 @@ def _apply_changes(root: Path, cache: Path, old: dict, new: dict) -> None:
|
|||
if "Close" in df.columns:
|
||||
updates["close"][sym] = df["Close"]
|
||||
elif sfx == "dividend" and "Dividends" in df.columns:
|
||||
updates["div"][sym] = df["Dividends"].fillna(0.0)
|
||||
updates["div"][sym] = _apply_corrections(sym, sfx, df["Dividends"]) \
|
||||
.fillna(0.0)
|
||||
elif sfx == "capitalGain" and "Capital Gains" in df.columns:
|
||||
updates["capg"][sym] = df["Capital Gains"].fillna(0.0)
|
||||
updates["capg"][sym] = _apply_corrections(sym, sfx, df["Capital Gains"]) \
|
||||
.fillna(0.0)
|
||||
for fname in removed:
|
||||
sfx, sym = _suffix(fname)
|
||||
if fname.startswith("corrections/"):
|
||||
_recompute_corrected(fname[12:])
|
||||
continue
|
||||
if fname.startswith("frozen/"):
|
||||
continue # frozen files are not data-root symbols
|
||||
if sym in frozen:
|
||||
continue # data-root file of a frozen symbol vanished; the
|
||||
# frozen copy remains authoritative
|
||||
sfx, sym = _suffix(fname)
|
||||
if sfx is not None:
|
||||
drops.add(sym)
|
||||
|
||||
|
|
|
|||
|
|
@ -933,3 +933,253 @@ the overnight screen and had exited with it.
|
|||
|
||||
**App:** Fund Lab tab shows the CEF shortlist table (character
|
||||
actual-vs-model flag, discount, 5y, vol, scenarios, tenders, score).
|
||||
|
||||
### CASH axis: money-market / cash-equivalent funds as a driver
|
||||
|
||||
**Problem:** money-market and ultra-short funds fell into the "no
|
||||
dominant driver" cluster. There WAS a cash sleeve (shv; bil was dropped
|
||||
from the regression for shv/bil collinearity), but cash funds still
|
||||
didn't load on it: a fund's yield is a near-CONSTANT in return space,
|
||||
so OLS puts it in the INTERCEPT (alpha_ann), not in any beta. shv/bil
|
||||
betas only measure the response to rate CHANGES — tiny for cash-like
|
||||
funds. Evidence: qcmmrx (Money Market Account) had shv 0.13, bil 0.12,
|
||||
R² 0.08, but alpha_ann 1.91%/yr = the average cash level over its
|
||||
history.
|
||||
|
||||
**Benchmark:** the canonical cash benchmark is the 13-week T-bill /
|
||||
0-3m Treasury index (SIXM). Local stand-ins: shv/sgov/bil/gbil
|
||||
total-return (Adj Close), trailing 1y ≈ 3.7% in the current regime.
|
||||
|
||||
**Fix (factors.py + cluster.py + app.py):**
|
||||
- `factors.cash_yield()`: shv trailing-1y total return (fallback sgov,
|
||||
bil) — the normalizer.
|
||||
- `factors.AXES = DRIVERS + ["cash"]`: a VIRTUAL cash axis per fund =
|
||||
alpha_ann / cash_yield (1.0 = "earns the cash rate"), from the full
|
||||
window (rec5 fallback when the row falls back to rec5). It is a
|
||||
clustering/display axis, NOT a regressor (the level is already in
|
||||
the intercept; regressing on a constant is collinear by design).
|
||||
- `cluster.loading_matrix()` appends the cash column (winsorized ±4
|
||||
like the betas). SLEEVE_NAME["cash"] = "cash (yield)".
|
||||
- `cluster.emphasized(V)`: the cash axis is a LEVEL, not a sensitivity
|
||||
— in raw Euclidean space a pure cash fund (0,...,0,~0.5) sits inside
|
||||
the low-exposure balanced/target-date cloud and k-means swallows it.
|
||||
K-means (app + run_kmeans) runs on the cash-2x-emphasized matrix;
|
||||
LABELS still use the raw values. The hclust tree stays raw.
|
||||
- `cluster.label()`: cash-aware — the median cash in a mixed
|
||||
low-exposure cluster is diluted, so cash counts as the driver at
|
||||
>=0.25 (vs 0.30 for betas) and must be >=1.5x the runner-up.
|
||||
|
||||
**Result (k=30):** the grab-bag 331-fund "no dominant driver" cluster
|
||||
splits into "cash (yield) +0.64" (n=187: qcmmrx + the ultra-short
|
||||
government/bond funds), "cash (yield) +1.26" (n=59 pure), and the
|
||||
genuinely balanced remainder. 637 funds now have CASH as their
|
||||
dominant axis (>=0.30 and > every beta) — mostly the short-duration
|
||||
complex, which is correct: their return IS mostly the coupon level.
|
||||
|
||||
**Note:** the machine rebooted during this work (12:50) — it silently
|
||||
kills nohup'd processes (the CEF batch and the first watchdog both
|
||||
died that way; the batch was resumable so no data was lost).
|
||||
server_watchdog.sh had to be relaunched manually; consider a
|
||||
boot-time starter (systemd/cron @reboot) if reboots repeat.
|
||||
- 2026-08-30 15:09 === stage screen ===
|
||||
- 2026-08-30 15:09 screen: 2384 funds, 2384 to do
|
||||
- 2026-08-30 15:10 screen: 100/2384
|
||||
- 2026-08-30 15:11 screen: 200/2384
|
||||
- 2026-08-30 15:11 screen: 300/2384
|
||||
- 2026-08-30 15:12 screen: 400/2384
|
||||
- 2026-08-30 15:12 screen: 500/2384
|
||||
- 2026-08-30 15:13 screen: 600/2384
|
||||
- 2026-08-30 15:13 screen: 700/2384
|
||||
- 2026-08-30 15:14 screen: 800/2384
|
||||
- 2026-08-30 15:14 screen: 900/2384
|
||||
- 2026-08-30 15:15 screen: 1000/2384
|
||||
- 2026-08-30 15:15 screen: 1100/2384
|
||||
- 2026-08-30 15:16 screen: 1200/2384
|
||||
- 2026-08-30 15:17 screen: 1300/2384
|
||||
- 2026-08-30 15:17 screen: 1400/2384
|
||||
- 2026-08-30 15:18 screen: 1500/2384
|
||||
- 2026-08-30 15:18 screen: 1600/2384
|
||||
- 2026-08-30 15:19 screen: 1700/2384
|
||||
- 2026-08-30 15:19 screen: 1800/2384
|
||||
- 2026-08-30 15:20 screen: 1900/2384
|
||||
- 2026-08-30 15:20 screen: 2000/2384
|
||||
- 2026-08-30 15:21 screen: 2100/2384
|
||||
- 2026-08-30 15:21 screen: 2200/2384
|
||||
- 2026-08-30 15:22 screen: 2300/2384
|
||||
- 2026-08-30 15:22 screen done: 2384 funds
|
||||
- 2026-08-30 15:22 === stage finalize ===
|
||||
- 2026-08-30 15:22 finalize: 2384 funds screened
|
||||
- 2026-08-30 15:22 1339 sleeve mix
|
||||
- 2026-08-30 15:22 1001 weak/unstable alpha
|
||||
- 2026-08-30 15:22 17 no 5y window
|
||||
- 2026-08-30 15:22 11 CANDIDATE
|
||||
- 2026-08-30 15:22 10 alpha, but correlated with current portfolio
|
||||
- 2026-08-30 15:22 6 alpha in 5y window, but not persistent
|
||||
- 2026-08-30 15:22 candidates v1 name-filter would have missed: ['aguax', 'etsix', 'femdx', 'hicox', 'prfrx', 'puls', 'rctix', 'rpifx', 'scfzx']
|
||||
- 2026-08-30 15:22 === overnight run finished in 0.2h ===
|
||||
|
||||
### Alphas recomputed in EXCESS of the 3-mo T-bill rate (risk-free netting)
|
||||
|
||||
**Question that triggered it:** "Are we using cash return as a risk-free
|
||||
rate in the alpha calculations?" — No. Alpha was the OLS intercept of
|
||||
RAW daily total returns. For a fund whose net sleeve exposure is not
|
||||
~100% (under-invested or levered), the raw intercept absorbs the T-bill
|
||||
yield on the uninvested/levered part, so "alpha" mixed skill with cash
|
||||
drag. Magnitude (5y, R²>0.5 funds): 582 funds >2%/yr apart, 533 in
|
||||
1-2%, 345 in 0.5-1%. Sum-of-betas was also polluted by level-matching
|
||||
(median 1.15; a plain growth fund like bggsx showed 3.7 with a −10%/yr
|
||||
"alpha" that was pure level-splitting).
|
||||
|
||||
**Changes:**
|
||||
- decompose.py: `rf_series()` = BIL (SPDR 1-3mo T-Bill) daily total
|
||||
return — the local stand-in for the 3-mo T-bill yield; `excess()`
|
||||
nets the fund AND the sleeves against it before every regression.
|
||||
Cash positions now contribute exactly zero (cash IS the rf).
|
||||
- CASH_SLEEVES {shv, bil} dropped from the regressors: in excess space
|
||||
they are ~0 columns (ill-conditioning); the cash position is captured
|
||||
by the residual instead. Same for factors.py (shv added to
|
||||
DROP_FROM_REGRESSION).
|
||||
- **FULL_WINDOW moved 1990-01-01 → 2007-06-01** (BIL inception):
|
||||
mixing raw pre-2007 with excess post-2007 returns breaks the
|
||||
full-window fit (cosix: R²≈0, zero components selected).
|
||||
- **CASH axis redefined** from alpha_ann/cash_yield (the old version
|
||||
was measuring the yield level that no longer lives in the intercept)
|
||||
to **net cash position = 1 − Σβ**: the betas are the net-invested
|
||||
mix, the leftover is cash/T-bills. Pure MMF → 1.0; levered → < 0.
|
||||
Labeled "cash (net posn)". `factors.cash_yield()` removed.
|
||||
- Alphas in the app are now true excess-return alphas: intercept of
|
||||
(fund − rf) on (sleeves − rf).
|
||||
|
||||
**Verification (probes):** qcmmrx (money market): alpha −0.17%/yr
|
||||
(t=−1.3, noise), cash 1.00. vsbsx (short-T index): alpha 0.03%, cash
|
||||
0.77 + short duration. bggsx: Σβ 1.25 (was 3.7), alpha −3.6%
|
||||
(t=−0.6). IVV: alpha 0.00% (t=+36.7). cosix full-window fixed
|
||||
(R² 0.60, vweax 0.45/agg 0.15/ief 0.15).
|
||||
|
||||
**Consequence — the CANDIDATE list shrank 250 → 11.** Most of the old
|
||||
250 were under-invested funds (bond funds with Σβ<1) whose "alpha" was
|
||||
the T-bill yield on their uninvested portion. The 11 that survive are
|
||||
funds whose excess alpha is real. Verdict mix now: 1339 sleeve mix,
|
||||
1001 weak/unstable alpha, 11 CANDIDATE, 10 correlated, 6 not
|
||||
persistent, 17 no 5y window.
|
||||
|
||||
**Reference visibility (the "what is alpha computed vs" question):**
|
||||
alpha is NOT vs one index — it is vs the fund's own fitted sleeve mix
|
||||
(BIC forward selection). fundlab/refback.py recomputes the forward
|
||||
selection per fund and stores `ref_5y`/`ref_full` strings in
|
||||
search_all.json; the app's alpha-search table now has a "reference
|
||||
(5y)" column.
|
||||
|
||||
**Backups of the raw-alpha era (NOT deleted):**
|
||||
factor_results_rawalpha.json, decompose_results_rawalpha.json,
|
||||
search_all_rawalpha.json, cluster_kmeans_rawalpha.json.
|
||||
|
||||
---
|
||||
|
||||
## Per-fund report: HTML + app + narrative engine (2026-08-30)
|
||||
|
||||
**Deliverable.** `fundlab/report.py` -> `reports/fund_report.html`
|
||||
(self-contained, plotly inlined, 20 MB) and `fundlab/reportdata.py` ->
|
||||
`reports/report_data.json` (3 MB, the app's static build). 24 funds: the
|
||||
11 excess-return candidates + the 13 unique shortlist funds (pmfkx/lcrix/
|
||||
egrsx are share classes of pmaix/lcorx/eagmx and are merged).
|
||||
|
||||
Per fund: max-history equity curve (fund vs fitted reference vs IVV);
|
||||
period table (full/5y/1y, the 5 market episodes, 6 calendar years) with
|
||||
the **fund-minus-reference** column (period alpha/timing); drivers
|
||||
(reference-model R²/alpha/t + 34-sleeve signature + curated decomposition
|
||||
verdict + N-PORT cross-check notes); the reference mix explained
|
||||
sleeve-by-sleeve (SLEEVE_DESC: what each exposure actually is); tax
|
||||
character + placement; and a peer table of the 4 best-alpha funds in the
|
||||
same k=30 return-driver cluster with computed adv/dis.
|
||||
|
||||
**BUG FOUND AND FIXED — `mix_series()` never applied the betas.** The
|
||||
"fitted reference" curve summed the RAW sleeve daily returns instead of
|
||||
β·return. For high-fit funds the reference was garbage (JLPSX "reference"
|
||||
+407% 5y vs the fund's +123%; CVSIX +465%; PMAIX +1160%). After the fix
|
||||
the mix tracks the fund (JLPSX ref +127% vs fund +123%). Every reference
|
||||
curve and table in the HTML report was wrong before this and has been
|
||||
regenerated. Lesson: a regression on returns does not hand you a price
|
||||
path — the β weighting is the whole point.
|
||||
|
||||
**Weak-fit funds anchor to CASH, not their fitted mix.** For idiosyncratic
|
||||
funds (R² < 0.5) the BIC forward selection can pick a statistically-thin
|
||||
OFFSETTING combination (SCFZX: +0.35 VIX futures, −0.23 20+y Treasuries,
|
||||
+0.10 HY) whose cumulated path is meaningless (a "reference" that loses
|
||||
79% in 2022 for a fund that lost 2.4%). Below the 0.5 fit gate the
|
||||
performance table and curve use BIL as the reference; the loadings are
|
||||
still shown with an explicit "weak fit — read with care" caveat.
|
||||
|
||||
**Narrative engine (`fundlab/narrative.py`).** Data-driven English prose,
|
||||
5 paragraphs per fund: (1) what the fund is (objective, N-PORT buckets,
|
||||
cluster); (2) the performance in plain terms (CAGR/vol/DD, 5y vs reference,
|
||||
episode behaviour, calendar-year pattern); (3) what is driving it — tiered
|
||||
by fit (≥0.7 "mostly the exposures", 0.5–0.7 "mix + residual", <0.5
|
||||
"idiosyncratic: here is the estimate and its t-stat"); (4) **what we do
|
||||
NOT know** — stated explicitly: the unexplained share, alpha steadiness
|
||||
(share of 6m windows trailing), recent-vs-full significance, short sample,
|
||||
holdings opacity (egrix: 100% in one managed fund, underlying undisclosed);
|
||||
(5) bottom line (account placement, best cluster peer, portfolio
|
||||
correlation). Rules learned while reviewing the prose: negative/weak 5y
|
||||
alpha must not be called "outperformance" (the template assumed positive
|
||||
alpha and lied about atesx, −1.6% t=−0.5); MIXED tax placement must not be
|
||||
rendered as "IRA"; a fund with no price history must not be assigned a
|
||||
cluster (zero loading vector parks everything in the cash cluster);
|
||||
drift < 0.5 = "roughly stable" (0.44 is not "tactical"); sleeve prose
|
||||
needs short names (dbb/gsg → "broad commodities") because SLEEVE_DESC
|
||||
lead-ins reference sibling tickers.
|
||||
|
||||
**App integration.** The Fund Lab "Summary" page now renders
|
||||
`reports/report_data.json`: at-a-glance table (24 funds: 5y, CAGR, maxDD,
|
||||
R²5y, alpha5y, cluster) + one expander per fund (narrative first, then
|
||||
chart, period table, drivers, reference mix, tax, peers) + an "expand
|
||||
all" checkbox. Static build so the page stays fast; regenerate with
|
||||
`python -m fundlab.reportdata` (~8 s) and `python -m fundlab.report`
|
||||
(~11 s for the HTML).
|
||||
|
||||
**Report charts: re-basing-on-zoom widget (2nd pass).** The first report
|
||||
build used static st.plotly_chart with pre-rebased series — zooming to a
|
||||
window left the lines starting at different levels (no comparison
|
||||
possible). Replaced with the SAME widget as the Equity curves tab
|
||||
(`chart_widget.equity_chart_html` + st.iframe): on every relayout each
|
||||
visible line is re-based to 1.0 at its left edge and y fits the visible
|
||||
data, so fund/reference/index are comparable in any window. report_data
|
||||
still stores the full-history series; the app divides by each series'
|
||||
first point before handing it to the widget (per-series 1.0 start, as
|
||||
the widget expects). Also removed the "expand all" checkbox (24 expanded
|
||||
sections made the page unusable and hid the sections below) and added a
|
||||
"rest of the Fund Lab continues below" marker.
|
||||
|
||||
**On-demand reports for any Symbol-box fund.** `reportdata.ensure_adhoc(syms)`
|
||||
builds the same full report entry (narrative, chart, period table, drivers,
|
||||
reference, tax, peers) for ARBITRARY symbols, cached in memory + on disk
|
||||
(reports/report_data_adhoc.json, gitignored) so repeat loads are instant and
|
||||
survive restarts; build time ~0.3-0.9 s per new fund after the one-time
|
||||
~30-60 s driver-panel warmup. The app triggers it for symbols that stand
|
||||
ALONE in the Symbol box (a parsed item with a single component) - portfolio
|
||||
components (comma-joined) are explicitly excluded, per user request. Ad-hoc
|
||||
entries render at the top of the Fund Lab Summary as group "A" (before the
|
||||
pre-built 24), the per-fund rendering was extracted into render_fund_report()
|
||||
shared by both, and a pointer at the top of the page tells the user where
|
||||
the generated reports are. ETFs with no name on file render as "A01 · TLT"
|
||||
(no duplicated name).
|
||||
|
||||
**Style-tilt battery in the report pipeline (2026-08-30, 3rd pass).**
|
||||
`fundlab/styletilt.py`: 22 style/asset sleeves (EFA/VWO, growth/value,
|
||||
IWM/RSP size+equal-weight, USMV/DFLVX low-vol, QUAL, MTUM, HDV/VYM
|
||||
dividend, TLT, GLD, FXE/FXY/FXU, the five big sectors) regressed on the
|
||||
fund's excess-of-T-bill returns, full history + 5y. Plain OLS gives every
|
||||
factor's β + t (exploratory); BIC forward selection gives the IDENTIFIED
|
||||
tilt stack (strict gate); residual alpha after the identified stack says
|
||||
"skill left or pure factor exposure". Data-driven commentary: tilt
|
||||
sentences with strength words (t≥10 strong / ≥5 clear / ≥2 modest),
|
||||
sign-specific phrasing for the tricky ones (short-euro = USD carry,
|
||||
anti-quality = flip side of high payout, anti-momentum = contrarian),
|
||||
5y-only factors called out separately, and an explicit residual-verdict
|
||||
paragraph. Wired as a "Style tilts" block (factor table + commentary)
|
||||
into both report builders (app + HTML); ~0.1-0.8 s per fund after the
|
||||
one-time battery-panel build. All 24 pre-built + 8 ad-hoc reports
|
||||
rebuilt (23/24 have the block; lcorx has no history). Worked example
|
||||
(lvhi): identified stack = intl-dev 0.78 + short EUR 0.42 + HDV +0.28
|
||||
(t+20) + anti-QUAL 0.21 (t-12) + short FXY + short VWO; residual alpha
|
||||
+2.3%/y t=+1.1 -> "factor exposure, not skill".
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ HERE = Path(__file__).parent
|
|||
RESULTS = HERE / "factor_results.json"
|
||||
TREE = HERE / "cluster_tree.json"
|
||||
KMEANS = HERE / "cluster_kmeans.json"
|
||||
from fundlab.factors import DRIVERS # noqa: E402
|
||||
from fundlab.factors import AXES, DRIVERS # noqa: E402
|
||||
|
||||
|
||||
def log(msg: str) -> None:
|
||||
|
|
@ -50,6 +50,11 @@ def loading_matrix() -> tuple[list[str], np.ndarray]:
|
|||
continue
|
||||
row = np.array([f["betas"].get(s, 0.0) or 0.0 for s in DRIVERS],
|
||||
dtype=float)
|
||||
# virtual CASH axis = net cash position = 1 - sum of the betas.
|
||||
# Alphas are in excess of the T-bill rate, so the betas are the
|
||||
# NET INVESTED mix; whatever is left over sits in cash/T-bills.
|
||||
# Pure money-market fund: all betas ~ 0 -> cash ~ 1.
|
||||
row = np.append(row, 1.0 - row.sum())
|
||||
# winsorize at +/-4: everything beyond that is an OLS noise fit
|
||||
# (R2 ~ 0.01, |t| < 2 - e.g. fyhtx shv +63.8), never a real
|
||||
# exposure (no open-end fund runs 400% of a sleeve)
|
||||
|
|
@ -120,7 +125,7 @@ def cluster_means(syms: list[str], V: np.ndarray,
|
|||
idx = [i for i, s in assign.items() if s == c]
|
||||
med = np.median(V[idx], axis=0)
|
||||
top = np.argsort(-np.abs(med))[:4]
|
||||
prof = {DRIVERS[t]: float(med[t]) for t in top
|
||||
prof = {AXES[t]: float(med[t]) for t in top
|
||||
if abs(med[t]) >= 0.05}
|
||||
out.append({"n": len(idx), "top": prof,
|
||||
"syms": [syms[i] for i in idx]})
|
||||
|
|
@ -140,15 +145,41 @@ SLEEVE_NAME = {
|
|||
"xlv": "healthcare", "xlp": "staples", "xlu": "utilities",
|
||||
"xly": "consumer disc", "xlb": "materials", "dbmf": "CTA/futures",
|
||||
"dbb": "commodities",
|
||||
"cash": "cash (net posn)",
|
||||
}
|
||||
|
||||
# the CASH axis is a POSITION (net cash, 1.0 = fully in cash), not a
|
||||
# return SENSITIVITY like the betas. In raw Euclidean space a
|
||||
# pure cash fund (0,...,0,~0.5) sits inside the cloud of low-exposure
|
||||
# balanced/target-date funds and k-means swallows it. Emphasize the axis
|
||||
# for DISTANCE only (labels still use the raw values).
|
||||
CASH_EMPHASIS = 2.0
|
||||
|
||||
|
||||
def emphasized(V: np.ndarray, ci: int) -> np.ndarray:
|
||||
W = V.copy()
|
||||
W[:, ci] *= CASH_EMPHASIS
|
||||
return W
|
||||
|
||||
|
||||
def label(prof: dict) -> str:
|
||||
# a real driver shows up as >=0.3 on a median loading; below that the
|
||||
# cluster is balanced mixes with no single dominant driver
|
||||
if not prof or max(abs(v) for v in prof.values()) < 0.30:
|
||||
# cluster is balanced mixes with no single dominant driver. The CASH
|
||||
# axis is a level, not a beta: in a mixed low-exposure cluster the
|
||||
# median cash is diluted, so it gets a slightly lower threshold and
|
||||
# must clearly beat the runner-up to count as THE driver.
|
||||
if not prof:
|
||||
return "no dominant driver (balanced/idio)"
|
||||
names = sorted(prof, key=lambda s: -abs(prof[s]))
|
||||
top_s, top_v = names[0], prof[names[0]]
|
||||
runner = abs(prof[names[1]]) if len(names) > 1 else 0.0
|
||||
if top_s == "cash":
|
||||
if top_v >= 0.25 and top_v >= 1.5 * runner:
|
||||
return " + ".join(f"{SLEEVE_NAME.get(s, s)} {prof[s]:+.2f}"
|
||||
for s in names[:3])
|
||||
return "no dominant driver (balanced/idio)"
|
||||
if abs(top_v) < 0.30:
|
||||
return "no dominant driver (balanced/idio)"
|
||||
return " + ".join(f"{SLEEVE_NAME.get(s, s)} {prof[s]:+.2f}"
|
||||
for s in names[:3])
|
||||
|
||||
|
|
@ -182,7 +213,7 @@ def kmeans(V: np.ndarray, k: int, seed: int = 0,
|
|||
|
||||
def run_kmeans(k: int = 30) -> dict:
|
||||
syms, V = loading_matrix()
|
||||
lab = kmeans(V, k)
|
||||
lab = kmeans(emphasized(V, AXES.index("cash")), k)
|
||||
out: dict[int, dict] = {}
|
||||
for c in range(k):
|
||||
idx = [i for i, l in enumerate(lab) if l == c]
|
||||
|
|
@ -190,7 +221,7 @@ def run_kmeans(k: int = 30) -> dict:
|
|||
continue
|
||||
med = np.median(V[idx], axis=0)
|
||||
top = np.argsort(-np.abs(med))[:4]
|
||||
prof = {DRIVERS[t]: float(med[t]) for t in top
|
||||
prof = {AXES[t]: float(med[t]) for t in top
|
||||
if abs(med[t]) >= 0.08}
|
||||
out[c] = {"n": len(idx), "top": prof, "label": label(prof),
|
||||
"syms": [syms[i] for i in idx]}
|
||||
|
|
@ -203,7 +234,7 @@ def run() -> None:
|
|||
log(f"cluster: {len(syms)} funds x {V.shape[1]} drivers")
|
||||
merges = hclust(V)
|
||||
TREE.write_text(json.dumps({"syms": syms, "merges": merges,
|
||||
"n": len(syms), "sleeves": DRIVERS}))
|
||||
"n": len(syms), "sleeves": AXES}))
|
||||
log(f"hierarchical tree written in {time.time() - t0:.0f}s -> {TREE.name}")
|
||||
# NOTE: fixed-k cuts of the tree peel small pure-sleeve clusters off a
|
||||
# giant blend blob (most funds are multi-sleeve mixes) - the useful
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
1
fundlab/cluster_kmeans_rawalpha.json
Normal file
1
fundlab/cluster_kmeans_rawalpha.json
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -22,6 +22,7 @@ intercept; alphas are annualized (x252); t-stats use the OLS covariance.
|
|||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from functools import lru_cache
|
||||
from pathlib import Path
|
||||
|
||||
import numpy as np
|
||||
|
|
@ -49,6 +50,29 @@ def adj_close(sym: str, root: Path = DATA) -> pd.Series | None:
|
|||
return s
|
||||
|
||||
|
||||
@lru_cache(maxsize=1)
|
||||
def rf_series() -> pd.Series | None:
|
||||
"""Daily risk-free rate: BIL (SPDR 1-3 Month T-Bill) total return —
|
||||
the local stand-in for the 3-month T-bill yield. Alphas are computed
|
||||
in EXCESS of this rate (both the fund and the sleeves are netted
|
||||
against it), so the intercept is a true excess-return alpha and a
|
||||
cash position contributes zero (cash IS the risk-free rate). 0 where
|
||||
BIL has no history (pre-2007)."""
|
||||
a = adj_close("bil")
|
||||
if a is None:
|
||||
return None
|
||||
return a.pct_change().fillna(0.0)
|
||||
|
||||
|
||||
def excess(panel: pd.DataFrame) -> pd.DataFrame:
|
||||
"""Net every column against the daily risk-free rate."""
|
||||
rf = rf_series()
|
||||
if rf is None:
|
||||
return panel
|
||||
rf = rf.reindex(panel.index).fillna(0.0)
|
||||
return panel.sub(rf, axis=0)
|
||||
|
||||
|
||||
def returns_panel(symbols: list[str], start: str | None = None) -> pd.DataFrame:
|
||||
"""Daily simple returns, outer-joined on dates (NaN where a series
|
||||
has no data). Callers must handle missing values per regressor —
|
||||
|
|
@ -207,9 +231,17 @@ CANDIDATES: dict[str, list[str]] = {
|
|||
}
|
||||
# share classes: same underlying fund
|
||||
ALIAS = {"pmfkx": "pmaix", "lcrix": "lcorx", "egrsx": "eagmx"}
|
||||
FULL_WINDOW = "1990-01-01" # effectively all history
|
||||
FULL_WINDOW = "2007-06-01" # from BIL inception: alphas are in excess of
|
||||
# the T-bill rate, which needs the rf series (raw pre-2007 returns
|
||||
# mixed with excess post-2007 returns breaks the full-window fit)
|
||||
RECENT_WINDOW = "2021-01-01" # last ~5 years
|
||||
|
||||
# sleeves that ARE the risk-free rate. Alphas are now computed in excess of
|
||||
# the T-bill rate, so these columns are ~0 in excess space and would make
|
||||
# the regression ill-conditioned. Cash exposure is captured by the residual
|
||||
# (1 - sum of betas) instead, so they are dropped from the regressors.
|
||||
CASH_SLEEVES = {"shv", "bil"}
|
||||
|
||||
|
||||
def _drift(rb: pd.DataFrame, full_beta: np.ndarray) -> dict[str, float]:
|
||||
"""Mean |rolling beta - full-sample beta| per component, as a fraction
|
||||
|
|
@ -225,13 +257,14 @@ def _drift(rb: pd.DataFrame, full_beta: np.ndarray) -> dict[str, float]:
|
|||
def decompose(fund: str, start: str = FULL_WINDOW,
|
||||
candidates: dict[str, list[str]] | None = None) -> dict:
|
||||
cand_syms = (candidates or CANDIDATES).get(fund, [])
|
||||
r = returns_panel([fund] + cand_syms, start=start)
|
||||
r = excess(returns_panel([fund] + cand_syms, start=start))
|
||||
if fund not in r.columns:
|
||||
return {"fund": fund, "error": "no return history in the data set",
|
||||
"verdict": "no return history", "start": start}
|
||||
y = r[fund].to_numpy()
|
||||
dates = r.index
|
||||
cand = {s: r[s].to_numpy() for s in r.columns if s != fund}
|
||||
cand = {s: r[s].to_numpy() for s in r.columns
|
||||
if s != fund and s not in CASH_SLEEVES}
|
||||
y_ok = ~np.isnan(y)
|
||||
if y_ok.sum() < 252:
|
||||
return {"fund": fund, "error": "insufficient return history",
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
1340
fundlab/decompose_results_rawalpha.json
Normal file
1340
fundlab/decompose_results_rawalpha.json
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
1
fundlab/factor_results_rawalpha.json
Normal file
1
fundlab/factor_results_rawalpha.json
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -69,9 +69,19 @@ SLEEVES_V2 = list(dict.fromkeys(BROAD_SLEEVES + EXTRA_SLEEVES))
|
|||
# short-rate exposure as huge offsetting shv/bil coefficients (shv +64 /
|
||||
# bil -54) - shv (1-3m) alone carries the cash/ultra-short axis, shy
|
||||
# keeps the 1-3y axis.
|
||||
DROP_FROM_REGRESSION = {"vea", "vug", "finux", "bil"}
|
||||
DROP_FROM_REGRESSION = {"vea", "vug", "finux", "bil", "shv"}
|
||||
# (bil/shv are the risk-free sleeves - alphas are now computed in
|
||||
# excess of the T-bill rate, where they are ~0 columns; the cash
|
||||
# position shows up in the residual / the virtual CASH axis instead)
|
||||
DRIVERS = [s for s in SLEEVES_V2 if s not in DROP_FROM_REGRESSION]
|
||||
|
||||
# clustering/display basis = the regression sleeves + a virtual CASH axis.
|
||||
# Alphas are computed in EXCESS of the T-bill rate (decompose.excess), so
|
||||
# the beta vector is the fund's NET INVESTED mix and the leftover
|
||||
# (1 - sum of betas) is its cash/T-bill position: a pure money-market
|
||||
# fund has all betas ~ 0 -> CASH ~ 1, a levered fund -> CASH < 0.
|
||||
AXES = DRIVERS + ["cash"]
|
||||
|
||||
|
||||
def _resid(y: pd.Series, X: pd.DataFrame) -> pd.Series:
|
||||
m = y.notna() & X.notna().all(axis=1)
|
||||
|
|
@ -93,6 +103,7 @@ def _panel() -> pd.DataFrame:
|
|||
log(f"building driver panel ({len(DRIVERS)} axes)")
|
||||
p = decompose.returns_panel(SLEEVES_V2).sort_index()
|
||||
p = p[~p.index.duplicated(keep="last")][DRIVERS]
|
||||
p = decompose.excess(p) # alphas are in excess of the T-bill rate
|
||||
# pure vol axis: vblix residualized on the core equity/duration axes
|
||||
core = [c for c in ("ivv", "tlt") if c in p.columns]
|
||||
if "vblix" in p.columns and core:
|
||||
|
|
@ -142,11 +153,16 @@ def _beta_window(y: pd.Series, X: pd.DataFrame, start: str) -> dict | None:
|
|||
}
|
||||
|
||||
|
||||
def factor_screen(sym: str, start: str = "1990-01-01") -> dict | None:
|
||||
def factor_screen(sym: str, start: str = None) -> dict | None:
|
||||
if start is None:
|
||||
start = decompose.FULL_WINDOW
|
||||
fund = decompose.adj_close(sym)
|
||||
if fund is None or len(fund) < 250:
|
||||
return None
|
||||
y = fund.pct_change().dropna()
|
||||
rf = decompose.rf_series()
|
||||
if rf is not None:
|
||||
y = y.sub(rf.reindex(y.index).fillna(0.0))
|
||||
X = _panel().reindex(y.index)
|
||||
# sleeves must have history for most of the fund's window
|
||||
avail = [c for c in X.columns if X[c].notna().mean() > 0.3]
|
||||
|
|
|
|||
14
fundlab/factors_run.log
Normal file
14
fundlab/factors_run.log
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
15:03:47 factor screen: 2384 funds, 2384 to do
|
||||
15:03:47 building driver panel (34 axes)
|
||||
15:03:55 200/2384
|
||||
15:04:02 400/2384
|
||||
15:04:10 600/2384
|
||||
15:04:18 800/2384
|
||||
15:04:30 1000/2384
|
||||
15:04:43 1200/2384
|
||||
15:04:52 1400/2384
|
||||
15:04:59 1600/2384
|
||||
15:05:07 1800/2384
|
||||
15:05:14 2000/2384
|
||||
15:05:21 2200/2384
|
||||
15:05:28 factor screen done: 2384 funds -> factor_results.json
|
||||
444
fundlab/narrative.py
Normal file
444
fundlab/narrative.py
Normal file
|
|
@ -0,0 +1,444 @@
|
|||
"""Per-fund narrative: English prose explaining the performance and its
|
||||
drivers, built from the analysis we have on file.
|
||||
|
||||
The prose is data-driven (every number comes from the computed results),
|
||||
and it is required to be honest about limits: when the return drivers
|
||||
are unknown or only weakly identified, the text says so explicitly.
|
||||
|
||||
Paragraphs:
|
||||
1. what the fund is (name, stated strategy if on file, what its
|
||||
N-PORT actually holds, which return-driver cluster it sits in)
|
||||
2. the performance in plain terms (full history, 5y, recent year,
|
||||
behaviour in the defined market episodes, calendar-year pattern)
|
||||
3. what is driving it (fit quality -> whose exposures vs idiosyncratic
|
||||
alpha; the economic meaning of the top loadings; weight stability)
|
||||
4. what we do NOT know (unexplained share, alpha steadiness, sample
|
||||
size, holdings opacity) - stated plainly
|
||||
5. bottom line (account placement, best cluster peers, role)
|
||||
|
||||
Run: .venv/bin/python -m fundlab.narrative (prints all narratives)
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
import numpy as np
|
||||
|
||||
from fundlab import report as _r
|
||||
from fundlab.searchlist import BROAD_SLEEVES
|
||||
from fundlab import decompose as _dc
|
||||
|
||||
HERE = Path(__file__).parent
|
||||
|
||||
_XC = json.loads((HERE / "xcheck_report.json").read_text()) \
|
||||
if (HERE / "xcheck_report.json").exists() else {}
|
||||
|
||||
|
||||
def _pct(x, nd=1) -> str:
|
||||
if x is None or (isinstance(x, float) and np.isnan(x)):
|
||||
return "no data"
|
||||
return f"{100 * x:+.{nd}f}%"
|
||||
|
||||
|
||||
def _num(x, nd=2) -> str:
|
||||
if x is None or (isinstance(x, float) and np.isnan(x)):
|
||||
return "n/a"
|
||||
return f"{x:.{nd}f}"
|
||||
|
||||
|
||||
# short prose names for sleeves whose SLEEVE_DESC lead-in references a
|
||||
# sibling ticker ("same HY exposure as VWEAX via a different fund")
|
||||
_PROSE_NAME = {
|
||||
"vea": "international developed markets",
|
||||
"efa": "international developed markets",
|
||||
"hyg": "high-yield corporate bonds",
|
||||
"vweax": "high-yield corporate bonds",
|
||||
"dbb": "broad commodities",
|
||||
"gsg": "broad commodities",
|
||||
"vblix": "crash vol (VIX futures)",
|
||||
"bil": "cash (T-bills)",
|
||||
"shv": "cash (T-bills)",
|
||||
}
|
||||
|
||||
|
||||
def _sleeve_prose(sym: str, beta: float) -> str:
|
||||
nm, desc = _r.sleeve_desc(sym)
|
||||
short = _PROSE_NAME.get(sym)
|
||||
head = short.split(";")[0].strip() if short else \
|
||||
desc.split(";")[0].strip()
|
||||
head = head[0].upper() + head[1:] if head else nm
|
||||
if abs(beta) < 0.15:
|
||||
return f"a small tilt to {head.lower()}"
|
||||
if beta > 0:
|
||||
return f"exposure to {head.lower()}"
|
||||
return f"short-like exposure to {head.lower()} (it rises when that " \
|
||||
f"asset falls)"
|
||||
|
||||
|
||||
def _top_sleeves(fr: dict, window: str, n: int = 3) -> list[tuple[str, float]]:
|
||||
f = fr.get(window) or {}
|
||||
betas = f.get("betas") or {}
|
||||
top = sorted(betas.items(), key=lambda kv: -abs(kv[1]))[:n]
|
||||
return [(s, b) for s, b in top if abs(b) >= 0.08]
|
||||
|
||||
|
||||
def _fit(fr: dict, srow: dict) -> tuple[float | None, float | None,
|
||||
float | None]:
|
||||
"""(r2, alpha_ann_5y, t5) preferring the reference-model numbers."""
|
||||
r2 = srow.get("r2_5y")
|
||||
a5 = srow.get("alpha_ann_5y")
|
||||
t5 = srow.get("alpha_t_5y")
|
||||
if not isinstance(r2, (int, float)):
|
||||
r2 = (fr.get("rec5") or fr.get("full") or {}).get("r2")
|
||||
if not isinstance(a5, (int, float)):
|
||||
a5 = (fr.get("rec5") or fr.get("full") or {}).get("alpha_ann")
|
||||
if not isinstance(t5, (int, float)):
|
||||
t5 = (fr.get("rec5") or fr.get("full") or {}).get("alpha_t")
|
||||
return (r2 if isinstance(r2, (int, float)) else None,
|
||||
a5 if isinstance(a5, (int, float)) else None,
|
||||
t5 if isinstance(t5, (int, float)) else None)
|
||||
|
||||
|
||||
def narrate(sym: str) -> list[str]:
|
||||
sym = sym.lower()
|
||||
srow = _r.search_row(sym)
|
||||
fr = _r.factor_row(sym)
|
||||
dr = _r.decomp_row(sym)
|
||||
tax = _r.tax_row(sym)
|
||||
ddr = _r.dd_row(sym)
|
||||
xcr = _XC.get(sym, {})
|
||||
p = _r.price(sym)
|
||||
name = (srow.get("name") or _r.FONDS.get(sym, {}).get("name")
|
||||
or (fr or {}).get("name") or sym.upper())
|
||||
out: list[str] = []
|
||||
|
||||
# ------------------------------------------------------------ 1. what
|
||||
who = []
|
||||
who.append(f"{sym.upper()} is the {name}.")
|
||||
obj = (_r.FONDS.get(sym) or {}).get("objective")
|
||||
if obj:
|
||||
first = obj.split(". ")[0].strip().rstrip(".")
|
||||
who.append(f"Stated strategy: {first}.")
|
||||
if xcr and not xcr.get("error"):
|
||||
b = [x["name"] for x in xcr.get("buckets", [])[:2]]
|
||||
if b:
|
||||
who.append(f"Per its latest N-PORT its actual holdings are "
|
||||
f"mostly {b[0]}"
|
||||
+ (f" and {b[1]}" if len(b) > 1 else "") + ".")
|
||||
out.append(" ".join(who))
|
||||
|
||||
if p is None:
|
||||
# no return history: do NOT claim a cluster - the loading vector
|
||||
# is all zeros and would park the fund in the cash cluster
|
||||
out.append("There is no local return history for this share "
|
||||
"class yet (new class), so performance and drivers "
|
||||
"cannot be measured from returns. The N-PORT shows "
|
||||
"what it holds: " + ((dr or {}).get("note")
|
||||
or "see holdings"))
|
||||
return out
|
||||
if sym in _r.MEMBER:
|
||||
_cid, clabel, cn = _r.MEMBER[sym]
|
||||
who = out[0]
|
||||
out[0] = (who + f" In the return-driver analysis it sits in the "
|
||||
f"'{clabel}' cluster with {cn - 1} other funds.")
|
||||
else:
|
||||
try:
|
||||
load = _r.fund_loading_row(fr)
|
||||
_cid, clabel = _r.cluster_of_row(load)
|
||||
out[0] = (out[0] + f" Its return-driver signature is closest "
|
||||
f"to the '{clabel}' cluster.")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
st = _r.perf_stats(p)
|
||||
r2, a5, t5 = _fit(fr, srow)
|
||||
tf = (fr.get("full") or {}).get("alpha_t")
|
||||
a_f = (fr.get("full") or {}).get("alpha_ann")
|
||||
refs = _r.ref_components(sym, fr)
|
||||
r2f_ = (fr.get("rec5") or fr.get("full") or {}).get("r2")
|
||||
fit = r2 if r2 is not None else r2f_
|
||||
r25 = srow.get("r2_5y") if isinstance(srow.get("r2_5y"), (int, float)) \
|
||||
else r2f_
|
||||
refs_curve = refs if (fit is not None and fit >= 0.5) else []
|
||||
mix = _r.mix_series(refs_curve) if refs_curve else _r.price("bil")
|
||||
ivv = _r.price("ivv")
|
||||
t5y = _r.window_ret(p, "2021-01-01", st["end"])
|
||||
t1y = _r.window_ret(p, "2025-09-01", st["end"])
|
||||
ref5y = _r.window_ret(mix, "2021-01-01", st["end"]) if mix is not None \
|
||||
else None
|
||||
iv5y = _r.window_ret(ivv, "2021-01-01", st["end"]) if ivv is not None \
|
||||
else None
|
||||
|
||||
# --------------------------------------------------------- 2. performance
|
||||
perf = []
|
||||
tot = p.iloc[-1] / p.iloc[0] - 1
|
||||
perf.append(
|
||||
f"Since {st['start'][:4]} it has compounded at "
|
||||
f"{_pct(st['cagr'])} per year (a {_pct(tot, 0)} total return) "
|
||||
f"with {_pct(st['vol'], 0)} annualized volatility and a maximum "
|
||||
f"drawdown of {100 * abs(st['mdd']):.0f}%.")
|
||||
perf.append(
|
||||
f"Over the last five years it returned {_pct(t5y)} versus "
|
||||
f"{_pct(ref5y)} for its reference"
|
||||
+ (f" and {_pct(iv5y)} for the S&P 500" if iv5y is not None else "")
|
||||
+ f". The last twelve months have done {_pct(t1y)}.")
|
||||
yrs = _r.annual_table(p, 7)
|
||||
pos = sum(1 for _y, v in yrs if v > 0)
|
||||
perf.append(f"It was positive in {pos} of the last {len(yrs)} "
|
||||
f"calendar years (including the partial current year).")
|
||||
# episodes
|
||||
rets = ddr.get("rets", {})
|
||||
if rets:
|
||||
best = max(rets.items(), key=lambda kv: kv[1])
|
||||
worst = min(rets.items(), key=lambda kv: kv[1])
|
||||
perf.append(
|
||||
f"Across the defined market episodes it did best in "
|
||||
f"'{best[0]}' ({_pct(best[1])}) and worst in '{worst[0]}' "
|
||||
f"({_pct(worst[1])}) - the peak-to-trough windows when "
|
||||
f"equities fell hardest.")
|
||||
_dv = ddr.get("verdict") or ""
|
||||
if _dv and not _dv.startswith("CANDIDATE"):
|
||||
perf.append(f"Its drawdown screen verdict: {_dv}.")
|
||||
out.append(" ".join(perf))
|
||||
|
||||
# --------------------------------------------------------- 3. drivers
|
||||
drv = []
|
||||
tops = _top_sleeves(fr, "rec5", 3)
|
||||
if fit is not None and fit >= 0.7:
|
||||
tops_txt = ", ".join(_sleeve_prose(s, b) for s, b in tops)
|
||||
drv.append(
|
||||
f"The fit is strong: {100 * fit:.0f}% of its excess returns "
|
||||
f"over the last five years are explained by its measured "
|
||||
f"exposures"
|
||||
+ (f" - {tops_txt}" if tops else "") + ".")
|
||||
drv.append(
|
||||
f"In other words, most of what this fund does is charge you "
|
||||
f"for those exposures in the form of a fund; what is left - "
|
||||
f"an alpha of {_pct(a5)} per year (t = {_num(t5, 1)}) - is "
|
||||
+ ("statistically indistinguishable from zero, i.e. the "
|
||||
"strategy is not clearly adding anything on top of the "
|
||||
"mix it owns."
|
||||
if (t5 or 0) < 1.75 else
|
||||
"small relative to the beta, but it is what separates "
|
||||
"this fund from the equivalent index mix.")
|
||||
)
|
||||
elif fit is not None and fit >= 0.5:
|
||||
tops_txt = ", ".join(_sleeve_prose(s, b) for s, b in tops)
|
||||
drv.append(
|
||||
f"The measured exposures explain a good share but not all "
|
||||
f"({100 * fit:.0f}% R²) of its excess returns."
|
||||
+ (f" The main ones: {tops_txt}." if tops else ""))
|
||||
drv.append(
|
||||
f"The residual is {_pct(a5)} per year (t = {_num(t5, 1)}): "
|
||||
+ ("a real edge on top of the mix, but a material part of "
|
||||
"the performance IS the mix - judge the exposures and "
|
||||
"the skill separately."
|
||||
if (t5 or 0) >= 1.75 else
|
||||
"not statistically distinct from noise at the five-year "
|
||||
"horizon, so treat the outperformance as part beta, part "
|
||||
"luck until it accumulates more history.")
|
||||
)
|
||||
else:
|
||||
tops_txt = ", ".join(_sleeve_prose(s, b) for s, b in tops)
|
||||
drv.append(
|
||||
f"The broad sleeve framework explains little of its excess "
|
||||
f"returns (R² = {_num(fit) if fit is not None else 'n/a'}). "
|
||||
+ (f"The loadings that do show up - {tops_txt} - are minor "
|
||||
"tilts, not the story."
|
||||
if tops else
|
||||
"No benchmark loading is even large."))
|
||||
long_ctx = ""
|
||||
if isinstance(a_f, (int, float)):
|
||||
long_ctx = (f" Over the full history the same estimate is "
|
||||
f"{_pct(a_f)} per year (t = {_num(tf, 1)}).")
|
||||
if (t5 or 0) >= 2:
|
||||
drv.append(
|
||||
f"The bulk of the performance is therefore "
|
||||
f"idiosyncratic: it comes from the fund's own holdings "
|
||||
f"and decisions, which nothing in our 34-sleeve space "
|
||||
f"replicates. The estimate of that idiosyncratic return "
|
||||
f"is {_pct(a5)} per year over the last five years "
|
||||
f"(t = {_num(t5, 1)}) - statistically significant, so "
|
||||
f"the outperformance is real; what the returns alone "
|
||||
f"cannot tell us is its source.{long_ctx}")
|
||||
elif (a5 or 0) >= 0:
|
||||
drv.append(
|
||||
f"The bulk of the performance is therefore "
|
||||
f"idiosyncratic: it comes from the fund's own holdings "
|
||||
f"and decisions, which nothing in our 34-sleeve space "
|
||||
f"replicates. The estimate of that idiosyncratic return "
|
||||
f"is {_pct(a5)} per year over the last five years "
|
||||
f"(t = {_num(t5, 1)}) - at that t-stat it is not yet "
|
||||
f"clearly different from a lucky streak.{long_ctx}")
|
||||
else:
|
||||
drv.append(
|
||||
f"Most of the performance is therefore idiosyncratic "
|
||||
f"rather than benchmark-like. The honest five-year read "
|
||||
f"of its excess return is {_pct(a5)} per year "
|
||||
f"(t = {_num(t5, 1)}): over the recent window this fund "
|
||||
f"is NOT measurably adding to its fitted reference.{long_ctx}")
|
||||
if (a5 or 0) < 0 and isinstance(tf, (int, float)) and tf >= 1.25:
|
||||
drv.append(
|
||||
f"The longer record is better: over the full history the "
|
||||
f"alpha is {_pct(a_f)} per year (t = {_num(tf, 1)}), "
|
||||
f"which IS significant - so the five-year estimate "
|
||||
f"looks like a flat patch in a longer positive trend, "
|
||||
f"not evidence the edge has gone.")
|
||||
if xcr and not xcr.get("error"):
|
||||
b = [x["name"] for x in xcr.get("buckets", [])[:2]]
|
||||
if b:
|
||||
drv.append(
|
||||
f"The N-PORT is consistent with that: the alpha is "
|
||||
f"plausibly coming from {b[0]}"
|
||||
+ (f" and {b[1]}" if len(b) > 1 else "")
|
||||
+ " - asset classes our sleeve set either does not "
|
||||
"model directly or models too coarsely. That is an "
|
||||
"interpretation from the holdings, not something "
|
||||
"the returns prove.")
|
||||
if obj and (a5 or 0) > 0:
|
||||
_o = obj.split(". ")[0].rstrip(".")
|
||||
if len(_o) > 110:
|
||||
_o = _o[:110].rsplit(" ", 1)[0] + "..."
|
||||
drv.append(
|
||||
f"The stated strategy ('{_o}') is a plausible mechanism "
|
||||
f"as well, but that is a hypothesis - the returns only "
|
||||
f"tell us the outperformance exists, not why.")
|
||||
# stability (curated funds)
|
||||
roll = (dr or {}).get("rolling") or {}
|
||||
if "verdict" in (dr or {}) and roll.get("max_drift") is not None:
|
||||
md = roll["max_drift"]
|
||||
drv.append(
|
||||
f"The curated decomposition's read: {dr['verdict']}. "
|
||||
f"Weight stability: the one-year rolling betas move by at "
|
||||
f"most {md:.2f} (relative to the full-sample weights) - "
|
||||
+ ("so the weights are roughly stable over time."
|
||||
if md < 0.5 else
|
||||
"so treat this as a tactically active fund, not a "
|
||||
"static mix."))
|
||||
out.append(" ".join(drv))
|
||||
|
||||
# ------------------------------------------------- 4. what we do NOT know
|
||||
unk = []
|
||||
if fit is not None:
|
||||
if (t5 or 0) >= 2:
|
||||
unk.append(
|
||||
f"To be explicit about the limits: "
|
||||
f"{100 * (1 - fit):.0f}% of this fund's excess return "
|
||||
f"is NOT attributed to any measured exposure by our "
|
||||
f"analysis - we know the outperformance is real, we do "
|
||||
f"not know from returns what produces it; the source "
|
||||
f"has to be read from the filings before sizing up.")
|
||||
else:
|
||||
unk.append(
|
||||
f"To be explicit about the limits: the excess return is "
|
||||
f"not measurable against noise at the current sample "
|
||||
f"size, so there is not even a reliable alpha to "
|
||||
f"attribute; {100 * (1 - fit):.0f}% of the return is "
|
||||
f"outside our sleeve model either way.")
|
||||
pf = srow.get("alpha_pos_frac")
|
||||
if isinstance(pf, (int, float)) and pf < 0.60:
|
||||
unk.append(
|
||||
f"The alpha is also not steady: in {100 * (1 - pf):.0f}% of "
|
||||
f"rolling six-month windows the fund trailed its reference, "
|
||||
f"so the five-year number is carrying periods of "
|
||||
f"underperformance.")
|
||||
if (t5 or 0) >= 2 and isinstance(tf, (int, float)) and tf < 1.25:
|
||||
unk.append(
|
||||
"The significance is recent - over the full history the "
|
||||
"alpha is not significant, so this is a provisional read on "
|
||||
"a ~5-year sample.")
|
||||
if st["years"] < 3:
|
||||
unk.append(
|
||||
f"The whole sample is short ({st['years']:.1f} years), so "
|
||||
f"every number above has a wide error bar.")
|
||||
if xcr.get("note"):
|
||||
unk.append(xcr["note"].rstrip(".") + ".")
|
||||
note = (dr or {}).get("note")
|
||||
if note and "N-PORT" in note:
|
||||
# holdings cross-check sentence (shortlist)
|
||||
for sentence in note.split(". "):
|
||||
if "N-PORT" in sentence or "holdings" in sentence.lower():
|
||||
unk.append(sentence.strip().rstrip(".") +
|
||||
" - the holdings check is the ground truth "
|
||||
"here, and the return model is only a "
|
||||
"description of it.")
|
||||
break
|
||||
if not unk:
|
||||
unk.append("No major caveats beyond the usual: the past fit may "
|
||||
"not persist, and the sleeves are models of the "
|
||||
"fund, not the fund itself.")
|
||||
out.append(" ".join(unk))
|
||||
|
||||
# --------------------------------------------------------- 5. bottom line
|
||||
bot = []
|
||||
loc = tax.get("location")
|
||||
if loc:
|
||||
basis = "N-PORT holdings" if tax.get("basis") == "N-PORT" \
|
||||
else "the sleeve model"
|
||||
if "MIXED" in loc:
|
||||
bot.append(
|
||||
f"Account placement: not settled by the model - the "
|
||||
f"sleeve model calls it MIXED, so the last 1099-DIV is "
|
||||
f"the arbiter before choosing taxable vs IRA.")
|
||||
else:
|
||||
bot.append(
|
||||
f"Account placement: "
|
||||
f"{'taxable' if 'TAXABLE' in loc else 'IRA'} "
|
||||
f"({basis} says {loc}).")
|
||||
# peers
|
||||
if sym in _r.MEMBER:
|
||||
cid = _r.MEMBER[sym][0]
|
||||
members = _r.KMEANS["clusters"][cid]["syms"]
|
||||
peers = []
|
||||
for s in members:
|
||||
if s == sym:
|
||||
continue
|
||||
v = _r.search_row(s)
|
||||
if isinstance(v.get("alpha_t_5y"), (int, float)) and \
|
||||
v["alpha_t_5y"] > 0:
|
||||
pp = _r.price(s)
|
||||
if pp is None:
|
||||
continue
|
||||
peers.append((v["alpha_t_5y"], v.get("alpha_ann_5y"), s))
|
||||
peers.sort(reverse=True)
|
||||
if peers:
|
||||
b_t, b_a, b_s = peers[0]
|
||||
bp = _r.price(b_s)
|
||||
bt5 = _r.window_ret(bp, "2021-01-01",
|
||||
_r.perf_stats(bp)["end"])
|
||||
bot.append(
|
||||
f"Within its cluster the strongest alternative is "
|
||||
f"{b_s.upper()} (5y {_pct(bt5)}, alpha t = {b_t:+.1f}); "
|
||||
f"the choice between them should turn on the conviction "
|
||||
f"in the strategy, the tax fit and the price paid, not "
|
||||
f"on the statistics - they are the same kind of "
|
||||
f"position.")
|
||||
cp = srow.get("corr_portfolio")
|
||||
if isinstance(cp, (int, float)):
|
||||
bot.append(
|
||||
f"Its correlation with your current portfolio is "
|
||||
f"{cp:+.2f} - "
|
||||
+ ("a genuine diversifier" if cp < 0.3
|
||||
else "not very diversified vs what you already own".rstrip("."))
|
||||
+ ".")
|
||||
out.append(" ".join(bot))
|
||||
return out
|
||||
|
||||
|
||||
def main() -> None:
|
||||
from fundlab.nport import FUND_TOKENS
|
||||
from fundlab.decompose import ALIAS
|
||||
cand = [v["sym"] for v in _r.SEARCH.values()
|
||||
if isinstance(v, dict)
|
||||
and str(v.get("verdict", "")).startswith("CANDIDATE")]
|
||||
short = [s for s in FUND_TOKENS if s not in ALIAS]
|
||||
for s in cand + short:
|
||||
print(f"=== {s.upper()} ===")
|
||||
for para in narrate(s):
|
||||
print(para)
|
||||
print()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
1
fundlab/overnight.pid
Normal file
1
fundlab/overnight.pid
Normal file
|
|
@ -0,0 +1 @@
|
|||
5847
|
||||
36
fundlab/overnight_rescreen.log
Normal file
36
fundlab/overnight_rescreen.log
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
15:09:56 === stage screen ===
|
||||
15:09:56 screen: 2384 funds, 2384 to do
|
||||
15:10:29 screen: 100/2384
|
||||
15:11:01 screen: 200/2384
|
||||
15:11:33 screen: 300/2384
|
||||
15:12:04 screen: 400/2384
|
||||
15:12:36 screen: 500/2384
|
||||
15:13:09 screen: 600/2384
|
||||
15:13:42 screen: 700/2384
|
||||
15:14:15 screen: 800/2384
|
||||
15:14:45 screen: 900/2384
|
||||
15:15:20 screen: 1000/2384
|
||||
15:15:56 screen: 1100/2384
|
||||
15:16:31 screen: 1200/2384
|
||||
15:17:07 screen: 1300/2384
|
||||
15:17:38 screen: 1400/2384
|
||||
15:18:14 screen: 1500/2384
|
||||
15:18:45 screen: 1600/2384
|
||||
15:19:16 screen: 1700/2384
|
||||
15:19:47 screen: 1800/2384
|
||||
15:20:19 screen: 1900/2384
|
||||
15:20:51 screen: 2000/2384
|
||||
15:21:23 screen: 2100/2384
|
||||
15:21:54 screen: 2200/2384
|
||||
15:22:26 screen: 2300/2384
|
||||
15:22:53 screen done: 2384 funds
|
||||
15:22:53 === stage finalize ===
|
||||
15:22:53 finalize: 2384 funds screened
|
||||
15:22:53 1339 sleeve mix
|
||||
15:22:53 1001 weak/unstable alpha
|
||||
15:22:53 17 no 5y window
|
||||
15:22:53 11 CANDIDATE
|
||||
15:22:53 10 alpha, but correlated with current portfolio
|
||||
15:22:53 6 alpha in 5y window, but not persistent
|
||||
15:22:53 candidates v1 name-filter would have missed: ['aguax', 'etsix', 'femdx', 'hicox', 'prfrx', 'puls', 'rctix', 'rpifx', 'scfzx']
|
||||
15:22:53 === overnight run finished in 0.2h ===
|
||||
98
fundlab/refback.log
Normal file
98
fundlab/refback.log
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
[2026-08-30 15:40:42] rows=2384 todo=2384
|
||||
[2026-08-30 15:40:48] 25/2384 done (saved)
|
||||
[2026-08-30 15:40:53] 50/2384 done (saved)
|
||||
[2026-08-30 15:40:59] 75/2384 done (saved)
|
||||
[2026-08-30 15:41:04] 100/2384 done (saved)
|
||||
[2026-08-30 15:41:10] 125/2384 done (saved)
|
||||
[2026-08-30 15:41:16] 150/2384 done (saved)
|
||||
[2026-08-30 15:41:22] 175/2384 done (saved)
|
||||
[2026-08-30 15:41:28] 200/2384 done (saved)
|
||||
[2026-08-30 15:41:33] 225/2384 done (saved)
|
||||
[2026-08-30 15:41:39] 250/2384 done (saved)
|
||||
[2026-08-30 15:41:45] 275/2384 done (saved)
|
||||
[2026-08-30 15:41:51] 300/2384 done (saved)
|
||||
[2026-08-30 15:41:57] 325/2384 done (saved)
|
||||
[2026-08-30 15:42:03] 350/2384 done (saved)
|
||||
[2026-08-30 15:42:08] 375/2384 done (saved)
|
||||
[2026-08-30 15:42:14] 400/2384 done (saved)
|
||||
[2026-08-30 15:42:20] 425/2384 done (saved)
|
||||
[2026-08-30 15:42:26] 450/2384 done (saved)
|
||||
[2026-08-30 15:42:32] 475/2384 done (saved)
|
||||
[2026-08-30 15:42:37] 500/2384 done (saved)
|
||||
[2026-08-30 15:42:42] 525/2384 done (saved)
|
||||
[2026-08-30 15:42:48] 550/2384 done (saved)
|
||||
[2026-08-30 15:42:54] 575/2384 done (saved)
|
||||
[2026-08-30 15:43:00] 600/2384 done (saved)
|
||||
[2026-08-30 15:43:06] 625/2384 done (saved)
|
||||
[2026-08-30 15:43:11] 650/2384 done (saved)
|
||||
[2026-08-30 15:43:18] 675/2384 done (saved)
|
||||
[2026-08-30 15:43:24] 700/2384 done (saved)
|
||||
[2026-08-30 15:43:29] 725/2384 done (saved)
|
||||
[2026-08-30 15:43:36] 750/2384 done (saved)
|
||||
[2026-08-30 15:43:42] 775/2384 done (saved)
|
||||
[2026-08-30 15:43:48] 800/2384 done (saved)
|
||||
[2026-08-30 15:43:53] 825/2384 done (saved)
|
||||
[2026-08-30 15:43:59] 850/2384 done (saved)
|
||||
[2026-08-30 15:44:05] 875/2384 done (saved)
|
||||
[2026-08-30 15:44:10] 900/2384 done (saved)
|
||||
[2026-08-30 15:44:16] 925/2384 done (saved)
|
||||
[2026-08-30 15:44:22] 950/2384 done (saved)
|
||||
[2026-08-30 15:44:28] 975/2384 done (saved)
|
||||
[2026-08-30 15:44:34] 1000/2384 done (saved)
|
||||
[2026-08-30 15:44:39] 1025/2384 done (saved)
|
||||
[2026-08-30 15:44:45] 1050/2384 done (saved)
|
||||
[2026-08-30 15:44:51] 1075/2384 done (saved)
|
||||
[2026-08-30 15:44:56] 1100/2384 done (saved)
|
||||
[2026-08-30 15:45:02] 1125/2384 done (saved)
|
||||
[2026-08-30 15:45:08] 1150/2384 done (saved)
|
||||
[2026-08-30 15:45:14] 1175/2384 done (saved)
|
||||
[2026-08-30 15:45:19] 1200/2384 done (saved)
|
||||
[2026-08-30 15:45:25] 1225/2384 done (saved)
|
||||
[2026-08-30 15:45:31] 1250/2384 done (saved)
|
||||
[2026-08-30 15:45:36] 1275/2384 done (saved)
|
||||
[2026-08-30 15:45:42] 1300/2384 done (saved)
|
||||
[2026-08-30 15:45:47] 1325/2384 done (saved)
|
||||
[2026-08-30 15:45:53] 1350/2384 done (saved)
|
||||
[2026-08-30 15:45:59] 1375/2384 done (saved)
|
||||
[2026-08-30 15:46:04] 1400/2384 done (saved)
|
||||
[2026-08-30 15:46:10] 1425/2384 done (saved)
|
||||
[2026-08-30 15:46:16] 1450/2384 done (saved)
|
||||
[2026-08-30 15:46:22] 1475/2384 done (saved)
|
||||
[2026-08-30 15:46:28] 1500/2384 done (saved)
|
||||
[2026-08-30 15:46:33] 1525/2384 done (saved)
|
||||
[2026-08-30 15:46:38] 1550/2384 done (saved)
|
||||
[2026-08-30 15:46:44] 1575/2384 done (saved)
|
||||
[2026-08-30 15:46:49] 1600/2384 done (saved)
|
||||
[2026-08-30 15:46:55] 1625/2384 done (saved)
|
||||
[2026-08-30 15:47:01] 1650/2384 done (saved)
|
||||
[2026-08-30 15:47:06] 1675/2384 done (saved)
|
||||
[2026-08-30 15:47:12] 1700/2384 done (saved)
|
||||
[2026-08-30 15:47:18] 1725/2384 done (saved)
|
||||
[2026-08-30 15:47:24] 1750/2384 done (saved)
|
||||
[2026-08-30 15:47:30] 1775/2384 done (saved)
|
||||
[2026-08-30 15:47:35] 1800/2384 done (saved)
|
||||
[2026-08-30 15:47:41] 1825/2384 done (saved)
|
||||
[2026-08-30 15:47:47] 1850/2384 done (saved)
|
||||
[2026-08-30 15:47:53] 1875/2384 done (saved)
|
||||
[2026-08-30 15:47:59] 1900/2384 done (saved)
|
||||
[2026-08-30 15:48:05] 1925/2384 done (saved)
|
||||
[2026-08-30 15:48:10] 1950/2384 done (saved)
|
||||
[2026-08-30 15:48:16] 1975/2384 done (saved)
|
||||
[2026-08-30 15:48:22] 2000/2384 done (saved)
|
||||
[2026-08-30 15:48:28] 2025/2384 done (saved)
|
||||
[2026-08-30 15:48:33] 2050/2384 done (saved)
|
||||
[2026-08-30 15:48:39] 2075/2384 done (saved)
|
||||
[2026-08-30 15:48:45] 2100/2384 done (saved)
|
||||
[2026-08-30 15:48:51] 2125/2384 done (saved)
|
||||
[2026-08-30 15:48:57] 2150/2384 done (saved)
|
||||
[2026-08-30 15:49:03] 2175/2384 done (saved)
|
||||
[2026-08-30 15:49:09] 2200/2384 done (saved)
|
||||
[2026-08-30 15:49:15] 2225/2384 done (saved)
|
||||
[2026-08-30 15:49:21] 2250/2384 done (saved)
|
||||
[2026-08-30 15:49:27] 2275/2384 done (saved)
|
||||
[2026-08-30 15:49:33] 2300/2384 done (saved)
|
||||
[2026-08-30 15:49:38] 2325/2384 done (saved)
|
||||
[2026-08-30 15:49:44] 2350/2384 done (saved)
|
||||
[2026-08-30 15:49:50] 2375/2384 done (saved)
|
||||
[2026-08-30 15:49:52] 2384/2384 done (saved)
|
||||
[2026-08-30 15:49:52] done: 2384 rows carry a reference
|
||||
76
fundlab/refback.py
Normal file
76
fundlab/refback.py
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
"""Backfill the per-fund alpha REFERENCE into search_all.json.
|
||||
|
||||
The alpha search verdict (fundlab/search.py) computes alpha as the OLS
|
||||
intercept of the fund's daily total returns against the sleeves BIC
|
||||
forward-selection picked from the 21 broad sleeve axes (the same set for
|
||||
every fund). The picked sleeves ARE the fund's reference - a fitted
|
||||
sleeve mix, not a single index - but the screen never stored them, so
|
||||
the app couldn't show them.
|
||||
|
||||
This script recomputes the forward selection (full + last-5y) for every
|
||||
screened fund and stores a compact, human-readable reference string on
|
||||
each row:
|
||||
|
||||
ref_5y "ivv +0.62, tlt +0.31" (sleeves picked for the 5y model)
|
||||
ref_full "ivv +0.38, efa +0.15, ..."
|
||||
"pure alpha (no sleeve selected)" when the model has no components
|
||||
|
||||
Resumable: rows that already carry ref_5y are skipped.
|
||||
|
||||
Run: .venv/bin/python -m fundlab.refback (logs to fundlab/refback.log)
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import time
|
||||
|
||||
from fundlab import decompose
|
||||
from fundlab.searchlist import BROAD_SLEEVES
|
||||
|
||||
HERE = __import__("pathlib").Path(__file__).parent
|
||||
SRC = HERE / "search_all.json"
|
||||
LOG = HERE / "refback.log"
|
||||
|
||||
|
||||
def log(msg: str) -> None:
|
||||
line = f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] {msg}"
|
||||
print(line, flush=True)
|
||||
with LOG.open("a") as f:
|
||||
f.write(line + "\n")
|
||||
|
||||
|
||||
def _fmt(m: dict) -> str:
|
||||
comps = m.get("components") or []
|
||||
if not comps:
|
||||
return "pure alpha (no sleeve selected)"
|
||||
return ", ".join(f"{c['sym']} {c['beta']:+.2f}" for c in comps)
|
||||
|
||||
|
||||
def run() -> None:
|
||||
d = json.loads(SRC.read_text())
|
||||
todo = [k for k, v in d.items()
|
||||
if isinstance(v, dict)
|
||||
and isinstance(v.get("r2_5y"), (int, float))
|
||||
and "ref_5y" not in v]
|
||||
log(f"rows={len(d)} todo={len(todo)}")
|
||||
for i, k in enumerate(todo, 1):
|
||||
sym = d[k]["sym"]
|
||||
try:
|
||||
rec = decompose.decompose(sym, start=decompose.RECENT_WINDOW,
|
||||
candidates={sym: BROAD_SLEEVES})
|
||||
full = decompose.decompose(sym, candidates={sym: BROAD_SLEEVES})
|
||||
d[k]["ref_5y"] = _fmt(rec)
|
||||
d[k]["ref_full"] = _fmt(full)
|
||||
except Exception as e: # noqa: BLE001 - batch must not die
|
||||
d[k]["ref_5y"] = f"(backfill failed: {e})"
|
||||
if i % 25 == 0 or i == len(todo):
|
||||
SRC.write_text(json.dumps(d, indent=1))
|
||||
log(f"{i}/{len(todo)} done (saved)")
|
||||
SRC.write_text(json.dumps(d, indent=1))
|
||||
n = sum(1 for v in d.values()
|
||||
if isinstance(v, dict) and v.get("ref_5y"))
|
||||
log(f"done: {n} rows carry a reference")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
run()
|
||||
835
fundlab/report.py
Normal file
835
fundlab/report.py
Normal file
|
|
@ -0,0 +1,835 @@
|
|||
"""Fund report: candidates + shortlist, self-contained HTML.
|
||||
|
||||
One section per fund:
|
||||
- equity curve over the maximum available period (fund vs its fitted
|
||||
reference mix vs IVV),
|
||||
- performance: full history, calendar years, and the defined market
|
||||
episodes (2022 bear, 2023 rate shock, 2024 vol spike, 2025 tariff
|
||||
crash, 2026 Q1) - fund vs reference mix vs IVV, with the fund-vs-
|
||||
reference gap (period alpha/timing),
|
||||
- what drove it: the excess-of-T-bill sleeve loadings (full + 5y),
|
||||
alpha + t, R^2, rolling drift, verdict,
|
||||
- the reference mix explained: each picked sleeve with what it
|
||||
actually exposes you to (not just the ticker),
|
||||
- tax character + taxable/IRA placement,
|
||||
- cluster peers: the 3-4 best funds of the same k=30 return-driver
|
||||
cluster, compared, with this fund's advantages/disadvantages.
|
||||
|
||||
Run: .venv/bin/python -m fundlab.report -> reports/fund_report.html
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import html
|
||||
import json
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
|
||||
from fundlab import cluster as _cl
|
||||
from fundlab import decompose
|
||||
from fundlab import factors
|
||||
from fundlab.searchlist import BROAD_SLEEVES
|
||||
|
||||
HERE = Path(__file__).parent
|
||||
REPORTS = HERE.parent / "reports"
|
||||
REPORTS.mkdir(exist_ok=True)
|
||||
OUT = REPORTS / "fund_report.html"
|
||||
|
||||
TAX = json.loads((HERE / "taxplan_results.json").read_text())
|
||||
DD = json.loads((HERE / "drawdown_results.json").read_text())
|
||||
FACTOR = json.loads((HERE / "factor_results.json").read_text())
|
||||
SEARCH = json.loads((HERE / "search_all.json").read_text())
|
||||
DECOMP = json.loads((HERE / "decompose_results.json").read_text())
|
||||
FONDS = json.loads((HERE.parent / "funds.json").read_text())
|
||||
KMEANS = json.loads((HERE / "cluster_kmeans.json").read_text())
|
||||
|
||||
# ------------------------------------------------------------------ sleeves
|
||||
# what each sleeve actually EXPOSES you to (the report must explain the
|
||||
# exposure, not just name the ticker)
|
||||
SLEEVE_DESC = {
|
||||
"qqq": ("US large growth (Nasdaq-100)",
|
||||
"growth/tech-heavy US equities; high sensitivity to earnings "
|
||||
"surprises and long-end rates (duration of growth cash flows)"),
|
||||
"ivv": ("US large blend (S&P 500)",
|
||||
"core US equity market; the default 'own the economy' exposure"),
|
||||
"iwm": ("US small cap (Russell 2000)",
|
||||
"small-cap cycle: domestic credit, margin pressure, IPO window"),
|
||||
"vea": ("Intl developed ex-US (Vanguard)",
|
||||
"developed-market equities outside the US (EU, Japan, UK); FX-"
|
||||
"hedged-off, currency moves matter"),
|
||||
"efa": ("Intl developed ex-US (MSCI EAFE)",
|
||||
"developed-market equities outside the US; same exposure as VEA "
|
||||
"via a different index provider"),
|
||||
"vwo": ("Emerging-market equity",
|
||||
"EM corporate profits + EM currency + China/FX flows; "
|
||||
"high-vol, high-carry, dollar-sensitive"),
|
||||
"vnq": ("US REITs",
|
||||
"physical real estate: rents vs rates, leverage in the property "
|
||||
"sector; equity-like income"),
|
||||
"bil": ("1-3 month T-bills (cash)",
|
||||
"the risk-free rate itself; ~zero volatility, pure carry"),
|
||||
"shv": ("0-3 month T-bills (ultra-short cash)",
|
||||
"the risk-free rate itself; netted out of the excess-return "
|
||||
"regression, shown only as part of a fund's cash position"),
|
||||
"shy": ("1-3 year Treasuries (short duration)",
|
||||
"short duration: modest rate sensitivity, ~cash-plus-carry"),
|
||||
"ief": ("7-10 year Treasuries (core duration)",
|
||||
"the core rate bet: price moves when the Fed path changes"),
|
||||
"tlt": ("20+ year Treasuries (long duration)",
|
||||
"levered duration: big moves on rate expectations, steepener/"
|
||||
"bull-steepener exposure"),
|
||||
"vblix": ("VIX futures (pure vol axis)",
|
||||
"crash insurance / short-vol funding; positive loading = "
|
||||
"long-vol (rises in panic), negative = short-vol carry"),
|
||||
"agg": ("Aggregate bonds (Treasuries + IG credit)",
|
||||
"the core bond market: ~60% Treasuries, IG corporates, MBS; "
|
||||
"moderate duration"),
|
||||
"vweax": ("High-yield corporate bonds",
|
||||
"credit spread cycle: HY junk yields, default risk in "
|
||||
"recessions, strong carry in stable times"),
|
||||
"hyg": ("High-yield corporate bonds (iShares)",
|
||||
"same HY credit-spread exposure as VWEAX via a different fund"),
|
||||
"vmbix": ("Agency RMBS (mortgage-backed)",
|
||||
"mortgage credit + prepayment/extension risk; the refi cycle"),
|
||||
"lqd": ("Investment-grade corporate bonds",
|
||||
"IG credit spreads over Treasuries; milder default risk than HY"),
|
||||
"finux": ("Intl bonds (Fidelity; TERMINATED 2017)",
|
||||
"non-US credit/duration; data ends 2017 so recent windows "
|
||||
"never use it"),
|
||||
"pff": ("Preferred stocks",
|
||||
"hybrid: fixed-rate equity-like instruments; rate + credit + "
|
||||
"equity risk in one"),
|
||||
"emb": ("Emerging-market debt",
|
||||
"EM sovereign/corporate carry; EM currency + dollar cycle"),
|
||||
"tip": ("TIPS (inflation-linked Treasuries)",
|
||||
"breakeven inflation exposure: rises when inflation "
|
||||
"expectations rise"),
|
||||
"vtv": ("US value",
|
||||
"cheap/asset-rich US names (financials, energy, cyclicals); "
|
||||
"value-vs-growth style cycle"),
|
||||
"dbmf": ("CTA / managed futures",
|
||||
"trend-following across futures; long in crises, earns "
|
||||
"un-correlated carry otherwise"),
|
||||
"dbb": ("Broad commodities",
|
||||
"commodity basket: inflation hedge + global growth proxy"),
|
||||
"djp": ("Natural gas",
|
||||
"a single volatile commodity: winter/hedging cycles"),
|
||||
"gsg": ("Broad commodities (SPDR)",
|
||||
"same commodity exposure as DBB via a different fund"),
|
||||
"gld": ("Gold",
|
||||
"crisis/inflation hedge; real-rate sensitive, no yield"),
|
||||
"fxe": ("Long euros vs the dollar",
|
||||
"EUR/USD: carries the euro interest-rate differential"),
|
||||
"fxy": ("Long yen vs the dollar",
|
||||
"USD/JPY: carries the Japan rate differential; carry-trade "
|
||||
"crowding risk"),
|
||||
"xlk": ("US tech sector", "the tech sector index"),
|
||||
"xlf": ("US financials sector", "banks/insurance: rate + credit cycle"),
|
||||
"xle": ("US energy sector", "oil prices + US drilling"),
|
||||
"xlv": ("US healthcare sector", "defensive pharma/providers"),
|
||||
"xlp": ("US staples sector", "defensive consumer"),
|
||||
"xlu": ("US utilities sector", "bond-proxy utilities; rate sensitive"),
|
||||
"xly": ("US consumer discretionary", "cyclicals: autos, retail, "
|
||||
"leisure; earnings cycle"),
|
||||
"xlb": ("US materials sector", "industrial materials: capex cycle"),
|
||||
}
|
||||
|
||||
|
||||
def sleeve_desc(sym: str) -> tuple[str, str]:
|
||||
return SLEEVE_DESC.get(sym, (sym.upper(), "no description on file"))
|
||||
|
||||
|
||||
# ------------------------------------------------------------------ data
|
||||
def price(sym: str) -> pd.Series | None:
|
||||
f = decompose.DATA / f"{sym.lower()}-history.csv"
|
||||
if not f.exists():
|
||||
return None
|
||||
try:
|
||||
s = (pd.read_csv(f, parse_dates=["Date"], index_col="Date")
|
||||
["Adj Close"].dropna())
|
||||
s = s[~s.index.duplicated(keep="last")].sort_index()
|
||||
except Exception:
|
||||
return None
|
||||
return s if len(s) > 40 else None
|
||||
|
||||
|
||||
EPISODES = [] # (label, start, end) from the drawdown engine
|
||||
for _e in DD["episodes"]:
|
||||
EPISODES.append((_e["label"], pd.Timestamp(_e["peak"]),
|
||||
pd.Timestamp(_e["trough"])))
|
||||
|
||||
# k=30 cluster membership (sym -> cluster id/label)
|
||||
MEMBER = {}
|
||||
for _c, _v in KMEANS["clusters"].items():
|
||||
for _s in _v["syms"]:
|
||||
MEMBER[_s] = (_c, _v["label"], _v["n"])
|
||||
|
||||
|
||||
def loading_matrix_cached():
|
||||
return _cl.loading_matrix()
|
||||
|
||||
|
||||
CENTROIDS = {} # sym -> (cluster, centroid) for NEW points
|
||||
|
||||
|
||||
def _centroids(syms: list[str], V: np.ndarray) -> dict[int, np.ndarray]:
|
||||
lab = _cl.kmeans(_cl.emphasized(V, _cl.AXES.index("cash")), 30)
|
||||
out = {}
|
||||
for c in range(30):
|
||||
idx = [i for i, l in enumerate(lab) if l == c]
|
||||
if idx:
|
||||
out[c] = np.median(V[idx], 0)
|
||||
return out
|
||||
|
||||
|
||||
def cluster_of_row(row: np.ndarray) -> tuple[str, str]:
|
||||
"""Assign a new loading row to the k=30 scheme (distance to cluster
|
||||
medians in the emphasized space)."""
|
||||
global CENTROIDS
|
||||
if not CENTROIDS:
|
||||
syms, V = loading_matrix_cached()
|
||||
CENTROIDS = _centroids(syms, V)
|
||||
r = row.copy()
|
||||
r[_cl.AXES.index("cash")] *= _cl.CASH_EMPHASIS
|
||||
best, bd = None, None
|
||||
for c, cent in CENTROIDS.items():
|
||||
d = float(np.sum((r - cent) ** 2))
|
||||
if bd is None or d < bd:
|
||||
best, bd = c, d
|
||||
for c, v in KMEANS["clusters"].items():
|
||||
if int(c) == best:
|
||||
return (c, v["label"])
|
||||
return (str(best), "?")
|
||||
|
||||
|
||||
def factor_row(sym: str) -> dict:
|
||||
"""Full + 5y excess-of-T-bill loadings for ANY fund (shortlist funds
|
||||
are not in the 2,384 factor file)."""
|
||||
if sym in FACTOR:
|
||||
return FACTOR[sym]
|
||||
r = factors.factor_screen(sym)
|
||||
return r or {}
|
||||
|
||||
|
||||
_FWD: dict = {}
|
||||
|
||||
|
||||
def ref_components(sym: str, fr: dict, window: str = "rec5") -> list[dict]:
|
||||
"""The fund's FORWARD-SELECTED reference (the mix its alpha is
|
||||
measured against): BIC-gated selection from the 21 broad sleeves,
|
||||
excess-of-T-bill. Recomputed (cached) because the screen stored only
|
||||
the display strings. Falls back to the 34-sleeve OLS loadings when
|
||||
the fund is not in the search universe."""
|
||||
key = (sym, window)
|
||||
if key in _FWD:
|
||||
return _FWD[key]
|
||||
out = None
|
||||
try:
|
||||
m = decompose.decompose(sym, start=decompose.RECENT_WINDOW
|
||||
if window == "rec5" else None,
|
||||
candidates={sym: BROAD_SLEEVES})
|
||||
if m.get("components"):
|
||||
out = [{"sym": c["sym"], "beta": c["beta"]}
|
||||
for c in m["components"]]
|
||||
except Exception:
|
||||
out = None
|
||||
if out is None:
|
||||
comps = (fr.get(window) or fr.get("full") or {}).get("betas") or {}
|
||||
out = [{"sym": s, "beta": b} for s, b in sorted(
|
||||
comps.items(), key=lambda kv: -abs(kv[1])) if abs(b) >= 0.08]
|
||||
_FWD[key] = out
|
||||
return out
|
||||
|
||||
|
||||
def search_row(sym: str) -> dict:
|
||||
return SEARCH.get(sym, {})
|
||||
|
||||
|
||||
def decomp_row(sym: str) -> dict:
|
||||
return DECOMP.get(sym, {})
|
||||
|
||||
|
||||
def tax_row(sym: str) -> dict:
|
||||
up = sym.upper()
|
||||
if up in TAX["shortlist"]:
|
||||
return TAX["shortlist"][up]
|
||||
for k in (sym, up, sym.lower()):
|
||||
if k in TAX["candidates"]:
|
||||
return TAX["candidates"][k]
|
||||
return {}
|
||||
|
||||
|
||||
def dd_row(sym: str) -> dict:
|
||||
return DD["funds"].get(sym, {})
|
||||
|
||||
|
||||
# ------------------------------------------------------------------ stats
|
||||
def perf_stats(p: pd.Series, rf_annual: float = 0.037) -> dict:
|
||||
r = p.pct_change().dropna()
|
||||
years = (p.index[-1] - p.index[0]).days / 365.25
|
||||
cagr = (p.iloc[-1] / p.iloc[0]) ** (1 / years) - 1 if years > 0.5 else np.nan
|
||||
vol = r.std() * np.sqrt(252)
|
||||
roll_max = p.cummax()
|
||||
mdd = float(((p / roll_max) - 1).min())
|
||||
sharpe = (cagr - rf_annual) / vol if vol > 0 else np.nan
|
||||
return {"start": str(p.index[0].date()), "end": str(p.index[-1].date()),
|
||||
"years": years, "cagr": cagr, "vol": vol, "mdd": mdd,
|
||||
"sharpe": sharpe}
|
||||
|
||||
|
||||
def window_ret(p: pd.Series, a, b) -> float | None:
|
||||
s = p[(p.index >= a) & (p.index <= b)]
|
||||
if len(s) < 2:
|
||||
return None
|
||||
return float(s.iloc[-1] / s.iloc[0] - 1)
|
||||
|
||||
|
||||
def annual_table(p: pd.Series, n: int = 8) -> list[tuple[str, float]]:
|
||||
yr = p.resample("YE").last().dropna()
|
||||
out = []
|
||||
for i in range(len(yr) - 1):
|
||||
lab = str(yr.index[i].year)
|
||||
if i == 0:
|
||||
continue
|
||||
out.append((lab, float(yr.iloc[i] / yr.iloc[i - 1] - 1)))
|
||||
# partial current year from last full year-end
|
||||
out.append(("YTD", float(p.iloc[-1] / yr.iloc[-1] - 1)))
|
||||
return out[-(n + 1):]
|
||||
|
||||
|
||||
def mix_series(refs: list[dict]) -> pd.Series | None:
|
||||
"""Fitted reference mix: sum of beta * sleeve daily returns, cumulated
|
||||
to a price path (rebased 100). Pure beta path - the fund minus this
|
||||
is the alpha path."""
|
||||
if not refs:
|
||||
b = price("bil")
|
||||
if b is None:
|
||||
return None
|
||||
return 100 * b / b.iloc[0]
|
||||
idx = None
|
||||
for c in refs:
|
||||
p = price(c["sym"])
|
||||
if p is None:
|
||||
continue
|
||||
r = c["beta"] * p.pct_change()
|
||||
idx = r if idx is None else idx.combine(r, lambda x, y: x + y,
|
||||
fill_value=0.0)
|
||||
if idx is None:
|
||||
return None
|
||||
idx = idx.fillna(0.0)
|
||||
path = (1 + idx).cumprod()
|
||||
return 100 * path / path.iloc[0]
|
||||
|
||||
|
||||
# ------------------------------------------------------------------ html
|
||||
PLOTLY_JS = ""
|
||||
|
||||
|
||||
def load_plotly():
|
||||
global PLOTLY_JS
|
||||
try:
|
||||
import plotly
|
||||
PLOTLY_JS = plotly.offline.get_plotlyjs()
|
||||
except Exception:
|
||||
PLOTLY_JS = None
|
||||
|
||||
|
||||
def fig_html(fig, h: int = 420) -> str:
|
||||
import plotly.io as pio
|
||||
s = pio.to_html(fig, full_html=False, include_plotlyjs=False,
|
||||
config={"displayModeBar": False}, div_id="")
|
||||
return s.replace("<div>", f'<div style="height:{h}px">')
|
||||
|
||||
|
||||
def equity_figure(sym: str, name: str, refs: list[dict]) -> str:
|
||||
import plotly.graph_objects as go
|
||||
p = price(sym)
|
||||
if p is None:
|
||||
return "<p>No local price history.</p>"
|
||||
fig = go.Figure()
|
||||
fig.add_trace(go.Scatter(x=p.index, y=100 * p / p.iloc[0],
|
||||
name=sym.upper(), line=dict(width=2)))
|
||||
m = mix_series(refs)
|
||||
if m is not None:
|
||||
fig.add_trace(go.Scatter(x=m.index, y=m, name="fitted reference",
|
||||
line=dict(width=1.2, dash="dash")))
|
||||
iv = price("ivv")
|
||||
if iv is not None:
|
||||
fig.add_trace(go.Scatter(
|
||||
x=iv.index, y=100 * iv / iv.iloc[0], name="IVV (S&P 500)",
|
||||
line=dict(width=1, dash="dot"), opacity=0.7))
|
||||
fig.update_layout(height=430, margin=dict(l=10, r=10, t=30, b=10),
|
||||
title=f"{html.escape(name)} - total return since "
|
||||
f"{p.index[0].year} (rebased 100)",
|
||||
legend=dict(orientation="h", y=1.08),
|
||||
hovermode="x unified")
|
||||
return fig_html(fig)
|
||||
|
||||
|
||||
def fmt_pct(x, nd=1, sign=True):
|
||||
if x is None or (isinstance(x, float) and np.isnan(x)):
|
||||
return "—"
|
||||
s = f"{100 * x:+.{nd}f}%" if sign else f"{100 * x:.{nd}f}%"
|
||||
return s
|
||||
|
||||
|
||||
def fmt_r2(x):
|
||||
return "—" if x is None or (isinstance(x, float) and np.isnan(x)) \
|
||||
else f"{x:.2f}"
|
||||
|
||||
|
||||
def perf_table(p: pd.Series, refs: list[dict]) -> str:
|
||||
m = mix_series(refs)
|
||||
iv = price("ivv")
|
||||
rows = []
|
||||
|
||||
def add(label, a, b, ann=False):
|
||||
fr_ = window_ret(p, a, b)
|
||||
mr = window_ret(m, a, b) if m is not None else None
|
||||
ir = window_ret(iv, a, b) if iv is not None else None
|
||||
gap = (fr_ - mr) if (fr_ is not None and mr is not None) else None
|
||||
rows.append(f"<tr><td>{label}</td>"
|
||||
f"<td>{fmt_pct(fr_)}</td><td>{fmt_pct(mr)}</td>"
|
||||
f"<td>{fmt_pct(ir)}</td><td>{fmt_pct(gap)}</td></tr>")
|
||||
|
||||
st = perf_stats(p)
|
||||
add("Full history", st["start"], st["end"])
|
||||
add("Last 5y", "2021-01-01", st["end"])
|
||||
add("Last 1y", "2025-09-01", st["end"])
|
||||
for lab, a, b in EPISODES:
|
||||
add(lab, a, b)
|
||||
# calendar years (last 6)
|
||||
yr = p.resample("YE").last().dropna()
|
||||
years = [str(yr.index[i].year) for i in range(1, len(yr))][-6:]
|
||||
for i, y in enumerate(years):
|
||||
a = f"{y}-01-01"
|
||||
b = f"{int(y) + 1}-01-01" if i < len(years) - 1 else st["end"]
|
||||
add(y, a, b)
|
||||
return ('<table><tr><th>period</th><th>fund</th><th>reference</th>'
|
||||
'<th>IVV</th><th>fund − ref</th></tr>' + "".join(rows)
|
||||
+ '</table><p class="small">fund − reference = period '
|
||||
'alpha/timing (the part of that period the sleeve mix does '
|
||||
'not explain). IVV shown for scale - for non-equity funds '
|
||||
'the IVV column is only context.</p>')
|
||||
|
||||
|
||||
def drivers_section(fr: dict, dr: dict, srow: dict) -> str:
|
||||
out = []
|
||||
if srow:
|
||||
a5 = srow.get("alpha_ann_5y")
|
||||
t5 = srow.get("alpha_t_5y")
|
||||
r25 = srow.get("r2_5y")
|
||||
if isinstance(r25, (int, float)) or isinstance(a5, (int, float)):
|
||||
out.append(
|
||||
f"<p><b>Reference model, last 5 years:</b> R² = "
|
||||
f"{fmt_r2(r25 if isinstance(r25, (int, float)) else None)}, "
|
||||
f"alpha = {fmt_pct(a5) if isinstance(a5, (int, float)) else '—'}"
|
||||
f"{' (t = ' + format(t5, '+.1f') + ')' if isinstance(t5, (int, float)) else ''} "
|
||||
f"vs the fitted reference mix (next section).")
|
||||
rf = (fr.get("full") or {}).get("alpha_ann")
|
||||
tf = (fr.get("full") or {}).get("alpha_t")
|
||||
r2f = srow.get("r2_full")
|
||||
if isinstance(r2f, (int, float)) or isinstance(rf, (int, float)):
|
||||
out.append(
|
||||
f"<p><b>Reference model, full history:</b> R² = "
|
||||
f"{fmt_r2(r2f if isinstance(r2f, (int, float)) else None)}, "
|
||||
f"alpha = {fmt_pct(rf) if isinstance(rf, (int, float)) else '—'}"
|
||||
f"{' (t = ' + format(tf, '+.1f') + ')' if isinstance(tf, (int, float)) else ''}.</p>")
|
||||
f = fr.get("rec5") or {}
|
||||
betas = f.get("betas") or {}
|
||||
top = sorted(betas.items(), key=lambda kv: -abs(kv[1]))[:6]
|
||||
if top:
|
||||
out.append(
|
||||
"<p><b>Return-driver signature (34 sleeves, for clustering "
|
||||
"context):</b> " + ", ".join(
|
||||
f"{s} {b:+.2f}" for s, b in top) + " - net cash "
|
||||
f"{1 - sum(betas.values()):+.2f}.</p>")
|
||||
# drift + verdict from the curated decomposition, when available
|
||||
if dr and "verdict" in dr:
|
||||
out.append(f"<p><b>Decomposition verdict:</b> "
|
||||
f"{html.escape(dr['verdict'])}</p>")
|
||||
roll = dr.get("rolling") or {}
|
||||
if roll.get("max_drift") is not None:
|
||||
out.append(
|
||||
f"<p>Weight stability: max 1y β-drift = "
|
||||
f"{roll['max_drift']:.2f} (relative to full-sample β; "
|
||||
f"0 = perfectly stable, >1 = the weight is unstable).</p>")
|
||||
note = dr.get("note")
|
||||
if note:
|
||||
out.append(f"<p class='small'>{html.escape(note)}</p>")
|
||||
if srow:
|
||||
v = str(srow.get("verdict", ""))
|
||||
if v:
|
||||
out.append(f"<p><b>Screen verdict:</b> {html.escape(v)}</p>")
|
||||
return "".join(out)
|
||||
|
||||
|
||||
def reference_section(refs: list[dict], refs_curve: list[dict],
|
||||
sym: str) -> str:
|
||||
weak = bool(refs) and not refs_curve
|
||||
caveat = ""
|
||||
if weak:
|
||||
caveat = ("<p class='small'><b>Weak fit - read with care.</b> "
|
||||
"These loadings are each individually significant but "
|
||||
"collectively explain little of the excess return; the "
|
||||
"economically meaningful picture is a mostly-cash "
|
||||
"vehicle with idiosyncratic alpha (the performance "
|
||||
"table anchors to cash, not to this mix).</p>")
|
||||
if not refs:
|
||||
srow = search_row(sym)
|
||||
a = srow.get("alpha_ann_5y")
|
||||
return caveat + ("<p><b>Reference: cash (the T-bill rate itself)."
|
||||
"</b> No "
|
||||
"sleeve passed the forward-selection gates, so the fund's "
|
||||
"excess returns are not explained by any benchmark mix - "
|
||||
f"its entire excess performance is idiosyncratic (5y alpha "
|
||||
f"{fmt_pct(a) if isinstance(a, (int, float)) else '—'}). "
|
||||
"There is no meaningful 'beta' to this fund; it is a "
|
||||
"standalone position.</p>")
|
||||
sb = sum(c["beta"] for c in refs)
|
||||
cash = 1 - sb
|
||||
rows = []
|
||||
for c in refs:
|
||||
nm, desc = sleeve_desc(c["sym"])
|
||||
rows.append(f"<tr><td><b>{c['sym'].upper()}</b> {c['beta']:+.2f}"
|
||||
f"</td><td>{html.escape(nm)}</td>"
|
||||
f"<td>{html.escape(desc)}</td></tr>")
|
||||
cash_line = ""
|
||||
if weak:
|
||||
cash_line = caveat + cash_line
|
||||
if cash > 0.05:
|
||||
cash_line = (f"<p>The loadings sum to {sb:.2f}, i.e. the fund is "
|
||||
f"~{cash:.0%} NET CASH (earns the T-bill rate; adds "
|
||||
f"zero excess alpha).</p>")
|
||||
elif cash < -0.05:
|
||||
cash_line = (f"The loadings sum to {sb:.2f}, i.e. the fund is ~"
|
||||
f"{-cash:.0%} NET LEVERED (borrows at ~the T-bill "
|
||||
f"rate; that financing shows up as negative cash).</p>")
|
||||
return ('<table><tr><th>loading</th><th>what it is</th>'
|
||||
'<th>what it exposes you to</th></tr>' + "".join(rows)
|
||||
+ "</table>" + cash_line
|
||||
+ '<p class="small">The reference is NOT one index - it is '
|
||||
'this fitted mix, rebuilt from the fund\'s own returns. '
|
||||
'"Alpha" everywhere in this report means outperformance vs '
|
||||
'this mix, in excess of the T-bill rate.</p>')
|
||||
|
||||
|
||||
def tax_section(sym: str) -> str:
|
||||
t = tax_row(sym)
|
||||
if not t:
|
||||
return "<p>No tax classification on file.</p>"
|
||||
loc = t.get("location", "?")
|
||||
basis = t.get("basis", "?")
|
||||
conf = {"N-PORT": "from actual N-PORT holdings (high confidence)",
|
||||
"sleeves": "from the return-sleeve mix (model, medium "
|
||||
"confidence)"}.get(basis, basis)
|
||||
notes = html.escape(t.get("notes") or "")
|
||||
rec = {"TAXABLE": "Keep in the <b>taxable</b> account.",
|
||||
"TAXABLE (munis)": "Keep in the <b>taxable</b> account - "
|
||||
"tax-exempt interest is wasted in an IRA.",
|
||||
"TAXABLE (defers to LTCG)": "Keep in the <b>taxable</b> "
|
||||
"account - the income mostly "
|
||||
"defers to the LTCG/ROC rate."}.get(
|
||||
loc, f"Recommended account: <b>{html.escape(loc)}</b>.")
|
||||
return (f"<p>Character score {t.get('score', '?')} "
|
||||
f"({conf}). <b>Placement: {rec}</b></p>"
|
||||
+ (f"<p class='small'>{notes}</p>" if notes else ""))
|
||||
|
||||
|
||||
def cluster_section(sym: str, fr: dict, row: np.ndarray | None) -> str:
|
||||
srow = search_row(sym)
|
||||
if sym in MEMBER:
|
||||
cid, clabel, cn = MEMBER[sym]
|
||||
members = KMEANS["clusters"][cid]["syms"]
|
||||
else:
|
||||
if row is None:
|
||||
return "<p>Not in the cluster scheme (no loading vector).</p>"
|
||||
cid, clabel = cluster_of_row(row)
|
||||
cn = KMEANS["clusters"].get(cid, {}).get("n", 0)
|
||||
members = KMEANS["clusters"].get(cid, {}).get("syms", [])
|
||||
peers = []
|
||||
for s in members:
|
||||
if s == sym:
|
||||
continue
|
||||
v = search_row(s)
|
||||
if not isinstance(v.get("alpha_t_5y"), (int, float)):
|
||||
continue
|
||||
peers.append((v["alpha_t_5y"], v.get("r2_5y") or 0, s, v))
|
||||
# best peers = highest POSITIVE alpha t (a fund with t = -5 is the
|
||||
# cluster's worst, not a peer worth copying); top-4, positives first
|
||||
peers.sort(key=lambda p: (p[0] > 0, p[0]), reverse=True)
|
||||
pos = [p for p in peers if p[0] > 0]
|
||||
peers = (pos + [p for p in peers if p[0] <= 0])[:4]
|
||||
peers = [p[2] for p in peers]
|
||||
if not peers:
|
||||
return (f"<p>In cluster <b>{html.escape(clabel)}</b> (n={cn}) but "
|
||||
"no peer with 5y alpha statistics.</p>")
|
||||
rows = []
|
||||
|
||||
def statline(s: str) -> str:
|
||||
p = price(s)
|
||||
if p is None:
|
||||
return ("—", "—", "—", "—", "—", "n/a")
|
||||
st = perf_stats(p)
|
||||
v = search_row(s)
|
||||
t5 = window_ret(p, "2021-01-01", st["end"])
|
||||
r2 = v.get("r2_5y")
|
||||
a5 = v.get("alpha_ann_5y")
|
||||
tt = v.get("alpha_t_5y")
|
||||
tax = (tax_row(s) or {}).get("location") or "n/a"
|
||||
return (fmt_pct(t5), fmt_pct(st["cagr"]), fmt_pct(st["mdd"]),
|
||||
fmt_r2(r2),
|
||||
(f"{fmt_pct(a5)} (t={tt:+.1f})"
|
||||
if isinstance(a5, (int, float)) else "—"), tax)
|
||||
|
||||
p = price(sym)
|
||||
st = perf_stats(p) if p is not None else {}
|
||||
my = statline(sym)
|
||||
rows.append(f"<tr class='me'><td><b>{sym.upper()} (this fund)</b></td>"
|
||||
+ "".join(f"<td>{x}</td>" for x in my) + "</tr>")
|
||||
for s in peers:
|
||||
rows.append(f"<tr><td>{s.upper()} — "
|
||||
f"{html.escape((search_row(s) or {}).get('name', '')[:40])}"
|
||||
f"</td>" + "".join(f"<td>{x}</td>" for x in statline(s))
|
||||
+ "</tr>")
|
||||
tbl = ('<table><tr><th>fund</th><th>5y</th><th>CAGR</th>'
|
||||
'<th>maxDD</th><th>R² 5y</th><th>alpha 5y</th><th>tax</th></tr>'
|
||||
+ "".join(rows) + "</table>")
|
||||
# advantages / disadvantages: computed deltas vs the peer set
|
||||
adv, dis = [], []
|
||||
if p is not None:
|
||||
t5 = window_ret(p, "2021-01-01", st["end"])
|
||||
vals = {}
|
||||
for s in peers:
|
||||
pp = price(s)
|
||||
if pp is None:
|
||||
continue
|
||||
ss = perf_stats(pp)
|
||||
vals[s] = (window_ret(pp, "2021-01-01", ss["end"]), ss["mdd"],
|
||||
ss["vol"])
|
||||
if vals:
|
||||
best_t5 = max(v[0] for v in vals.values() if v[0] is not None)
|
||||
best_dd = max(v[1] for v in vals.values())
|
||||
low_vol = min(v[2] for v in vals.values())
|
||||
if t5 is not None and t5 >= best_t5 - 0.02:
|
||||
adv.append("5y return at the top of the cluster")
|
||||
elif t5 is not None and t5 < best_t5 - 0.10:
|
||||
dis.append(f"5y return trails the best peer by "
|
||||
f"{100 * (best_t5 - t5):.0f}pp")
|
||||
if st["mdd"] > best_dd + 0.05:
|
||||
dis.append(f"deeper drawdown than the calmest peer "
|
||||
f"({fmt_pct(st['mdd'])} vs {fmt_pct(best_dd)})")
|
||||
elif st["mdd"] < best_dd - 0.05:
|
||||
adv.append("sharpest drawdown in the cluster")
|
||||
if st["vol"] < low_vol - 0.02:
|
||||
adv.append("lowest volatility in the cluster")
|
||||
elif st["vol"] > low_vol + 0.05:
|
||||
dis.append("meaningfully more volatile than the "
|
||||
"calmest peer")
|
||||
txt = ""
|
||||
if adv:
|
||||
txt += "<p><b>Advantages vs peers:</b> " + "; ".join(adv) + ".</p>"
|
||||
if dis:
|
||||
txt += "<p><b>Disadvantages vs peers:</b> " + "; ".join(dis) + ".</p>"
|
||||
if not txt:
|
||||
txt = ("<p>The fund sits in the middle of its cluster - no "
|
||||
"decisive edge on return, drawdown or volatility vs the "
|
||||
"peers; the choice among them should come down to alpha "
|
||||
"quality (t-stat), tax fit and the conviction in the "
|
||||
"strategy.</p>")
|
||||
return (f"<p>Cluster: <b>{html.escape(clabel)}</b> "
|
||||
f"(n={cn}, k=30 grouping by return-driver signature).</p>"
|
||||
+ tbl + txt)
|
||||
|
||||
|
||||
def fund_loading_row(fr: dict) -> np.ndarray:
|
||||
f = fr.get("full") or fr.get("rec5") or {}
|
||||
betas = f.get("betas") or {}
|
||||
row = np.array([betas.get(s, 0.0) or 0.0 for s in factors.DRIVERS],
|
||||
dtype=float)
|
||||
return np.append(row, 1.0 - row.sum())
|
||||
|
||||
|
||||
def strategy_block(sym: str) -> str:
|
||||
f = FONDS.get(sym)
|
||||
if not f:
|
||||
return ""
|
||||
out = ""
|
||||
if f.get("strategy"):
|
||||
out += f"<details><summary>Strategy (excerpt from the filing)</summary>"
|
||||
f"<p class='small'>{html.escape(f['strategy'])}</p></details>"
|
||||
return out
|
||||
|
||||
|
||||
def style_block(sym: str) -> str:
|
||||
from fundlab import styletilt
|
||||
prof = styletilt.style_profile(sym)
|
||||
if not prof or not prof.get("full"):
|
||||
return ""
|
||||
f5 = {x["sym"]: x for x in (prof.get("rec5") or {}).get("factors", [])}
|
||||
rows = []
|
||||
for x in prof["full"]["factors"]:
|
||||
y5 = f5.get(x["sym"], {})
|
||||
if abs(x["t"]) < 2 and abs(y5.get("t", 0) or 0) < 2:
|
||||
continue
|
||||
rows.append(
|
||||
f"<tr><td>{html.escape(x['name'])}</td>"
|
||||
f"<td>{x['beta']:+.2f}</td><td>{x['t']:+.1f}</td>"
|
||||
f"<td>{y5['beta']:+.2f}</td><td>{y5['t']:+.1f}</td>"
|
||||
f"<td>{'✓' if x['sym'] in prof.get('identified', []) else ''}</td></tr>")
|
||||
tbl = ('<table><tr><th>factor</th><th>β full</th><th>t full</th>'
|
||||
'<th>β 5y</th><th>t 5y</th><th>identified</th></tr>'
|
||||
+ "".join(rows) + "</table>")
|
||||
para = "".join(f"<p>{html.escape(p)}</p>" for p in prof.get("commentary", []))
|
||||
return ('<h4>Style tilts</h4>'
|
||||
'<p class="small">22 style/asset sleeves regressed on the '
|
||||
'excess returns of the fund (US funds proxy the global '
|
||||
'factors); "identified" = survived the BIC forward-selection '
|
||||
'gate on the full history.</p>' + tbl + para)
|
||||
|
||||
|
||||
def narrative_block(sym: str) -> str:
|
||||
from fundlab.narrative import narrate
|
||||
return "".join(f"<p>{html.escape(par)}</p>" for par in narrate(sym))
|
||||
|
||||
|
||||
# ------------------------------------------------------------------ build
|
||||
def fund_section(sym: str, title: str, subtitle: str) -> str:
|
||||
fr = factor_row(sym)
|
||||
dr = decomp_row(sym)
|
||||
srow = search_row(sym)
|
||||
name = (srow.get("name") or (FONDS.get(sym) or {}).get("name")
|
||||
or (fr or {}).get("name") or sym.upper())
|
||||
refs = ref_components(sym, fr)
|
||||
load = fund_loading_row(fr) if fr else None
|
||||
# weak-fit (idiosyncratic) funds: the forward-selected mix is a
|
||||
# statistically-thin spec combination (offsetting VIX/duration legs);
|
||||
# anchoring the table to it misleads (a "reference" that loses 79% in
|
||||
# 2022 for a fund that lost 2.4%). Below the fit gate the honest
|
||||
# reference is CASH - the fund IS ~net-cash + idiosyncratic alpha.
|
||||
r25 = srow.get("r2_5y") if isinstance(srow.get("r2_5y"),
|
||||
(int, float)) else None
|
||||
r2f = (fr.get("rec5") or fr.get("full") or {}).get("r2")
|
||||
fit = r25 if r25 is not None else r2f
|
||||
refs_curve = refs if (fit is not None and fit >= 0.5) else []
|
||||
return f"""
|
||||
<h3 id="{sym}">{html.escape(title)}
|
||||
<span class="sub">{html.escape(subtitle)}</span></h3>
|
||||
<div class="fund">{strategy_block(sym)}
|
||||
<h4>Discussion</h4>
|
||||
{narrative_block(sym)}
|
||||
{equity_figure(sym, name, refs_curve)}
|
||||
<h4>Performance</h4>
|
||||
{perf_table(price(sym), refs_curve) if price(sym) is not None else '<p>no price data</p>'}
|
||||
<h4>What drove the returns</h4>
|
||||
{drivers_section(fr, dr, srow)}
|
||||
{style_block(sym)}
|
||||
<h4>The reference mix - and what it exposes you to</h4>
|
||||
{reference_section(refs, refs_curve, sym)}
|
||||
<h4>Tax character & placement</h4>
|
||||
{tax_section(sym)}
|
||||
<h4>Peer comparison (same return-driver cluster)</h4>
|
||||
{cluster_section(sym, fr, load)}
|
||||
</div>"""
|
||||
|
||||
|
||||
def main() -> None:
|
||||
t0 = time.time()
|
||||
load_plotly()
|
||||
print("building report ...", flush=True)
|
||||
|
||||
cand = [v for v in SEARCH.values()
|
||||
if isinstance(v, dict)
|
||||
and str(v.get("verdict", "")).startswith("CANDIDATE")]
|
||||
cand.sort(key=lambda v: -(v.get("alpha_t_5y")
|
||||
if isinstance(v.get("alpha_t_5y"),
|
||||
(int, float)) else -9))
|
||||
|
||||
# shortlist: the 16 actively-managed funds (3 are share classes of
|
||||
# the same fund: pmfkx=pmaix, lcrix=lcorx, egrsx=eagmx)
|
||||
from fundlab.decompose import ALIAS
|
||||
from fundlab.nport import FUND_TOKENS
|
||||
short = [s for s in FUND_TOKENS if s not in ALIAS]
|
||||
|
||||
toc = []
|
||||
body = []
|
||||
for i, v in enumerate(cand, 1):
|
||||
s = v["sym"]
|
||||
toc.append(f'<li><a href="#{s}">{s.upper()}</a> — '
|
||||
f'{html.escape((v.get("name") or "")[:48])}</li>')
|
||||
body.append(fund_section(
|
||||
s, f"C{i:02d} · {s.upper()}",
|
||||
f"{v.get('name', '')} — {str(v.get('verdict', ''))[:60]}"))
|
||||
for i, s in enumerate(short, 1):
|
||||
nm = (FONDS.get(s) or {}).get("name", s.upper())
|
||||
toc.append(f'<li><a href="#{s}">S{i:02d} · {s.upper()}</a> — '
|
||||
f'{html.escape(nm[:48])}</li>')
|
||||
body.append(fund_section(s, f"S{i:02d} · {s.upper()}", nm))
|
||||
|
||||
doc = f"""<!DOCTYPE html>
|
||||
<html><head><meta charset="utf-8">
|
||||
<title>Fund report - candidates & shortlist</title>
|
||||
<style>
|
||||
body {{ font-family: -apple-system, 'Segoe UI', Helvetica, Arial, sans-serif;
|
||||
margin: 0; color: #1a1a2e; background: #fafafa; }}
|
||||
.wrap {{ display: flex; }}
|
||||
nav {{ width: 270px; min-width: 270px; position: sticky; top: 0;
|
||||
height: 100vh; overflow-y: auto; background: #fff;
|
||||
border-right: 1px solid #ddd; padding: 16px; box-sizing: border-box; }}
|
||||
main {{ flex: 1; padding: 24px 36px; max-width: 1150px; }}
|
||||
h1 {{ font-size: 26px; }} h3 {{ border-top: 3px solid #1a1a2e;
|
||||
padding-top: 18px; margin-top: 40px; }}
|
||||
h3 .sub {{ font-weight: normal; font-size: 14px; color: #555;
|
||||
display: block; margin-top: 4px; }}
|
||||
h4 {{ margin: 18px 0 6px; font-size: 15px; }}
|
||||
table {{ border-collapse: collapse; margin: 8px 0 14px; font-size: 13px; }}
|
||||
th, td {{ border: 1px solid #ccc; padding: 4px 9px; text-align: left; }}
|
||||
th {{ background: #eee; }}
|
||||
tr.me td {{ background: #fff8e1; }}
|
||||
.small {{ color: #555; font-size: 12.5px; }}
|
||||
nav a {{ text-decoration: none; color: #1a1a2e; font-size: 13px;
|
||||
display: block; padding: 3px 0; }}
|
||||
nav a:hover {{ color: #b00020; }}
|
||||
nav h2 {{ font-size: 14px; margin: 14px 0 6px; }}
|
||||
details {{ margin: 6px 0; }} summary {{ cursor: pointer;
|
||||
font-size: 13px; color: #333; }}
|
||||
</style>
|
||||
{"<script>" + PLOTLY_JS + "</script>" if PLOTLY_JS else
|
||||
'<script src="https://cdn.plot.ly/plotly-2.35.2.min.js"></script>'}
|
||||
</head><body><div class="wrap">
|
||||
<nav>
|
||||
<b>Return-driver report</b><br><span class="small">generated
|
||||
{time.strftime('%Y-%m-%d %H:%M')}</span>
|
||||
<h2>Candidates (alpha screen, excess of T-bill)</h2>
|
||||
<ol>{''.join(toc[:len(cand)])}</ol>
|
||||
<h2>Shortlist (your funds)</h2>
|
||||
<ol start="{len(cand) + 1}">{''.join(toc[len(cand):])}</ol>
|
||||
</nav>
|
||||
<main>
|
||||
<h1>Fund report - {len(cand)} alpha candidates & {len(short)}
|
||||
shortlist funds</h1>
|
||||
<p class="small"><b>Method.</b> Every alpha in this report is computed
|
||||
<b>in excess of the 3-month T-bill rate</b> (BIL total return as the
|
||||
local risk-free series): the fund's daily total returns are regressed on
|
||||
sleeve benchmarks that are netted against the same rate, so a cash
|
||||
position contributes exactly zero. "Reference" is never one index - it
|
||||
is each fund's <b>own fitted sleeve mix</b> (BIC forward selection on the
|
||||
broad axes, or the full 34-sleeve OLS for the loadings). R² measures how
|
||||
much of the excess return the mix explains; alpha is what is left.
|
||||
"Net cash" = 1 − (sum of loadings). Equity curves are total-return
|
||||
(Adj Close) over the maximum local history, rebased to 100.</p>
|
||||
{''.join(body)}
|
||||
<p class="small" style="margin-top:40px">Generated by fundlab.report -
|
||||
data as of {time.strftime('%Y-%m-%d')}. Local price histories may lag a
|
||||
day or two. Cluster = k=30 k-means on the excess-return loading vectors
|
||||
(34 sleeves + net-cash axis).</p>
|
||||
</main></div></body></html>"""
|
||||
OUT.write_text(doc)
|
||||
print(f"wrote {OUT} in {time.time() - t0:.0f}s "
|
||||
f"({len(doc) / 1e6:.1f} MB)")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
400
fundlab/reportdata.py
Normal file
400
fundlab/reportdata.py
Normal file
|
|
@ -0,0 +1,400 @@
|
|||
"""Build reports/report_data.json: everything the web app (and the HTML
|
||||
report) need for the per-fund report pages, in one structured file.
|
||||
|
||||
One entry per fund (11 alpha candidates + 13 shortlist funds):
|
||||
meta name, verdict, group, order
|
||||
narrative list of prose paragraphs (fundlab.narrative)
|
||||
chart {dates, fund, ref, ivv} (downsampled price paths, rebased)
|
||||
perf rows [period, fund, reference, ivv, fund-ref] (strings)
|
||||
drivers markdown lines (reference model, signature, verdicts)
|
||||
reference {rows [[loading, name, exposure]], weak, netcash, text}
|
||||
tax plain text
|
||||
peers {cluster, rows, proscons}
|
||||
|
||||
Run: .venv/bin/python -m fundlab.reportdata
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
|
||||
from fundlab import report as _r
|
||||
from fundlab import decompose
|
||||
from fundlab import styletilt
|
||||
from fundlab.narrative import narrate
|
||||
|
||||
HERE = Path(__file__).parent
|
||||
OUT = HERE.parent / "reports" / "report_data.json"
|
||||
|
||||
MAX_PTS = 1500
|
||||
|
||||
|
||||
def _down(s: pd.Series) -> tuple[list, list]:
|
||||
if s is None:
|
||||
return [], []
|
||||
if len(s) > MAX_PTS:
|
||||
s = s.iloc[:: (len(s) // MAX_PTS + 1)]
|
||||
return [str(d.date()) for d in s.index], [float(v) for v in s]
|
||||
|
||||
|
||||
def _chart(sym: str, refs_curve: list[dict]) -> dict:
|
||||
p = _r.price(sym)
|
||||
fd, fv = _down(100 * p / p.iloc[0] if p is not None else None)
|
||||
if refs_curve:
|
||||
mix = _r.mix_series(refs_curve)
|
||||
else:
|
||||
b = _r.price("bil")
|
||||
mix = 100 * b / b.iloc[0] if b is not None else None
|
||||
md, mv = _down(mix)
|
||||
iv = _r.price("ivv")
|
||||
id_, ivv = _down(100 * iv / iv.iloc[0] if iv is not None else None)
|
||||
return {"dates": fd, "fund": fv, "ref_dates": md, "ref": mv,
|
||||
"ivv_dates": id_, "ivv": ivv}
|
||||
|
||||
|
||||
def _perf_rows(sym: str, refs_curve: list[dict]) -> list[list[str]]:
|
||||
p = _r.price(sym)
|
||||
if p is None:
|
||||
return []
|
||||
mix = (_r.mix_series(refs_curve) if refs_curve
|
||||
else _r.price("bil"))
|
||||
iv = _r.price("ivv")
|
||||
st = _r.perf_stats(p)
|
||||
rows = []
|
||||
|
||||
def add(label, a, b):
|
||||
fr_ = _r.window_ret(p, a, b)
|
||||
mr = _r.window_ret(mix, a, b)
|
||||
ir = _r.window_ret(iv, a, b)
|
||||
gap = (fr_ - mr) if (fr_ is not None and mr is not None) else None
|
||||
rows.append([label, _r.fmt_pct(fr_), _r.fmt_pct(mr),
|
||||
_r.fmt_pct(ir), _r.fmt_pct(gap)])
|
||||
|
||||
add("Full history", st["start"], st["end"])
|
||||
add("Last 5y", "2021-01-01", st["end"])
|
||||
add("Last 1y", "2025-09-01", st["end"])
|
||||
for lab, a, b in _r.EPISODES:
|
||||
add(lab, a, b)
|
||||
yr = p.resample("YE").last().dropna()
|
||||
years = [str(yr.index[i].year) for i in range(1, len(yr))][-6:]
|
||||
for i, y in enumerate(years):
|
||||
a = f"{y}-01-01"
|
||||
b = f"{int(y) + 1}-01-01" if i < len(years) - 1 else st["end"]
|
||||
add(y, a, b)
|
||||
return rows
|
||||
|
||||
|
||||
def _drivers(sym: str, fr: dict, srow: dict, dr: dict) -> list[str]:
|
||||
out = []
|
||||
a5 = srow.get("alpha_ann_5y")
|
||||
t5 = srow.get("alpha_t_5y")
|
||||
r25 = srow.get("r2_5y")
|
||||
if isinstance(r25, (int, float)) or isinstance(a5, (int, float)):
|
||||
out.append(
|
||||
f"**Reference model, last 5 years:** R² = "
|
||||
f"{_r.fmt_r2(r25 if isinstance(r25, (int, float)) else None)}, "
|
||||
f"alpha = "
|
||||
f"{_r.fmt_pct(a5) if isinstance(a5, (int, float)) else '—'}"
|
||||
f"{' (t = ' + format(t5, '+.1f') + ')' if isinstance(t5, (int, float)) else ''}")
|
||||
a_f = (fr.get("full") or {}).get("alpha_ann")
|
||||
t_f = (fr.get("full") or {}).get("alpha_t")
|
||||
r2f = srow.get("r2_full")
|
||||
if isinstance(r2f, (int, float)) or isinstance(a_f, (int, float)):
|
||||
out.append(
|
||||
f"**Reference model, full history:** R² = "
|
||||
f"{_r.fmt_r2(r2f if isinstance(r2f, (int, float)) else None)}, "
|
||||
f"alpha = "
|
||||
f"{_r.fmt_pct(a_f) if isinstance(a_f, (int, float)) else '—'}"
|
||||
f"{' (t = ' + format(t_f, '+.1f') + ')' if isinstance(t_f, (int, float)) else ''}.")
|
||||
f = fr.get("rec5") or {}
|
||||
betas = f.get("betas") or {}
|
||||
top = sorted(betas.items(), key=lambda kv: -abs(kv[1]))[:6]
|
||||
if top:
|
||||
out.append("**Return-driver signature (34 sleeves):** "
|
||||
+ ", ".join(f"`{s}` {b:+.2f}" for s, b in top)
|
||||
+ f" - net cash {1 - sum(betas.values()):+.2f}.")
|
||||
if dr and "verdict" in dr:
|
||||
out.append(f"**Decomposition verdict:** {dr['verdict']}")
|
||||
roll = dr.get("rolling") or {}
|
||||
if roll.get("max_drift") is not None:
|
||||
out.append(f"Weight stability: max 1y β-drift = "
|
||||
f"{roll['max_drift']:.2f} (0 = perfectly stable, "
|
||||
f">1 = unstable).")
|
||||
if dr.get("note"):
|
||||
out.append(f"*{dr['note']}*")
|
||||
if srow.get("verdict"):
|
||||
out.append(f"**Screen verdict:** {srow['verdict']}")
|
||||
return out
|
||||
|
||||
|
||||
def _reference(sym: str, fr: dict, refs: list[dict],
|
||||
refs_curve: list[dict]) -> dict:
|
||||
rows = []
|
||||
for c in refs:
|
||||
nm, desc = _r.sleeve_desc(c["sym"])
|
||||
rows.append([f"{c['sym'].upper()} {c['beta']:+.2f}", nm, desc])
|
||||
sb = sum(c["beta"] for c in refs)
|
||||
cash = 1 - sb
|
||||
if cash > 0.05:
|
||||
net = f"loadings sum to {sb:.2f} → ~{cash:.0%} net cash"
|
||||
elif cash < -0.05:
|
||||
net = f"loadings sum to {sb:.2f} → ~{-cash:.0%} net levered"
|
||||
else:
|
||||
net = f"loadings sum to {sb:.2f} → fully invested"
|
||||
weak = bool(refs) and not refs_curve
|
||||
text = ("**Weak fit - read with care.** These loadings are each "
|
||||
"individually significant but collectively explain little; "
|
||||
"the performance table anchors to cash, not this mix."
|
||||
if weak else
|
||||
"The reference is the fund's own fitted sleeve mix; "
|
||||
"'alpha' everywhere means outperformance vs this mix, in "
|
||||
"excess of the T-bill rate.")
|
||||
return {"rows": rows, "weak": weak, "netcash": net, "text": text}
|
||||
|
||||
|
||||
def _tax(sym: str) -> str:
|
||||
t = _r.tax_row(sym)
|
||||
if not t:
|
||||
return "No tax classification on file."
|
||||
loc = t.get("location", "?")
|
||||
basis = t.get("basis", "?")
|
||||
conf = "from actual N-PORT holdings (high confidence)" \
|
||||
if basis == "N-PORT" else "from the return-sleeve mix (model)"
|
||||
s = (f"Character score {t.get('score', '?')} ({conf}). ")
|
||||
if "MIXED" in loc:
|
||||
s += "Model says MIXED - the last 1099-DIV is the arbiter."
|
||||
elif "TAXABLE" in loc:
|
||||
if "munis" in loc:
|
||||
s += ("Keep in the **taxable** account "
|
||||
"(munis - tax-exempt interest is wasted in an IRA).")
|
||||
elif "defers" in loc:
|
||||
s += ("Keep in the **taxable** account "
|
||||
"(income mostly defers to the LTCG/ROC rate).")
|
||||
else:
|
||||
s += "Keep in the **taxable** account."
|
||||
else:
|
||||
s += f"Recommended account: **{loc}**."
|
||||
if t.get("notes"):
|
||||
s += f" _{t['notes']}_"
|
||||
return s
|
||||
|
||||
|
||||
def _peers(sym: str, fr: dict) -> dict:
|
||||
# no return history: a zero loading vector would park the fund in the
|
||||
# cash cluster - no peer table for a fund with no measured returns
|
||||
if _r.price(sym) is None:
|
||||
return {}
|
||||
if sym in _r.MEMBER:
|
||||
cid, clabel, cn = _r.MEMBER[sym]
|
||||
members = _r.KMEANS["clusters"][cid]["syms"]
|
||||
else:
|
||||
try:
|
||||
cid, clabel = _r.cluster_of_row(_r.fund_loading_row(fr))
|
||||
except Exception:
|
||||
return {}
|
||||
cn = _r.KMEANS["clusters"].get(cid, {}).get("n", 0)
|
||||
members = _r.KMEANS["clusters"].get(cid, {}).get("syms", [])
|
||||
peers = []
|
||||
for s in members:
|
||||
if s == sym:
|
||||
continue
|
||||
v = _r.search_row(s)
|
||||
if isinstance(v.get("alpha_t_5y"), (int, float)):
|
||||
peers.append((v["alpha_t_5y"], s))
|
||||
peers.sort(key=lambda x: (x[0] > 0, x[0]), reverse=True)
|
||||
pos = [p for p in peers if p[0] > 0]
|
||||
peers = [s for _t, s in (pos + [p for p in peers if p[0] <= 0])[:4]]
|
||||
|
||||
def statline(s: str) -> list[str]:
|
||||
p = _r.price(s)
|
||||
if p is None:
|
||||
return ["—", "—", "—", "—", "—", "n/a"]
|
||||
st = _r.perf_stats(p)
|
||||
v = _r.search_row(s)
|
||||
t5 = _r.window_ret(p, "2021-01-01", st["end"])
|
||||
a5 = v.get("alpha_ann_5y")
|
||||
tt = v.get("alpha_t_5y")
|
||||
tax = (_r.tax_row(s) or {}).get("location") or "n/a"
|
||||
return [_r.fmt_pct(t5), _r.fmt_pct(st["cagr"]),
|
||||
_r.fmt_pct(st["mdd"]),
|
||||
_r.fmt_r2(v.get("r2_5y")),
|
||||
(f"{_r.fmt_pct(a5)} (t={tt:+.1f})"
|
||||
if isinstance(a5, (int, float)) else "—"), tax]
|
||||
|
||||
rows = [[f"{sym.upper()} (this fund)", *statline(sym)]]
|
||||
for s in peers:
|
||||
rows.append([s.upper(), *statline(s)])
|
||||
|
||||
# pros / cons
|
||||
adv, dis = [], []
|
||||
p = _r.price(sym)
|
||||
if p is not None and peers:
|
||||
st = _r.perf_stats(p)
|
||||
t5 = _r.window_ret(p, "2021-01-01", st["end"])
|
||||
vals = {}
|
||||
for s in peers:
|
||||
pp = _r.price(s)
|
||||
if pp is None:
|
||||
continue
|
||||
ss = _r.perf_stats(pp)
|
||||
vals[s] = (_r.window_ret(pp, "2021-01-01", ss["end"]),
|
||||
ss["mdd"], ss["vol"])
|
||||
if vals:
|
||||
best_t5 = max(v[0] for v in vals.values() if v[0] is not None)
|
||||
best_dd = max(v[1] for v in vals.values())
|
||||
low_vol = min(v[2] for v in vals.values())
|
||||
if t5 is not None and t5 >= best_t5 - 0.02:
|
||||
adv.append("5y return at the top of the cluster")
|
||||
elif t5 is not None and t5 < best_t5 - 0.10:
|
||||
dis.append(f"5y return trails the best peer by "
|
||||
f"{100 * (best_t5 - t5):.0f}pp")
|
||||
if st["mdd"] < best_dd - 0.05:
|
||||
adv.append("sharpest drawdown in the cluster")
|
||||
elif st["mdd"] > best_dd + 0.05:
|
||||
dis.append(f"deeper drawdown than the calmest peer "
|
||||
f"({_r.fmt_pct(st['mdd'])} vs "
|
||||
f"{_r.fmt_pct(best_dd)})")
|
||||
if st["vol"] < low_vol - 0.02:
|
||||
adv.append("lowest volatility in the cluster")
|
||||
elif st["vol"] > low_vol + 0.05:
|
||||
dis.append("meaningfully more volatile than the "
|
||||
"calmest peer")
|
||||
if adv:
|
||||
pc = "**Advantages vs peers:** " + "; ".join(adv) + "."
|
||||
elif dis:
|
||||
pc = "**Disadvantages vs peers:** " + "; ".join(dis) + "."
|
||||
else:
|
||||
pc = ("Middle of the cluster - no decisive edge on return, "
|
||||
"drawdown or volatility; the choice comes down to alpha "
|
||||
"quality (t), tax fit and conviction in the strategy.")
|
||||
if dis and adv:
|
||||
pc += " **Disadvantages:** " + "; ".join(dis) + "."
|
||||
return {"cluster": clabel, "n": cn,
|
||||
"rows": rows, "proscons": pc}
|
||||
|
||||
|
||||
ADHOC_FILE = HERE.parent / "reports" / "report_data_adhoc.json"
|
||||
_ADHOC_MEM: dict = None # lazy-loaded disk cache
|
||||
|
||||
|
||||
def _adhoc_store() -> dict:
|
||||
global _ADHOC_MEM
|
||||
if _ADHOC_MEM is None:
|
||||
try:
|
||||
_ADHOC_MEM = json.loads(ADHOC_FILE.read_text())
|
||||
except Exception:
|
||||
_ADHOC_MEM = {"funds": {}}
|
||||
return _ADHOC_MEM
|
||||
|
||||
|
||||
def ensure_adhoc(syms: list[str]) -> dict[str, dict]:
|
||||
"""Build report entries for ARBITRARY funds (any symbol the user puts
|
||||
in the portfolio box), cached in memory + on disk so repeat loads are
|
||||
instant and survive server restarts. The one-time ~30-60 s driver-panel
|
||||
build happens on the first call in a fresh process."""
|
||||
store = _adhoc_store()
|
||||
funds = store["funds"]
|
||||
missing = [s for s in syms
|
||||
if s not in funds
|
||||
and _r.price(s) is not None]
|
||||
if missing:
|
||||
for s in missing:
|
||||
funds[s] = build_fund(s, "adhoc",
|
||||
order=len(funds) + 1)
|
||||
ADHOC_FILE.parent.mkdir(exist_ok=True)
|
||||
ADHOC_FILE.write_text(json.dumps(store))
|
||||
return {s: funds[s] for s in syms if s in funds}
|
||||
|
||||
|
||||
def build_fund(sym: str, group: str, order: int) -> dict:
|
||||
t0 = time.time()
|
||||
fr = _r.factor_row(sym)
|
||||
dr = _r.decomp_row(sym)
|
||||
srow = _r.search_row(sym)
|
||||
name = (srow.get("name") or _r.FONDS.get(sym, {}).get("name")
|
||||
or (fr or {}).get("name") or sym.upper())
|
||||
refs = _r.ref_components(sym, fr)
|
||||
r2f_ = (fr.get("rec5") or fr.get("full") or {}).get("r2")
|
||||
r25 = srow.get("r2_5y") if isinstance(srow.get("r2_5y"), (int, float)) \
|
||||
else None
|
||||
fit = r25 if r25 is not None else r2f_
|
||||
refs_curve = refs if (fit is not None and fit >= 0.5) else []
|
||||
p = _r.price(sym)
|
||||
st_ = _r.perf_stats(p) if p is not None else {}
|
||||
stats = {"t5y": _r.fmt_pct(_r.window_ret(p, "2021-01-01",
|
||||
st_["end"])) if p is not None
|
||||
else "—",
|
||||
"cagr": _r.fmt_pct(st_.get("cagr")),
|
||||
"mdd": _r.fmt_pct(st_.get("mdd")),
|
||||
"r2_5y": _r.fmt_r2(srow.get("r2_5y")),
|
||||
"alpha_5y": (f"{_r.fmt_pct(srow['alpha_ann_5y'])} "
|
||||
f"(t={srow['alpha_t_5y']:+.1f})"
|
||||
if isinstance(srow.get("alpha_ann_5y"),
|
||||
(int, float)) else "—")}
|
||||
d = {
|
||||
"meta": {"sym": sym, "name": name, "group": group, "order": order,
|
||||
"verdict": srow.get("verdict", ""),
|
||||
"objective": (_r.FONDS.get(sym) or {}).get("objective",
|
||||
"")},
|
||||
"stats": stats,
|
||||
"narrative": narrate(sym),
|
||||
"chart": _chart(sym, refs_curve),
|
||||
"perf": _perf_rows(sym, refs_curve),
|
||||
"drivers": _drivers(sym, fr, srow, dr),
|
||||
"reference": _reference(sym, fr, refs, refs_curve),
|
||||
"tax": _tax(sym),
|
||||
"peers": _peers(sym, fr),
|
||||
}
|
||||
try:
|
||||
d["style"] = styletilt.style_profile(sym)
|
||||
except Exception:
|
||||
d["style"] = None
|
||||
print(f" {sym:8s} {time.time() - t0:5.1f}s", flush=True)
|
||||
return d
|
||||
|
||||
|
||||
def main() -> None:
|
||||
from fundlab.decompose import ALIAS
|
||||
from fundlab.nport import FUND_TOKENS
|
||||
t0 = time.time()
|
||||
cand = [v["sym"] for v in _r.SEARCH.values()
|
||||
if isinstance(v, dict)
|
||||
and str(v.get("verdict", "")).startswith("CANDIDATE")]
|
||||
cand.sort(key=lambda s: -(_r.SEARCH[s]["alpha_t_5y"]
|
||||
if isinstance(_r.SEARCH[s].get("alpha_t_5y"),
|
||||
(int, float)) else -9))
|
||||
short = [s for s in FUND_TOKENS if s not in ALIAS]
|
||||
data = {"generated": time.strftime("%Y-%m-%d %H:%M"),
|
||||
"funds": {}}
|
||||
i = 0
|
||||
for s in cand:
|
||||
i += 1
|
||||
data["funds"][s] = build_fund(s, "candidate", i)
|
||||
for s in short:
|
||||
i += 1
|
||||
data["funds"][s] = build_fund(s, "shortlist", i)
|
||||
OUT.parent.mkdir(exist_ok=True)
|
||||
OUT.write_text(json.dumps(data))
|
||||
# rebuild any on-demand (Symbol-box) reports so they gain the new
|
||||
# sections too; keep their "adhoc" group
|
||||
if ADHOC_FILE.exists():
|
||||
try:
|
||||
_old = json.loads(ADHOC_FILE.read_text())["funds"]
|
||||
except Exception:
|
||||
_old = {}
|
||||
for j, s in enumerate(_old, 1):
|
||||
if s in cand or s in short:
|
||||
continue
|
||||
_old[s] = build_fund(s, "adhoc", order=-j)
|
||||
ADHOC_FILE.write_text(json.dumps({"funds": _old}))
|
||||
print(f"rebuilt {len(_old)} ad-hoc reports")
|
||||
print(f"wrote {OUT} in {time.time() - t0:.0f}s "
|
||||
f"({OUT.stat().st_size / 1e6:.1f} MB, {len(data['funds'])} funds)")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
47683
fundlab/search_all.json
47683
fundlab/search_all.json
File diff suppressed because one or more lines are too long
1
fundlab/search_all_rawalpha.json
Normal file
1
fundlab/search_all_rawalpha.json
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -1,2 +1,4 @@
|
|||
2026-08-28 14:52:00
|
||||
server_watchdog: no answer on :8599 - relaunching
|
||||
2026-08-30 13:26:18
|
||||
server_watchdog: no answer on :8599 - relaunching
|
||||
|
|
|
|||
257
fundlab/styletilt.py
Normal file
257
fundlab/styletilt.py
Normal file
|
|
@ -0,0 +1,257 @@
|
|||
"""Style-tilt battery: mathematical factor identification for one fund.
|
||||
|
||||
Regresses the fund's daily excess-of-T-bill returns on a battery of 22
|
||||
style/asset sleeves (US funds proxying the global style factors; a fund
|
||||
expresses them in its own universe, so betas are the right sign and
|
||||
magnitude but approximate), over the full history and the last 5 years:
|
||||
|
||||
* plain OLS -> every factor's beta + t-stat (exploratory view)
|
||||
* BIC forward selection -> the IDENTIFIED tilt stack (the strict gate:
|
||||
a factor is only in if it measurably improves the model)
|
||||
* residual alpha after the identified stack -> "is there skill left?"
|
||||
|
||||
Plus data-driven English commentary (fundlab.styletilt.commentary).
|
||||
|
||||
Caveats stated in the commentary, not hidden: US sleeves proxy global
|
||||
factors; style sleeves are mutually collinear, so single-OLS t-stats are
|
||||
indicative and the BIC set is the identification.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
|
||||
from fundlab import decompose
|
||||
|
||||
# factor label -> sleeve ticker (US proxies for the global factors)
|
||||
BATTERY: dict[str, str] = {
|
||||
"int-dev (EFA)": "efa", "EM (VWO)": "vwo", "growth (VUG)": "vug",
|
||||
"value (VTV)": "vtv", "small (IWM)": "iwm", "equalwt (RSP)": "rsp",
|
||||
"lowvol (USMV)": "usmv", "lowvol (DFLVX)": "dflvx",
|
||||
"quality (QUAL)": "qual", "momentum (MTUM)": "mtum",
|
||||
"dividend (HDV)": "hdv", "div-apprec (VYM)": "vym",
|
||||
"longdur (TLT)": "tlt", "gold (GLD)": "gld",
|
||||
"EUR (FXE)": "fxe", "JPY (FXY)": "fxy", "AUD (FXU)": "fxu",
|
||||
"utilities (XLU)": "xlu", "staples (XLP)": "xlp",
|
||||
"health (XLV)": "xlv", "banks (XLF)": "xlf", "energy (XLE)": "xle",
|
||||
}
|
||||
SYMS = list(dict.fromkeys(BATTERY.values()))
|
||||
INV = {v: k for k, v in BATTERY.items()}
|
||||
|
||||
_PANEL: pd.DataFrame | None = None
|
||||
|
||||
|
||||
def _panel() -> pd.DataFrame:
|
||||
"""Battery sleeves' daily EXCESS-of-T-bill returns, cached per process."""
|
||||
global _PANEL
|
||||
if _PANEL is None:
|
||||
_PANEL = decompose.excess(
|
||||
decompose.returns_panel(SYMS, start=decompose.FULL_WINDOW))
|
||||
return _PANEL
|
||||
|
||||
|
||||
def _fund_excess(sym: str) -> pd.Series:
|
||||
p = decompose.adj_close(sym)
|
||||
if p is None:
|
||||
return pd.Series(dtype=float)
|
||||
y = p.pct_change()
|
||||
rf = decompose.rf_series()
|
||||
if rf is not None:
|
||||
y = y.sub(rf.reindex(y.index).fillna(0.0))
|
||||
return y
|
||||
|
||||
|
||||
def _fit(y: pd.Series, a: str | None, b: str | None) -> dict:
|
||||
x = _panel()
|
||||
idx = x.index
|
||||
msk = idx >= (a or idx[0])
|
||||
if b is not None:
|
||||
msk &= idx <= b
|
||||
x = x[msk]
|
||||
y = y.reindex(x.index)
|
||||
ok = y.notna() & x.notna().all(axis=1)
|
||||
if ok.sum() < 252:
|
||||
return {}
|
||||
X = np.column_stack([np.ones(int(ok.sum()))] +
|
||||
[x[s][ok].to_numpy() for s in SYMS])
|
||||
yn = y[ok].to_numpy()
|
||||
beta, *_ = np.linalg.lstsq(X, yn, rcond=None)
|
||||
res = yn - X @ beta
|
||||
dof = max(int(ok.sum()) - len(SYMS) - 1, 1)
|
||||
sigma2 = float(res @ res) / dof
|
||||
se = np.sqrt(np.diag(np.linalg.inv(X.T @ X)) * sigma2)
|
||||
t = np.where(se > 0, beta / se, 0.0)
|
||||
r2 = 1 - float(res @ res) / float((yn - yn.mean()) @ (yn - yn.mean()))
|
||||
return {
|
||||
"n": int(ok.sum()),
|
||||
"start": str(x.index[ok][0].date()),
|
||||
"end": str(x.index[ok][-1].date()),
|
||||
"r2": float(r2),
|
||||
"alpha_ann": float(beta[0] * 252),
|
||||
"alpha_t": float(t[0]),
|
||||
"factors": [
|
||||
{"name": INV[s], "sym": s, "beta": float(beta[k + 1]),
|
||||
"t": float(t[k + 1])}
|
||||
for k, s in enumerate(SYMS)],
|
||||
}
|
||||
|
||||
|
||||
def _forward(y: pd.Series, a: str | None, b: str | None) -> list[str]:
|
||||
"""BIC-gated forward selection over the battery -> identified sleeves."""
|
||||
x = _panel()
|
||||
idx = x.index
|
||||
msk = idx >= (a or idx[0])
|
||||
if b is not None:
|
||||
msk &= idx <= b
|
||||
x = x[msk]
|
||||
y = y.reindex(x.index)
|
||||
ok = y.notna()
|
||||
if ok.sum() < 252:
|
||||
return []
|
||||
cand = {s: x[s].to_numpy() for s in SYMS}
|
||||
chosen, _m, _okk = decompose.forward_select(y.to_numpy(), cand, y_ok=ok)
|
||||
return list(chosen)
|
||||
|
||||
|
||||
# ------------------------------------------------------------- commentary
|
||||
# human meaning of each sleeve (used for the prose)
|
||||
MEANING: dict[str, str] = {
|
||||
"efa": "international developed markets", "vwo": "emerging markets",
|
||||
"vug": "US growth equities", "vtv": "US value equities",
|
||||
"iwm": "US small caps", "rsp": "equal-weight (small-tilted) US",
|
||||
"usmv": "low volatility", "dflvx": "low volatility",
|
||||
"qual": "quality (high-ROE, low-debt, stable earnings)",
|
||||
"mtum": "momentum (recent winners)", "hdv": "high dividend",
|
||||
"vym": "high dividend (appreciation-tilted)",
|
||||
"tlt": "long-duration Treasuries", "gld": "gold",
|
||||
"fxe": "the euro", "fxy": "the yen", "fxu": "the Australian dollar",
|
||||
"xlu": "utilities (defensive bond-proxy)",
|
||||
"xlp": "consumer staples (defensive)",
|
||||
"xlv": "healthcare (defensive)", "xlf": "banks/financials",
|
||||
"xle": "energy",
|
||||
}
|
||||
# sign-specific phrasing where the generic 'tilt toward/away from' is wrong
|
||||
SPECIAL: dict[tuple[str, bool], str] = {
|
||||
("fxe", False): ("short-euro position that carries the USD/EUR "
|
||||
"interest-rate differential"),
|
||||
("fxy", False): ("short-yen position that carries the USD/JPY "
|
||||
"rate differential"),
|
||||
("fxu", False): "short-AUD position (USD carry)",
|
||||
("fxu", True): "long-AUD position (AUD carry)",
|
||||
("fxe", True): "long-euro position (exposed to EUR moves)",
|
||||
("fxy", True): "long-yen position (safe-haven/carry)",
|
||||
("qual", False): ("anti-quality tilt - systematically underweight "
|
||||
"high-ROE, low-debt names; the mechanical flip side "
|
||||
"of a high-payout dividend mandate"),
|
||||
("qual", True): "quality tilt (high-ROE, low-debt, stable earnings)",
|
||||
("mtum", False): ("anti-momentum character - it does not chase "
|
||||
"recent winners (low-turnover/contrarian)"),
|
||||
("mtum", True): "momentum tilt (preference for recent winners)",
|
||||
("hdv", True): ("high-dividend tilt - a systematic preference for "
|
||||
"income-paying names"),
|
||||
("hdv", False): "underweight to high-dividend names",
|
||||
("vym", True): "dividend-appreciation tilt (growing payers)",
|
||||
("rsp", False): "cap-weight concentration (tilt away from "
|
||||
"equal-weight/small)",
|
||||
("rsp", True): "equal-weight (small-tilted) exposure",
|
||||
("vwo", False): "developed-only tilt (away from emerging markets)",
|
||||
("vwo", True): "an emerging-market tilt",
|
||||
("usmv", True): "low-volatility (defensive beta) tilt",
|
||||
("dflvx", True): "low-volatility (defensive beta) tilt",
|
||||
("dflvx", False): "underweight to low-volatility names",
|
||||
("usmv", False): "underweight to low-volatility names",
|
||||
}
|
||||
|
||||
|
||||
def _strength(t: float) -> str:
|
||||
a = abs(t)
|
||||
return "strong" if a >= 10 else "clear" if a >= 5 else "modest"
|
||||
|
||||
|
||||
def _tilt_sentence(f: dict) -> str:
|
||||
s = f["sym"]
|
||||
key = (s, f["beta"] > 0)
|
||||
if key in SPECIAL:
|
||||
body = SPECIAL[key]
|
||||
else:
|
||||
m = MEANING.get(s, f["name"])
|
||||
body = (f"tilt toward {m}" if f["beta"] > 0
|
||||
else f"tilt away from {m}")
|
||||
return (f"{_strength(f['t'])} {body} "
|
||||
f"(β {f['beta']:+.2f}, t {f['t']:+.0f})")
|
||||
|
||||
|
||||
def commentary(sym: str, prof: dict) -> list[str]:
|
||||
"""English prose for the style-tilt block (data-driven)."""
|
||||
if not prof or not prof.get("full"):
|
||||
return []
|
||||
full, rec5 = prof["full"], prof.get("rec5") or {}
|
||||
sig_full = {f["sym"]: f for f in full["factors"] if abs(f["t"]) >= 2}
|
||||
sig_5 = {f["sym"]: f for f in rec5.get("factors", [])
|
||||
if abs(f["t"]) >= 2}
|
||||
out = []
|
||||
# paragraph 1: the identified stack
|
||||
parts = []
|
||||
core = sig_full.get("efa")
|
||||
if core:
|
||||
parts.append(
|
||||
f"the core exposure is {abs(core['beta']):.0%} of "
|
||||
f"international developed equities (t {core['t']:+.0f})")
|
||||
for f in sorted(sig_full.values(), key=lambda x: -abs(x["t"])):
|
||||
if f["sym"] == "efa":
|
||||
continue
|
||||
parts.append(_tilt_sentence(f))
|
||||
if parts:
|
||||
out.append(
|
||||
f"Style-tilt analysis (22 style/asset sleeves regressed on "
|
||||
f"the fund's excess returns; US funds proxying the global "
|
||||
f"factors): over {full['start'][:4]}-to-{full['end'][:4]} the "
|
||||
f"fit explains {full['r2']:.0%} of the excess return (R² "
|
||||
f"{full['r2']:.2f}). The statistically identified tilt stack: "
|
||||
+ "; ".join(parts) + ".")
|
||||
# factors that only appear in the 5y window
|
||||
recent_only = [s for s in sig_5
|
||||
if s not in sig_full and s != "efa"]
|
||||
if recent_only:
|
||||
out.append(
|
||||
"Visible only in the recent 5-year window: "
|
||||
+ "; ".join(_tilt_sentence(sig_5[s]) for s in recent_only)
|
||||
+ " - newer behavior, or a factor the longer sample dilutes.")
|
||||
# paragraph 2: the residual - is there skill left?
|
||||
a, t = full["alpha_ann"], full["alpha_t"]
|
||||
if abs(t) < 1.75:
|
||||
out.append(
|
||||
f"After stripping the identified tilts, the residual excess "
|
||||
f"return is {a * 100:+.1f}%/year (t {t:+.1f}) - NOT "
|
||||
f"statistically significant: the fund's outperformance is "
|
||||
f"factor exposure, not skill alpha.")
|
||||
else:
|
||||
out.append(
|
||||
f"After stripping the identified tilts, a significant "
|
||||
f"residual of {a * 100:+.1f}%/year (t {t:+.1f}) remains - "
|
||||
f"genuine alpha on top of the factor stack.")
|
||||
out.append(
|
||||
"Caveat: the sleeves are US funds proxying global factors; the "
|
||||
"fund expresses them in its own holdings, so the betas are the "
|
||||
"right sign and magnitude but approximate. An index-matched "
|
||||
"benchmark (the fund's own published index, when one exists) "
|
||||
"would absorb part of the residual as well.")
|
||||
return out
|
||||
|
||||
|
||||
def style_profile(sym: str) -> dict | None:
|
||||
"""Full + 5y battery fits, the BIC-identified stack, and commentary.
|
||||
|
||||
Returns None when the fund has no usable local history."""
|
||||
y = _fund_excess(sym)
|
||||
if len(y.dropna()) < 252:
|
||||
return None
|
||||
full = _fit(y, None, None)
|
||||
if not full:
|
||||
return None
|
||||
rec5 = _fit(y, "2021-01-01", None)
|
||||
prof = {"full": full,
|
||||
"rec5": rec5 or {},
|
||||
"identified": _forward(y, None, None)}
|
||||
prof["commentary"] = commentary(sym, prof)
|
||||
return prof
|
||||
0
overrides/corrections/.gitkeep
Normal file
0
overrides/corrections/.gitkeep
Normal file
2
overrides/frozen/aaalx-capitalGain.csv
Normal file
2
overrides/frozen/aaalx-capitalGain.csv
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
Date,Capital Gains
|
||||
2022-12-28,0.007000
|
||||
|
6
overrides/frozen/aaalx-dividend.csv
Normal file
6
overrides/frozen/aaalx-dividend.csv
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
Date,Dividends
|
||||
2024-12-20,0.399900
|
||||
2025-04-08,0.065200
|
||||
2021-12-28,0.250300
|
||||
2022-12-28,0.007100
|
||||
2023-12-21,0.280200
|
||||
|
1034
overrides/frozen/aaalx-history.csv
Normal file
1034
overrides/frozen/aaalx-history.csv
Normal file
File diff suppressed because it is too large
Load Diff
7
overrides/frozen/aaalx.json
Normal file
7
overrides/frozen/aaalx.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"symbol": "aaalx",
|
||||
"longName": "American Century Asset Allocation Portfolios Inc. - One Choice Blend 2015\u00a0Portfolio Fund",
|
||||
"freeze_date": "2025-04-17",
|
||||
"created": "2026-08-31",
|
||||
"reason": "yahoo-empty"
|
||||
}
|
||||
4
overrides/frozen/abqzx-capitalGain.csv
Normal file
4
overrides/frozen/abqzx-capitalGain.csv
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
Date,Capital Gains
|
||||
2021-12-03,0.018000
|
||||
2016-12-07,0.040000
|
||||
2020-12-04,0.145000
|
||||
|
76
overrides/frozen/abqzx-dividend.csv
Normal file
76
overrides/frozen/abqzx-dividend.csv
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
Date,Dividends
|
||||
2019-02-28,0.027378
|
||||
2019-06-28,0.032440
|
||||
2020-09-30,0.029451
|
||||
2021-09-30,0.021411
|
||||
2023-09-29,0.030585
|
||||
2024-03-28,0.033582
|
||||
2024-07-31,0.036753
|
||||
2019-10-31,0.028129
|
||||
2021-11-30,0.015153
|
||||
2019-07-31,0.029595
|
||||
2019-11-29,0.032274
|
||||
2024-11-29,0.033543
|
||||
2020-01-31,0.033029
|
||||
2020-04-30,0.027369
|
||||
2022-04-29,0.022921
|
||||
2024-10-31,0.033149
|
||||
2019-01-31,0.029606
|
||||
2021-02-26,0.027489
|
||||
2021-03-31,0.030588
|
||||
2021-07-30,0.025064
|
||||
2023-11-30,0.031725
|
||||
2021-05-28,0.024247
|
||||
2021-08-31,0.021447
|
||||
2021-12-03,0.017700
|
||||
2024-04-30,0.033871
|
||||
2020-03-31,0.027427
|
||||
2021-01-29,0.027906
|
||||
2022-12-30,0.033246
|
||||
2023-04-28,0.029077
|
||||
2024-08-30,0.042260
|
||||
2020-12-04,0.144700
|
||||
2022-12-02,0.044800
|
||||
2023-06-30,0.032841
|
||||
2024-06-28,0.031146
|
||||
2023-01-31,0.036682
|
||||
2019-03-29,0.033541
|
||||
2019-08-30,0.032235
|
||||
2020-02-28,0.028150
|
||||
2020-06-30,0.028395
|
||||
2020-08-31,0.027902
|
||||
2021-10-29,0.020966
|
||||
2022-11-30,0.032311
|
||||
2024-12-31,0.030620
|
||||
2022-02-28,0.022998
|
||||
2022-08-31,0.030780
|
||||
2020-10-30,0.031190
|
||||
2020-11-30,0.026206
|
||||
2020-12-31,0.027202
|
||||
2022-03-31,0.021258
|
||||
2022-09-30,0.023069
|
||||
2023-03-31,0.037445
|
||||
2023-05-31,0.034867
|
||||
2024-01-31,0.033743
|
||||
2019-04-30,0.033428
|
||||
2020-05-29,0.031073
|
||||
2021-04-30,0.028135
|
||||
2022-01-31,0.018929
|
||||
2023-10-31,0.028526
|
||||
2024-05-31,0.036527
|
||||
2019-05-31,0.036744
|
||||
2019-09-30,0.028360
|
||||
2019-12-31,0.031747
|
||||
2022-06-30,0.021610
|
||||
2022-10-31,0.027292
|
||||
2023-12-29,0.033158
|
||||
2024-02-29,0.037804
|
||||
2021-06-30,0.021983
|
||||
2021-12-31,0.024863
|
||||
2022-05-31,0.026023
|
||||
2022-07-29,0.032376
|
||||
2023-02-28,0.033407
|
||||
2024-09-30,0.030860
|
||||
2020-07-31,0.032462
|
||||
2023-07-31,0.030966
|
||||
2023-08-31,0.036161
|
||||
|
1516
overrides/frozen/abqzx-history.csv
Normal file
1516
overrides/frozen/abqzx-history.csv
Normal file
File diff suppressed because it is too large
Load Diff
7
overrides/frozen/abqzx.json
Normal file
7
overrides/frozen/abqzx.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"symbol": "abqzx",
|
||||
"longName": "AB Bond Fund, Inc. - AB Total Return Bond Portfolio",
|
||||
"freeze_date": "2025-01-08",
|
||||
"created": "2026-08-31",
|
||||
"reason": "yahoo-empty"
|
||||
}
|
||||
1
overrides/frozen/adusx-dividend.csv
Normal file
1
overrides/frozen/adusx-dividend.csv
Normal file
|
|
@ -0,0 +1 @@
|
|||
Date,Dividends,ctime
|
||||
|
503
overrides/frozen/adusx-history.csv
Normal file
503
overrides/frozen/adusx-history.csv
Normal file
|
|
@ -0,0 +1,503 @@
|
|||
Date,Open,High,Low,Close,Adj Close,Volume,ctime
|
||||
2015-12-21,15.000000,15.000000,15.000000,15.000000,15.000000,0,2017-08-22
|
||||
2015-12-22,14.960000,14.960000,14.960000,14.960000,14.960000,0,2017-08-22
|
||||
2015-12-23,14.970000,14.970000,14.970000,14.970000,14.970000,0,2017-08-22
|
||||
2015-12-24,14.990000,14.990000,14.990000,14.990000,14.990000,0,2017-08-22
|
||||
2015-12-28,14.990000,14.990000,14.990000,14.990000,14.990000,0,2017-08-22
|
||||
2015-12-29,15.010000,15.010000,15.010000,15.010000,15.010000,0,2017-08-22
|
||||
2015-12-30,15.000000,15.000000,15.000000,15.000000,15.000000,0,2017-08-22
|
||||
2015-12-31,15.010000,15.010000,15.010000,15.010000,15.010000,0,2017-08-22
|
||||
2016-01-04,14.980000,14.980000,14.980000,14.980000,14.980000,0,2017-08-22
|
||||
2016-01-05,15.010000,15.010000,15.010000,15.010000,15.010000,0,2017-08-22
|
||||
2016-01-06,15.050000,15.050000,15.050000,15.050000,15.050000,0,2017-08-22
|
||||
2016-01-07,15.010000,15.010000,15.010000,15.010000,15.010000,0,2017-08-22
|
||||
2016-01-08,15.020000,15.020000,15.020000,15.020000,15.020000,0,2017-08-22
|
||||
2016-01-11,15.090000,15.090000,15.090000,15.090000,15.090000,0,2017-08-22
|
||||
2016-01-12,15.150000,15.150000,15.150000,15.150000,15.150000,0,2017-08-22
|
||||
2016-01-13,15.090000,15.090000,15.090000,15.090000,15.090000,0,2017-08-22
|
||||
2016-01-14,15.080000,15.080000,15.080000,15.080000,15.080000,0,2017-08-22
|
||||
2016-01-15,15.010000,15.010000,15.010000,15.010000,15.010000,0,2017-08-22
|
||||
2016-01-19,15.120000,15.120000,15.120000,15.120000,15.120000,0,2017-08-22
|
||||
2016-01-20,15.090000,15.090000,15.090000,15.090000,15.090000,0,2017-08-22
|
||||
2016-01-21,15.050000,15.050000,15.050000,15.050000,15.050000,0,2017-08-22
|
||||
2016-01-22,15.100000,15.100000,15.100000,15.100000,15.100000,0,2017-08-22
|
||||
2016-01-25,15.090000,15.090000,15.090000,15.090000,15.090000,0,2017-08-22
|
||||
2016-01-26,15.100000,15.100000,15.100000,15.100000,15.100000,0,2017-08-22
|
||||
2016-01-27,15.090000,15.090000,15.090000,15.090000,15.090000,0,2017-08-22
|
||||
2016-01-28,15.140000,15.140000,15.140000,15.140000,15.140000,0,2017-08-22
|
||||
2016-01-29,15.170000,15.170000,15.170000,15.170000,15.170000,0,2017-08-22
|
||||
2016-02-01,15.190000,15.190000,15.190000,15.190000,15.190000,0,2017-08-22
|
||||
2016-02-02,15.220000,15.220000,15.220000,15.220000,15.220000,0,2017-08-22
|
||||
2016-02-03,15.140000,15.140000,15.140000,15.140000,15.140000,0,2017-08-22
|
||||
2016-02-04,15.020000,15.020000,15.020000,15.020000,15.020000,0,2017-08-22
|
||||
2016-02-05,15.000000,15.000000,15.000000,15.000000,15.000000,0,2017-08-22
|
||||
2016-02-08,15.010000,15.010000,15.010000,15.010000,15.010000,0,2017-08-22
|
||||
2016-02-09,15.050000,15.050000,15.050000,15.050000,15.050000,0,2017-08-22
|
||||
2016-02-10,15.070000,15.070000,15.070000,15.070000,15.070000,0,2017-08-22
|
||||
2016-02-11,15.090000,15.090000,15.090000,15.090000,15.090000,0,2017-08-22
|
||||
2016-02-12,15.060000,15.060000,15.060000,15.060000,15.060000,0,2017-08-22
|
||||
2016-02-16,15.010000,15.010000,15.010000,15.010000,15.010000,0,2017-08-22
|
||||
2016-02-17,14.960000,14.960000,14.960000,14.960000,14.960000,0,2017-08-22
|
||||
2016-02-18,14.920000,14.920000,14.920000,14.920000,14.920000,0,2017-08-22
|
||||
2016-02-19,14.940000,14.940000,14.940000,14.940000,14.940000,0,2017-08-22
|
||||
2016-02-22,14.860000,14.860000,14.860000,14.860000,14.860000,0,2017-08-22
|
||||
2016-02-23,14.890000,14.890000,14.890000,14.890000,14.890000,0,2017-08-22
|
||||
2016-02-24,14.890000,14.890000,14.890000,14.890000,14.890000,0,2017-08-22
|
||||
2016-02-25,14.910000,14.910000,14.910000,14.910000,14.910000,0,2017-08-22
|
||||
2016-02-26,14.840000,14.840000,14.840000,14.840000,14.840000,0,2017-08-22
|
||||
2016-02-29,14.790000,14.790000,14.790000,14.790000,14.790000,0,2017-08-22
|
||||
2016-03-01,14.710000,14.710000,14.710000,14.710000,14.710000,0,2017-08-22
|
||||
2016-03-02,14.710000,14.710000,14.710000,14.710000,14.710000,0,2017-08-22
|
||||
2016-03-03,14.640000,14.640000,14.640000,14.640000,14.640000,0,2017-08-22
|
||||
2016-03-04,14.600000,14.600000,14.600000,14.600000,14.600000,0,2017-08-22
|
||||
2016-03-07,14.520000,14.520000,14.520000,14.520000,14.520000,0,2017-08-22
|
||||
2016-03-08,14.610000,14.610000,14.610000,14.610000,14.610000,0,2017-08-22
|
||||
2016-03-09,14.640000,14.640000,14.640000,14.640000,14.640000,0,2017-08-22
|
||||
2016-03-10,14.700000,14.700000,14.700000,14.700000,14.700000,0,2017-08-22
|
||||
2016-03-11,14.710000,14.710000,14.710000,14.710000,14.710000,0,2017-08-22
|
||||
2016-03-14,14.740000,14.740000,14.740000,14.740000,14.740000,0,2017-08-22
|
||||
2016-03-15,14.790000,14.790000,14.790000,14.790000,14.790000,0,2017-08-22
|
||||
2016-03-16,14.780000,14.780000,14.780000,14.780000,14.780000,0,2017-08-22
|
||||
2016-03-17,14.720000,14.720000,14.720000,14.720000,14.720000,0,2017-08-22
|
||||
2016-03-18,14.710000,14.710000,14.710000,14.710000,14.710000,0,2017-08-22
|
||||
2016-03-21,14.740000,14.740000,14.740000,14.740000,14.740000,0,2017-08-22
|
||||
2016-03-22,14.720000,14.720000,14.720000,14.720000,14.720000,0,2017-08-22
|
||||
2016-03-23,14.800000,14.800000,14.800000,14.800000,14.800000,0,2017-08-22
|
||||
2016-03-24,14.790000,14.790000,14.790000,14.790000,14.790000,0,2017-08-22
|
||||
2016-03-28,14.790000,14.790000,14.790000,14.790000,14.790000,0,2017-08-22
|
||||
2016-03-29,14.800000,14.800000,14.800000,14.800000,14.800000,0,2017-08-22
|
||||
2016-03-30,14.810000,14.810000,14.810000,14.810000,14.810000,0,2017-08-22
|
||||
2016-03-31,14.790000,14.790000,14.790000,14.790000,14.790000,0,2017-08-22
|
||||
2016-04-01,14.820000,14.820000,14.820000,14.820000,14.820000,0,2017-08-22
|
||||
2016-04-04,14.880000,14.880000,14.880000,14.880000,14.880000,0,2017-08-22
|
||||
2016-04-05,14.950000,14.950000,14.950000,14.950000,14.950000,0,2017-08-22
|
||||
2016-04-06,14.980000,14.980000,14.980000,14.980000,14.980000,0,2017-08-22
|
||||
2016-04-07,15.010000,15.010000,15.010000,15.010000,15.010000,0,2017-08-22
|
||||
2016-04-08,15.020000,15.020000,15.020000,15.020000,15.020000,0,2017-08-22
|
||||
2016-04-11,14.990000,14.990000,14.990000,14.990000,14.990000,0,2017-08-22
|
||||
2016-04-12,15.000000,15.000000,15.000000,15.000000,15.000000,0,2017-08-22
|
||||
2016-04-13,14.880000,14.880000,14.880000,14.880000,14.880000,0,2017-08-22
|
||||
2016-04-14,14.880000,14.880000,14.880000,14.880000,14.880000,0,2017-08-22
|
||||
2016-04-15,14.870000,14.870000,14.870000,14.870000,14.870000,0,2017-08-22
|
||||
2016-04-18,14.870000,14.870000,14.870000,14.870000,14.870000,0,2017-08-22
|
||||
2016-04-19,14.890000,14.890000,14.890000,14.890000,14.890000,0,2017-08-22
|
||||
2016-04-20,14.870000,14.870000,14.870000,14.870000,14.870000,0,2017-08-22
|
||||
2016-04-21,14.820000,14.820000,14.820000,14.820000,14.820000,0,2017-08-22
|
||||
2016-04-22,14.720000,14.720000,14.720000,14.720000,14.720000,0,2017-08-22
|
||||
2016-04-25,14.800000,14.800000,14.800000,14.800000,14.800000,0,2017-08-22
|
||||
2016-04-26,14.780000,14.780000,14.780000,14.780000,14.780000,0,2017-08-22
|
||||
2016-04-27,14.760000,14.760000,14.760000,14.760000,14.760000,0,2017-08-22
|
||||
2016-04-28,14.800000,14.800000,14.800000,14.800000,14.800000,0,2017-08-22
|
||||
2016-04-29,14.790000,14.790000,14.790000,14.790000,14.790000,0,2017-08-22
|
||||
2016-05-02,14.850000,14.850000,14.850000,14.850000,14.850000,0,2017-08-22
|
||||
2016-05-03,14.870000,14.870000,14.870000,14.870000,14.870000,0,2017-08-22
|
||||
2016-05-04,15.010000,15.010000,15.010000,15.010000,15.010000,0,2017-08-22
|
||||
2016-05-05,15.050000,15.050000,15.050000,15.050000,15.050000,0,2017-08-22
|
||||
2016-05-06,15.060000,15.060000,15.060000,15.060000,15.060000,0,2017-08-22
|
||||
2016-05-09,15.150000,15.150000,15.150000,15.150000,15.150000,0,2017-08-22
|
||||
2016-05-10,15.170000,15.170000,15.170000,15.170000,15.170000,0,2017-08-22
|
||||
2016-05-11,15.160000,15.160000,15.160000,15.160000,15.160000,0,2017-08-22
|
||||
2016-05-12,15.180000,15.180000,15.180000,15.180000,15.180000,0,2017-08-22
|
||||
2016-05-13,15.210000,15.210000,15.210000,15.210000,15.210000,0,2017-08-22
|
||||
2016-05-16,15.190000,15.190000,15.190000,15.190000,15.190000,0,2017-08-22
|
||||
2016-05-17,15.100000,15.100000,15.100000,15.100000,15.100000,0,2017-08-22
|
||||
2016-05-18,15.170000,15.170000,15.170000,15.170000,15.170000,0,2017-08-22
|
||||
2016-05-20,15.140000,15.140000,15.140000,15.140000,15.140000,0,2017-08-22
|
||||
2016-05-23,15.080000,15.080000,15.080000,15.080000,15.080000,0,2017-08-22
|
||||
2016-05-24,15.100000,15.100000,15.100000,15.100000,15.100000,0,2017-08-22
|
||||
2016-05-25,15.040000,15.040000,15.040000,15.040000,15.040000,0,2017-08-22
|
||||
2016-05-26,15.080000,15.080000,15.080000,15.080000,15.080000,0,2017-08-22
|
||||
2016-05-27,15.070000,15.070000,15.070000,15.070000,15.070000,0,2017-08-22
|
||||
2016-05-31,15.040000,15.040000,15.040000,15.040000,15.040000,0,2017-08-22
|
||||
2016-06-01,15.060000,15.060000,15.060000,15.060000,15.060000,0,2017-08-22
|
||||
2016-06-02,15.030000,15.030000,15.030000,15.030000,15.030000,0,2017-08-22
|
||||
2016-06-03,15.030000,15.030000,15.030000,15.030000,15.030000,0,2017-08-22
|
||||
2016-06-06,14.930000,14.930000,14.930000,14.930000,14.930000,0,2017-08-22
|
||||
2016-06-07,14.910000,14.910000,14.910000,14.910000,14.910000,0,2017-08-22
|
||||
2016-06-08,14.950000,14.950000,14.950000,14.950000,14.950000,0,2017-08-22
|
||||
2016-06-09,14.990000,14.990000,14.990000,14.990000,14.990000,0,2017-08-22
|
||||
2016-06-10,15.040000,15.040000,15.040000,15.040000,15.040000,0,2017-08-22
|
||||
2016-06-13,15.070000,15.070000,15.070000,15.070000,15.070000,0,2017-08-22
|
||||
2016-06-14,15.090000,15.090000,15.090000,15.090000,15.090000,0,2017-08-22
|
||||
2016-06-15,15.050000,15.050000,15.050000,15.050000,15.050000,0,2017-08-22
|
||||
2016-06-16,15.060000,15.060000,15.060000,15.060000,15.060000,0,2017-08-22
|
||||
2016-06-17,15.000000,15.000000,15.000000,15.000000,15.000000,0,2017-08-22
|
||||
2016-06-20,14.920000,14.920000,14.920000,14.920000,14.920000,0,2017-08-22
|
||||
2016-06-21,14.990000,14.990000,14.990000,14.990000,14.990000,0,2017-08-22
|
||||
2016-06-22,14.980000,14.980000,14.980000,14.980000,14.980000,0,2017-08-22
|
||||
2016-06-23,14.910000,14.910000,14.910000,14.910000,14.910000,0,2017-08-22
|
||||
2016-06-24,15.090000,15.090000,15.090000,15.090000,15.090000,0,2017-08-22
|
||||
2016-06-27,15.250000,15.250000,15.250000,15.250000,15.250000,0,2017-08-22
|
||||
2016-06-28,15.190000,15.190000,15.190000,15.190000,15.190000,0,2017-08-22
|
||||
2016-06-29,15.140000,15.140000,15.140000,15.140000,15.140000,0,2017-08-22
|
||||
2016-06-30,15.150000,15.150000,15.150000,15.150000,15.150000,0,2017-08-22
|
||||
2016-07-01,15.070000,15.070000,15.070000,15.070000,15.070000,0,2017-08-22
|
||||
2016-07-05,15.210000,15.210000,15.210000,15.210000,15.210000,0,2017-08-22
|
||||
2016-07-06,15.180000,15.180000,15.180000,15.180000,15.180000,0,2017-08-22
|
||||
2016-07-07,15.210000,15.210000,15.210000,15.210000,15.210000,0,2017-08-22
|
||||
2016-07-08,15.170000,15.170000,15.170000,15.170000,15.170000,0,2017-08-22
|
||||
2016-07-11,15.120000,15.120000,15.120000,15.120000,15.120000,0,2017-08-22
|
||||
2016-07-12,14.970000,14.970000,14.970000,14.970000,14.970000,0,2017-08-22
|
||||
2016-07-13,14.970000,14.970000,14.970000,14.970000,14.970000,0,2017-08-22
|
||||
2016-07-14,14.990000,14.990000,14.990000,14.990000,14.990000,0,2017-08-22
|
||||
2016-07-15,15.000000,15.000000,15.000000,15.000000,15.000000,0,2017-08-22
|
||||
2016-07-18,14.990000,14.990000,14.990000,14.990000,14.990000,0,2017-08-22
|
||||
2016-07-19,15.110000,15.110000,15.110000,15.110000,15.110000,0,2017-08-22
|
||||
2016-07-20,15.070000,15.070000,15.070000,15.070000,15.070000,0,2017-08-22
|
||||
2016-07-21,14.980000,14.980000,14.980000,14.980000,14.980000,0,2017-08-22
|
||||
2016-07-22,15.020000,15.020000,15.020000,15.020000,15.020000,0,2017-08-22
|
||||
2016-07-25,15.010000,15.010000,15.010000,15.010000,15.010000,0,2017-08-22
|
||||
2016-07-26,14.870000,14.870000,14.870000,14.870000,14.870000,0,2017-08-22
|
||||
2016-07-27,14.890000,14.890000,14.890000,14.890000,14.890000,0,2017-08-22
|
||||
2016-07-28,14.960000,14.960000,14.960000,14.960000,14.960000,0,2017-08-22
|
||||
2016-07-29,14.960000,14.960000,14.960000,14.960000,14.960000,0,2017-08-22
|
||||
2016-08-01,14.990000,14.990000,14.990000,14.990000,14.990000,0,2017-08-22
|
||||
2016-08-02,15.070000,15.070000,15.070000,15.070000,15.070000,0,2017-08-22
|
||||
2016-08-03,15.060000,15.060000,15.060000,15.060000,15.060000,0,2017-08-22
|
||||
2016-08-04,15.010000,15.010000,15.010000,15.010000,15.010000,0,2017-08-22
|
||||
2016-08-05,14.950000,14.950000,14.950000,14.950000,14.950000,0,2017-08-22
|
||||
2016-08-08,14.920000,14.920000,14.920000,14.920000,14.920000,0,2017-08-22
|
||||
2016-08-09,14.940000,14.940000,14.940000,14.940000,14.940000,0,2017-08-22
|
||||
2016-08-10,14.930000,14.930000,14.930000,14.930000,14.930000,0,2017-08-22
|
||||
2016-08-11,14.900000,14.900000,14.900000,14.900000,14.900000,0,2017-08-22
|
||||
2016-08-12,14.910000,14.910000,14.910000,14.910000,14.910000,0,2017-08-22
|
||||
2016-08-15,14.880000,14.880000,14.880000,14.880000,14.880000,0,2017-08-22
|
||||
2016-08-16,14.780000,14.780000,14.780000,14.780000,14.780000,0,2017-08-22
|
||||
2016-08-17,14.850000,14.850000,14.850000,14.850000,14.850000,0,2017-08-22
|
||||
2016-08-18,14.840000,14.840000,14.840000,14.840000,14.840000,0,2017-08-22
|
||||
2016-08-19,14.840000,14.840000,14.840000,14.840000,14.840000,0,2017-08-22
|
||||
2016-08-22,14.870000,14.870000,14.870000,14.870000,14.870000,0,2017-08-22
|
||||
2016-08-23,14.870000,14.870000,14.870000,14.870000,14.870000,0,2017-08-22
|
||||
2016-08-24,14.850000,14.850000,14.850000,14.850000,14.850000,0,2017-08-22
|
||||
2016-08-25,14.780000,14.780000,14.780000,14.780000,14.780000,0,2017-08-22
|
||||
2016-08-26,14.820000,14.820000,14.820000,14.820000,14.820000,0,2017-08-22
|
||||
2016-08-29,14.810000,14.810000,14.810000,14.810000,14.810000,0,2017-08-22
|
||||
2016-08-30,14.830000,14.830000,14.830000,14.830000,14.830000,0,2017-08-22
|
||||
2016-08-31,14.840000,14.840000,14.840000,14.840000,14.840000,0,2017-08-22
|
||||
2016-09-01,14.850000,14.850000,14.850000,14.850000,14.850000,0,2017-08-22
|
||||
2016-09-02,14.830000,14.830000,14.830000,14.830000,14.830000,0,2017-08-22
|
||||
2016-09-06,14.790000,14.790000,14.790000,14.790000,14.790000,0,2017-08-22
|
||||
2016-09-07,14.770000,14.770000,14.770000,14.770000,14.770000,0,2017-08-22
|
||||
2016-09-08,14.790000,14.790000,14.790000,14.790000,14.790000,0,2017-08-22
|
||||
2016-09-09,14.910000,14.910000,14.910000,14.910000,14.910000,0,2017-08-22
|
||||
2016-09-12,14.860000,14.860000,14.860000,14.860000,14.860000,0,2017-08-22
|
||||
2016-09-13,14.910000,14.910000,14.910000,14.910000,14.910000,0,2017-08-22
|
||||
2016-09-14,14.960000,14.960000,14.960000,14.960000,14.960000,0,2017-08-22
|
||||
2016-09-15,14.930000,14.930000,14.930000,14.930000,14.930000,0,2017-08-22
|
||||
2016-09-16,14.960000,14.960000,14.960000,14.960000,14.960000,0,2017-08-22
|
||||
2016-09-19,14.950000,14.950000,14.950000,14.950000,14.950000,0,2017-08-22
|
||||
2016-09-20,14.980000,14.980000,14.980000,14.980000,14.980000,0,2017-08-22
|
||||
2016-09-21,14.950000,14.950000,14.950000,14.950000,14.950000,0,2017-08-22
|
||||
2016-09-22,14.930000,14.930000,14.930000,14.930000,14.930000,0,2017-08-22
|
||||
2016-09-23,14.910000,14.910000,14.910000,14.910000,14.910000,0,2017-08-22
|
||||
2016-09-26,14.900000,14.900000,14.900000,14.900000,14.900000,0,2017-08-22
|
||||
2016-09-27,14.880000,14.880000,14.880000,14.880000,14.880000,0,2017-08-22
|
||||
2016-09-28,14.840000,14.840000,14.840000,14.840000,14.840000,0,2017-08-22
|
||||
2016-09-29,14.790000,14.790000,14.790000,14.790000,14.790000,0,2017-08-22
|
||||
2016-09-30,14.770000,14.770000,14.770000,14.770000,14.770000,0,2017-08-22
|
||||
2016-10-03,14.770000,14.770000,14.770000,14.770000,14.770000,0,2017-08-22
|
||||
2016-10-04,14.810000,14.810000,14.810000,14.810000,14.810000,0,2017-08-22
|
||||
2016-10-05,14.810000,14.810000,14.810000,14.810000,14.810000,0,2017-08-22
|
||||
2016-10-06,14.810000,14.810000,14.810000,14.810000,14.810000,0,2017-08-22
|
||||
2016-10-07,14.850000,14.850000,14.850000,14.850000,14.850000,0,2017-08-22
|
||||
2016-10-10,14.910000,14.910000,14.910000,14.910000,14.910000,0,2017-08-22
|
||||
2016-10-11,14.890000,14.890000,14.890000,14.890000,14.890000,0,2017-08-22
|
||||
2016-10-12,14.870000,14.870000,14.870000,14.870000,14.870000,0,2017-08-22
|
||||
2016-10-13,14.860000,14.860000,14.860000,14.860000,14.860000,0,2017-08-22
|
||||
2016-10-14,14.880000,14.880000,14.880000,14.880000,14.880000,0,2017-08-22
|
||||
2016-10-17,14.860000,14.860000,14.860000,14.860000,14.860000,0,2017-08-22
|
||||
2016-10-18,14.810000,14.810000,14.810000,14.810000,14.810000,0,2017-08-22
|
||||
2016-10-19,14.730000,14.730000,14.730000,14.730000,14.730000,0,2017-08-22
|
||||
2016-10-20,14.750000,14.750000,14.750000,14.750000,14.750000,0,2017-08-22
|
||||
2016-10-21,14.780000,14.780000,14.780000,14.780000,14.780000,0,2017-08-22
|
||||
2016-10-24,14.780000,14.780000,14.780000,14.780000,14.780000,0,2017-08-22
|
||||
2016-10-25,14.800000,14.800000,14.800000,14.800000,14.800000,0,2017-08-22
|
||||
2016-10-26,14.800000,14.800000,14.800000,14.800000,14.800000,0,2017-08-22
|
||||
2016-10-27,14.750000,14.750000,14.750000,14.750000,14.750000,0,2017-08-22
|
||||
2016-10-28,14.770000,14.770000,14.770000,14.770000,14.770000,0,2017-08-22
|
||||
2016-10-31,14.710000,14.710000,14.710000,14.710000,14.710000,0,2017-08-22
|
||||
2016-11-01,14.730000,14.730000,14.730000,14.730000,14.730000,0,2017-08-22
|
||||
2016-11-02,14.620000,14.620000,14.620000,14.620000,14.620000,0,2017-08-22
|
||||
2016-11-03,14.620000,14.620000,14.620000,14.620000,14.620000,0,2017-08-22
|
||||
2016-11-04,14.600000,14.600000,14.600000,14.600000,14.600000,0,2017-08-22
|
||||
2016-11-07,14.590000,14.590000,14.590000,14.590000,14.590000,0,2017-08-22
|
||||
2016-11-08,14.600000,14.600000,14.600000,14.600000,14.600000,0,2017-08-22
|
||||
2016-11-09,14.600000,14.600000,14.600000,14.600000,14.600000,0,2017-08-22
|
||||
2016-11-10,14.560000,14.560000,14.560000,14.560000,14.560000,0,2017-08-22
|
||||
2016-11-11,14.500000,14.500000,14.500000,14.500000,14.500000,0,2017-08-22
|
||||
2016-11-14,14.510000,14.510000,14.510000,14.510000,14.510000,0,2017-08-22
|
||||
2016-11-15,14.550000,14.550000,14.550000,14.550000,14.550000,0,2017-08-22
|
||||
2016-11-16,14.510000,14.510000,14.510000,14.510000,14.510000,0,2017-08-22
|
||||
2016-11-17,14.580000,14.580000,14.580000,14.580000,14.580000,0,2017-08-22
|
||||
2016-11-18,14.560000,14.560000,14.560000,14.560000,14.560000,0,2017-08-22
|
||||
2016-11-21,14.550000,14.550000,14.550000,14.550000,14.550000,0,2017-08-22
|
||||
2016-11-22,14.450000,14.450000,14.450000,14.450000,14.450000,0,2017-08-22
|
||||
2016-11-23,14.460000,14.460000,14.460000,14.460000,14.460000,0,2017-08-22
|
||||
2016-11-25,14.440000,14.440000,14.440000,14.440000,14.440000,0,2017-08-22
|
||||
2016-11-28,14.380000,14.380000,14.380000,14.380000,14.380000,0,2017-08-22
|
||||
2016-11-29,14.420000,14.420000,14.420000,14.420000,14.420000,0,2017-08-22
|
||||
2016-11-30,14.510000,14.510000,14.510000,14.510000,14.510000,0,2017-08-22
|
||||
2016-12-01,14.510000,14.510000,14.510000,14.510000,14.510000,0,2017-08-22
|
||||
2016-12-02,14.500000,14.500000,14.500000,14.500000,14.500000,0,2017-08-22
|
||||
2016-12-05,14.490000,14.490000,14.490000,14.490000,14.490000,0,2017-08-22
|
||||
2016-12-06,14.480000,14.480000,14.480000,14.480000,14.480000,0,2017-08-22
|
||||
2016-12-07,14.420000,14.420000,14.420000,14.420000,14.420000,0,2017-08-22
|
||||
2016-12-08,14.440000,14.440000,14.440000,14.440000,14.440000,0,2017-08-22
|
||||
2016-12-09,14.420000,14.420000,14.420000,14.420000,14.420000,0,2017-08-22
|
||||
2016-12-12,14.350000,14.350000,14.350000,14.350000,14.350000,0,2017-08-22
|
||||
2016-12-13,14.390000,14.390000,14.390000,14.390000,14.390000,0,2017-08-22
|
||||
2016-12-14,14.440000,14.440000,14.440000,14.440000,14.440000,0,2017-08-22
|
||||
2016-12-15,14.440000,14.440000,14.440000,14.440000,14.440000,0,2017-08-22
|
||||
2016-12-16,14.410000,14.410000,14.410000,14.410000,14.410000,0,2017-08-22
|
||||
2016-12-19,14.390000,14.390000,14.390000,14.390000,14.390000,0,2017-08-22
|
||||
2016-12-20,14.380000,14.380000,14.380000,14.380000,14.380000,0,2017-08-22
|
||||
2016-12-21,14.390000,14.390000,14.390000,14.390000,14.390000,0,2017-08-22
|
||||
2016-12-22,14.400000,14.400000,14.400000,14.400000,14.400000,0,2017-08-22
|
||||
2016-12-23,14.400000,14.400000,14.400000,14.400000,14.400000,0,2017-08-22
|
||||
2016-12-27,14.390000,14.390000,14.390000,14.390000,14.390000,0,2017-08-22
|
||||
2016-12-28,14.390000,14.390000,14.390000,14.390000,14.390000,0,2017-08-22
|
||||
2016-12-29,14.400000,14.400000,14.400000,14.400000,14.400000,0,2017-08-22
|
||||
2016-12-30,14.380000,14.380000,14.380000,14.380000,14.380000,0,2017-08-22
|
||||
2017-01-03,14.360000,14.360000,14.360000,14.360000,14.360000,0,2017-08-22
|
||||
2017-01-04,14.330000,14.330000,14.330000,14.330000,14.330000,0,2017-08-22
|
||||
2017-01-05,14.370000,14.370000,14.370000,14.370000,14.370000,0,2017-08-22
|
||||
2017-01-06,14.330000,14.330000,14.330000,14.330000,14.330000,0,2017-08-22
|
||||
2017-01-09,14.360000,14.360000,14.360000,14.360000,14.360000,0,2017-08-22
|
||||
2017-01-10,14.350000,14.350000,14.350000,14.350000,14.350000,0,2017-08-22
|
||||
2017-01-11,14.420000,14.420000,14.420000,14.420000,14.420000,0,2017-08-22
|
||||
2017-01-12,14.370000,14.370000,14.370000,14.370000,14.370000,0,2017-08-22
|
||||
2017-01-13,14.430000,14.430000,14.430000,14.430000,14.430000,0,2017-08-22
|
||||
2017-01-17,14.390000,14.390000,14.390000,14.390000,14.390000,0,2017-08-22
|
||||
2017-01-18,14.420000,14.420000,14.420000,14.420000,14.420000,0,2017-08-22
|
||||
2017-01-19,14.430000,14.430000,14.430000,14.430000,14.430000,0,2017-08-22
|
||||
2017-01-20,14.470000,14.470000,14.470000,14.470000,14.470000,0,2017-08-22
|
||||
2017-01-23,14.470000,14.470000,14.470000,14.470000,14.470000,0,2017-08-22
|
||||
2017-01-24,14.430000,14.430000,14.430000,14.430000,14.430000,0,2017-08-22
|
||||
2017-01-25,14.450000,14.450000,14.450000,14.450000,14.450000,0,2017-08-22
|
||||
2017-01-26,14.490000,14.490000,14.490000,14.490000,14.490000,0,2017-08-22
|
||||
2017-01-27,14.480000,14.480000,14.480000,14.480000,14.480000,0,2017-08-22
|
||||
2017-01-30,14.440000,14.440000,14.440000,14.440000,14.440000,0,2017-08-22
|
||||
2017-01-31,14.420000,14.420000,14.420000,14.420000,14.420000,0,2017-08-22
|
||||
2017-02-01,14.440000,14.440000,14.440000,14.440000,14.440000,0,2017-08-22
|
||||
2017-02-02,14.450000,14.450000,14.450000,14.450000,14.450000,0,2017-08-22
|
||||
2017-02-03,14.430000,14.430000,14.430000,14.430000,14.430000,0,2017-08-22
|
||||
2017-02-06,14.390000,14.390000,14.390000,14.390000,14.390000,0,2017-08-22
|
||||
2017-02-07,14.390000,14.390000,14.390000,14.390000,14.390000,0,2017-08-22
|
||||
2017-02-08,14.330000,14.330000,14.330000,14.330000,14.330000,0,2017-08-22
|
||||
2017-02-09,14.340000,14.340000,14.340000,14.340000,14.340000,0,2017-08-22
|
||||
2017-02-10,14.300000,14.300000,14.300000,14.300000,14.300000,0,2017-08-22
|
||||
2017-02-13,14.310000,14.310000,14.310000,14.310000,14.310000,0,2017-08-22
|
||||
2017-02-14,14.300000,14.300000,14.300000,14.300000,14.300000,0,2017-08-22
|
||||
2017-02-15,14.280000,14.280000,14.280000,14.280000,14.280000,0,2017-08-22
|
||||
2017-02-16,14.200000,14.200000,14.200000,14.200000,14.200000,0,2017-08-22
|
||||
2017-02-17,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-08-22
|
||||
2017-02-21,14.170000,14.170000,14.170000,14.170000,14.170000,0,2017-08-22
|
||||
2017-02-22,14.160000,14.160000,14.160000,14.160000,14.160000,0,2017-08-22
|
||||
2017-02-23,14.120000,14.120000,14.120000,14.120000,14.120000,0,2017-08-22
|
||||
2017-02-24,14.090000,14.090000,14.090000,14.090000,14.090000,0,2017-08-22
|
||||
2017-02-27,14.110000,14.110000,14.110000,14.110000,14.110000,0,2017-08-22
|
||||
2017-02-28,14.140000,14.140000,14.140000,14.140000,14.140000,0,2017-08-22
|
||||
2017-03-01,14.110000,14.110000,14.110000,14.110000,14.110000,0,2017-08-22
|
||||
2017-03-02,14.080000,14.080000,14.080000,14.080000,14.080000,0,2017-08-22
|
||||
2017-03-03,14.120000,14.120000,14.120000,14.120000,14.120000,0,2017-08-22
|
||||
2017-03-06,14.120000,14.120000,14.120000,14.120000,14.120000,0,2017-08-22
|
||||
2017-03-07,14.120000,14.120000,14.120000,14.120000,14.120000,0,2017-08-22
|
||||
2017-03-08,14.060000,14.060000,14.060000,14.060000,14.060000,0,2017-08-22
|
||||
2017-03-09,14.090000,14.090000,14.090000,14.090000,14.090000,0,2017-08-22
|
||||
2017-03-10,14.090000,14.090000,14.090000,14.090000,14.090000,0,2017-08-22
|
||||
2017-03-13,14.180000,14.180000,14.180000,14.180000,14.180000,0,2017-08-22
|
||||
2017-03-14,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-08-22
|
||||
2017-03-15,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-08-22
|
||||
2017-03-16,14.120000,14.120000,14.120000,14.120000,14.120000,0,2017-08-22
|
||||
2017-03-17,14.130000,14.130000,14.130000,14.130000,14.130000,0,2017-08-22
|
||||
2017-03-20,14.100000,14.100000,14.100000,14.100000,14.100000,0,2017-08-22
|
||||
2017-03-21,14.020000,14.020000,14.020000,14.020000,14.020000,0,2017-08-22
|
||||
2017-03-22,14.020000,14.020000,14.020000,14.020000,14.020000,0,2017-08-22
|
||||
2017-03-23,14.030000,14.030000,14.030000,14.030000,14.030000,0,2017-08-22
|
||||
2017-03-24,14.030000,14.030000,14.030000,14.030000,14.030000,0,2017-08-22
|
||||
2017-03-27,14.060000,14.060000,14.060000,14.060000,14.060000,0,2017-08-22
|
||||
2017-03-28,14.100000,14.100000,14.100000,14.100000,14.100000,0,2017-08-22
|
||||
2017-03-29,14.110000,14.110000,14.110000,14.110000,14.110000,0,2017-08-22
|
||||
2017-03-30,14.120000,14.120000,14.120000,14.120000,14.120000,0,2017-08-22
|
||||
2017-03-31,14.120000,14.120000,14.120000,14.120000,14.120000,0,2017-08-22
|
||||
2017-04-03,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-08-22
|
||||
2017-04-04,14.200000,14.200000,14.200000,14.200000,14.200000,0,2017-08-22
|
||||
2017-04-05,14.180000,14.180000,14.180000,14.180000,14.180000,0,2017-08-22
|
||||
2017-04-06,14.210000,14.210000,14.210000,14.210000,14.210000,0,2017-08-22
|
||||
2017-04-07,14.220000,14.220000,14.220000,14.220000,14.220000,0,2017-08-22
|
||||
2017-04-10,14.170000,14.170000,14.170000,14.170000,14.170000,0,2017-08-22
|
||||
2017-04-11,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-08-22
|
||||
2017-04-12,14.130000,14.130000,14.130000,14.130000,14.130000,0,2017-08-22
|
||||
2017-04-13,14.100000,14.100000,14.100000,14.100000,14.100000,0,2017-08-22
|
||||
2017-04-17,14.080000,14.080000,14.080000,14.080000,14.080000,0,2017-08-22
|
||||
2017-04-18,14.060000,14.060000,14.060000,14.060000,14.060000,0,2017-08-22
|
||||
2017-04-19,14.010000,14.010000,14.010000,14.010000,14.010000,0,2017-08-22
|
||||
2017-04-20,14.030000,14.030000,14.030000,14.030000,14.030000,0,2017-08-22
|
||||
2017-04-21,14.000000,14.000000,14.000000,14.000000,14.000000,0,2017-08-22
|
||||
2017-04-24,14.050000,14.050000,14.050000,14.050000,14.050000,0,2017-08-22
|
||||
2017-04-25,14.090000,14.090000,14.090000,14.090000,14.090000,0,2017-08-22
|
||||
2017-04-26,14.090000,14.090000,14.090000,14.090000,14.090000,0,2017-08-22
|
||||
2017-04-27,14.070000,14.070000,14.070000,14.070000,14.070000,0,2017-08-22
|
||||
2017-04-28,14.040000,14.040000,14.040000,14.040000,14.040000,0,2017-08-22
|
||||
2017-05-01,14.080000,14.080000,14.080000,14.080000,14.080000,0,2017-08-22
|
||||
2017-05-02,14.090000,14.090000,14.090000,14.090000,14.090000,0,2017-08-22
|
||||
2017-05-03,14.110000,14.110000,14.110000,14.110000,14.110000,0,2017-08-22
|
||||
2017-05-04,14.080000,14.080000,14.080000,14.080000,14.080000,0,2017-08-22
|
||||
2017-05-05,14.060000,14.060000,14.060000,14.060000,14.060000,0,2017-08-22
|
||||
2017-05-08,14.040000,14.040000,14.040000,14.040000,14.040000,0,2017-08-22
|
||||
2017-05-09,14.000000,14.000000,14.000000,14.000000,14.000000,0,2017-08-22
|
||||
2017-05-10,14.000000,14.000000,14.000000,14.000000,14.000000,0,2017-08-22
|
||||
2017-05-11,14.020000,14.020000,14.020000,14.020000,14.020000,0,2017-08-22
|
||||
2017-05-12,14.040000,14.040000,14.040000,14.040000,14.040000,0,2017-08-22
|
||||
2017-05-15,14.060000,14.060000,14.060000,14.060000,14.060000,0,2017-08-22
|
||||
2017-05-16,14.090000,14.090000,14.090000,14.090000,14.090000,0,2017-08-22
|
||||
2017-05-17,13.970000,13.970000,13.970000,13.970000,13.970000,0,2017-08-22
|
||||
2017-05-18,14.030000,14.030000,14.030000,14.030000,14.030000,0,2017-08-22
|
||||
2017-05-19,14.050000,14.050000,14.050000,14.050000,14.050000,0,2017-08-22
|
||||
2017-05-22,14.090000,14.090000,14.090000,14.090000,14.090000,0,2017-08-22
|
||||
2017-05-23,14.140000,14.140000,14.140000,14.140000,14.140000,0,2017-08-22
|
||||
2017-05-24,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-08-22
|
||||
2017-05-25,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-08-22
|
||||
2017-05-26,14.190000,14.190000,14.190000,14.190000,14.190000,0,2017-08-22
|
||||
2017-05-30,14.130000,14.130000,14.130000,14.130000,14.130000,0,2017-08-22
|
||||
2017-05-31,14.090000,14.090000,14.090000,14.090000,14.090000,0,2017-08-22
|
||||
2017-06-01,14.060000,14.060000,14.060000,14.060000,14.060000,0,2017-08-22
|
||||
2017-06-02,14.090000,14.090000,14.090000,14.090000,14.090000,0,2017-08-22
|
||||
2017-06-05,14.100000,14.100000,14.100000,14.100000,14.100000,0,2017-08-22
|
||||
2017-06-06,14.130000,14.130000,14.130000,14.130000,14.130000,0,2017-08-22
|
||||
2017-06-07,14.190000,14.190000,14.190000,14.190000,14.190000,0,2017-08-22
|
||||
2017-06-08,14.230000,14.230000,14.230000,14.230000,14.230000,0,2017-08-22
|
||||
2017-06-09,14.120000,14.120000,14.120000,14.120000,14.120000,0,2017-08-22
|
||||
2017-06-12,14.010000,14.010000,14.010000,14.010000,14.010000,0,2017-08-22
|
||||
2017-06-13,14.060000,14.060000,14.060000,14.060000,14.060000,0,2017-08-22
|
||||
2017-06-14,14.050000,14.050000,14.050000,14.050000,14.050000,0,2017-08-22
|
||||
2017-06-15,14.040000,14.040000,14.040000,14.040000,14.040000,0,2017-08-22
|
||||
2017-06-16,14.030000,14.030000,14.030000,14.030000,14.030000,0,2017-08-22
|
||||
2017-06-19,14.100000,14.100000,14.100000,14.100000,14.100000,0,2017-08-22
|
||||
2017-06-20,14.120000,14.120000,14.120000,14.120000,14.120000,0,2017-08-22
|
||||
2017-06-21,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-08-22
|
||||
2017-06-22,14.120000,14.120000,14.120000,14.120000,14.120000,0,2017-08-22
|
||||
2017-06-23,14.100000,14.100000,14.100000,14.100000,14.100000,0,2017-08-22
|
||||
2017-06-26,14.040000,14.040000,14.040000,14.040000,14.040000,0,2017-08-22
|
||||
2017-06-27,14.000000,14.000000,14.000000,14.000000,14.000000,0,2017-08-22
|
||||
2017-06-28,14.050000,14.050000,14.050000,14.050000,14.050000,0,2017-08-22
|
||||
2017-06-29,13.980000,13.980000,13.980000,13.980000,13.980000,0,2017-08-22
|
||||
2017-06-30,13.960000,13.960000,13.960000,13.960000,13.960000,0,2017-08-22
|
||||
2017-07-03,13.910000,13.910000,13.910000,13.910000,13.910000,0,2017-08-22
|
||||
2017-07-05,14.040000,14.040000,14.040000,14.040000,14.040000,0,2017-08-22
|
||||
2017-07-06,14.090000,14.090000,14.090000,14.090000,14.090000,0,2017-08-22
|
||||
2017-07-07,14.110000,14.110000,14.110000,14.110000,14.110000,0,2017-08-22
|
||||
2017-07-10,14.120000,14.120000,14.120000,14.120000,14.120000,0,2017-08-22
|
||||
2017-07-11,14.130000,14.130000,14.130000,14.130000,14.130000,0,2017-08-22
|
||||
2017-07-12,14.170000,14.170000,14.170000,14.170000,14.170000,0,2017-08-22
|
||||
2017-07-13,14.140000,14.140000,14.140000,14.140000,14.140000,0,2017-08-22
|
||||
2017-07-14,14.130000,14.130000,14.130000,14.130000,14.130000,0,2017-08-22
|
||||
2017-07-17,14.090000,14.090000,14.090000,14.090000,14.090000,0,2017-08-22
|
||||
2017-07-18,14.120000,14.120000,14.120000,14.120000,14.120000,0,2017-08-22
|
||||
2017-07-19,14.170000,14.170000,14.170000,14.170000,14.170000,0,2017-08-22
|
||||
2017-07-20,14.170000,14.170000,14.170000,14.170000,14.170000,0,2017-08-22
|
||||
2017-07-21,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-08-22
|
||||
2017-07-24,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-08-22
|
||||
2017-07-25,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-08-22
|
||||
2017-07-26,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-08-22
|
||||
2017-07-27,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-08-22
|
||||
2017-07-28,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-08-22
|
||||
2017-07-31,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-08-22
|
||||
2017-08-01,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-08-22
|
||||
2017-08-02,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-08-22
|
||||
2017-08-03,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-08-22
|
||||
2017-08-04,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-08-22
|
||||
2017-08-07,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-08-22
|
||||
2017-08-08,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-08-22
|
||||
2017-08-09,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-08-22
|
||||
2017-08-10,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-08-22
|
||||
2017-08-11,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-08-22
|
||||
2017-08-14,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-08-22
|
||||
2017-08-15,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-08-22
|
||||
2017-08-16,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-08-22
|
||||
2017-08-17,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-08-22
|
||||
2017-08-18,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-08-22
|
||||
2017-08-21,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-08-22
|
||||
2017-08-22,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-08-24 08:26:38
|
||||
2017-08-23,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-08-24 08:26:38
|
||||
2017-08-24,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-08-25 07:50:50
|
||||
2017-08-25,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-08-26 07:47:11
|
||||
2017-08-28,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-08-29 07:18:44
|
||||
2017-08-29,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-08-29 22:27:18
|
||||
2017-08-30,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-08-30 21:26:47
|
||||
2017-08-31,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-09-01 08:18:04
|
||||
2017-09-01,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-09-05 07:48:27
|
||||
2017-09-05,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-09-06 07:03:16
|
||||
2017-09-06,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-09-07 07:38:19
|
||||
2017-09-07,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-09-08 07:09:10
|
||||
2017-09-08,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-09-09 08:43:50
|
||||
2017-09-11,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-09-13 06:44:33
|
||||
2017-09-12,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-09-13 14:29:06
|
||||
2017-09-13,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-09-15 07:54:07
|
||||
2017-09-14,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-09-15 07:54:07
|
||||
2017-09-15,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-09-18 07:57:00
|
||||
2017-09-18,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-09-19 07:04:50
|
||||
2017-09-19,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-09-20 07:02:59
|
||||
2017-09-20,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-09-21 06:52:01
|
||||
2017-09-21,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-09-22 07:46:25
|
||||
2017-09-22,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-09-23 08:05:02
|
||||
2017-09-25,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-09-26 07:33:50
|
||||
2017-09-26,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-09-27 07:38:44
|
||||
2017-09-27,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-09-28 06:48:39
|
||||
2017-09-28,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-09-29 08:00:20
|
||||
2017-09-29,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-10-04 07:54:54
|
||||
2017-10-02,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-10-04 07:54:54
|
||||
2017-10-03,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-10-04 07:54:54
|
||||
2017-10-04,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-10-05 07:13:33
|
||||
2017-10-05,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-10-06 06:58:57
|
||||
2017-10-06,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-10-09 07:35:40
|
||||
2017-10-09,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-10-10 07:30:35
|
||||
2017-10-10,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-10-11 07:10:33
|
||||
2017-10-11,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-10-12 07:02:18
|
||||
2017-10-12,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-10-13 07:44:41
|
||||
2017-10-13,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-10-15 21:31:35
|
||||
2017-10-16,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-10-17 07:24:53
|
||||
2017-10-17,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-10-18 06:38:28
|
||||
2017-10-18,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-10-19 07:41:01
|
||||
2017-10-19,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-10-20 07:48:13
|
||||
2017-10-20,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-10-23 07:36:15
|
||||
2017-10-23,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-10-24 07:44:32
|
||||
2017-10-24,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-10-26 06:30:50
|
||||
2017-10-25,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-10-26 06:30:50
|
||||
2017-10-26,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-10-31 08:26:49
|
||||
2017-10-27,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-10-31 08:26:49
|
||||
2017-10-30,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-10-31 08:26:49
|
||||
2017-10-31,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-11-01 07:49:35
|
||||
2017-11-01,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-11-07 10:58:03
|
||||
2017-11-02,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-11-07 10:58:03
|
||||
2017-11-03,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-11-07 10:58:03
|
||||
2017-11-06,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-11-07 10:58:03
|
||||
2017-11-07,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-11-08 07:52:27
|
||||
2017-11-08,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-11-15 07:55:39
|
||||
2017-11-09,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-11-15 07:55:39
|
||||
2017-11-10,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-11-15 07:55:39
|
||||
2017-11-13,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-11-15 07:55:39
|
||||
2017-11-14,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-11-15 07:55:39
|
||||
2017-11-15,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-11-20 07:43:46
|
||||
2017-11-16,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-11-20 07:43:46
|
||||
2017-11-17,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-11-20 07:43:46
|
||||
2017-11-20,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-11-28 13:58:38
|
||||
2017-11-21,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-11-28 13:58:38
|
||||
2017-11-22,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-11-28 13:58:38
|
||||
2017-11-24,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-11-28 13:58:38
|
||||
2017-11-27,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-11-28 13:58:38
|
||||
2017-11-28,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-11-30 07:17:01
|
||||
2017-11-29,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-11-30 07:17:01
|
||||
2017-11-30,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-12-02 19:04:46
|
||||
2017-12-01,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-12-02 19:04:46
|
||||
2017-12-04,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-12-06 14:41:27
|
||||
2017-12-05,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-12-06 14:41:27
|
||||
2017-12-06,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-12-11 20:07:47
|
||||
2017-12-07,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-12-11 20:07:47
|
||||
2017-12-08,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-12-11 20:07:47
|
||||
2017-12-11,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-12-12 07:18:16
|
||||
2017-12-12,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-12-13 10:46:22
|
||||
2017-12-13,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-12-14 07:15:00
|
||||
2017-12-14,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-12-15 07:46:46
|
||||
2017-12-15,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-12-19 07:11:54
|
||||
2017-12-18,14.150000,14.150000,14.150000,14.150000,14.150000,0,2017-12-19 07:11:54
|
||||
|
7
overrides/frozen/adusx.json
Normal file
7
overrides/frozen/adusx.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"symbol": "adusx",
|
||||
"longName": "?",
|
||||
"freeze_date": "2017-12-18",
|
||||
"created": "2026-08-31",
|
||||
"reason": "yahoo-empty"
|
||||
}
|
||||
5
overrides/frozen/aectx-capitalGain.csv
Normal file
5
overrides/frozen/aectx-capitalGain.csv
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Date,Capital Gains
|
||||
2021-12-21,1.204000
|
||||
2017-12-19,0.016000
|
||||
2018-12-18,0.414000
|
||||
2020-12-22,0.608000
|
||||
|
10
overrides/frozen/aectx-dividend.csv
Normal file
10
overrides/frozen/aectx-dividend.csv
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
Date,Dividends
|
||||
2019-12-17,0.092000
|
||||
2020-12-22,0.608000
|
||||
2022-12-21,0.291000
|
||||
2024-12-17,0.052000
|
||||
2016-12-20,0.124000
|
||||
2017-12-19,0.206000
|
||||
2018-12-18,0.414000
|
||||
2021-12-21,1.276000
|
||||
2024-03-19,0.164000
|
||||
|
2
overrides/frozen/aectx-history.csv
Normal file
2
overrides/frozen/aectx-history.csv
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
Date,Open,High,Low,Close,Adj Close,Volume
|
||||
2025-09-23,14.420000,14.420000,14.420000,14.420000,14.420000,0
|
||||
|
7
overrides/frozen/aectx.json
Normal file
7
overrides/frozen/aectx.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"symbol": "aectx",
|
||||
"longName": "American Century World Mutual Funds, Inc. - Emerging Markets Small Cap Fund",
|
||||
"freeze_date": "2025-09-23",
|
||||
"created": "2026-08-31",
|
||||
"reason": "yahoo-empty"
|
||||
}
|
||||
478
overrides/frozen/afxpx-dividend.csv
Normal file
478
overrides/frozen/afxpx-dividend.csv
Normal file
|
|
@ -0,0 +1,478 @@
|
|||
Date,Dividends,ctime
|
||||
2013-04-01,0.007,2017-08-22
|
||||
2017-07-03,0.014,2017-08-22
|
||||
2014-08-01,0.012,2017-08-22
|
||||
2017-01-03,0.014,2017-08-22
|
||||
2014-02-03,0.007,2017-08-22
|
||||
2013-07-01,0.031,2017-08-22
|
||||
2013-01-02,0.007,2017-08-22
|
||||
2012-06-01,0.013,2017-08-22
|
||||
2015-12-22,0.22,2017-08-22
|
||||
2013-10-01,0.007,2017-08-22
|
||||
2014-12-01,0.009,2017-08-22
|
||||
2011-12-30,0.004,2017-08-22
|
||||
2016-06-01,0.016,2017-08-22
|
||||
2015-05-01,0.005,2017-08-22
|
||||
2015-03-02,0.004,2017-08-22
|
||||
2012-09-04,0.036,2017-08-22
|
||||
2012-04-02,0.016,2017-08-22
|
||||
2013-08-01,0.025,2017-08-22
|
||||
2016-04-01,0.014,2017-08-22
|
||||
2012-03-01,0.057,2017-08-22
|
||||
2015-02-02,0.006,2017-08-22
|
||||
2016-12-01,0.014,2017-08-22
|
||||
2012-07-02,0.038,2017-08-22
|
||||
2016-10-03,0.013,2017-08-22
|
||||
2013-11-01,0.009,2017-08-22
|
||||
2014-01-02,0.007,2017-08-22
|
||||
2016-07-01,0.028,2017-08-22
|
||||
2012-10-01,0.046,2017-08-22
|
||||
2015-06-01,0.01,2017-08-22
|
||||
2015-12-01,0.013,2017-08-22
|
||||
2014-05-01,0.01,2017-08-22
|
||||
2017-04-03,0.018,2017-08-22
|
||||
2012-12-20,0.137,2017-08-22
|
||||
2015-09-01,0.005,2017-08-22
|
||||
2016-03-01,0.013,2017-08-22
|
||||
2011-11-30,0.003,2017-08-22
|
||||
2014-11-03,0.011,2017-08-22
|
||||
2016-11-01,0.013,2017-08-22
|
||||
2012-08-01,0.023,2017-08-22
|
||||
2015-04-01,0.004,2017-08-22
|
||||
2012-05-01,0.006,2017-08-22
|
||||
2016-02-01,0.013,2017-08-22
|
||||
2016-08-01,0.016,2017-08-22
|
||||
2015-07-01,0.024,2017-08-22
|
||||
2015-01-02,0.02,2017-08-22
|
||||
2012-01-31,0.004,2017-08-22
|
||||
2012-12-03,0.018,2017-08-22
|
||||
2014-06-02,0.013,2017-08-22
|
||||
2015-10-01,0.014,2017-08-22
|
||||
2013-03-01,0.004,2017-08-22
|
||||
2017-08-01,0.025,2017-08-22
|
||||
2013-05-01,0.009,2017-08-22
|
||||
2013-12-20,0.069,2017-08-22
|
||||
2014-09-02,0.015,2017-08-22
|
||||
2017-03-01,0.013,2017-08-22
|
||||
2015-11-02,0.011,2017-08-22
|
||||
2017-05-01,0.01,2017-08-22
|
||||
2014-04-01,0.009,2017-08-22
|
||||
2016-01-04,0.025,2017-08-22
|
||||
2013-02-01,0.006,2017-08-22
|
||||
2015-08-03,0.009,2017-08-22
|
||||
2017-06-01,0.021,2017-08-22
|
||||
2014-07-01,0.028,2017-08-22
|
||||
2014-12-22,0.105,2017-08-22
|
||||
2016-05-03,0.015,2017-08-22
|
||||
2013-06-03,0.02,2017-08-22
|
||||
2013-12-02,0.008,2017-08-22
|
||||
2014-10-01,0.013,2017-08-22
|
||||
2011-10-31,0.003,2017-08-22
|
||||
2017-02-01,0.025,2017-08-22
|
||||
2014-03-03,0.012,2017-08-22
|
||||
2013-09-03,0.026,2017-08-22
|
||||
2017-10-02,0.015,2017-10-10 07:30:35
|
||||
2013-01-02,0.007,2017-10-20 09:54:16
|
||||
2012-06-01,0.013,2017-10-20 09:54:16
|
||||
2015-12-22,0.22,2017-10-20 09:54:16
|
||||
2013-10-01,0.007,2017-10-20 09:54:16
|
||||
2014-12-01,0.009,2017-10-20 09:54:16
|
||||
2011-12-30,0.004,2017-10-20 09:54:16
|
||||
2016-06-01,0.016,2017-10-20 09:54:16
|
||||
2015-05-01,0.005,2017-10-20 09:54:16
|
||||
2015-03-02,0.004,2017-10-20 09:54:16
|
||||
2012-09-04,0.036,2017-10-20 09:54:16
|
||||
2012-04-02,0.016,2017-10-20 09:54:16
|
||||
2013-08-01,0.025,2017-10-20 09:54:16
|
||||
2016-04-01,0.014,2017-10-20 09:54:16
|
||||
2012-03-01,0.057,2017-10-20 09:54:16
|
||||
2015-02-02,0.006,2017-10-20 09:54:16
|
||||
2016-12-01,0.014,2017-10-20 09:54:16
|
||||
2012-07-02,0.038,2017-10-20 09:54:16
|
||||
2016-10-03,0.013,2017-10-20 09:54:16
|
||||
2013-11-01,0.009,2017-10-20 09:54:16
|
||||
2014-01-02,0.007,2017-10-20 09:54:16
|
||||
2016-07-01,0.028,2017-10-20 09:54:16
|
||||
2012-10-01,0.046,2017-10-20 09:54:16
|
||||
2015-06-01,0.01,2017-10-20 09:54:16
|
||||
2015-12-01,0.013,2017-10-20 09:54:16
|
||||
2014-05-01,0.01,2017-10-20 09:54:16
|
||||
2017-04-03,0.018,2017-10-20 09:54:16
|
||||
2012-12-20,0.137,2017-10-20 09:54:16
|
||||
2015-09-01,0.005,2017-10-20 09:54:16
|
||||
2016-03-01,0.013,2017-10-20 09:54:16
|
||||
2011-11-30,0.003,2017-10-20 09:54:16
|
||||
2014-11-03,0.011,2017-10-20 09:54:16
|
||||
2016-11-01,0.013,2017-10-20 09:54:16
|
||||
2012-08-01,0.023,2017-10-20 09:54:16
|
||||
2015-04-01,0.004,2017-10-20 09:54:16
|
||||
2012-05-01,0.006,2017-10-20 09:54:16
|
||||
2016-02-01,0.013,2017-10-20 09:54:16
|
||||
2016-08-01,0.016,2017-10-20 09:54:16
|
||||
2015-07-01,0.024,2017-10-20 09:54:16
|
||||
2015-01-02,0.02,2017-10-20 09:54:16
|
||||
2012-01-31,0.004,2017-10-20 09:54:16
|
||||
2012-12-03,0.018,2017-10-20 09:54:16
|
||||
2014-06-02,0.013,2017-10-20 09:54:16
|
||||
2015-10-01,0.014,2017-10-20 09:54:16
|
||||
2013-03-01,0.004,2017-10-20 09:54:16
|
||||
2017-08-01,0.025,2017-10-20 09:54:16
|
||||
2013-05-01,0.009,2017-10-20 09:54:16
|
||||
2013-12-20,0.069,2017-10-20 09:54:16
|
||||
2014-09-02,0.015,2017-10-20 09:54:16
|
||||
2017-03-01,0.013,2017-10-20 09:54:16
|
||||
2015-11-02,0.011,2017-10-20 09:54:16
|
||||
2017-05-01,0.01,2017-10-20 09:54:16
|
||||
2014-04-01,0.009,2017-10-20 09:54:16
|
||||
2016-01-04,0.025,2017-10-20 09:54:16
|
||||
2013-02-01,0.006,2017-10-20 09:54:16
|
||||
2015-08-03,0.009,2017-10-20 09:54:16
|
||||
2017-06-01,0.021,2017-10-20 09:54:16
|
||||
2014-07-01,0.028,2017-10-20 09:54:16
|
||||
2014-12-22,0.105,2017-10-20 09:54:16
|
||||
2016-05-03,0.015,2017-10-20 09:54:16
|
||||
2017-09-01,0.015,2017-10-20 09:54:16
|
||||
2013-06-03,0.02,2017-10-20 09:54:16
|
||||
2013-12-02,0.008,2017-10-20 09:54:16
|
||||
2014-10-01,0.013,2017-10-20 09:54:16
|
||||
2011-10-31,0.003,2017-10-20 09:54:16
|
||||
2017-02-01,0.025,2017-10-20 09:54:16
|
||||
2014-03-03,0.012,2017-10-20 09:54:16
|
||||
2013-09-03,0.026,2017-10-20 09:54:16
|
||||
2017-11-01,0.016,2017-11-15 07:55:39
|
||||
2013-08-01,0.025,2017-11-15 07:55:39
|
||||
2016-04-01,0.014,2017-11-15 07:55:39
|
||||
2012-03-01,0.057,2017-11-15 07:55:39
|
||||
2015-02-02,0.006,2017-11-15 07:55:39
|
||||
2016-12-01,0.014,2017-11-15 07:55:39
|
||||
2012-07-02,0.038,2017-11-15 07:55:39
|
||||
2016-10-03,0.013,2017-11-15 07:55:39
|
||||
2013-11-01,0.009,2017-11-15 07:55:39
|
||||
2014-01-02,0.007,2017-11-15 07:55:39
|
||||
2016-07-01,0.028,2017-11-15 07:55:39
|
||||
2012-10-01,0.046,2017-11-15 07:55:39
|
||||
2015-06-01,0.01,2017-11-15 07:55:39
|
||||
2015-12-01,0.013,2017-11-15 07:55:39
|
||||
2014-05-01,0.01,2017-11-15 07:55:39
|
||||
2017-04-03,0.018,2017-11-15 07:55:39
|
||||
2012-12-20,0.137,2017-11-15 07:55:39
|
||||
2015-09-01,0.005,2017-11-15 07:55:39
|
||||
2016-03-01,0.013,2017-11-15 07:55:39
|
||||
2011-11-30,0.003,2017-11-15 07:55:39
|
||||
2014-11-03,0.011,2017-11-15 07:55:39
|
||||
2016-11-01,0.013,2017-11-15 07:55:39
|
||||
2012-08-01,0.023,2017-11-15 07:55:39
|
||||
2015-04-01,0.004,2017-11-15 07:55:39
|
||||
2012-05-01,0.006,2017-11-15 07:55:39
|
||||
2016-02-01,0.013,2017-11-15 07:55:39
|
||||
2016-08-01,0.016,2017-11-15 07:55:39
|
||||
2015-07-01,0.024,2017-11-15 07:55:39
|
||||
2015-01-02,0.02,2017-11-15 07:55:39
|
||||
2012-01-31,0.004,2017-11-15 07:55:39
|
||||
2012-12-03,0.018,2017-11-15 07:55:39
|
||||
2014-06-02,0.013,2017-11-15 07:55:39
|
||||
2015-10-01,0.014,2017-11-15 07:55:39
|
||||
2013-03-01,0.004,2017-11-15 07:55:39
|
||||
2017-08-01,0.025,2017-11-15 07:55:39
|
||||
2013-05-01,0.009,2017-11-15 07:55:39
|
||||
2013-12-20,0.069,2017-11-15 07:55:39
|
||||
2014-09-02,0.015,2017-11-15 07:55:39
|
||||
2017-03-01,0.013,2017-11-15 07:55:39
|
||||
2015-11-02,0.011,2017-11-15 07:55:39
|
||||
2017-05-01,0.01,2017-11-15 07:55:39
|
||||
2014-04-01,0.009,2017-11-15 07:55:39
|
||||
2016-01-04,0.025,2017-11-15 07:55:39
|
||||
2013-02-01,0.006,2017-11-15 07:55:39
|
||||
2015-08-03,0.009,2017-11-15 07:55:39
|
||||
2017-06-01,0.021,2017-11-15 07:55:39
|
||||
2014-07-01,0.028,2017-11-15 07:55:39
|
||||
2014-12-22,0.105,2017-11-15 07:55:39
|
||||
2016-05-03,0.015,2017-11-15 07:55:39
|
||||
2017-09-01,0.015,2017-11-15 07:55:39
|
||||
2013-06-03,0.02,2017-11-15 07:55:39
|
||||
2013-12-02,0.008,2017-11-15 07:55:39
|
||||
2014-10-01,0.013,2017-11-15 07:55:39
|
||||
2011-10-31,0.003,2017-11-15 07:55:39
|
||||
2017-02-01,0.025,2017-11-15 07:55:39
|
||||
2014-03-03,0.012,2017-11-15 07:55:39
|
||||
2013-09-03,0.026,2017-11-15 07:55:39
|
||||
2017-12-01,0.017,2017-12-11 20:07:47
|
||||
2015-07-01,0.024,2017-12-11 20:07:47
|
||||
2015-01-02,0.02,2017-12-11 20:07:47
|
||||
2012-01-31,0.004,2017-12-11 20:07:47
|
||||
2012-12-03,0.018,2017-12-11 20:07:47
|
||||
2014-06-02,0.013,2017-12-11 20:07:47
|
||||
2015-10-01,0.014,2017-12-11 20:07:47
|
||||
2013-03-01,0.004,2017-12-11 20:07:47
|
||||
2017-08-01,0.025,2017-12-11 20:07:47
|
||||
2013-05-01,0.009,2017-12-11 20:07:47
|
||||
2013-12-20,0.069,2017-12-11 20:07:47
|
||||
2014-09-02,0.015,2017-12-11 20:07:47
|
||||
2017-03-01,0.013,2017-12-11 20:07:47
|
||||
2015-11-02,0.011,2017-12-11 20:07:47
|
||||
2017-05-01,0.01,2017-12-11 20:07:47
|
||||
2014-04-01,0.009,2017-12-11 20:07:47
|
||||
2016-01-04,0.025,2017-12-11 20:07:47
|
||||
2013-02-01,0.006,2017-12-11 20:07:47
|
||||
2015-08-03,0.009,2017-12-11 20:07:47
|
||||
2017-06-01,0.021,2017-12-11 20:07:47
|
||||
2014-07-01,0.028,2017-12-11 20:07:47
|
||||
2014-12-22,0.105,2017-12-11 20:07:47
|
||||
2016-05-03,0.015,2017-12-11 20:07:47
|
||||
2017-09-01,0.015,2017-12-11 20:07:47
|
||||
2013-06-03,0.02,2017-12-11 20:07:47
|
||||
2013-12-02,0.008,2017-12-11 20:07:47
|
||||
2014-10-01,0.013,2017-12-11 20:07:47
|
||||
2011-10-31,0.003,2017-12-11 20:07:47
|
||||
2017-02-01,0.025,2017-12-11 20:07:47
|
||||
2014-03-03,0.012,2017-12-11 20:07:47
|
||||
2013-09-03,0.026,2017-12-11 20:07:47
|
||||
2018-01-02,0.023,2018-01-16 07:54:11
|
||||
2016-04-01,0.014,2018-01-16 07:54:11
|
||||
2012-03-01,0.057,2018-01-16 07:54:11
|
||||
2015-02-02,0.006,2018-01-16 07:54:11
|
||||
2016-12-01,0.014,2018-01-16 07:54:11
|
||||
2012-07-02,0.038,2018-01-16 07:54:11
|
||||
2016-10-03,0.013,2018-01-16 07:54:11
|
||||
2013-11-01,0.009,2018-01-16 07:54:11
|
||||
2014-01-02,0.007,2018-01-16 07:54:11
|
||||
2016-07-01,0.028,2018-01-16 07:54:11
|
||||
2012-10-01,0.046,2018-01-16 07:54:11
|
||||
2015-06-01,0.01,2018-01-16 07:54:11
|
||||
2015-12-01,0.013,2018-01-16 07:54:11
|
||||
2014-05-01,0.01,2018-01-16 07:54:11
|
||||
2017-04-03,0.018,2018-01-16 07:54:11
|
||||
2012-12-20,0.137,2018-01-16 07:54:11
|
||||
2015-09-01,0.005,2018-01-16 07:54:11
|
||||
2016-03-01,0.013,2018-01-16 07:54:11
|
||||
2011-11-30,0.003,2018-01-16 07:54:11
|
||||
2014-11-03,0.011,2018-01-16 07:54:11
|
||||
2016-11-01,0.013,2018-01-16 07:54:11
|
||||
2012-08-01,0.023,2018-01-16 07:54:11
|
||||
2015-04-01,0.004,2018-01-16 07:54:11
|
||||
2012-05-01,0.006,2018-01-16 07:54:11
|
||||
2016-02-01,0.013,2018-01-16 07:54:11
|
||||
2016-08-01,0.016,2018-01-16 07:54:11
|
||||
2017-12-01,0.017,2018-01-16 07:54:11
|
||||
2015-07-01,0.024,2018-01-16 07:54:11
|
||||
2015-01-02,0.02,2018-01-16 07:54:11
|
||||
2012-01-31,0.004,2018-01-16 07:54:11
|
||||
2012-12-03,0.018,2018-01-16 07:54:11
|
||||
2014-06-02,0.013,2018-01-16 07:54:11
|
||||
2015-10-01,0.014,2018-01-16 07:54:11
|
||||
2013-03-01,0.004,2018-01-16 07:54:11
|
||||
2017-08-01,0.025,2018-01-16 07:54:11
|
||||
2013-05-01,0.009,2018-01-16 07:54:11
|
||||
2013-12-20,0.069,2018-01-16 07:54:11
|
||||
2014-09-02,0.015,2018-01-16 07:54:11
|
||||
2017-03-01,0.013,2018-01-16 07:54:11
|
||||
2015-11-02,0.011,2018-01-16 07:54:11
|
||||
2017-05-01,0.01,2018-01-16 07:54:11
|
||||
2014-04-01,0.009,2018-01-16 07:54:11
|
||||
2016-01-04,0.025,2018-01-16 07:54:11
|
||||
2013-02-01,0.006,2018-01-16 07:54:11
|
||||
2015-08-03,0.009,2018-01-16 07:54:11
|
||||
2017-06-01,0.021,2018-01-16 07:54:11
|
||||
2014-07-01,0.028,2018-01-16 07:54:11
|
||||
2014-12-22,0.105,2018-01-16 07:54:11
|
||||
2016-05-03,0.015,2018-01-16 07:54:11
|
||||
2017-09-01,0.015,2018-01-16 07:54:11
|
||||
2013-06-03,0.02,2018-01-16 07:54:11
|
||||
2013-12-02,0.008,2018-01-16 07:54:11
|
||||
2014-10-01,0.013,2018-01-16 07:54:11
|
||||
2011-10-31,0.003,2018-01-16 07:54:11
|
||||
2017-02-01,0.025,2018-01-16 07:54:11
|
||||
2014-03-03,0.012,2018-01-16 07:54:11
|
||||
2013-09-03,0.026,2018-01-16 07:54:11
|
||||
2018-02-01,0.017,2018-02-26 21:44:31
|
||||
2015-03-02,0.004,2018-02-26 21:44:31
|
||||
2012-09-04,0.036,2018-02-26 21:44:31
|
||||
2012-04-02,0.016,2018-02-26 21:44:31
|
||||
2017-11-01,0.016,2018-02-26 21:44:31
|
||||
2013-08-01,0.025,2018-02-26 21:44:31
|
||||
2018-01-02,0.023,2018-02-26 21:44:31
|
||||
2016-04-01,0.014,2018-02-26 21:44:31
|
||||
2012-03-01,0.057,2018-02-26 21:44:31
|
||||
2015-02-02,0.006,2018-02-26 21:44:31
|
||||
2016-12-01,0.014,2018-02-26 21:44:31
|
||||
2012-07-02,0.038,2018-02-26 21:44:31
|
||||
2016-10-03,0.013,2018-02-26 21:44:31
|
||||
2013-11-01,0.009,2018-02-26 21:44:31
|
||||
2014-01-02,0.007,2018-02-26 21:44:31
|
||||
2016-07-01,0.028,2018-02-26 21:44:31
|
||||
2012-10-01,0.046,2018-02-26 21:44:31
|
||||
2015-06-01,0.01,2018-02-26 21:44:31
|
||||
2015-12-01,0.013,2018-02-26 21:44:31
|
||||
2014-05-01,0.01,2018-02-26 21:44:31
|
||||
2017-04-03,0.018,2018-02-26 21:44:31
|
||||
2012-12-20,0.137,2018-02-26 21:44:31
|
||||
2015-09-01,0.005,2018-02-26 21:44:31
|
||||
2016-03-01,0.013,2018-02-26 21:44:31
|
||||
2011-11-30,0.003,2018-02-26 21:44:31
|
||||
2014-11-03,0.011,2018-02-26 21:44:31
|
||||
2016-11-01,0.013,2018-02-26 21:44:31
|
||||
2012-08-01,0.023,2018-02-26 21:44:31
|
||||
2015-04-01,0.004,2018-02-26 21:44:31
|
||||
2012-05-01,0.006,2018-02-26 21:44:31
|
||||
2016-02-01,0.013,2018-02-26 21:44:31
|
||||
2016-08-01,0.016,2018-02-26 21:44:31
|
||||
2017-12-01,0.017,2018-02-26 21:44:31
|
||||
2015-07-01,0.024,2018-02-26 21:44:31
|
||||
2015-01-02,0.02,2018-02-26 21:44:31
|
||||
2012-01-31,0.004,2018-02-26 21:44:31
|
||||
2012-12-03,0.018,2018-02-26 21:44:31
|
||||
2014-06-02,0.013,2018-02-26 21:44:31
|
||||
2015-10-01,0.014,2018-02-26 21:44:31
|
||||
2013-03-01,0.004,2018-02-26 21:44:31
|
||||
2017-08-01,0.025,2018-02-26 21:44:31
|
||||
2013-05-01,0.009,2018-02-26 21:44:31
|
||||
2013-12-20,0.069,2018-02-26 21:44:31
|
||||
2014-09-02,0.015,2018-02-26 21:44:31
|
||||
2017-03-01,0.013,2018-02-26 21:44:31
|
||||
2015-11-02,0.011,2018-02-26 21:44:31
|
||||
2017-05-01,0.01,2018-02-26 21:44:31
|
||||
2014-04-01,0.009,2018-02-26 21:44:31
|
||||
2016-01-04,0.025,2018-02-26 21:44:31
|
||||
2013-02-01,0.006,2018-02-26 21:44:31
|
||||
2015-08-03,0.009,2018-02-26 21:44:31
|
||||
2017-06-01,0.021,2018-02-26 21:44:31
|
||||
2014-07-01,0.028,2018-02-26 21:44:31
|
||||
2014-12-22,0.105,2018-02-26 21:44:31
|
||||
2016-05-03,0.015,2018-02-26 21:44:31
|
||||
2017-09-01,0.015,2018-02-26 21:44:31
|
||||
2013-06-03,0.02,2018-02-26 21:44:31
|
||||
2013-12-02,0.008,2018-02-26 21:44:31
|
||||
2014-10-01,0.013,2018-02-26 21:44:31
|
||||
2011-10-31,0.003,2018-02-26 21:44:31
|
||||
2017-02-01,0.025,2018-02-26 21:44:31
|
||||
2014-03-03,0.012,2018-02-26 21:44:31
|
||||
2013-09-03,0.026,2018-02-26 21:44:31
|
||||
2018-03-01,0.019,2018-03-09 21:59:16
|
||||
2017-09-01,0.015,2018-03-09 21:59:16
|
||||
2013-06-03,0.02,2018-03-09 21:59:16
|
||||
2013-12-02,0.008,2018-03-09 21:59:16
|
||||
2014-10-01,0.013,2018-03-09 21:59:16
|
||||
2011-10-31,0.003,2018-03-09 21:59:16
|
||||
2017-02-01,0.025,2018-03-09 21:59:16
|
||||
2014-03-03,0.012,2018-03-09 21:59:16
|
||||
2013-09-03,0.026,2018-03-09 21:59:16
|
||||
2018-04-02,0.021,2018-04-13 15:05:34
|
||||
2015-05-01,0.005,2018-04-13 15:05:34
|
||||
2018-02-01,0.017,2018-04-13 15:05:34
|
||||
2015-03-02,0.004,2018-04-13 15:05:34
|
||||
2012-09-04,0.036,2018-04-13 15:05:34
|
||||
2012-04-02,0.016,2018-04-13 15:05:34
|
||||
2017-11-01,0.016,2018-04-13 15:05:34
|
||||
2013-08-01,0.025,2018-04-13 15:05:34
|
||||
2018-01-02,0.023,2018-04-13 15:05:34
|
||||
2016-04-01,0.014,2018-04-13 15:05:34
|
||||
2012-03-01,0.057,2018-04-13 15:05:34
|
||||
2015-02-02,0.006,2018-04-13 15:05:34
|
||||
2016-12-01,0.014,2018-04-13 15:05:34
|
||||
2012-07-02,0.038,2018-04-13 15:05:34
|
||||
2016-10-03,0.013,2018-04-13 15:05:34
|
||||
2013-11-01,0.009,2018-04-13 15:05:34
|
||||
2014-01-02,0.007,2018-04-13 15:05:34
|
||||
2016-07-01,0.028,2018-04-13 15:05:34
|
||||
2012-10-01,0.046,2018-04-13 15:05:34
|
||||
2015-06-01,0.01,2018-04-13 15:05:34
|
||||
2015-12-01,0.013,2018-04-13 15:05:34
|
||||
2014-05-01,0.01,2018-04-13 15:05:34
|
||||
2017-04-03,0.018,2018-04-13 15:05:34
|
||||
2012-12-20,0.137,2018-04-13 15:05:34
|
||||
2015-09-01,0.005,2018-04-13 15:05:34
|
||||
2016-03-01,0.013,2018-04-13 15:05:34
|
||||
2011-11-30,0.003,2018-04-13 15:05:34
|
||||
2014-11-03,0.011,2018-04-13 15:05:34
|
||||
2016-11-01,0.013,2018-04-13 15:05:34
|
||||
2012-08-01,0.023,2018-04-13 15:05:34
|
||||
2015-04-01,0.004,2018-04-13 15:05:34
|
||||
2012-05-01,0.006,2018-04-13 15:05:34
|
||||
2016-02-01,0.013,2018-04-13 15:05:34
|
||||
2016-08-01,0.016,2018-04-13 15:05:34
|
||||
2017-12-01,0.017,2018-04-13 15:05:34
|
||||
2015-07-01,0.024,2018-04-13 15:05:34
|
||||
2015-01-02,0.02,2018-04-13 15:05:34
|
||||
2012-01-31,0.004,2018-04-13 15:05:34
|
||||
2012-12-03,0.018,2018-04-13 15:05:34
|
||||
2014-06-02,0.013,2018-04-13 15:05:34
|
||||
2015-10-01,0.014,2018-04-13 15:05:34
|
||||
2013-03-01,0.004,2018-04-13 15:05:34
|
||||
2017-08-01,0.025,2018-04-13 15:05:34
|
||||
2013-05-01,0.009,2018-04-13 15:05:34
|
||||
2013-12-20,0.069,2018-04-13 15:05:34
|
||||
2014-09-02,0.015,2018-04-13 15:05:34
|
||||
2017-03-01,0.013,2018-04-13 15:05:34
|
||||
2015-11-02,0.011,2018-04-13 15:05:34
|
||||
2017-05-01,0.01,2018-04-13 15:05:34
|
||||
2014-04-01,0.009,2018-04-13 15:05:34
|
||||
2016-01-04,0.025,2018-04-13 15:05:34
|
||||
2013-02-01,0.006,2018-04-13 15:05:34
|
||||
2015-08-03,0.009,2018-04-13 15:05:34
|
||||
2017-06-01,0.021,2018-04-13 15:05:34
|
||||
2014-07-01,0.028,2018-04-13 15:05:34
|
||||
2014-12-22,0.105,2018-04-13 15:05:34
|
||||
2016-05-03,0.015,2018-04-13 15:05:34
|
||||
2018-03-01,0.019,2018-04-13 15:05:34
|
||||
2017-09-01,0.015,2018-04-13 15:05:34
|
||||
2013-06-03,0.02,2018-04-13 15:05:34
|
||||
2013-12-02,0.008,2018-04-13 15:05:34
|
||||
2014-10-01,0.013,2018-04-13 15:05:34
|
||||
2011-10-31,0.003,2018-04-13 15:05:34
|
||||
2017-02-01,0.025,2018-04-13 15:05:34
|
||||
2014-03-03,0.012,2018-04-13 15:05:34
|
||||
2013-09-03,0.026,2018-04-13 15:05:34
|
||||
2018-05-01,0.023,2018-12-20 11:23:51
|
||||
2012-10-01,0.046,2018-12-20 11:23:51
|
||||
2015-06-01,0.01,2018-12-20 11:23:51
|
||||
2015-12-01,0.013,2018-12-20 11:23:51
|
||||
2018-08-01,0.033,2018-12-20 11:23:51
|
||||
2014-05-01,0.01,2018-12-20 11:23:51
|
||||
2017-04-03,0.018,2018-12-20 11:23:51
|
||||
2012-12-20,0.137,2018-12-20 11:23:51
|
||||
2015-09-01,0.005,2018-12-20 11:23:51
|
||||
2016-03-01,0.013,2018-12-20 11:23:51
|
||||
2011-11-30,0.003,2018-12-20 11:23:51
|
||||
2014-11-03,0.011,2018-12-20 11:23:51
|
||||
2016-11-01,0.013,2018-12-20 11:23:51
|
||||
2012-08-01,0.023,2018-12-20 11:23:51
|
||||
2015-04-01,0.004,2018-12-20 11:23:51
|
||||
2012-05-01,0.006,2018-12-20 11:23:51
|
||||
2016-02-01,0.013,2018-12-20 11:23:51
|
||||
2016-08-01,0.016,2018-12-20 11:23:51
|
||||
2017-12-01,0.017,2018-12-20 11:23:51
|
||||
2018-06-01,0.021,2018-12-20 11:23:51
|
||||
2015-07-01,0.024,2018-12-20 11:23:51
|
||||
2015-01-02,0.02,2018-12-20 11:23:51
|
||||
2012-01-31,0.004,2018-12-20 11:23:51
|
||||
2012-12-03,0.018,2018-12-20 11:23:51
|
||||
2014-06-02,0.013,2018-12-20 11:23:51
|
||||
2015-10-01,0.014,2018-12-20 11:23:51
|
||||
2018-09-04,0.023,2018-12-20 11:23:51
|
||||
2013-03-01,0.004,2018-12-20 11:23:51
|
||||
2017-08-01,0.025,2018-12-20 11:23:51
|
||||
2013-05-01,0.009,2018-12-20 11:23:51
|
||||
2013-12-20,0.069,2018-12-20 11:23:51
|
||||
2014-09-02,0.015,2018-12-20 11:23:51
|
||||
2017-03-01,0.013,2018-12-20 11:23:51
|
||||
2015-11-02,0.011,2018-12-20 11:23:51
|
||||
2017-05-01,0.01,2018-12-20 11:23:51
|
||||
2014-04-01,0.009,2018-12-20 11:23:51
|
||||
2016-01-04,0.025,2018-12-20 11:23:51
|
||||
2018-07-02,0.022,2018-12-20 11:23:51
|
||||
2013-02-01,0.006,2018-12-20 11:23:51
|
||||
2015-08-03,0.009,2018-12-20 11:23:51
|
||||
2017-06-01,0.021,2018-12-20 11:23:51
|
||||
2014-07-01,0.028,2018-12-20 11:23:51
|
||||
2018-10-01,0.008,2018-12-20 11:23:51
|
||||
2014-12-22,0.105,2018-12-20 11:23:51
|
||||
2016-05-03,0.015,2018-12-20 11:23:51
|
||||
2018-03-01,0.019,2018-12-20 11:23:51
|
||||
2017-09-01,0.015,2018-12-20 11:23:51
|
||||
2013-06-03,0.02,2018-12-20 11:23:51
|
||||
2013-12-02,0.008,2018-12-20 11:23:51
|
||||
2014-10-01,0.013,2018-12-20 11:23:51
|
||||
2011-10-31,0.003,2018-12-20 11:23:51
|
||||
2017-02-01,0.025,2018-12-20 11:23:51
|
||||
2014-03-03,0.012,2018-12-20 11:23:51
|
||||
2013-09-03,0.026,2018-12-20 11:23:51
|
||||
|
16800
overrides/frozen/afxpx-history.csv
Normal file
16800
overrides/frozen/afxpx-history.csv
Normal file
File diff suppressed because it is too large
Load Diff
7
overrides/frozen/afxpx.json
Normal file
7
overrides/frozen/afxpx.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"symbol": "afxpx",
|
||||
"longName": "?",
|
||||
"freeze_date": "2018-12-11",
|
||||
"created": "2026-08-31",
|
||||
"reason": "yahoo-empty"
|
||||
}
|
||||
7
overrides/frozen/agazx-capitalGain.csv
Normal file
7
overrides/frozen/agazx-capitalGain.csv
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
Date,Capital Gains
|
||||
2015-12-03,0.093000
|
||||
2017-12-05,0.759000
|
||||
2018-12-07,0.334000
|
||||
2021-12-09,0.367000
|
||||
2024-12-12,0.260000
|
||||
2025-02-21,1.364000
|
||||
|
9
overrides/frozen/agazx-dividend.csv
Normal file
9
overrides/frozen/agazx-dividend.csv
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
Date,Dividends
|
||||
2023-12-27,0.342230
|
||||
2024-12-12,0.260230
|
||||
2024-12-27,0.210040
|
||||
2025-02-21,1.363530
|
||||
2025-03-25,0.134190
|
||||
2019-12-09,0.032500
|
||||
2021-12-09,0.367200
|
||||
2022-12-28,0.098270
|
||||
|
1572
overrides/frozen/agazx-history.csv
Normal file
1572
overrides/frozen/agazx-history.csv
Normal file
File diff suppressed because it is too large
Load Diff
7
overrides/frozen/agazx.json
Normal file
7
overrides/frozen/agazx.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"symbol": "agazx",
|
||||
"longName": "Allspring Funds Trust - Allspring Global Long/Short Equity Fund",
|
||||
"freeze_date": "2025-04-07",
|
||||
"created": "2026-08-31",
|
||||
"reason": "yahoo-empty"
|
||||
}
|
||||
13
overrides/frozen/akrex-capitalGain.csv
Normal file
13
overrides/frozen/akrex-capitalGain.csv
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
Date,Capital Gains
|
||||
2021-12-10,2.340000
|
||||
2023-12-08,2.044000
|
||||
2024-12-06,3.273000
|
||||
2012-12-14,0.252000
|
||||
2014-12-12,0.467000
|
||||
2016-12-16,0.046000
|
||||
2017-12-15,0.200000
|
||||
2019-12-13,1.331000
|
||||
2025-08-25,3.020000
|
||||
2013-12-13,0.404000
|
||||
2018-12-14,0.188000
|
||||
2022-12-09,3.120000
|
||||
|
7
overrides/frozen/akrex-dividend.csv
Normal file
7
overrides/frozen/akrex-dividend.csv
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
Date,Dividends
|
||||
2021-12-10,2.340140
|
||||
2022-12-09,3.120430
|
||||
2023-12-08,2.044210
|
||||
2024-12-06,3.272590
|
||||
2025-08-25,3.020290
|
||||
2019-12-13,1.330690
|
||||
|
1702
overrides/frozen/akrex-history.csv
Normal file
1702
overrides/frozen/akrex-history.csv
Normal file
File diff suppressed because it is too large
Load Diff
7
overrides/frozen/akrex.json
Normal file
7
overrides/frozen/akrex.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"symbol": "akrex",
|
||||
"longName": "Akre Focus Retail",
|
||||
"freeze_date": "2025-10-09",
|
||||
"created": "2026-08-31",
|
||||
"reason": "yahoo-empty"
|
||||
}
|
||||
9
overrides/frozen/alasx-dividend.csv
Normal file
9
overrides/frozen/alasx-dividend.csv
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
Date,Dividends,ctime
|
||||
2014-12-18,0.078,2017-08-22
|
||||
2015-12-17,0.042,2017-08-22
|
||||
2016-12-15,0.117,2017-08-22
|
||||
2015-03-10,0.007,2017-08-22
|
||||
2014-09-09,0.042,2017-08-22
|
||||
2017-12-14,0.08,2017-12-27 07:42:40
|
||||
2015-03-10,0.007,2017-12-27 07:42:40
|
||||
2014-09-09,0.042,2017-12-27 07:42:40
|
||||
|
8399
overrides/frozen/alasx-history.csv
Normal file
8399
overrides/frozen/alasx-history.csv
Normal file
File diff suppressed because it is too large
Load Diff
7
overrides/frozen/alasx.json
Normal file
7
overrides/frozen/alasx.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"symbol": "alasx",
|
||||
"longName": "?",
|
||||
"freeze_date": "2018-04-27",
|
||||
"created": "2026-08-31",
|
||||
"reason": "yahoo-empty"
|
||||
}
|
||||
16
overrides/frozen/amfzx-dividend.csv
Normal file
16
overrides/frozen/amfzx-dividend.csv
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
Date,Dividends,ctime
|
||||
2012-12-18,0.011,2017-08-22
|
||||
2013-12-17,0.403,2017-08-22
|
||||
2014-12-17,0.292,2017-08-22
|
||||
2019-02-07,4.44,2019-12-19 07:25:20
|
||||
2019-03-07,4.43,2019-04-16 10:50:03
|
||||
2019-02-07,4.44,2019-04-16 10:50:03
|
||||
2019-04-09,4.45,2019-04-16 10:50:03
|
||||
2019-12-09,0.158,2019-12-19 07:25:20
|
||||
2012-12-18,0.0,2021-03-01 22:16:32
|
||||
2012-12-18,0.011,2019-12-19 07:25:20
|
||||
2013-12-17,0.0,2021-03-01 22:16:32
|
||||
2013-12-17,0.403,2019-12-19 07:25:20
|
||||
2014-12-17,0.0,2021-03-01 22:16:32
|
||||
2014-12-17,0.292,2019-12-19 07:25:20
|
||||
2019-03-07,4.43,2019-12-19 07:25:20
|
||||
|
573
overrides/frozen/amfzx-history.csv
Normal file
573
overrides/frozen/amfzx-history.csv
Normal file
|
|
@ -0,0 +1,573 @@
|
|||
Date,Open,High,Low,Close,Adj Close,Volume
|
||||
2019-01-02,11.430000,11.430000,11.430000,11.430000,11.430000,0
|
||||
2019-01-03,11.430000,11.430000,11.430000,11.430000,11.430000,0
|
||||
2019-01-04,11.530000,11.530000,11.530000,11.530000,11.530000,0
|
||||
2019-01-07,11.470000,11.470000,11.470000,11.470000,11.470000,0
|
||||
2019-01-08,11.360000,11.360000,11.360000,11.360000,11.360000,0
|
||||
2019-01-09,11.300000,11.300000,11.300000,11.300000,11.300000,0
|
||||
2019-01-10,11.250000,11.250000,11.250000,11.250000,11.250000,0
|
||||
2019-01-11,11.250000,11.250000,11.250000,11.250000,11.250000,0
|
||||
2019-01-14,11.300000,11.300000,11.300000,11.300000,11.300000,0
|
||||
2019-01-15,11.280000,11.280000,11.280000,11.280000,11.280000,0
|
||||
2019-01-16,11.250000,11.250000,11.250000,11.250000,11.250000,0
|
||||
2019-01-17,11.170000,11.170000,11.170000,11.170000,11.170000,0
|
||||
2019-01-18,11.040000,11.040000,11.040000,11.040000,11.040000,0
|
||||
2019-01-22,11.220000,11.220000,11.220000,11.220000,11.220000,0
|
||||
2019-01-23,11.220000,11.220000,11.220000,11.220000,11.220000,0
|
||||
2019-01-24,11.230000,11.230000,11.230000,11.230000,11.230000,0
|
||||
2019-01-25,11.210000,11.210000,11.210000,11.210000,11.210000,0
|
||||
2019-01-28,11.290000,11.290000,11.290000,11.290000,11.290000,0
|
||||
2019-01-29,11.290000,11.290000,11.290000,11.290000,11.290000,0
|
||||
2019-01-30,11.260000,11.260000,11.260000,11.260000,11.260000,0
|
||||
2019-01-31,11.230000,11.230000,11.230000,11.230000,11.230000,0
|
||||
2019-02-01,11.250000,11.250000,11.250000,11.250000,11.250000,0
|
||||
2019-02-04,11.240000,11.240000,11.240000,11.240000,11.240000,0
|
||||
2019-02-05,11.240000,11.240000,11.240000,11.240000,11.240000,0
|
||||
2019-02-06,11.250000,11.250000,11.250000,11.250000,11.250000,0
|
||||
2019-02-07,11.240000,11.240000,11.240000,11.240000,11.240000,0
|
||||
2019-02-08,11.240000,11.240000,11.240000,11.240000,11.240000,0
|
||||
2019-02-11,11.240000,11.240000,11.240000,11.240000,11.240000,0
|
||||
2019-02-12,11.260000,11.260000,11.260000,11.260000,11.260000,0
|
||||
2019-02-13,11.260000,11.260000,11.260000,11.260000,11.260000,0
|
||||
2019-02-14,11.260000,11.260000,11.260000,11.260000,11.260000,0
|
||||
2019-02-15,11.260000,11.260000,11.260000,11.260000,11.260000,0
|
||||
2019-02-19,11.260000,11.260000,11.260000,11.260000,11.260000,0
|
||||
2019-02-20,11.280000,11.280000,11.280000,11.280000,11.280000,0
|
||||
2019-02-21,11.280000,11.280000,11.280000,11.280000,11.280000,0
|
||||
2019-02-22,11.300000,11.300000,11.300000,11.300000,11.300000,0
|
||||
2019-02-25,11.280000,11.280000,11.280000,11.280000,11.280000,0
|
||||
2019-02-26,11.280000,11.280000,11.280000,11.280000,11.280000,0
|
||||
2019-02-27,11.280000,11.280000,11.280000,11.280000,11.280000,0
|
||||
2019-02-28,11.280000,11.280000,11.280000,11.280000,11.280000,0
|
||||
2019-03-01,11.300000,11.300000,11.300000,11.300000,11.300000,0
|
||||
2019-03-04,11.280000,11.280000,11.280000,11.280000,11.280000,0
|
||||
2019-03-05,11.270000,11.270000,11.270000,11.270000,11.270000,0
|
||||
2019-03-06,11.240000,11.240000,11.240000,11.240000,11.240000,0
|
||||
2019-03-07,11.200000,11.200000,11.200000,11.200000,11.200000,0
|
||||
2019-03-08,11.200000,11.200000,11.200000,11.200000,11.200000,0
|
||||
2019-03-11,11.400000,11.400000,11.400000,11.400000,11.400000,0
|
||||
2019-03-12,11.420000,11.420000,11.420000,11.420000,11.420000,0
|
||||
2019-03-13,11.430000,11.430000,11.430000,11.430000,11.430000,0
|
||||
2019-03-14,11.430000,11.430000,11.430000,11.430000,11.430000,0
|
||||
2019-03-15,11.450000,11.450000,11.450000,11.450000,11.450000,0
|
||||
2019-03-18,11.440000,11.440000,11.440000,11.440000,11.440000,0
|
||||
2019-03-19,11.440000,11.440000,11.440000,11.440000,11.440000,0
|
||||
2019-03-20,11.430000,11.430000,11.430000,11.430000,11.430000,0
|
||||
2019-03-21,11.440000,11.440000,11.440000,11.440000,11.440000,0
|
||||
2019-03-22,11.390000,11.390000,11.390000,11.390000,11.390000,0
|
||||
2019-03-25,11.410000,11.410000,11.410000,11.410000,11.410000,0
|
||||
2019-03-26,11.450000,11.450000,11.450000,11.450000,11.450000,0
|
||||
2019-03-27,11.430000,11.430000,11.430000,11.430000,11.430000,0
|
||||
2019-03-28,11.470000,11.470000,11.470000,11.470000,11.470000,0
|
||||
2019-03-29,11.490000,11.490000,11.490000,11.490000,11.490000,0
|
||||
2019-04-01,11.500000,11.500000,11.500000,11.500000,11.500000,0
|
||||
2019-04-02,11.500000,11.500000,11.500000,11.500000,11.500000,0
|
||||
2019-04-03,11.500000,11.500000,11.500000,11.500000,11.500000,0
|
||||
2019-04-04,11.510000,11.510000,11.510000,11.510000,11.510000,0
|
||||
2019-04-05,11.520000,11.520000,11.520000,11.520000,11.520000,0
|
||||
2019-04-08,11.520000,11.520000,11.520000,11.520000,11.520000,0
|
||||
2019-04-09,11.500000,11.500000,11.500000,11.500000,11.500000,0
|
||||
2019-04-10,11.530000,11.530000,11.530000,11.530000,11.530000,0
|
||||
2019-04-11,11.540000,11.540000,11.540000,11.540000,11.540000,0
|
||||
2019-04-12,11.580000,11.580000,11.580000,11.580000,11.580000,0
|
||||
2019-04-15,11.580000,11.580000,11.580000,11.580000,11.580000,0
|
||||
2019-04-16,11.580000,11.580000,11.580000,11.580000,11.580000,0
|
||||
2019-04-17,11.580000,11.580000,11.580000,11.580000,11.580000,0
|
||||
2019-04-18,11.580000,11.580000,11.580000,11.580000,11.580000,0
|
||||
2019-04-22,11.590000,11.590000,11.590000,11.590000,11.590000,0
|
||||
2019-04-23,11.640000,11.640000,11.640000,11.640000,11.640000,0
|
||||
2019-04-24,11.630000,11.630000,11.630000,11.630000,11.630000,0
|
||||
2019-04-25,11.620000,11.620000,11.620000,11.620000,11.620000,0
|
||||
2019-04-26,11.640000,11.640000,11.640000,11.640000,11.640000,0
|
||||
2019-04-29,11.640000,11.640000,11.640000,11.640000,11.640000,0
|
||||
2019-04-30,11.640000,11.640000,11.640000,11.640000,11.640000,0
|
||||
2019-05-01,11.610000,11.610000,11.610000,11.610000,11.610000,0
|
||||
2019-05-02,11.600000,11.600000,11.600000,11.600000,11.600000,0
|
||||
2019-05-03,11.620000,11.620000,11.620000,11.620000,11.620000,0
|
||||
2019-05-06,11.570000,11.570000,11.570000,11.570000,11.570000,0
|
||||
2019-05-07,11.570000,11.570000,11.570000,11.570000,11.570000,0
|
||||
2019-05-08,11.560000,11.560000,11.560000,11.560000,11.560000,0
|
||||
2019-05-09,11.510000,11.510000,11.510000,11.510000,11.510000,0
|
||||
2019-05-10,11.540000,11.540000,11.540000,11.540000,11.540000,0
|
||||
2019-05-13,11.180000,11.180000,11.180000,11.180000,11.180000,0
|
||||
2019-05-14,11.330000,11.330000,11.330000,11.330000,11.330000,0
|
||||
2019-05-15,11.330000,11.330000,11.330000,11.330000,11.330000,0
|
||||
2019-05-16,11.330000,11.330000,11.330000,11.330000,11.330000,0
|
||||
2019-05-17,11.330000,11.330000,11.330000,11.330000,11.330000,0
|
||||
2019-05-20,11.320000,11.320000,11.320000,11.320000,11.320000,0
|
||||
2019-05-21,11.380000,11.380000,11.380000,11.380000,11.380000,0
|
||||
2019-05-22,11.360000,11.360000,11.360000,11.360000,11.360000,0
|
||||
2019-05-23,11.290000,11.290000,11.290000,11.290000,11.290000,0
|
||||
2019-05-24,11.350000,11.350000,11.350000,11.350000,11.350000,0
|
||||
2019-05-28,11.270000,11.270000,11.270000,11.270000,11.270000,0
|
||||
2019-05-29,11.160000,11.160000,11.160000,11.160000,11.160000,0
|
||||
2019-05-30,11.190000,11.190000,11.190000,11.190000,11.190000,0
|
||||
2019-05-31,11.040000,11.040000,11.040000,11.040000,11.040000,0
|
||||
2019-06-03,10.990000,10.990000,10.990000,10.990000,10.990000,0
|
||||
2019-06-04,11.240000,11.240000,11.240000,11.240000,11.240000,0
|
||||
2019-06-05,11.230000,11.230000,11.230000,11.230000,11.230000,0
|
||||
2019-06-06,11.240000,11.240000,11.240000,11.240000,11.240000,0
|
||||
2019-06-07,11.230000,11.230000,11.230000,11.230000,11.230000,0
|
||||
2019-06-10,11.240000,11.240000,11.240000,11.240000,11.240000,0
|
||||
2019-06-11,11.230000,11.230000,11.230000,11.230000,11.230000,0
|
||||
2019-06-12,11.240000,11.240000,11.240000,11.240000,11.240000,0
|
||||
2019-06-13,11.240000,11.240000,11.240000,11.240000,11.240000,0
|
||||
2019-06-14,11.240000,11.240000,11.240000,11.240000,11.240000,0
|
||||
2019-06-17,11.240000,11.240000,11.240000,11.240000,11.240000,0
|
||||
2019-06-18,11.240000,11.240000,11.240000,11.240000,11.240000,0
|
||||
2019-06-19,11.250000,11.250000,11.250000,11.250000,11.250000,0
|
||||
2019-06-20,11.250000,11.250000,11.250000,11.250000,11.250000,0
|
||||
2019-06-21,11.240000,11.240000,11.240000,11.240000,11.240000,0
|
||||
2019-06-24,11.240000,11.240000,11.240000,11.240000,11.240000,0
|
||||
2019-06-25,11.220000,11.220000,11.220000,11.220000,11.220000,0
|
||||
2019-06-26,11.220000,11.220000,11.220000,11.220000,11.220000,0
|
||||
2019-06-27,11.250000,11.250000,11.250000,11.250000,11.250000,0
|
||||
2019-06-28,11.250000,11.250000,11.250000,11.250000,11.250000,0
|
||||
2019-07-01,11.250000,11.250000,11.250000,11.250000,11.250000,0
|
||||
2019-07-02,11.270000,11.270000,11.270000,11.270000,11.270000,0
|
||||
2019-07-03,11.280000,11.280000,11.280000,11.280000,11.280000,0
|
||||
2019-07-05,11.270000,11.270000,11.270000,11.270000,11.270000,0
|
||||
2019-07-08,11.250000,11.250000,11.250000,11.250000,11.250000,0
|
||||
2019-07-09,11.250000,11.250000,11.250000,11.250000,11.250000,0
|
||||
2019-07-10,11.290000,11.290000,11.290000,11.290000,11.290000,0
|
||||
2019-07-11,11.290000,11.290000,11.290000,11.290000,11.290000,0
|
||||
2019-07-12,11.300000,11.300000,11.300000,11.300000,11.300000,0
|
||||
2019-07-15,11.300000,11.300000,11.300000,11.300000,11.300000,0
|
||||
2019-07-16,11.300000,11.300000,11.300000,11.300000,11.300000,0
|
||||
2019-07-17,11.280000,11.280000,11.280000,11.280000,11.280000,0
|
||||
2019-07-18,11.310000,11.310000,11.310000,11.310000,11.310000,0
|
||||
2019-07-19,11.240000,11.240000,11.240000,11.240000,11.240000,0
|
||||
2019-07-22,11.290000,11.290000,11.290000,11.290000,11.290000,0
|
||||
2019-07-23,11.350000,11.350000,11.350000,11.350000,11.350000,0
|
||||
2019-07-24,11.360000,11.360000,11.360000,11.360000,11.360000,0
|
||||
2019-07-25,11.360000,11.360000,11.360000,11.360000,11.360000,0
|
||||
2019-07-26,11.420000,11.420000,11.420000,11.420000,11.420000,0
|
||||
2019-07-29,11.430000,11.430000,11.430000,11.430000,11.430000,0
|
||||
2019-07-30,11.390000,11.390000,11.390000,11.390000,11.390000,0
|
||||
2019-07-31,11.350000,11.350000,11.350000,11.350000,11.350000,0
|
||||
2019-08-01,11.280000,11.280000,11.280000,11.280000,11.280000,0
|
||||
2019-08-02,11.210000,11.210000,11.210000,11.210000,11.210000,0
|
||||
2019-08-05,10.820000,10.820000,10.820000,10.820000,10.820000,0
|
||||
2019-08-06,10.980000,10.980000,10.980000,10.980000,10.980000,0
|
||||
2019-08-07,11.010000,11.010000,11.010000,11.010000,11.010000,0
|
||||
2019-08-08,11.170000,11.170000,11.170000,11.170000,11.170000,0
|
||||
2019-08-09,11.180000,11.180000,11.180000,11.180000,11.180000,0
|
||||
2019-08-12,11.150000,11.150000,11.150000,11.150000,11.150000,0
|
||||
2019-08-13,11.300000,11.300000,11.300000,11.300000,11.300000,0
|
||||
2019-08-14,11.240000,11.240000,11.240000,11.240000,11.240000,0
|
||||
2019-08-15,11.240000,11.240000,11.240000,11.240000,11.240000,0
|
||||
2019-08-16,11.420000,11.420000,11.420000,11.420000,11.420000,0
|
||||
2019-08-19,11.410000,11.410000,11.410000,11.410000,11.410000,0
|
||||
2019-08-20,11.440000,11.440000,11.440000,11.440000,11.440000,0
|
||||
2019-08-21,11.400000,11.400000,11.400000,11.400000,11.400000,0
|
||||
2019-08-22,11.390000,11.390000,11.390000,11.390000,11.390000,0
|
||||
2019-08-23,11.370000,11.370000,11.370000,11.370000,11.370000,0
|
||||
2019-08-26,11.500000,11.500000,11.500000,11.500000,11.500000,0
|
||||
2019-08-27,11.400000,11.400000,11.400000,11.400000,11.400000,0
|
||||
2019-08-28,11.500000,11.500000,11.500000,11.500000,11.500000,0
|
||||
2019-08-29,11.660000,11.660000,11.660000,11.660000,11.660000,0
|
||||
2019-08-30,11.660000,11.660000,11.660000,11.660000,11.660000,0
|
||||
2019-09-03,11.660000,11.660000,11.660000,11.660000,11.660000,0
|
||||
2019-09-04,11.670000,11.670000,11.670000,11.670000,11.670000,0
|
||||
2019-09-05,11.690000,11.690000,11.690000,11.690000,11.690000,0
|
||||
2019-09-06,11.730000,11.730000,11.730000,11.730000,11.730000,0
|
||||
2019-09-09,11.730000,11.730000,11.730000,11.730000,11.730000,0
|
||||
2019-09-10,11.730000,11.730000,11.730000,11.730000,11.730000,0
|
||||
2019-09-11,11.670000,11.670000,11.670000,11.670000,11.670000,0
|
||||
2019-09-12,11.670000,11.670000,11.670000,11.670000,11.670000,0
|
||||
2019-09-13,11.680000,11.680000,11.680000,11.680000,11.680000,0
|
||||
2019-09-16,11.650000,11.650000,11.650000,11.650000,11.650000,0
|
||||
2019-09-17,11.670000,11.670000,11.670000,11.670000,11.670000,0
|
||||
2019-09-18,11.700000,11.700000,11.700000,11.700000,11.700000,0
|
||||
2019-09-19,11.690000,11.690000,11.690000,11.690000,11.690000,0
|
||||
2019-09-20,11.640000,11.640000,11.640000,11.640000,11.640000,0
|
||||
2019-09-23,11.670000,11.670000,11.670000,11.670000,11.670000,0
|
||||
2019-09-24,11.550000,11.550000,11.550000,11.550000,11.550000,0
|
||||
2019-09-25,11.640000,11.640000,11.640000,11.640000,11.640000,0
|
||||
2019-09-26,11.630000,11.630000,11.630000,11.630000,11.630000,0
|
||||
2019-09-27,11.610000,11.610000,11.610000,11.610000,11.610000,0
|
||||
2019-09-30,11.680000,11.680000,11.680000,11.680000,11.680000,0
|
||||
2019-10-01,11.660000,11.660000,11.660000,11.660000,11.660000,0
|
||||
2019-10-02,11.660000,11.660000,11.660000,11.660000,11.660000,0
|
||||
2019-10-03,11.750000,11.750000,11.750000,11.750000,11.750000,0
|
||||
2019-10-04,11.790000,11.790000,11.790000,11.790000,11.790000,0
|
||||
2019-10-07,11.790000,11.790000,11.790000,11.790000,11.790000,0
|
||||
2019-10-08,11.790000,11.790000,11.790000,11.790000,11.790000,0
|
||||
2019-10-09,11.870000,11.870000,11.870000,11.870000,11.870000,0
|
||||
2019-10-10,11.890000,11.890000,11.890000,11.890000,11.890000,0
|
||||
2019-10-11,11.880000,11.880000,11.880000,11.880000,11.880000,0
|
||||
2019-10-14,11.900000,11.900000,11.900000,11.900000,11.900000,0
|
||||
2019-10-15,11.910000,11.910000,11.910000,11.910000,11.910000,0
|
||||
2019-10-16,11.920000,11.920000,11.920000,11.920000,11.920000,0
|
||||
2019-10-17,11.920000,11.920000,11.920000,11.920000,11.920000,0
|
||||
2019-10-18,11.920000,11.920000,11.920000,11.920000,11.920000,0
|
||||
2019-10-21,11.970000,11.970000,11.970000,11.970000,11.970000,0
|
||||
2019-10-22,11.950000,11.950000,11.950000,11.950000,11.950000,0
|
||||
2019-10-23,11.970000,11.970000,11.970000,11.970000,11.970000,0
|
||||
2019-10-24,11.980000,11.980000,11.980000,11.980000,11.980000,0
|
||||
2019-10-25,12.000000,12.000000,12.000000,12.000000,12.000000,0
|
||||
2019-10-28,11.990000,11.990000,11.990000,11.990000,11.990000,0
|
||||
2019-10-29,12.000000,12.000000,12.000000,12.000000,12.000000,0
|
||||
2019-10-30,12.020000,12.020000,12.020000,12.020000,12.020000,0
|
||||
2019-10-31,12.030000,12.030000,12.030000,12.030000,12.030000,0
|
||||
2019-11-01,12.130000,12.130000,12.130000,12.130000,12.130000,0
|
||||
2019-11-04,12.130000,12.130000,12.130000,12.130000,12.130000,0
|
||||
2019-11-05,12.120000,12.120000,12.120000,12.120000,12.120000,0
|
||||
2019-11-06,12.130000,12.130000,12.130000,12.130000,12.130000,0
|
||||
2019-11-07,12.130000,12.130000,12.130000,12.130000,12.130000,0
|
||||
2019-11-08,12.160000,12.160000,12.160000,12.160000,12.160000,0
|
||||
2019-11-11,12.160000,12.160000,12.160000,12.160000,12.160000,0
|
||||
2019-11-12,12.170000,12.170000,12.170000,12.170000,12.170000,0
|
||||
2019-11-13,12.160000,12.160000,12.160000,12.160000,12.160000,0
|
||||
2019-11-14,12.170000,12.170000,12.170000,12.170000,12.170000,0
|
||||
2019-11-15,12.200000,12.200000,12.200000,12.200000,12.200000,0
|
||||
2019-11-18,12.200000,12.200000,12.200000,12.200000,12.200000,0
|
||||
2019-11-19,12.200000,12.200000,12.200000,12.200000,12.200000,0
|
||||
2019-11-20,12.190000,12.190000,12.190000,12.190000,12.190000,0
|
||||
2019-11-21,12.160000,12.160000,12.160000,12.160000,12.160000,0
|
||||
2019-11-22,12.190000,12.190000,12.190000,12.190000,12.190000,0
|
||||
2019-11-25,12.220000,12.220000,12.220000,12.220000,12.220000,0
|
||||
2019-11-26,12.220000,12.220000,12.220000,12.220000,12.220000,0
|
||||
2019-11-27,12.220000,12.220000,12.220000,12.220000,12.220000,0
|
||||
2019-11-29,12.220000,12.220000,12.220000,12.220000,12.220000,0
|
||||
2019-12-02,12.170000,12.170000,12.170000,12.170000,12.170000,0
|
||||
2019-12-03,12.090000,12.090000,12.090000,12.090000,12.090000,0
|
||||
2019-12-04,12.150000,12.150000,12.150000,12.150000,12.150000,0
|
||||
2019-12-05,12.150000,12.150000,12.150000,12.150000,12.150000,0
|
||||
2019-12-06,12.160000,12.160000,12.160000,12.160000,12.160000,0
|
||||
2019-12-09,11.950000,11.950000,11.950000,11.950000,11.950000,0
|
||||
2019-12-10,11.950000,11.950000,11.950000,11.950000,11.950000,0
|
||||
2019-12-11,11.950000,11.950000,11.950000,11.950000,11.950000,0
|
||||
2019-12-12,11.960000,11.960000,11.960000,11.960000,11.960000,0
|
||||
2019-12-13,11.990000,11.990000,11.990000,11.990000,11.990000,0
|
||||
2019-12-16,12.000000,12.000000,12.000000,12.000000,12.000000,0
|
||||
2019-12-17,12.000000,12.000000,12.000000,12.000000,12.000000,0
|
||||
2019-12-18,12.000000,12.000000,12.000000,12.000000,12.000000,0
|
||||
2019-12-19,12.010000,12.010000,12.010000,12.010000,12.010000,0
|
||||
2019-12-20,12.000000,12.000000,12.000000,12.000000,12.000000,0
|
||||
2019-12-23,12.000000,12.000000,12.000000,12.000000,12.000000,0
|
||||
2019-12-24,12.010000,12.010000,12.010000,12.010000,12.010000,0
|
||||
2019-12-26,12.010000,12.010000,12.010000,12.010000,12.010000,0
|
||||
2019-12-27,11.990000,11.990000,11.990000,11.990000,11.990000,0
|
||||
2019-12-30,11.970000,11.970000,11.970000,11.970000,11.970000,0
|
||||
2019-12-31,12.000000,12.000000,12.000000,12.000000,12.000000,0
|
||||
2020-01-02,12.010000,12.010000,12.010000,12.010000,12.010000,0
|
||||
2020-01-03,11.970000,11.970000,11.970000,11.970000,11.970000,0
|
||||
2020-01-06,11.970000,11.970000,11.970000,11.970000,11.970000,0
|
||||
2020-01-07,11.980000,11.980000,11.980000,11.980000,11.980000,0
|
||||
2020-01-08,12.000000,12.000000,12.000000,12.000000,12.000000,0
|
||||
2020-01-09,12.010000,12.010000,12.010000,12.010000,12.010000,0
|
||||
2020-01-10,12.010000,12.010000,12.010000,12.010000,12.010000,0
|
||||
2020-01-13,12.050000,12.050000,12.050000,12.050000,12.050000,0
|
||||
2020-01-14,12.060000,12.060000,12.060000,12.060000,12.060000,0
|
||||
2020-01-15,12.060000,12.060000,12.060000,12.060000,12.060000,0
|
||||
2020-01-16,12.070000,12.070000,12.070000,12.070000,12.070000,0
|
||||
2020-01-17,12.070000,12.070000,12.070000,12.070000,12.070000,0
|
||||
2020-01-21,12.070000,12.070000,12.070000,12.070000,12.070000,0
|
||||
2020-01-22,12.070000,12.070000,12.070000,12.070000,12.070000,0
|
||||
2020-01-23,12.070000,12.070000,12.070000,12.070000,12.070000,0
|
||||
2020-01-24,11.990000,11.990000,11.990000,11.990000,11.990000,0
|
||||
2020-01-27,11.890000,11.890000,11.890000,11.890000,11.890000,0
|
||||
2020-01-28,12.020000,12.020000,12.020000,12.020000,12.020000,0
|
||||
2020-01-29,12.000000,12.000000,12.000000,12.000000,12.000000,0
|
||||
2020-01-30,12.000000,12.000000,12.000000,12.000000,12.000000,0
|
||||
2020-01-31,11.900000,11.900000,11.900000,11.900000,11.900000,0
|
||||
2020-02-03,12.010000,12.010000,12.010000,12.010000,12.010000,0
|
||||
2020-02-04,12.020000,12.020000,12.020000,12.020000,12.020000,0
|
||||
2020-02-05,12.030000,12.030000,12.030000,12.030000,12.030000,0
|
||||
2020-02-06,12.030000,12.030000,12.030000,12.030000,12.030000,0
|
||||
2020-02-07,12.020000,12.020000,12.020000,12.020000,12.020000,0
|
||||
2020-02-10,12.030000,12.030000,12.030000,12.030000,12.030000,0
|
||||
2020-02-11,12.030000,12.030000,12.030000,12.030000,12.030000,0
|
||||
2020-02-12,12.060000,12.060000,12.060000,12.060000,12.060000,0
|
||||
2020-02-13,12.060000,12.060000,12.060000,12.060000,12.060000,0
|
||||
2020-02-14,12.060000,12.060000,12.060000,12.060000,12.060000,0
|
||||
2020-02-18,12.050000,12.050000,12.050000,12.050000,12.050000,0
|
||||
2020-02-19,12.050000,12.050000,12.050000,12.050000,12.050000,0
|
||||
2020-02-20,12.040000,12.040000,12.040000,12.040000,12.040000,0
|
||||
2020-02-21,12.030000,12.030000,12.030000,12.030000,12.030000,0
|
||||
2020-02-24,11.750000,11.750000,11.750000,11.750000,11.750000,0
|
||||
2020-02-25,11.420000,11.420000,11.420000,11.420000,11.420000,0
|
||||
2020-02-26,11.340000,11.340000,11.340000,11.340000,11.340000,0
|
||||
2020-02-27,10.820000,10.820000,10.820000,10.820000,10.820000,0
|
||||
2020-02-28,10.800000,10.800000,10.800000,10.800000,10.800000,0
|
||||
2020-03-02,11.140000,11.140000,11.140000,11.140000,11.140000,0
|
||||
2020-03-03,11.020000,11.020000,11.020000,11.020000,11.020000,0
|
||||
2020-03-04,11.390000,11.390000,11.390000,11.390000,11.390000,0
|
||||
2020-03-05,11.420000,11.420000,11.420000,11.420000,11.420000,0
|
||||
2020-03-06,11.340000,11.340000,11.340000,11.340000,11.340000,0
|
||||
2020-03-09,10.580000,10.580000,10.580000,10.580000,10.580000,0
|
||||
2020-03-10,10.930000,10.930000,10.930000,10.930000,10.930000,0
|
||||
2020-03-11,10.680000,10.680000,10.680000,10.680000,10.680000,0
|
||||
2020-03-12,9.870000,9.870000,9.870000,9.870000,9.870000,0
|
||||
2020-03-13,10.630000,10.630000,10.630000,10.630000,10.630000,0
|
||||
2020-03-16,9.410000,9.410000,9.410000,9.410000,9.410000,0
|
||||
2020-03-17,9.830000,9.830000,9.830000,9.830000,9.830000,0
|
||||
2020-03-18,9.410000,9.410000,9.410000,9.410000,9.410000,0
|
||||
2020-03-19,9.510000,9.510000,9.510000,9.510000,9.510000,0
|
||||
2020-03-20,9.240000,9.240000,9.240000,9.240000,9.240000,0
|
||||
2020-03-23,9.040000,9.040000,9.040000,9.040000,9.040000,0
|
||||
2020-03-24,9.840000,9.840000,9.840000,9.840000,9.840000,0
|
||||
2020-03-25,9.870000,9.870000,9.870000,9.870000,9.870000,0
|
||||
2020-03-26,10.280000,10.280000,10.280000,10.280000,10.280000,0
|
||||
2020-03-27,10.210000,10.210000,10.210000,10.210000,10.210000,0
|
||||
2020-03-30,10.240000,10.240000,10.240000,10.240000,10.240000,0
|
||||
2020-03-31,10.230000,10.230000,10.230000,10.230000,10.230000,0
|
||||
2020-04-01,9.770000,9.770000,9.770000,9.770000,9.770000,0
|
||||
2020-04-02,9.980000,9.980000,9.980000,9.980000,9.980000,0
|
||||
2020-04-03,9.960000,9.960000,9.960000,9.960000,9.960000,0
|
||||
2020-04-06,10.170000,10.170000,10.170000,10.170000,10.170000,0
|
||||
2020-04-07,10.180000,10.180000,10.180000,10.180000,10.180000,0
|
||||
2020-04-08,9.940000,9.940000,9.940000,9.940000,9.940000,0
|
||||
2020-04-09,9.760000,9.760000,9.760000,9.760000,9.760000,0
|
||||
2020-04-13,9.890000,9.890000,9.890000,9.890000,9.890000,0
|
||||
2020-04-14,9.590000,9.590000,9.590000,9.590000,9.590000,0
|
||||
2020-04-15,9.820000,9.820000,9.820000,9.820000,9.820000,0
|
||||
2020-04-16,9.820000,9.820000,9.820000,9.820000,9.820000,0
|
||||
2020-04-17,9.820000,9.820000,9.820000,9.820000,9.820000,0
|
||||
2020-04-20,9.860000,9.860000,9.860000,9.860000,9.860000,0
|
||||
2020-04-21,9.900000,9.900000,9.900000,9.900000,9.900000,0
|
||||
2020-04-22,10.060000,10.060000,10.060000,10.060000,10.060000,0
|
||||
2020-04-23,10.060000,10.060000,10.060000,10.060000,10.060000,0
|
||||
2020-04-24,10.010000,10.010000,10.010000,10.010000,10.010000,0
|
||||
2020-04-27,9.820000,9.820000,9.820000,9.820000,9.820000,0
|
||||
2020-04-28,9.770000,9.770000,9.770000,9.770000,9.770000,0
|
||||
2020-04-29,9.550000,9.550000,9.550000,9.550000,9.550000,0
|
||||
2020-04-30,9.700000,9.700000,9.700000,9.700000,9.700000,0
|
||||
2020-05-01,9.820000,9.820000,9.820000,9.820000,9.820000,0
|
||||
2020-05-04,9.860000,9.860000,9.860000,9.860000,9.860000,0
|
||||
2020-05-05,9.910000,9.910000,9.910000,9.910000,9.910000,0
|
||||
2020-05-06,9.920000,9.920000,9.920000,9.920000,9.920000,0
|
||||
2020-05-07,9.910000,9.910000,9.910000,9.910000,9.910000,0
|
||||
2020-05-08,9.870000,9.870000,9.870000,9.870000,9.870000,0
|
||||
2020-05-11,9.890000,9.890000,9.890000,9.890000,9.890000,0
|
||||
2020-05-12,10.140000,10.140000,10.140000,10.140000,10.140000,0
|
||||
2020-05-13,9.920000,9.920000,9.920000,9.920000,9.920000,0
|
||||
2020-05-14,10.010000,10.010000,10.010000,10.010000,10.010000,0
|
||||
2020-05-15,10.040000,10.040000,10.040000,10.040000,10.040000,0
|
||||
2020-05-18,9.930000,9.930000,9.930000,9.930000,9.930000,0
|
||||
2020-05-19,10.030000,10.030000,10.030000,10.030000,10.030000,0
|
||||
2020-05-20,9.890000,9.890000,9.890000,9.890000,9.890000,0
|
||||
2020-05-21,9.920000,9.920000,9.920000,9.920000,9.920000,0
|
||||
2020-05-22,9.890000,9.890000,9.890000,9.890000,9.890000,0
|
||||
2020-05-26,9.800000,9.800000,9.800000,9.800000,9.800000,0
|
||||
2020-05-27,9.660000,9.660000,9.660000,9.660000,9.660000,0
|
||||
2020-05-28,9.720000,9.720000,9.720000,9.720000,9.720000,0
|
||||
2020-05-29,9.750000,9.750000,9.750000,9.750000,9.750000,0
|
||||
2020-06-01,9.740000,9.740000,9.740000,9.740000,9.740000,0
|
||||
2020-06-02,9.690000,9.690000,9.690000,9.690000,9.690000,0
|
||||
2020-06-03,9.570000,9.570000,9.570000,9.570000,9.570000,0
|
||||
2020-06-04,9.570000,9.570000,9.570000,9.570000,9.570000,0
|
||||
2020-06-05,9.380000,9.380000,9.380000,9.380000,9.380000,0
|
||||
2020-06-08,9.260000,9.260000,9.260000,9.260000,9.260000,0
|
||||
2020-06-09,9.350000,9.350000,9.350000,9.350000,9.350000,0
|
||||
2020-06-10,9.420000,9.420000,9.420000,9.420000,9.420000,0
|
||||
2020-06-11,9.370000,9.370000,9.370000,9.370000,9.370000,0
|
||||
2020-06-12,9.430000,9.430000,9.430000,9.430000,9.430000,0
|
||||
2020-06-15,9.490000,9.490000,9.490000,9.490000,9.490000,0
|
||||
2020-06-16,9.560000,9.560000,9.560000,9.560000,9.560000,0
|
||||
2020-06-17,9.610000,9.610000,9.610000,9.610000,9.610000,0
|
||||
2020-06-18,9.630000,9.630000,9.630000,9.630000,9.630000,0
|
||||
2020-06-19,9.610000,9.610000,9.610000,9.610000,9.610000,0
|
||||
2020-06-22,9.610000,9.610000,9.610000,9.610000,9.610000,0
|
||||
2020-06-23,9.610000,9.610000,9.610000,9.610000,9.610000,0
|
||||
2020-06-24,9.760000,9.760000,9.760000,9.760000,9.760000,0
|
||||
2020-06-25,9.880000,9.880000,9.880000,9.880000,9.880000,0
|
||||
2020-06-26,9.810000,9.810000,9.810000,9.810000,9.810000,0
|
||||
2020-06-29,9.970000,9.970000,9.970000,9.970000,9.970000,0
|
||||
2020-06-30,10.090000,10.090000,10.090000,10.090000,10.090000,0
|
||||
2020-07-01,10.100000,10.100000,10.100000,10.100000,10.100000,0
|
||||
2020-07-02,10.050000,10.050000,10.050000,10.050000,10.050000,0
|
||||
2020-07-06,9.970000,9.970000,9.970000,9.970000,9.970000,0
|
||||
2020-07-07,10.090000,10.090000,10.090000,10.090000,10.090000,0
|
||||
2020-07-08,10.080000,10.080000,10.080000,10.080000,10.080000,0
|
||||
2020-07-09,10.080000,10.080000,10.080000,10.080000,10.080000,0
|
||||
2020-07-10,10.080000,10.080000,10.080000,10.080000,10.080000,0
|
||||
2020-07-13,10.080000,10.080000,10.080000,10.080000,10.080000,0
|
||||
2020-07-14,10.060000,10.060000,10.060000,10.060000,10.060000,0
|
||||
2020-07-15,10.050000,10.050000,10.050000,10.050000,10.050000,0
|
||||
2020-07-16,10.090000,10.090000,10.090000,10.090000,10.090000,0
|
||||
2020-07-17,10.070000,10.070000,10.070000,10.070000,10.070000,0
|
||||
2020-07-20,10.160000,10.160000,10.160000,10.160000,10.160000,0
|
||||
2020-07-21,10.120000,10.120000,10.120000,10.120000,10.120000,0
|
||||
2020-07-22,10.110000,10.110000,10.110000,10.110000,10.110000,0
|
||||
2020-07-23,10.110000,10.110000,10.110000,10.110000,10.110000,0
|
||||
2020-07-24,10.060000,10.060000,10.060000,10.060000,10.060000,0
|
||||
2020-07-27,10.150000,10.150000,10.150000,10.150000,10.150000,0
|
||||
2020-07-28,10.140000,10.140000,10.140000,10.140000,10.140000,0
|
||||
2020-07-29,10.140000,10.140000,10.140000,10.140000,10.140000,0
|
||||
2020-07-30,10.140000,10.140000,10.140000,10.140000,10.140000,0
|
||||
2020-07-31,10.150000,10.150000,10.150000,10.150000,10.150000,0
|
||||
2020-08-03,10.200000,10.200000,10.200000,10.200000,10.200000,0
|
||||
2020-08-04,10.200000,10.200000,10.200000,10.200000,10.200000,0
|
||||
2020-08-05,10.200000,10.200000,10.200000,10.200000,10.200000,0
|
||||
2020-08-06,10.200000,10.200000,10.200000,10.200000,10.200000,0
|
||||
2020-08-07,10.200000,10.200000,10.200000,10.200000,10.200000,0
|
||||
2020-08-10,10.180000,10.180000,10.180000,10.180000,10.180000,0
|
||||
2020-08-11,10.130000,10.130000,10.130000,10.130000,10.130000,0
|
||||
2020-08-12,10.230000,10.230000,10.230000,10.230000,10.230000,0
|
||||
2020-08-13,10.230000,10.230000,10.230000,10.230000,10.230000,0
|
||||
2020-08-14,10.230000,10.230000,10.230000,10.230000,10.230000,0
|
||||
2020-08-17,10.230000,10.230000,10.230000,10.230000,10.230000,0
|
||||
2020-08-18,10.230000,10.230000,10.230000,10.230000,10.230000,0
|
||||
2020-08-19,10.230000,10.230000,10.230000,10.230000,10.230000,0
|
||||
2020-08-20,10.230000,10.230000,10.230000,10.230000,10.230000,0
|
||||
2020-08-21,10.230000,10.230000,10.230000,10.230000,10.230000,0
|
||||
2020-08-24,10.240000,10.240000,10.240000,10.240000,10.240000,0
|
||||
2020-08-25,10.240000,10.240000,10.240000,10.240000,10.240000,0
|
||||
2020-08-26,10.230000,10.230000,10.230000,10.230000,10.230000,0
|
||||
2020-08-27,10.230000,10.230000,10.230000,10.230000,10.230000,0
|
||||
2020-08-28,10.230000,10.230000,10.230000,10.230000,10.230000,0
|
||||
2020-08-31,10.230000,10.230000,10.230000,10.230000,10.230000,0
|
||||
2020-09-01,10.240000,10.240000,10.240000,10.240000,10.240000,0
|
||||
2020-09-02,10.240000,10.240000,10.240000,10.240000,10.240000,0
|
||||
2020-09-03,10.240000,10.240000,10.240000,10.240000,10.240000,0
|
||||
2020-09-04,10.140000,10.140000,10.140000,10.140000,10.140000,0
|
||||
2020-09-08,10.160000,10.160000,10.160000,10.160000,10.160000,0
|
||||
2020-09-09,10.160000,10.160000,10.160000,10.160000,10.160000,0
|
||||
2020-09-10,10.160000,10.160000,10.160000,10.160000,10.160000,0
|
||||
2020-09-11,10.130000,10.130000,10.130000,10.130000,10.130000,0
|
||||
2020-09-14,10.290000,10.290000,10.290000,10.290000,10.290000,0
|
||||
2020-09-15,10.300000,10.300000,10.300000,10.300000,10.300000,0
|
||||
2020-09-16,10.300000,10.300000,10.300000,10.300000,10.300000,0
|
||||
2020-09-17,10.300000,10.300000,10.300000,10.300000,10.300000,0
|
||||
2020-09-18,10.230000,10.230000,10.230000,10.230000,10.230000,0
|
||||
2020-09-21,10.210000,10.210000,10.210000,10.210000,10.210000,0
|
||||
2020-09-22,10.200000,10.200000,10.200000,10.200000,10.200000,0
|
||||
2020-09-23,10.130000,10.130000,10.130000,10.130000,10.130000,0
|
||||
2020-09-24,10.140000,10.140000,10.140000,10.140000,10.140000,0
|
||||
2020-09-25,10.220000,10.220000,10.220000,10.220000,10.220000,0
|
||||
2020-09-28,10.300000,10.300000,10.300000,10.300000,10.300000,0
|
||||
2020-09-29,10.300000,10.300000,10.300000,10.300000,10.300000,0
|
||||
2020-09-30,10.320000,10.320000,10.320000,10.320000,10.320000,0
|
||||
2020-10-01,10.350000,10.350000,10.350000,10.350000,10.350000,0
|
||||
2020-10-02,10.350000,10.350000,10.350000,10.350000,10.350000,0
|
||||
2020-10-05,10.370000,10.370000,10.370000,10.370000,10.370000,0
|
||||
2020-10-06,10.370000,10.370000,10.370000,10.370000,10.370000,0
|
||||
2020-10-07,10.420000,10.420000,10.420000,10.420000,10.420000,0
|
||||
2020-10-08,10.420000,10.420000,10.420000,10.420000,10.420000,0
|
||||
2020-10-09,10.420000,10.420000,10.420000,10.420000,10.420000,0
|
||||
2020-10-12,10.420000,10.420000,10.420000,10.420000,10.420000,0
|
||||
2020-10-13,10.420000,10.420000,10.420000,10.420000,10.420000,0
|
||||
2020-10-14,10.420000,10.420000,10.420000,10.420000,10.420000,0
|
||||
2020-10-15,10.420000,10.420000,10.420000,10.420000,10.420000,0
|
||||
2020-10-16,10.400000,10.400000,10.400000,10.400000,10.400000,0
|
||||
2020-10-19,10.370000,10.370000,10.370000,10.370000,10.370000,0
|
||||
2020-10-20,10.380000,10.380000,10.380000,10.380000,10.380000,0
|
||||
2020-10-21,10.380000,10.380000,10.380000,10.380000,10.380000,0
|
||||
2020-10-22,10.390000,10.390000,10.390000,10.390000,10.390000,0
|
||||
2020-10-23,10.390000,10.390000,10.390000,10.390000,10.390000,0
|
||||
2020-10-26,10.390000,10.390000,10.390000,10.390000,10.390000,0
|
||||
2020-10-27,10.390000,10.390000,10.390000,10.390000,10.390000,0
|
||||
2020-10-28,10.270000,10.270000,10.270000,10.270000,10.270000,0
|
||||
2020-10-29,10.270000,10.270000,10.270000,10.270000,10.270000,0
|
||||
2020-10-30,10.270000,10.270000,10.270000,10.270000,10.270000,0
|
||||
2020-11-02,10.270000,10.270000,10.270000,10.270000,10.270000,0
|
||||
2020-11-03,10.270000,10.270000,10.270000,10.270000,10.270000,0
|
||||
2020-11-04,10.260000,10.260000,10.260000,10.260000,10.260000,0
|
||||
2020-11-05,10.260000,10.260000,10.260000,10.260000,10.260000,0
|
||||
2020-11-06,10.260000,10.260000,10.260000,10.260000,10.260000,0
|
||||
2020-11-09,10.260000,10.260000,10.260000,10.260000,10.260000,0
|
||||
2020-11-10,10.260000,10.260000,10.260000,10.260000,10.260000,0
|
||||
2020-11-11,10.260000,10.260000,10.260000,10.260000,10.260000,0
|
||||
2020-11-12,10.260000,10.260000,10.260000,10.260000,10.260000,0
|
||||
2020-11-13,10.320000,10.320000,10.320000,10.320000,10.320000,0
|
||||
2020-11-16,10.320000,10.320000,10.320000,10.320000,10.320000,0
|
||||
2020-11-17,10.320000,10.320000,10.320000,10.320000,10.320000,0
|
||||
2020-11-18,10.320000,10.320000,10.320000,10.320000,10.320000,0
|
||||
2020-11-19,10.320000,10.320000,10.320000,10.320000,10.320000,0
|
||||
2020-11-20,10.300000,10.300000,10.300000,10.300000,10.300000,0
|
||||
2020-11-23,10.320000,10.320000,10.320000,10.320000,10.320000,0
|
||||
2020-11-24,10.320000,10.320000,10.320000,10.320000,10.320000,0
|
||||
2020-11-25,10.320000,10.320000,10.320000,10.320000,10.320000,0
|
||||
2020-11-27,10.310000,10.310000,10.310000,10.310000,10.310000,0
|
||||
2020-11-30,10.310000,10.310000,10.310000,10.310000,10.310000,0
|
||||
2020-12-01,10.330000,10.330000,10.330000,10.330000,10.330000,0
|
||||
2020-12-02,10.330000,10.330000,10.330000,10.330000,10.330000,0
|
||||
2020-12-03,10.330000,10.330000,10.330000,10.330000,10.330000,0
|
||||
2020-12-04,10.330000,10.330000,10.330000,10.330000,10.330000,0
|
||||
2020-12-07,10.330000,10.330000,10.330000,10.330000,10.330000,0
|
||||
2020-12-08,10.320000,10.320000,10.320000,10.320000,10.320000,0
|
||||
2020-12-09,10.320000,10.320000,10.320000,10.320000,10.320000,0
|
||||
2020-12-10,10.330000,10.330000,10.330000,10.330000,10.330000,0
|
||||
2020-12-11,10.320000,10.320000,10.320000,10.320000,10.320000,0
|
||||
2020-12-14,10.310000,10.310000,10.310000,10.310000,10.310000,0
|
||||
2020-12-15,10.340000,10.340000,10.340000,10.340000,10.340000,0
|
||||
2020-12-16,10.340000,10.340000,10.340000,10.340000,10.340000,0
|
||||
2020-12-17,10.340000,10.340000,10.340000,10.340000,10.340000,0
|
||||
2020-12-18,10.340000,10.340000,10.340000,10.340000,10.340000,0
|
||||
2020-12-21,10.340000,10.340000,10.340000,10.340000,10.340000,0
|
||||
2020-12-22,10.330000,10.330000,10.330000,10.330000,10.330000,0
|
||||
2020-12-23,10.340000,10.340000,10.340000,10.340000,10.340000,0
|
||||
2020-12-24,10.340000,10.340000,10.340000,10.340000,10.340000,0
|
||||
2020-12-28,10.330000,10.330000,10.330000,10.330000,10.330000,0
|
||||
2020-12-29,10.330000,10.330000,10.330000,10.330000,10.330000,0
|
||||
2020-12-30,10.350000,10.350000,10.350000,10.350000,10.350000,0
|
||||
2020-12-31,10.350000,10.350000,10.350000,10.350000,10.350000,0
|
||||
2021-01-04,10.350000,10.350000,10.350000,10.350000,10.350000,0
|
||||
2021-01-05,10.370000,10.370000,10.370000,10.370000,10.370000,0
|
||||
2021-01-06,10.370000,10.370000,10.370000,10.370000,10.370000,0
|
||||
2021-01-07,10.370000,10.370000,10.370000,10.370000,10.370000,0
|
||||
2021-01-08,10.370000,10.370000,10.370000,10.370000,10.370000,0
|
||||
2021-01-11,10.370000,10.370000,10.370000,10.370000,10.370000,0
|
||||
2021-01-12,10.370000,10.370000,10.370000,10.370000,10.370000,0
|
||||
2021-01-13,10.360000,10.360000,10.360000,10.360000,10.360000,0
|
||||
2021-01-14,10.360000,10.360000,10.360000,10.360000,10.360000,0
|
||||
2021-01-15,10.360000,10.360000,10.360000,10.360000,10.360000,0
|
||||
2021-01-19,10.370000,10.370000,10.370000,10.370000,10.370000,0
|
||||
2021-01-20,10.370000,10.370000,10.370000,10.370000,10.370000,0
|
||||
2021-01-21,10.370000,10.370000,10.370000,10.370000,10.370000,0
|
||||
2021-01-22,10.370000,10.370000,10.370000,10.370000,10.370000,0
|
||||
2021-01-25,10.370000,10.370000,10.370000,10.370000,10.370000,0
|
||||
2021-01-26,10.370000,10.370000,10.370000,10.370000,10.370000,0
|
||||
2021-01-27,10.360000,10.360000,10.360000,10.360000,10.360000,0
|
||||
2021-01-28,10.380000,10.380000,10.380000,10.380000,10.380000,0
|
||||
2021-01-29,10.380000,10.380000,10.380000,10.380000,10.380000,0
|
||||
2021-02-01,10.480000,10.480000,10.480000,10.480000,10.480000,0
|
||||
2021-02-02,10.510000,10.510000,10.510000,10.510000,10.510000,0
|
||||
2021-02-03,10.510000,10.510000,10.510000,10.510000,10.510000,0
|
||||
2021-02-04,10.510000,10.510000,10.510000,10.510000,10.510000,0
|
||||
2021-02-05,10.510000,10.510000,10.510000,10.510000,10.510000,0
|
||||
2021-02-08,10.500000,10.500000,10.500000,10.500000,10.500000,0
|
||||
2021-02-09,10.500000,10.500000,10.500000,10.500000,10.500000,0
|
||||
2021-02-10,10.500000,10.500000,10.500000,10.500000,10.500000,0
|
||||
2021-02-11,10.500000,10.500000,10.500000,10.500000,10.500000,0
|
||||
2021-02-12,10.500000,10.500000,10.500000,10.500000,10.500000,0
|
||||
2021-02-16,10.500000,10.500000,10.500000,10.500000,10.500000,0
|
||||
2021-02-17,10.500000,10.500000,10.500000,10.500000,10.500000,0
|
||||
2021-02-18,10.470000,10.470000,10.470000,10.470000,10.470000,0
|
||||
2021-02-19,10.470000,10.470000,10.470000,10.470000,10.470000,0
|
||||
2021-02-22,10.470000,10.470000,10.470000,10.470000,10.470000,0
|
||||
2021-02-23,10.460000,10.460000,10.460000,10.460000,10.460000,0
|
||||
2021-02-24,10.470000,10.470000,10.470000,10.470000,10.470000,0
|
||||
2021-02-25,10.420000,10.420000,10.420000,10.420000,10.420000,0
|
||||
2021-02-26,10.420000,10.420000,10.420000,10.420000,10.420000,0
|
||||
2021-03-01,10.500000,10.500000,10.500000,10.500000,10.500000,0
|
||||
2021-03-02,10.490000,10.490000,10.490000,10.490000,10.490000,0
|
||||
2021-03-03,10.490000,10.490000,10.490000,10.490000,10.490000,0
|
||||
2021-03-04,10.470000,10.470000,10.470000,10.470000,10.470000,0
|
||||
2021-03-05,10.560000,10.560000,10.560000,10.560000,10.560000,0
|
||||
2021-03-08,10.560000,10.560000,10.560000,10.560000,10.560000,0
|
||||
2021-03-09,10.620000,10.620000,10.620000,10.620000,10.620000,0
|
||||
2021-03-10,10.620000,10.620000,10.620000,10.620000,10.620000,0
|
||||
2021-03-11,10.620000,10.620000,10.620000,10.620000,10.620000,0
|
||||
2021-03-12,10.620000,10.620000,10.620000,10.620000,10.620000,0
|
||||
2021-03-15,10.610000,10.610000,10.610000,10.610000,10.610000,0
|
||||
2021-03-16,10.610000,10.610000,10.610000,10.610000,10.610000,0
|
||||
2021-03-17,10.620000,10.620000,10.620000,10.620000,10.620000,0
|
||||
2021-03-18,10.620000,10.620000,10.620000,10.620000,10.620000,0
|
||||
2021-03-19,10.640000,10.640000,10.640000,10.640000,10.640000,0
|
||||
2021-03-22,10.630000,10.630000,10.630000,10.630000,10.630000,0
|
||||
2021-03-23,10.580000,10.580000,10.580000,10.580000,10.580000,0
|
||||
2021-03-24,10.540000,10.540000,10.540000,10.540000,10.540000,0
|
||||
2021-03-25,10.580000,10.580000,10.580000,10.580000,10.580000,0
|
||||
2021-03-26,10.630000,10.630000,10.630000,10.630000,10.630000,0
|
||||
2021-03-29,10.590000,10.590000,10.590000,10.590000,10.590000,0
|
||||
2021-03-30,10.600000,10.600000,10.600000,10.600000,10.600000,0
|
||||
2021-03-31,10.640000,10.640000,10.640000,10.640000,10.640000,0
|
||||
2021-04-01,10.640000,10.640000,10.640000,10.640000,10.640000,0
|
||||
2021-04-05,10.640000,10.640000,10.640000,10.640000,10.640000,0
|
||||
2021-04-06,10.640000,10.640000,10.640000,10.640000,10.640000,0
|
||||
2021-04-07,10.640000,10.640000,10.640000,10.640000,10.640000,0
|
||||
2021-04-08,10.640000,10.640000,10.640000,10.640000,10.640000,0
|
||||
2021-04-09,10.640000,10.640000,10.640000,10.640000,10.640000,0
|
||||
|
7
overrides/frozen/amfzx.json
Normal file
7
overrides/frozen/amfzx.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"symbol": "amfzx",
|
||||
"longName": "Investment Managers Series Trust - 361 Managed Futures Strategy Fund",
|
||||
"freeze_date": "2021-04-09",
|
||||
"created": "2026-08-31",
|
||||
"reason": "yahoo-empty"
|
||||
}
|
||||
3
overrides/frozen/andrx-capitalGain.csv
Normal file
3
overrides/frozen/andrx-capitalGain.csv
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
Date,Capital Gains
|
||||
2014-12-19,0.282000
|
||||
2017-12-20,0.015000
|
||||
|
9
overrides/frozen/andrx-dividend.csv
Normal file
9
overrides/frozen/andrx-dividend.csv
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
Date,Dividends
|
||||
2025-12-17,0.784130
|
||||
2026-04-28,6.557670
|
||||
2019-12-23,0.354020
|
||||
2020-12-22,0.262650
|
||||
2021-12-23,0.400300
|
||||
2022-12-19,0.267040
|
||||
2023-12-18,0.433520
|
||||
2024-12-17,0.336460
|
||||
|
1843
overrides/frozen/andrx-history.csv
Normal file
1843
overrides/frozen/andrx-history.csv
Normal file
File diff suppressed because it is too large
Load Diff
7
overrides/frozen/andrx.json
Normal file
7
overrides/frozen/andrx.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"symbol": "andrx",
|
||||
"longName": "AQR Funds - AQR International Defensive Style Fund",
|
||||
"freeze_date": "2026-05-01",
|
||||
"created": "2026-08-31",
|
||||
"reason": "yahoo-empty"
|
||||
}
|
||||
14
overrides/frozen/arwdx-capitalGain.csv
Normal file
14
overrides/frozen/arwdx-capitalGain.csv
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
Date,Capital Gains
|
||||
2019-12-30,0.866000
|
||||
2021-12-28,0.665000
|
||||
2024-12-20,0.317000
|
||||
2025-06-10,0.977000
|
||||
2016-12-29,0.128000
|
||||
2017-10-19,0.113000
|
||||
2017-12-28,0.010000
|
||||
2020-12-29,0.770000
|
||||
2022-12-28,0.254000
|
||||
2023-12-21,0.247000
|
||||
2014-12-30,0.048000
|
||||
2015-12-30,0.155000
|
||||
2018-12-27,0.556000
|
||||
|
16
overrides/frozen/arwdx-dividend.csv
Normal file
16
overrides/frozen/arwdx-dividend.csv
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
Date,Dividends
|
||||
2014-12-30,0.284000
|
||||
2017-10-19,0.218000
|
||||
2021-12-28,1.273000
|
||||
2023-12-21,0.593000
|
||||
2025-06-10,1.092000
|
||||
2017-12-28,0.179000
|
||||
2018-12-31,0.421000
|
||||
2020-12-29,0.991000
|
||||
2015-12-30,0.343000
|
||||
2016-12-29,0.277000
|
||||
2024-12-20,0.743000
|
||||
2013-12-30,0.147000
|
||||
2018-12-27,0.977000
|
||||
2019-12-30,1.142000
|
||||
2022-12-28,0.622000
|
||||
|
2
overrides/frozen/arwdx-history.csv
Normal file
2
overrides/frozen/arwdx-history.csv
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
Date,Open,High,Low,Close,Adj Close,Volume
|
||||
2025-09-23,8.650000,8.650000,8.650000,8.650000,8.650000,0
|
||||
|
7
overrides/frozen/arwdx.json
Normal file
7
overrides/frozen/arwdx.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"symbol": "arwdx",
|
||||
"longName": "American Century Asset Allocation Portfolios, Inc. - One Choice 2025 Portfolio",
|
||||
"freeze_date": "2025-09-23",
|
||||
"created": "2026-08-31",
|
||||
"reason": "yahoo-empty"
|
||||
}
|
||||
5
overrides/frozen/atezx-capitalGain.csv
Normal file
5
overrides/frozen/atezx-capitalGain.csv
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Date,Capital Gains
|
||||
2021-12-07,17.691000
|
||||
2022-12-06,2.947000
|
||||
2024-12-10,11.705000
|
||||
2025-12-09,18.145000
|
||||
|
6
overrides/frozen/atezx-dividend.csv
Normal file
6
overrides/frozen/atezx-dividend.csv
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
Date,Dividends
|
||||
2022-12-06,3.798000
|
||||
2023-12-05,0.469000
|
||||
2024-12-10,11.705000
|
||||
2025-12-09,18.145000
|
||||
2021-12-07,17.691000
|
||||
|
2
overrides/frozen/atezx-history.csv
Normal file
2
overrides/frozen/atezx-history.csv
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
Date,Open,High,Low,Close,Adj Close,Volume
|
||||
2026-07-17,137.520004,137.520004,137.520004,137.520004,137.520004,0
|
||||
|
7
overrides/frozen/atezx.json
Normal file
7
overrides/frozen/atezx.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"symbol": "atezx",
|
||||
"longName": "AB Sustainable Global Thematic Z",
|
||||
"freeze_date": "2026-07-17",
|
||||
"created": "2026-08-31",
|
||||
"reason": "yahoo-empty"
|
||||
}
|
||||
491
overrides/frozen/atmdx-dividend.csv
Normal file
491
overrides/frozen/atmdx-dividend.csv
Normal file
|
|
@ -0,0 +1,491 @@
|
|||
Date,Dividends,ctime
|
||||
2014-07-31,0.016,2017-08-22
|
||||
2011-02-28,0.006,2017-08-22
|
||||
2011-08-31,0.008,2017-08-22
|
||||
2017-03-31,0.02,2017-08-22
|
||||
2016-12-30,0.022,2017-08-22
|
||||
2017-06-30,0.024,2017-08-22
|
||||
2009-06-30,0.009,2017-08-22
|
||||
2011-12-28,0.023,2017-08-22
|
||||
2011-12-30,0.007,2017-08-22
|
||||
2013-06-28,0.003,2017-08-22
|
||||
2012-08-31,0.006,2017-08-22
|
||||
2015-04-30,0.014,2017-08-22
|
||||
2016-08-31,0.018,2017-08-22
|
||||
2012-02-29,0.012,2017-08-22
|
||||
2013-04-30,0.011,2017-08-22
|
||||
2013-10-31,0.004,2017-08-22
|
||||
2013-12-31,0.008,2017-08-22
|
||||
2012-03-30,0.014,2017-08-22
|
||||
2011-01-31,0.008,2017-08-22
|
||||
2015-11-30,0.016,2017-08-22
|
||||
2012-06-29,0.013,2017-08-22
|
||||
2015-08-31,0.015,2017-08-22
|
||||
2016-02-29,0.019,2017-08-22
|
||||
2012-09-28,0.003,2017-08-22
|
||||
2011-11-30,0.008,2017-08-22
|
||||
2015-03-31,0.007,2017-08-22
|
||||
2012-04-30,0.015,2017-08-22
|
||||
2009-05-29,0.001,2017-08-22
|
||||
2012-10-31,0.003,2017-08-22
|
||||
2015-06-30,0.015,2017-08-22
|
||||
2011-03-31,0.007,2017-08-22
|
||||
2016-10-31,0.019,2017-08-22
|
||||
2012-11-30,0.002,2017-08-22
|
||||
2014-05-30,0.012,2017-08-22
|
||||
2009-12-31,0.016,2017-08-22
|
||||
2011-06-30,0.008,2017-08-22
|
||||
2013-12-27,0.014,2017-08-22
|
||||
2016-11-30,0.02,2017-08-22
|
||||
2014-08-29,0.015,2017-08-22
|
||||
2015-12-29,0.263,2017-08-22
|
||||
2015-12-31,0.019,2017-08-22
|
||||
2010-02-26,0.012,2017-08-22
|
||||
2013-05-31,0.007,2017-08-22
|
||||
2013-11-29,0.006,2017-08-22
|
||||
2014-09-30,0.016,2017-08-22
|
||||
2011-10-31,0.009,2017-08-22
|
||||
2017-05-31,0.021,2017-08-22
|
||||
2009-12-09,0.043,2017-08-22
|
||||
2013-08-30,0.001,2017-08-22
|
||||
2014-02-28,0.007,2017-08-22
|
||||
2010-09-30,0.008,2017-08-22
|
||||
2014-01-31,0.008,2017-08-22
|
||||
2010-01-29,0.018,2017-08-22
|
||||
2010-07-30,0.008,2017-08-22
|
||||
2014-10-31,0.017,2017-08-22
|
||||
2013-03-28,0.004,2017-08-22
|
||||
2014-11-28,0.014,2017-08-22
|
||||
2013-09-30,0.003,2017-08-22
|
||||
2010-10-29,0.008,2017-08-22
|
||||
2016-05-31,0.018,2017-08-22
|
||||
2010-12-08,0.007,2017-08-22
|
||||
2015-02-27,0.006,2017-08-22
|
||||
2009-09-30,0.014,2017-08-22
|
||||
2010-11-30,0.011,2017-08-22
|
||||
2012-05-31,0.015,2017-08-22
|
||||
2013-07-31,0.001,2017-08-22
|
||||
2010-08-31,0.007,2017-08-22
|
||||
2016-03-31,0.02,2017-08-22
|
||||
2010-05-28,0.013,2017-08-22
|
||||
2017-07-31,0.02,2017-08-22
|
||||
2009-07-31,0.023,2017-08-22
|
||||
2016-06-30,0.018,2017-08-22
|
||||
2015-05-29,0.016,2017-08-22
|
||||
2009-10-30,0.027,2017-08-22
|
||||
2012-12-27,0.068,2017-08-22
|
||||
2014-04-30,0.007,2017-08-22
|
||||
2011-05-31,0.012,2017-08-22
|
||||
2009-08-31,0.015,2017-08-22
|
||||
2016-01-29,0.017,2017-08-22
|
||||
2016-07-29,0.017,2017-08-22
|
||||
2013-02-28,0.006,2017-08-22
|
||||
2014-12-29,0.111,2017-08-22
|
||||
2014-12-31,0.01,2017-08-22
|
||||
2012-01-31,0.005,2017-08-22
|
||||
2012-07-31,0.007,2017-08-22
|
||||
2015-09-30,0.017,2017-08-22
|
||||
2017-04-28,0.019,2017-08-22
|
||||
2011-09-30,0.009,2017-08-22
|
||||
2017-02-28,0.017,2017-08-22
|
||||
2014-03-31,0.005,2017-08-22
|
||||
2011-04-29,0.009,2017-08-22
|
||||
2015-07-31,0.015,2017-08-22
|
||||
2014-06-30,0.016,2017-08-22
|
||||
2011-07-29,0.006,2017-08-22
|
||||
2010-03-31,0.011,2017-08-22
|
||||
2015-10-30,0.017,2017-08-22
|
||||
2010-06-30,0.008,2017-08-22
|
||||
2010-12-31,0.01,2017-08-22
|
||||
2017-01-31,0.017,2017-08-22
|
||||
2009-11-30,0.014,2017-08-22
|
||||
2016-04-29,0.018,2017-08-22
|
||||
2017-09-29,0.023,2017-10-20 09:54:16
|
||||
2012-08-31,0.006,2017-10-20 09:54:16
|
||||
2015-04-30,0.014,2017-10-20 09:54:16
|
||||
2016-08-31,0.018,2017-10-20 09:54:16
|
||||
2012-02-29,0.012,2017-10-20 09:54:16
|
||||
2013-04-30,0.011,2017-10-20 09:54:16
|
||||
2013-10-31,0.004,2017-10-20 09:54:16
|
||||
2013-12-31,0.008,2017-10-20 09:54:16
|
||||
2012-03-30,0.014,2017-10-20 09:54:16
|
||||
2011-01-31,0.008,2017-10-20 09:54:16
|
||||
2015-11-30,0.016,2017-10-20 09:54:16
|
||||
2012-06-29,0.013,2017-10-20 09:54:16
|
||||
2015-08-31,0.015,2017-10-20 09:54:16
|
||||
2016-02-29,0.019,2017-10-20 09:54:16
|
||||
2012-09-28,0.003,2017-10-20 09:54:16
|
||||
2011-11-30,0.008,2017-10-20 09:54:16
|
||||
2015-03-31,0.007,2017-10-20 09:54:16
|
||||
2012-04-30,0.015,2017-10-20 09:54:16
|
||||
2009-05-29,0.001,2017-10-20 09:54:16
|
||||
2012-10-31,0.003,2017-10-20 09:54:16
|
||||
2015-06-30,0.015,2017-10-20 09:54:16
|
||||
2011-03-31,0.007,2017-10-20 09:54:16
|
||||
2016-10-31,0.019,2017-10-20 09:54:16
|
||||
2012-11-30,0.002,2017-10-20 09:54:16
|
||||
2014-05-30,0.012,2017-10-20 09:54:16
|
||||
2009-12-31,0.016,2017-10-20 09:54:16
|
||||
2011-06-30,0.008,2017-10-20 09:54:16
|
||||
2013-12-27,0.014,2017-10-20 09:54:16
|
||||
2016-11-30,0.02,2017-10-20 09:54:16
|
||||
2014-08-29,0.015,2017-10-20 09:54:16
|
||||
2015-12-29,0.263,2017-10-20 09:54:16
|
||||
2015-12-31,0.019,2017-10-20 09:54:16
|
||||
2010-02-26,0.012,2017-10-20 09:54:16
|
||||
2013-05-31,0.007,2017-10-20 09:54:16
|
||||
2013-11-29,0.006,2017-10-20 09:54:16
|
||||
2014-09-30,0.016,2017-10-20 09:54:16
|
||||
2011-10-31,0.009,2017-10-20 09:54:16
|
||||
2017-05-31,0.021,2017-10-20 09:54:16
|
||||
2009-12-09,0.043,2017-10-20 09:54:16
|
||||
2013-08-30,0.001,2017-10-20 09:54:16
|
||||
2014-02-28,0.007,2017-10-20 09:54:16
|
||||
2010-09-30,0.008,2017-10-20 09:54:16
|
||||
2014-01-31,0.008,2017-10-20 09:54:16
|
||||
2010-01-29,0.018,2017-10-20 09:54:16
|
||||
2010-07-30,0.008,2017-10-20 09:54:16
|
||||
2014-10-31,0.017,2017-10-20 09:54:16
|
||||
2013-03-28,0.004,2017-10-20 09:54:16
|
||||
2014-11-28,0.014,2017-10-20 09:54:16
|
||||
2013-09-30,0.003,2017-10-20 09:54:16
|
||||
2010-10-29,0.008,2017-10-20 09:54:16
|
||||
2016-05-31,0.018,2017-10-20 09:54:16
|
||||
2010-12-08,0.007,2017-10-20 09:54:16
|
||||
2015-02-27,0.006,2017-10-20 09:54:16
|
||||
2009-09-30,0.014,2017-10-20 09:54:16
|
||||
2010-11-30,0.011,2017-10-20 09:54:16
|
||||
2012-05-31,0.015,2017-10-20 09:54:16
|
||||
2013-07-31,0.001,2017-10-20 09:54:16
|
||||
2010-08-31,0.007,2017-10-20 09:54:16
|
||||
2016-03-31,0.02,2017-10-20 09:54:16
|
||||
2010-05-28,0.013,2017-10-20 09:54:16
|
||||
2017-07-31,0.02,2017-10-20 09:54:16
|
||||
2009-07-31,0.023,2017-10-20 09:54:16
|
||||
2016-06-30,0.018,2017-10-20 09:54:16
|
||||
2015-05-29,0.016,2017-10-20 09:54:16
|
||||
2009-10-30,0.027,2017-10-20 09:54:16
|
||||
2012-12-27,0.068,2017-10-20 09:54:16
|
||||
2014-04-30,0.007,2017-10-20 09:54:16
|
||||
2011-05-31,0.012,2017-10-20 09:54:16
|
||||
2009-08-31,0.015,2017-10-20 09:54:16
|
||||
2016-01-29,0.017,2017-10-20 09:54:16
|
||||
2016-07-29,0.017,2017-10-20 09:54:16
|
||||
2013-02-28,0.006,2017-10-20 09:54:16
|
||||
2014-12-29,0.111,2017-10-20 09:54:16
|
||||
2014-12-31,0.01,2017-10-20 09:54:16
|
||||
2012-01-31,0.005,2017-10-20 09:54:16
|
||||
2012-07-31,0.007,2017-10-20 09:54:16
|
||||
2015-09-30,0.017,2017-10-20 09:54:16
|
||||
2017-04-28,0.019,2017-10-20 09:54:16
|
||||
2011-09-30,0.009,2017-10-20 09:54:16
|
||||
2017-02-28,0.017,2017-10-20 09:54:16
|
||||
2014-03-31,0.005,2017-10-20 09:54:16
|
||||
2011-04-29,0.009,2017-10-20 09:54:16
|
||||
2015-07-31,0.015,2017-10-20 09:54:16
|
||||
2014-06-30,0.016,2017-10-20 09:54:16
|
||||
2011-07-29,0.006,2017-10-20 09:54:16
|
||||
2010-03-31,0.011,2017-10-20 09:54:16
|
||||
2015-10-30,0.017,2017-10-20 09:54:16
|
||||
2017-08-31,0.021,2017-10-20 09:54:16
|
||||
2010-06-30,0.008,2017-10-20 09:54:16
|
||||
2010-12-31,0.01,2017-10-20 09:54:16
|
||||
2017-01-31,0.017,2017-10-20 09:54:16
|
||||
2009-11-30,0.014,2017-10-20 09:54:16
|
||||
2016-04-29,0.018,2017-10-20 09:54:16
|
||||
2017-10-31,0.022,2017-11-15 07:55:39
|
||||
2012-02-29,0.012,2017-11-15 07:55:39
|
||||
2013-04-30,0.011,2017-11-15 07:55:39
|
||||
2013-10-31,0.004,2017-11-15 07:55:39
|
||||
2013-12-31,0.008,2017-11-15 07:55:39
|
||||
2012-03-30,0.014,2017-11-15 07:55:39
|
||||
2011-01-31,0.008,2017-11-15 07:55:39
|
||||
2015-11-30,0.016,2017-11-15 07:55:39
|
||||
2012-06-29,0.013,2017-11-15 07:55:39
|
||||
2015-08-31,0.015,2017-11-15 07:55:39
|
||||
2016-02-29,0.019,2017-11-15 07:55:39
|
||||
2012-09-28,0.003,2017-11-15 07:55:39
|
||||
2011-11-30,0.008,2017-11-15 07:55:39
|
||||
2015-03-31,0.007,2017-11-15 07:55:39
|
||||
2012-04-30,0.015,2017-11-15 07:55:39
|
||||
2009-05-29,0.001,2017-11-15 07:55:39
|
||||
2012-10-31,0.003,2017-11-15 07:55:39
|
||||
2015-06-30,0.015,2017-11-15 07:55:39
|
||||
2011-03-31,0.007,2017-11-15 07:55:39
|
||||
2016-10-31,0.019,2017-11-15 07:55:39
|
||||
2012-11-30,0.002,2017-11-15 07:55:39
|
||||
2014-05-30,0.012,2017-11-15 07:55:39
|
||||
2009-12-31,0.016,2017-11-15 07:55:39
|
||||
2011-06-30,0.008,2017-11-15 07:55:39
|
||||
2013-12-27,0.014,2017-11-15 07:55:39
|
||||
2016-11-30,0.02,2017-11-15 07:55:39
|
||||
2014-08-29,0.015,2017-11-15 07:55:39
|
||||
2015-12-29,0.263,2017-11-15 07:55:39
|
||||
2015-12-31,0.019,2017-11-15 07:55:39
|
||||
2010-02-26,0.012,2017-11-15 07:55:39
|
||||
2013-05-31,0.007,2017-11-15 07:55:39
|
||||
2013-11-29,0.006,2017-11-15 07:55:39
|
||||
2014-09-30,0.016,2017-11-15 07:55:39
|
||||
2011-10-31,0.009,2017-11-15 07:55:39
|
||||
2017-05-31,0.021,2017-11-15 07:55:39
|
||||
2009-12-09,0.043,2017-11-15 07:55:39
|
||||
2013-08-30,0.001,2017-11-15 07:55:39
|
||||
2014-02-28,0.007,2017-11-15 07:55:39
|
||||
2010-09-30,0.008,2017-11-15 07:55:39
|
||||
2014-01-31,0.008,2017-11-15 07:55:39
|
||||
2010-01-29,0.018,2017-11-15 07:55:39
|
||||
2010-07-30,0.008,2017-11-15 07:55:39
|
||||
2014-10-31,0.017,2017-11-15 07:55:39
|
||||
2013-03-28,0.004,2017-11-15 07:55:39
|
||||
2014-11-28,0.014,2017-11-15 07:55:39
|
||||
2013-09-30,0.003,2017-11-15 07:55:39
|
||||
2010-10-29,0.008,2017-11-15 07:55:39
|
||||
2016-05-31,0.018,2017-11-15 07:55:39
|
||||
2010-12-08,0.007,2017-11-15 07:55:39
|
||||
2015-02-27,0.006,2017-11-15 07:55:39
|
||||
2009-09-30,0.014,2017-11-15 07:55:39
|
||||
2010-11-30,0.011,2017-11-15 07:55:39
|
||||
2012-05-31,0.015,2017-11-15 07:55:39
|
||||
2013-07-31,0.001,2017-11-15 07:55:39
|
||||
2010-08-31,0.007,2017-11-15 07:55:39
|
||||
2016-03-31,0.02,2017-11-15 07:55:39
|
||||
2010-05-28,0.013,2017-11-15 07:55:39
|
||||
2017-07-31,0.02,2017-11-15 07:55:39
|
||||
2009-07-31,0.023,2017-11-15 07:55:39
|
||||
2016-06-30,0.018,2017-11-15 07:55:39
|
||||
2015-05-29,0.016,2017-11-15 07:55:39
|
||||
2009-10-30,0.027,2017-11-15 07:55:39
|
||||
2012-12-27,0.068,2017-11-15 07:55:39
|
||||
2014-04-30,0.007,2017-11-15 07:55:39
|
||||
2011-05-31,0.012,2017-11-15 07:55:39
|
||||
2009-08-31,0.015,2017-11-15 07:55:39
|
||||
2016-01-29,0.017,2017-11-15 07:55:39
|
||||
2016-07-29,0.017,2017-11-15 07:55:39
|
||||
2013-02-28,0.006,2017-11-15 07:55:39
|
||||
2014-12-29,0.111,2017-11-15 07:55:39
|
||||
2014-12-31,0.01,2017-11-15 07:55:39
|
||||
2012-01-31,0.005,2017-11-15 07:55:39
|
||||
2012-07-31,0.007,2017-11-15 07:55:39
|
||||
2015-09-30,0.017,2017-11-15 07:55:39
|
||||
2017-04-28,0.019,2017-11-15 07:55:39
|
||||
2011-09-30,0.009,2017-11-15 07:55:39
|
||||
2017-02-28,0.017,2017-11-15 07:55:39
|
||||
2014-03-31,0.005,2017-11-15 07:55:39
|
||||
2011-04-29,0.009,2017-11-15 07:55:39
|
||||
2015-07-31,0.015,2017-11-15 07:55:39
|
||||
2014-06-30,0.016,2017-11-15 07:55:39
|
||||
2011-07-29,0.006,2017-11-15 07:55:39
|
||||
2010-03-31,0.011,2017-11-15 07:55:39
|
||||
2015-10-30,0.017,2017-11-15 07:55:39
|
||||
2017-08-31,0.021,2017-11-15 07:55:39
|
||||
2010-06-30,0.008,2017-11-15 07:55:39
|
||||
2010-12-31,0.01,2017-11-15 07:55:39
|
||||
2017-01-31,0.017,2017-11-15 07:55:39
|
||||
2009-11-30,0.014,2017-11-15 07:55:39
|
||||
2016-04-29,0.018,2017-11-15 07:55:39
|
||||
2017-11-30,0.023,2017-12-11 20:07:47
|
||||
2014-12-29,0.111,2017-12-11 20:07:47
|
||||
2014-12-31,0.01,2017-12-11 20:07:47
|
||||
2012-01-31,0.005,2017-12-11 20:07:47
|
||||
2012-07-31,0.007,2017-12-11 20:07:47
|
||||
2015-09-30,0.017,2017-12-11 20:07:47
|
||||
2017-04-28,0.019,2017-12-11 20:07:47
|
||||
2011-09-30,0.009,2017-12-11 20:07:47
|
||||
2017-02-28,0.017,2017-12-11 20:07:47
|
||||
2014-03-31,0.005,2017-12-11 20:07:47
|
||||
2011-04-29,0.009,2017-12-11 20:07:47
|
||||
2015-07-31,0.015,2017-12-11 20:07:47
|
||||
2014-06-30,0.016,2017-12-11 20:07:47
|
||||
2011-07-29,0.006,2017-12-11 20:07:47
|
||||
2010-03-31,0.011,2017-12-11 20:07:47
|
||||
2015-10-30,0.017,2017-12-11 20:07:47
|
||||
2017-08-31,0.021,2017-12-11 20:07:47
|
||||
2010-06-30,0.008,2017-12-11 20:07:47
|
||||
2010-12-31,0.01,2017-12-11 20:07:47
|
||||
2017-01-31,0.017,2017-12-11 20:07:47
|
||||
2009-11-30,0.014,2017-12-11 20:07:47
|
||||
2016-04-29,0.018,2017-12-11 20:07:47
|
||||
2017-12-27,0.192,2018-01-16 07:54:11
|
||||
2012-03-30,0.014,2018-01-16 07:54:11
|
||||
2011-01-31,0.008,2018-01-16 07:54:11
|
||||
2017-12-29,0.026,2018-01-16 07:54:11
|
||||
2015-11-30,0.016,2018-01-16 07:54:11
|
||||
2012-06-29,0.013,2018-01-16 07:54:11
|
||||
2015-08-31,0.015,2018-01-16 07:54:11
|
||||
2016-02-29,0.019,2018-01-16 07:54:11
|
||||
2012-09-28,0.003,2018-01-16 07:54:11
|
||||
2011-11-30,0.008,2018-01-16 07:54:11
|
||||
2015-03-31,0.007,2018-01-16 07:54:11
|
||||
2012-04-30,0.015,2018-01-16 07:54:11
|
||||
2009-05-29,0.001,2018-01-16 07:54:11
|
||||
2012-10-31,0.003,2018-01-16 07:54:11
|
||||
2015-06-30,0.015,2018-01-16 07:54:11
|
||||
2011-03-31,0.007,2018-01-16 07:54:11
|
||||
2016-10-31,0.019,2018-01-16 07:54:11
|
||||
2012-11-30,0.002,2018-01-16 07:54:11
|
||||
2014-05-30,0.012,2018-01-16 07:54:11
|
||||
2009-12-31,0.016,2018-01-16 07:54:11
|
||||
2011-06-30,0.008,2018-01-16 07:54:11
|
||||
2013-12-27,0.014,2018-01-16 07:54:11
|
||||
2016-11-30,0.02,2018-01-16 07:54:11
|
||||
2014-08-29,0.015,2018-01-16 07:54:11
|
||||
2015-12-29,0.263,2018-01-16 07:54:11
|
||||
2015-12-31,0.019,2018-01-16 07:54:11
|
||||
2010-02-26,0.012,2018-01-16 07:54:11
|
||||
2013-05-31,0.007,2018-01-16 07:54:11
|
||||
2013-11-29,0.006,2018-01-16 07:54:11
|
||||
2014-09-30,0.016,2018-01-16 07:54:11
|
||||
2011-10-31,0.009,2018-01-16 07:54:11
|
||||
2017-05-31,0.021,2018-01-16 07:54:11
|
||||
2009-12-09,0.043,2018-01-16 07:54:11
|
||||
2013-08-30,0.001,2018-01-16 07:54:11
|
||||
2014-02-28,0.007,2018-01-16 07:54:11
|
||||
2010-09-30,0.008,2018-01-16 07:54:11
|
||||
2014-01-31,0.008,2018-01-16 07:54:11
|
||||
2010-01-29,0.018,2018-01-16 07:54:11
|
||||
2010-07-30,0.008,2018-01-16 07:54:11
|
||||
2014-10-31,0.017,2018-01-16 07:54:11
|
||||
2013-03-28,0.004,2018-01-16 07:54:11
|
||||
2014-11-28,0.014,2018-01-16 07:54:11
|
||||
2013-09-30,0.003,2018-01-16 07:54:11
|
||||
2010-10-29,0.008,2018-01-16 07:54:11
|
||||
2016-05-31,0.018,2018-01-16 07:54:11
|
||||
2010-12-08,0.007,2018-01-16 07:54:11
|
||||
2015-02-27,0.006,2018-01-16 07:54:11
|
||||
2009-09-30,0.014,2018-01-16 07:54:11
|
||||
2010-11-30,0.011,2018-01-16 07:54:11
|
||||
2012-05-31,0.015,2018-01-16 07:54:11
|
||||
2013-07-31,0.001,2018-01-16 07:54:11
|
||||
2010-08-31,0.007,2018-01-16 07:54:11
|
||||
2016-03-31,0.02,2018-01-16 07:54:11
|
||||
2010-05-28,0.013,2018-01-16 07:54:11
|
||||
2017-07-31,0.02,2018-01-16 07:54:11
|
||||
2009-07-31,0.023,2018-01-16 07:54:11
|
||||
2016-06-30,0.018,2018-01-16 07:54:11
|
||||
2015-05-29,0.016,2018-01-16 07:54:11
|
||||
2009-10-30,0.027,2018-01-16 07:54:11
|
||||
2012-12-27,0.068,2018-01-16 07:54:11
|
||||
2014-04-30,0.007,2018-01-16 07:54:11
|
||||
2011-05-31,0.012,2018-01-16 07:54:11
|
||||
2009-08-31,0.015,2018-01-16 07:54:11
|
||||
2016-01-29,0.017,2018-01-16 07:54:11
|
||||
2016-07-29,0.017,2018-01-16 07:54:11
|
||||
2013-02-28,0.006,2018-01-16 07:54:11
|
||||
2017-11-30,0.023,2018-01-16 07:54:11
|
||||
2014-12-29,0.111,2018-01-16 07:54:11
|
||||
2014-12-31,0.01,2018-01-16 07:54:11
|
||||
2012-01-31,0.005,2018-01-16 07:54:11
|
||||
2012-07-31,0.007,2018-01-16 07:54:11
|
||||
2015-09-30,0.017,2018-01-16 07:54:11
|
||||
2017-04-28,0.019,2018-01-16 07:54:11
|
||||
2011-09-30,0.009,2018-01-16 07:54:11
|
||||
2017-02-28,0.017,2018-01-16 07:54:11
|
||||
2014-03-31,0.005,2018-01-16 07:54:11
|
||||
2011-04-29,0.009,2018-01-16 07:54:11
|
||||
2015-07-31,0.015,2018-01-16 07:54:11
|
||||
2014-06-30,0.016,2018-01-16 07:54:11
|
||||
2011-07-29,0.006,2018-01-16 07:54:11
|
||||
2010-03-31,0.011,2018-01-16 07:54:11
|
||||
2015-10-30,0.017,2018-01-16 07:54:11
|
||||
2017-08-31,0.021,2018-01-16 07:54:11
|
||||
2010-06-30,0.008,2018-01-16 07:54:11
|
||||
2010-12-31,0.01,2018-01-16 07:54:11
|
||||
2017-01-31,0.017,2018-01-16 07:54:11
|
||||
2009-11-30,0.014,2018-01-16 07:54:11
|
||||
2016-04-29,0.018,2018-01-16 07:54:11
|
||||
2018-01-31,0.027,2018-02-26 21:44:31
|
||||
2009-09-30,0.014,2018-02-26 21:44:31
|
||||
2010-11-30,0.011,2018-02-26 21:44:31
|
||||
2012-05-31,0.015,2018-02-26 21:44:31
|
||||
2013-07-31,0.001,2018-02-26 21:44:31
|
||||
2010-08-31,0.007,2018-02-26 21:44:31
|
||||
2016-03-31,0.02,2018-02-26 21:44:31
|
||||
2010-05-28,0.013,2018-02-26 21:44:31
|
||||
2017-07-31,0.02,2018-02-26 21:44:31
|
||||
2009-07-31,0.023,2018-02-26 21:44:31
|
||||
2016-06-30,0.018,2018-02-26 21:44:31
|
||||
2015-05-29,0.016,2018-02-26 21:44:31
|
||||
2009-10-30,0.027,2018-02-26 21:44:31
|
||||
2012-12-27,0.068,2018-02-26 21:44:31
|
||||
2014-04-30,0.007,2018-02-26 21:44:31
|
||||
2011-05-31,0.012,2018-02-26 21:44:31
|
||||
2009-08-31,0.015,2018-02-26 21:44:31
|
||||
2016-01-29,0.017,2018-02-26 21:44:31
|
||||
2016-07-29,0.017,2018-02-26 21:44:31
|
||||
2013-02-28,0.006,2018-02-26 21:44:31
|
||||
2017-11-30,0.023,2018-02-26 21:44:31
|
||||
2014-12-29,0.111,2018-02-26 21:44:31
|
||||
2014-12-31,0.01,2018-02-26 21:44:31
|
||||
2012-01-31,0.005,2018-02-26 21:44:31
|
||||
2012-07-31,0.007,2018-02-26 21:44:31
|
||||
2015-09-30,0.017,2018-02-26 21:44:31
|
||||
2017-04-28,0.019,2018-02-26 21:44:31
|
||||
2011-09-30,0.009,2018-02-26 21:44:31
|
||||
2017-02-28,0.017,2018-02-26 21:44:31
|
||||
2014-03-31,0.005,2018-02-26 21:44:31
|
||||
2011-04-29,0.009,2018-02-26 21:44:31
|
||||
2015-07-31,0.015,2018-02-26 21:44:31
|
||||
2014-06-30,0.016,2018-02-26 21:44:31
|
||||
2011-07-29,0.006,2018-02-26 21:44:31
|
||||
2010-03-31,0.011,2018-02-26 21:44:31
|
||||
2015-10-30,0.017,2018-02-26 21:44:31
|
||||
2017-08-31,0.021,2018-02-26 21:44:31
|
||||
2010-06-30,0.008,2018-02-26 21:44:31
|
||||
2010-12-31,0.01,2018-02-26 21:44:31
|
||||
2017-01-31,0.017,2018-02-26 21:44:31
|
||||
2009-11-30,0.014,2018-02-26 21:44:31
|
||||
2016-04-29,0.018,2018-02-26 21:44:31
|
||||
2018-02-28,0.025,2018-03-09 21:59:16
|
||||
2014-01-31,0.008,2018-03-09 21:59:16
|
||||
2010-01-29,0.018,2018-03-09 21:59:16
|
||||
2010-07-30,0.008,2018-03-09 21:59:16
|
||||
2014-10-31,0.017,2018-03-09 21:59:16
|
||||
2013-03-28,0.004,2018-03-09 21:59:16
|
||||
2014-11-28,0.014,2018-03-09 21:59:16
|
||||
2013-09-30,0.003,2018-03-09 21:59:16
|
||||
2010-10-29,0.008,2018-03-09 21:59:16
|
||||
2016-05-31,0.018,2018-03-09 21:59:16
|
||||
2010-12-08,0.007,2018-03-09 21:59:16
|
||||
2015-02-27,0.006,2018-03-09 21:59:16
|
||||
2018-01-31,0.027,2018-03-09 21:59:16
|
||||
2009-09-30,0.014,2018-03-09 21:59:16
|
||||
2010-11-30,0.011,2018-03-09 21:59:16
|
||||
2012-05-31,0.015,2018-03-09 21:59:16
|
||||
2013-07-31,0.001,2018-03-09 21:59:16
|
||||
2010-08-31,0.007,2018-03-09 21:59:16
|
||||
2016-03-31,0.02,2018-03-09 21:59:16
|
||||
2010-05-28,0.013,2018-03-09 21:59:16
|
||||
2017-07-31,0.02,2018-03-09 21:59:16
|
||||
2009-07-31,0.023,2018-03-09 21:59:16
|
||||
2016-06-30,0.018,2018-03-09 21:59:16
|
||||
2015-05-29,0.016,2018-03-09 21:59:16
|
||||
2009-10-30,0.027,2018-03-09 21:59:16
|
||||
2012-12-27,0.068,2018-03-09 21:59:16
|
||||
2014-04-30,0.007,2018-03-09 21:59:16
|
||||
2011-05-31,0.012,2018-03-09 21:59:16
|
||||
2009-08-31,0.015,2018-03-09 21:59:16
|
||||
2016-01-29,0.017,2018-03-09 21:59:16
|
||||
2016-07-29,0.017,2018-03-09 21:59:16
|
||||
2013-02-28,0.006,2018-03-09 21:59:16
|
||||
2017-11-30,0.023,2018-03-09 21:59:16
|
||||
2014-12-29,0.111,2018-03-09 21:59:16
|
||||
2014-12-31,0.01,2018-03-09 21:59:16
|
||||
2012-01-31,0.005,2018-03-09 21:59:16
|
||||
2012-07-31,0.007,2018-03-09 21:59:16
|
||||
2015-09-30,0.017,2018-03-09 21:59:16
|
||||
2017-04-28,0.019,2018-03-09 21:59:16
|
||||
2011-09-30,0.009,2018-03-09 21:59:16
|
||||
2017-02-28,0.017,2018-03-09 21:59:16
|
||||
2014-03-31,0.005,2018-03-09 21:59:16
|
||||
2011-04-29,0.009,2018-03-09 21:59:16
|
||||
2015-07-31,0.015,2018-03-09 21:59:16
|
||||
2014-06-30,0.016,2018-03-09 21:59:16
|
||||
2011-07-29,0.006,2018-03-09 21:59:16
|
||||
2010-03-31,0.011,2018-03-09 21:59:16
|
||||
2015-10-30,0.017,2018-03-09 21:59:16
|
||||
2017-08-31,0.021,2018-03-09 21:59:16
|
||||
2010-06-30,0.008,2018-03-09 21:59:16
|
||||
2010-12-31,0.01,2018-03-09 21:59:16
|
||||
2017-01-31,0.017,2018-03-09 21:59:16
|
||||
2009-11-30,0.014,2018-03-09 21:59:16
|
||||
2016-04-29,0.018,2018-03-09 21:59:16
|
||||
|
33583
overrides/frozen/atmdx-history.csv
Normal file
33583
overrides/frozen/atmdx-history.csv
Normal file
File diff suppressed because it is too large
Load Diff
7
overrides/frozen/atmdx.json
Normal file
7
overrides/frozen/atmdx.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"symbol": "atmdx",
|
||||
"longName": "?",
|
||||
"freeze_date": "2018-03-23",
|
||||
"created": "2026-08-31",
|
||||
"reason": "yahoo-empty"
|
||||
}
|
||||
5
overrides/frozen/avgyx-capitalGain.csv
Normal file
5
overrides/frozen/avgyx-capitalGain.csv
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Date,Capital Gains
|
||||
2021-12-20,2.743000
|
||||
2016-12-23,0.029000
|
||||
2017-12-22,0.817000
|
||||
2019-12-23,0.331000
|
||||
|
6
overrides/frozen/avgyx-dividend.csv
Normal file
6
overrides/frozen/avgyx-dividend.csv
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
Date,Dividends
|
||||
2019-12-23,0.558100
|
||||
2021-12-20,2.859500
|
||||
2022-12-20,0.222000
|
||||
2023-12-19,0.702600
|
||||
2024-12-18,1.305000
|
||||
|
1715
overrides/frozen/avgyx-history.csv
Normal file
1715
overrides/frozen/avgyx-history.csv
Normal file
File diff suppressed because it is too large
Load Diff
7
overrides/frozen/avgyx.json
Normal file
7
overrides/frozen/avgyx.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"symbol": "avgyx",
|
||||
"longName": "BNY Mellon Advantage Funds, Inc. - BNY Mellon Dynamic Total Return Fund",
|
||||
"freeze_date": "2025-10-24",
|
||||
"created": "2026-08-31",
|
||||
"reason": "yahoo-empty"
|
||||
}
|
||||
5
overrides/frozen/bafmx-capitalGain.csv
Normal file
5
overrides/frozen/bafmx-capitalGain.csv
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Date,Capital Gains
|
||||
2018-12-17,0.114000
|
||||
2019-12-16,0.036000
|
||||
2021-12-14,1.749000
|
||||
2022-12-13,0.814000
|
||||
|
5
overrides/frozen/bafmx-dividend.csv
Normal file
5
overrides/frozen/bafmx-dividend.csv
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Date,Dividends
|
||||
2019-12-16,0.035660
|
||||
2021-12-14,1.749320
|
||||
2022-12-13,0.813930
|
||||
2025-12-15,7.440010
|
||||
|
2
overrides/frozen/bafmx-history.csv
Normal file
2
overrides/frozen/bafmx-history.csv
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
Date,Open,High,Low,Close,Adj Close,Volume
|
||||
2026-04-24,9.920400,9.920400,9.920400,9.920400,9.920400,0
|
||||
|
7
overrides/frozen/bafmx.json
Normal file
7
overrides/frozen/bafmx.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"symbol": "bafmx",
|
||||
"longName": "Brown Advisory Mid-Cap Growth Instl",
|
||||
"freeze_date": "2026-04-24",
|
||||
"created": "2026-08-31",
|
||||
"reason": "yahoo-empty"
|
||||
}
|
||||
9
overrides/frozen/bbgpx-capitalGain.csv
Normal file
9
overrides/frozen/bbgpx-capitalGain.csv
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
Date,Capital Gains
|
||||
2018-12-21,0.017000
|
||||
2019-12-23,0.004000
|
||||
2022-12-19,0.002000
|
||||
2009-12-22,0.192000
|
||||
2010-12-22,0.365000
|
||||
2011-12-21,0.125000
|
||||
2012-12-21,0.201000
|
||||
2017-12-22,0.004000
|
||||
|
284
overrides/frozen/bbgpx-dividend.csv
Normal file
284
overrides/frozen/bbgpx-dividend.csv
Normal file
|
|
@ -0,0 +1,284 @@
|
|||
Date,Dividends
|
||||
2003-10-31,0.052000
|
||||
2014-02-28,0.019000
|
||||
2017-11-30,0.026000
|
||||
2008-12-31,0.035000
|
||||
2021-02-26,0.017000
|
||||
2021-07-30,0.013000
|
||||
2024-06-28,0.026000
|
||||
2002-12-31,0.015000
|
||||
2012-07-31,0.033000
|
||||
2014-07-31,0.019000
|
||||
2014-08-29,0.021000
|
||||
2014-10-31,0.021000
|
||||
2016-06-30,0.022000
|
||||
2005-05-31,0.035000
|
||||
2006-11-30,0.042000
|
||||
2015-06-30,0.017000
|
||||
2018-08-31,0.030000
|
||||
2021-08-31,0.011000
|
||||
2024-03-28,0.023000
|
||||
2006-03-31,0.037000
|
||||
2011-08-31,0.031000
|
||||
2011-10-31,0.034000
|
||||
2016-04-29,0.024000
|
||||
2019-04-30,0.030000
|
||||
2020-07-31,0.028000
|
||||
2023-01-31,0.019000
|
||||
2013-05-31,0.034000
|
||||
2013-07-31,0.033000
|
||||
2015-01-30,0.020000
|
||||
2017-02-28,0.024000
|
||||
2019-10-31,0.025000
|
||||
2025-09-30,0.029000
|
||||
2025-10-31,0.029000
|
||||
2006-01-31,0.041000
|
||||
2015-07-31,0.021000
|
||||
2016-02-29,0.024000
|
||||
2004-10-29,0.022000
|
||||
2007-12-31,0.042000
|
||||
2009-12-31,0.027000
|
||||
2011-12-21,0.125000
|
||||
2013-03-28,0.032000
|
||||
2023-07-31,0.023000
|
||||
2013-04-30,0.034000
|
||||
2015-08-31,0.023000
|
||||
2020-10-30,0.021000
|
||||
2021-03-31,0.016000
|
||||
2008-11-28,0.034000
|
||||
2017-10-31,0.028000
|
||||
2021-12-31,0.013000
|
||||
2025-03-31,0.028000
|
||||
2005-09-30,0.035000
|
||||
2007-10-31,0.044000
|
||||
2009-06-30,0.040000
|
||||
2010-05-28,0.031000
|
||||
2018-12-31,0.029000
|
||||
2019-12-23,0.004000
|
||||
2020-06-30,0.029000
|
||||
2024-09-30,0.026000
|
||||
2009-12-22,0.192000
|
||||
2012-03-30,0.037000
|
||||
2021-05-28,0.014000
|
||||
2004-03-31,0.049000
|
||||
2008-06-30,0.039000
|
||||
2009-09-30,0.026000
|
||||
2010-08-31,0.024000
|
||||
2011-11-30,0.035000
|
||||
2013-01-31,0.029000
|
||||
2019-03-29,0.029000
|
||||
2003-04-30,0.052000
|
||||
2005-11-30,0.035000
|
||||
2013-11-29,0.027000
|
||||
2022-07-29,0.020000
|
||||
2006-06-30,0.037000
|
||||
2008-07-31,0.039000
|
||||
2018-12-21,0.017000
|
||||
2022-12-30,0.019000
|
||||
2024-11-29,0.026000
|
||||
2003-05-30,0.052000
|
||||
2005-02-28,0.035000
|
||||
2007-03-30,0.042000
|
||||
2012-05-31,0.034000
|
||||
2023-10-31,0.026000
|
||||
2003-11-28,0.052000
|
||||
2004-12-31,0.042000
|
||||
2008-08-29,0.036000
|
||||
2011-05-31,0.030000
|
||||
2021-04-30,0.017000
|
||||
2024-05-31,0.028000
|
||||
2004-05-28,0.049000
|
||||
2005-07-29,0.035000
|
||||
2007-04-30,0.043000
|
||||
2011-07-29,0.032000
|
||||
2018-01-31,0.026000
|
||||
2018-03-29,0.026000
|
||||
2021-06-30,0.015000
|
||||
2017-06-30,0.026000
|
||||
2008-01-31,0.042000
|
||||
2008-10-31,0.031000
|
||||
2010-11-30,0.026000
|
||||
2012-04-30,0.035000
|
||||
2012-12-31,0.028000
|
||||
2015-10-30,0.025000
|
||||
2016-01-29,0.024000
|
||||
2019-09-30,0.025000
|
||||
2024-07-31,0.024000
|
||||
2003-06-30,0.052000
|
||||
2005-01-31,0.035000
|
||||
2011-03-31,0.024000
|
||||
2013-12-31,0.021000
|
||||
2020-05-29,0.028000
|
||||
2008-02-29,0.042000
|
||||
2020-01-31,0.026000
|
||||
2020-12-31,0.019000
|
||||
2006-08-31,0.042000
|
||||
2007-11-30,0.044000
|
||||
2010-02-26,0.027000
|
||||
2011-04-29,0.027000
|
||||
2011-06-30,0.031000
|
||||
2020-08-31,0.022000
|
||||
2022-09-30,0.020000
|
||||
2024-01-31,0.023000
|
||||
2006-04-28,0.037000
|
||||
2007-06-29,0.043000
|
||||
2010-10-29,0.025000
|
||||
2013-02-28,0.033000
|
||||
2013-10-31,0.028000
|
||||
2020-02-28,0.028000
|
||||
2023-05-31,0.021000
|
||||
2004-07-30,0.039000
|
||||
2010-12-22,0.365000
|
||||
2003-07-31,0.052000
|
||||
2009-02-27,0.032000
|
||||
2012-09-28,0.030000
|
||||
2013-06-28,0.036000
|
||||
2018-11-30,0.028000
|
||||
2010-03-31,0.031000
|
||||
2010-04-30,0.040000
|
||||
2017-09-29,0.031000
|
||||
2022-11-30,0.019000
|
||||
2011-02-28,0.023000
|
||||
2013-09-30,0.030000
|
||||
2023-09-29,0.024000
|
||||
2009-04-30,0.037000
|
||||
2018-09-28,0.030000
|
||||
2022-05-31,0.018000
|
||||
2006-05-31,0.037000
|
||||
2007-09-28,0.043000
|
||||
2023-12-29,0.023000
|
||||
2024-12-31,0.026000
|
||||
2004-06-30,0.049000
|
||||
2004-11-30,0.042000
|
||||
2007-07-31,0.046000
|
||||
2017-04-28,0.023000
|
||||
2018-05-31,0.028000
|
||||
2019-08-30,0.026000
|
||||
2022-08-31,0.020000
|
||||
2008-03-31,0.041000
|
||||
2011-01-31,0.026000
|
||||
2017-08-31,0.030000
|
||||
2019-01-31,0.027000
|
||||
2023-04-28,0.020000
|
||||
2006-07-31,0.042000
|
||||
2006-12-29,0.042000
|
||||
2024-08-30,0.026000
|
||||
2025-05-30,0.028000
|
||||
2012-02-29,0.034000
|
||||
2022-01-31,0.011000
|
||||
2008-05-30,0.040000
|
||||
2017-07-31,0.028000
|
||||
2019-02-28,0.028000
|
||||
2015-05-29,0.017000
|
||||
2024-10-31,0.026000
|
||||
2010-07-30,0.025000
|
||||
2011-12-30,0.037000
|
||||
2012-08-31,0.031000
|
||||
2012-12-21,0.201000
|
||||
2003-09-30,0.052000
|
||||
2007-08-31,0.043000
|
||||
2016-10-31,0.023000
|
||||
2007-02-28,0.042000
|
||||
2009-10-30,0.031000
|
||||
2022-03-31,0.014000
|
||||
2023-02-28,0.022000
|
||||
2005-12-30,0.108000
|
||||
2012-06-29,0.034000
|
||||
2014-12-31,0.020000
|
||||
2018-02-28,0.028000
|
||||
2019-12-31,0.026000
|
||||
2017-01-31,0.024000
|
||||
2021-01-29,0.021000
|
||||
2011-09-30,0.033000
|
||||
2016-09-30,0.023000
|
||||
2005-10-31,0.035000
|
||||
2020-03-31,0.028000
|
||||
2022-10-31,0.020000
|
||||
2022-12-19,0.002000
|
||||
2024-04-30,0.027000
|
||||
2025-06-30,0.028000
|
||||
2020-09-30,0.024000
|
||||
2021-11-30,0.012000
|
||||
2025-11-28,0.029000
|
||||
2003-08-29,0.052000
|
||||
2007-01-31,0.042000
|
||||
2015-02-27,0.020000
|
||||
2015-04-30,0.016000
|
||||
2017-03-31,0.022000
|
||||
2003-03-31,0.052000
|
||||
2004-08-31,0.022000
|
||||
2007-05-31,0.043000
|
||||
2008-09-30,0.037000
|
||||
2009-08-31,0.036000
|
||||
2010-12-31,0.029000
|
||||
2013-08-30,0.030000
|
||||
2017-05-31,0.025000
|
||||
2006-02-28,0.038000
|
||||
2014-01-31,0.021000
|
||||
2019-05-31,0.029000
|
||||
2020-04-30,0.030000
|
||||
2003-12-31,0.052000
|
||||
2014-03-31,0.018000
|
||||
2023-11-30,0.023000
|
||||
2009-01-30,0.031000
|
||||
2016-07-29,0.024000
|
||||
2004-09-30,0.022000
|
||||
2006-09-29,0.042000
|
||||
2009-05-29,0.040000
|
||||
2010-01-29,0.027000
|
||||
2010-06-30,0.026000
|
||||
2010-09-30,0.025000
|
||||
2015-09-30,0.027000
|
||||
2014-04-30,0.019000
|
||||
2014-11-28,0.021000
|
||||
2016-03-31,0.024000
|
||||
2016-11-30,0.024000
|
||||
2020-11-30,0.022000
|
||||
2025-08-29,0.028000
|
||||
2022-02-28,0.012000
|
||||
2023-08-31,0.025000
|
||||
2025-01-31,0.027000
|
||||
2014-09-30,0.023000
|
||||
2015-03-31,0.018000
|
||||
2016-12-30,0.024000
|
||||
2025-04-30,0.027000
|
||||
2003-02-28,0.052000
|
||||
2016-05-31,0.023000
|
||||
2019-11-29,0.026000
|
||||
2025-07-31,0.028000
|
||||
2005-04-29,0.035000
|
||||
2009-03-31,0.035000
|
||||
2018-04-30,0.027000
|
||||
2022-06-30,0.021000
|
||||
2024-02-29,0.023000
|
||||
2005-06-30,0.035000
|
||||
2008-04-30,0.041000
|
||||
2012-01-31,0.037000
|
||||
2015-11-30,0.025000
|
||||
2018-07-31,0.028000
|
||||
2021-09-30,0.015000
|
||||
2023-03-31,0.021000
|
||||
2009-07-31,0.039000
|
||||
2004-01-30,0.052000
|
||||
2016-08-31,0.023000
|
||||
2019-07-31,0.027000
|
||||
2025-02-28,0.027000
|
||||
2023-06-30,0.021000
|
||||
2004-02-27,0.052000
|
||||
2004-04-30,0.049000
|
||||
2012-11-30,0.029000
|
||||
2014-05-30,0.019000
|
||||
2018-06-29,0.028000
|
||||
2018-10-31,0.029000
|
||||
2022-04-29,0.016000
|
||||
2012-10-31,0.030000
|
||||
2014-06-30,0.019000
|
||||
2015-12-31,0.025000
|
||||
2005-08-31,0.035000
|
||||
2009-11-30,0.026000
|
||||
2019-06-28,0.027000
|
||||
2005-03-31,0.035000
|
||||
2017-12-22,0.004000
|
||||
2021-10-29,0.014000
|
||||
2006-10-31,0.042000
|
||||
2017-12-29,0.027000
|
||||
|
5792
overrides/frozen/bbgpx-history.csv
Normal file
5792
overrides/frozen/bbgpx-history.csv
Normal file
File diff suppressed because it is too large
Load Diff
7
overrides/frozen/bbgpx.json
Normal file
7
overrides/frozen/bbgpx.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"symbol": "bbgpx",
|
||||
"longName": "BlackRock ETF Trust II - iShares Mortgage-Backed Securities Active ETF",
|
||||
"freeze_date": "2025-12-26",
|
||||
"created": "2026-08-31",
|
||||
"reason": "yahoo-empty"
|
||||
}
|
||||
11
overrides/frozen/bcmix-capitalGain.csv
Normal file
11
overrides/frozen/bcmix-capitalGain.csv
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
Date,Capital Gains
|
||||
2012-12-14,0.354000
|
||||
2016-12-13,0.611000
|
||||
2019-12-12,0.613000
|
||||
2020-12-11,0.453000
|
||||
2022-12-12,1.859000
|
||||
2014-12-12,1.809000
|
||||
2015-12-11,11.223000
|
||||
2017-12-12,2.419000
|
||||
2018-12-12,1.137000
|
||||
2021-12-10,0.500000
|
||||
|
11
overrides/frozen/bcmix-dividend.csv
Normal file
11
overrides/frozen/bcmix-dividend.csv
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
Date,Dividends
|
||||
2019-12-12,0.613000
|
||||
2021-12-10,0.500000
|
||||
2022-12-12,1.859000
|
||||
2012-12-14,0.354000
|
||||
2014-12-12,1.809000
|
||||
2015-12-11,11.223000
|
||||
2016-12-13,0.611000
|
||||
2017-12-12,2.419000
|
||||
2018-12-12,1.137000
|
||||
2020-12-11,0.453000
|
||||
|
3269
overrides/frozen/bcmix-history.csv
Normal file
3269
overrides/frozen/bcmix-history.csv
Normal file
File diff suppressed because it is too large
Load Diff
7
overrides/frozen/bcmix.json
Normal file
7
overrides/frozen/bcmix.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"symbol": "bcmix",
|
||||
"longName": "Brown Capital Management Mutual Funds - The Brown Capital Management Mid Company Fund",
|
||||
"freeze_date": "2024-12-11",
|
||||
"created": "2026-08-31",
|
||||
"reason": "yahoo-empty"
|
||||
}
|
||||
2
overrides/frozen/bfslx-dividend.csv
Normal file
2
overrides/frozen/bfslx-dividend.csv
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
Date,Dividends,ctime
|
||||
2014-12-02,0.191,2017-08-22
|
||||
|
2712
overrides/frozen/bfslx-history.csv
Normal file
2712
overrides/frozen/bfslx-history.csv
Normal file
File diff suppressed because it is too large
Load Diff
7
overrides/frozen/bfslx.json
Normal file
7
overrides/frozen/bfslx.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"symbol": "bfslx",
|
||||
"longName": "?",
|
||||
"freeze_date": "2018-03-16",
|
||||
"created": "2026-08-31",
|
||||
"reason": "yahoo-empty"
|
||||
}
|
||||
4
overrides/frozen/bgaqx-dividend.csv
Normal file
4
overrides/frozen/bgaqx-dividend.csv
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
Date,Dividends
|
||||
2017-12-06,0.007000
|
||||
2018-12-06,0.114000
|
||||
2019-12-04,0.724000
|
||||
|
19
overrides/frozen/bgaqx-history.csv
Normal file
19
overrides/frozen/bgaqx-history.csv
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
Date,Open,High,Low,Close,Adj Close,Volume
|
||||
2020-03-05,0.100000,0.100000,0.100000,0.100000,0.100000,0
|
||||
2020-03-06,0.100000,0.100000,0.100000,0.100000,0.100000,0
|
||||
2020-03-09,0.100000,0.100000,0.100000,0.100000,0.100000,0
|
||||
2020-03-10,0.100000,0.100000,0.100000,0.100000,0.100000,0
|
||||
2020-03-11,0.100000,0.100000,0.100000,0.100000,0.100000,0
|
||||
2020-03-12,0.100000,0.100000,0.100000,0.100000,0.100000,0
|
||||
2020-03-13,0.100000,0.100000,0.100000,0.100000,0.100000,0
|
||||
2020-03-16,0.100000,0.100000,0.100000,0.100000,0.100000,0
|
||||
2020-03-17,0.100000,0.100000,0.100000,0.100000,0.100000,0
|
||||
2020-03-18,0.100000,0.100000,0.100000,0.100000,0.100000,0
|
||||
2020-03-19,0.100000,0.100000,0.100000,0.100000,0.100000,0
|
||||
2020-03-20,0.100000,0.100000,0.100000,0.100000,0.100000,0
|
||||
2020-03-23,0.100000,0.100000,0.100000,0.100000,0.100000,0
|
||||
2020-03-24,0.100000,0.100000,0.100000,0.100000,0.100000,0
|
||||
2020-03-25,0.100000,0.100000,0.100000,0.100000,0.100000,0
|
||||
2020-03-26,0.100000,0.100000,0.100000,0.100000,0.100000,0
|
||||
2020-03-27,0.100000,0.100000,0.100000,0.100000,0.100000,0
|
||||
2020-03-30,0.100000,0.100000,0.100000,0.100000,0.100000,0
|
||||
|
7
overrides/frozen/bgaqx.json
Normal file
7
overrides/frozen/bgaqx.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"symbol": "bgaqx",
|
||||
"longName": "BMO Global Long/Short Equity Fund Class A",
|
||||
"freeze_date": "2020-03-30",
|
||||
"created": "2026-08-31",
|
||||
"reason": "yahoo-empty"
|
||||
}
|
||||
4
overrides/frozen/bgrsx-capitalGain.csv
Normal file
4
overrides/frozen/bgrsx-capitalGain.csv
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
Date,Capital Gains
|
||||
2018-12-13,0.203000
|
||||
2024-09-19,1.467000
|
||||
2015-12-17,0.044000
|
||||
|
8
overrides/frozen/bgrsx-dividend.csv
Normal file
8
overrides/frozen/bgrsx-dividend.csv
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
Date,Dividends
|
||||
2016-12-15,0.015000
|
||||
2018-12-13,0.203000
|
||||
2019-12-12,0.104000
|
||||
2022-12-08,0.304000
|
||||
2023-12-14,0.201000
|
||||
2024-09-19,1.592000
|
||||
2015-12-17,0.044000
|
||||
|
2698
overrides/frozen/bgrsx-history.csv
Normal file
2698
overrides/frozen/bgrsx-history.csv
Normal file
File diff suppressed because it is too large
Load Diff
7
overrides/frozen/bgrsx.json
Normal file
7
overrides/frozen/bgrsx.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"symbol": "bgrsx",
|
||||
"longName": "The RBB Fund, Inc. - Boston Partners Global Long/Short Fund",
|
||||
"freeze_date": "2024-12-30",
|
||||
"created": "2026-08-31",
|
||||
"reason": "yahoo-empty"
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user