Compare commits
No commits in common. "9263283995e717f0631ceb39415413e96ea9dc76" and "6f6d6b8047e49408c8ebde3a27a7f911625b89f5" have entirely different histories.
9263283995
...
6f6d6b8047
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -9,4 +9,3 @@ fundlab/nport_cache/raw/
|
|||
fundlab/universe_cache/
|
||||
fundlab/xcheck_run.log
|
||||
fundlab/streamlit.log
|
||||
reports/report_data_adhoc.json
|
||||
|
|
|
|||
253
app.py
253
app.py
|
|
@ -403,17 +403,6 @@ 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"])
|
||||
|
|
@ -587,110 +576,6 @@ 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())
|
||||
|
|
@ -710,74 +595,25 @@ with tab_fundlab:
|
|||
_DR = json.loads(_dc.RESULTS.read_text())
|
||||
except Exception:
|
||||
_DR = {}
|
||||
# --- 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(_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.")
|
||||
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 "—",
|
||||
})
|
||||
st.dataframe(pd.DataFrame(_sum_rows), width="stretch")
|
||||
|
||||
# --- alpha search: all screened funds (shortlist + longlist + harvest)
|
||||
with st.expander("Alpha search — all screened funds, ranked"):
|
||||
|
|
@ -824,7 +660,6 @@ 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 "—"),
|
||||
|
|
@ -835,18 +670,14 @@ with tab_fundlab:
|
|||
})
|
||||
st.dataframe(pd.DataFrame(_tbl), width="stretch")
|
||||
st.caption(
|
||||
"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.")
|
||||
"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.")
|
||||
|
||||
# --- return-driver clusters: k-means on 35-sleeve loading vectors ---
|
||||
with st.expander(
|
||||
|
|
@ -860,11 +691,7 @@ with tab_fundlab:
|
|||
_syms, _V = _cl.loading_matrix()
|
||||
_fr = json.loads((_dc.RESULTS.parent /
|
||||
"factor_results.json").read_text())
|
||||
# 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)
|
||||
_lab = _cl.kmeans(_V, _ck)
|
||||
_sumrows = []
|
||||
for c in range(_ck):
|
||||
idx = [i for i, l in enumerate(_lab) if l == c]
|
||||
|
|
@ -872,7 +699,7 @@ with tab_fundlab:
|
|||
continue
|
||||
med = _np.median(_V[idx], 0)
|
||||
top = _np.argsort(-_np.abs(med))[:4]
|
||||
prof = {_fac.AXES[t]: float(med[t]) for t in top
|
||||
prof = {_fac.DRIVERS[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]
|
||||
|
|
@ -909,7 +736,7 @@ with tab_fundlab:
|
|||
continue
|
||||
med = _np.median(_V[idx], 0)
|
||||
top = _np.argsort(-_np.abs(med))[:4]
|
||||
prof = {_fac.AXES[t]: float(med[t]) for t in top
|
||||
prof = {_fac.DRIVERS[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]
|
||||
|
|
@ -940,14 +767,11 @@ with tab_fundlab:
|
|||
r.pop("_t")
|
||||
st.dataframe(pd.DataFrame(_rows), width="stretch")
|
||||
st.caption(
|
||||
"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 "
|
||||
"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 "
|
||||
"signatures. 'corr port' is shown for reference only - "
|
||||
"high-corr funds are REPLACEMENTS for current holdings, "
|
||||
"not rejections.")
|
||||
|
|
@ -1268,10 +1092,9 @@ with tab_fundlab:
|
|||
if _dr.get("note"):
|
||||
st.markdown("**Holdings cross-check:** " + _dr["note"])
|
||||
st.caption(
|
||||
"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 "
|
||||
"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 "
|
||||
"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,56 +28,6 @@ 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")
|
||||
|
|
@ -100,37 +50,16 @@ 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 sym, f in _panel_paths(root, suffix):
|
||||
for f in sorted(root.glob(f"*-{suffix}.csv")):
|
||||
try:
|
||||
df = _read_csv_clean(f)
|
||||
except Exception:
|
||||
continue
|
||||
if col in df.columns:
|
||||
cols.append(_apply_corrections(sym, suffix, df[col]))
|
||||
syms.append(sym)
|
||||
cols.append(df[col])
|
||||
syms.append(f.name[: -len(f"-{suffix}.csv")])
|
||||
if not cols:
|
||||
return pd.DataFrame()
|
||||
out = pd.concat(cols, axis=1)
|
||||
|
|
@ -167,26 +96,13 @@ 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
|
||||
plus the frozen overrides (namespaced under 'frozen/')."""
|
||||
"""{filename: (mtime_ns, size)} for every csv/json file in the data root."""
|
||||
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
|
||||
|
||||
|
||||
|
|
@ -238,53 +154,14 @@ 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(_path(fname))
|
||||
df = _read_csv_clean(root / fname)
|
||||
except Exception:
|
||||
continue # e.g. a file mid-download
|
||||
if sfx == "history":
|
||||
|
|
@ -293,22 +170,11 @@ 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] = _apply_corrections(sym, sfx, df["Dividends"]) \
|
||||
.fillna(0.0)
|
||||
updates["div"][sym] = df["Dividends"].fillna(0.0)
|
||||
elif sfx == "capitalGain" and "Capital Gains" in df.columns:
|
||||
updates["capg"][sym] = _apply_corrections(sym, sfx, df["Capital Gains"]) \
|
||||
.fillna(0.0)
|
||||
updates["capg"][sym] = 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,253 +933,3 @@ 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 AXES, DRIVERS # noqa: E402
|
||||
from fundlab.factors import DRIVERS # noqa: E402
|
||||
|
||||
|
||||
def log(msg: str) -> None:
|
||||
|
|
@ -50,11 +50,6 @@ 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)
|
||||
|
|
@ -125,7 +120,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 = {AXES[t]: float(med[t]) for t in top
|
||||
prof = {DRIVERS[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]})
|
||||
|
|
@ -145,41 +140,15 @@ 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. 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:
|
||||
# cluster is balanced mixes with no single dominant driver
|
||||
if not prof or max(abs(v) for v in prof.values()) < 0.30:
|
||||
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])
|
||||
|
||||
|
|
@ -213,7 +182,7 @@ def kmeans(V: np.ndarray, k: int, seed: int = 0,
|
|||
|
||||
def run_kmeans(k: int = 30) -> dict:
|
||||
syms, V = loading_matrix()
|
||||
lab = kmeans(emphasized(V, AXES.index("cash")), k)
|
||||
lab = kmeans(V, k)
|
||||
out: dict[int, dict] = {}
|
||||
for c in range(k):
|
||||
idx = [i for i, l in enumerate(lab) if l == c]
|
||||
|
|
@ -221,7 +190,7 @@ def run_kmeans(k: int = 30) -> dict:
|
|||
continue
|
||||
med = np.median(V[idx], axis=0)
|
||||
top = np.argsort(-np.abs(med))[:4]
|
||||
prof = {AXES[t]: float(med[t]) for t in top
|
||||
prof = {DRIVERS[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]}
|
||||
|
|
@ -234,7 +203,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": AXES}))
|
||||
"n": len(syms), "sleeves": DRIVERS}))
|
||||
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
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -22,7 +22,6 @@ 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
|
||||
|
|
@ -50,29 +49,6 @@ 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 —
|
||||
|
|
@ -231,17 +207,9 @@ CANDIDATES: dict[str, list[str]] = {
|
|||
}
|
||||
# share classes: same underlying fund
|
||||
ALIAS = {"pmfkx": "pmaix", "lcrix": "lcorx", "egrsx": "eagmx"}
|
||||
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)
|
||||
FULL_WINDOW = "1990-01-01" # effectively all history
|
||||
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
|
||||
|
|
@ -257,14 +225,13 @@ 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 = excess(returns_panel([fund] + cand_syms, start=start))
|
||||
r = 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 and s not in CASH_SLEEVES}
|
||||
cand = {s: r[s].to_numpy() for s in r.columns if s != fund}
|
||||
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
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -69,19 +69,9 @@ 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", "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)
|
||||
DROP_FROM_REGRESSION = {"vea", "vug", "finux", "bil"}
|
||||
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)
|
||||
|
|
@ -103,7 +93,6 @@ 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:
|
||||
|
|
@ -153,16 +142,11 @@ def _beta_window(y: pd.Series, X: pd.DataFrame, start: str) -> dict | None:
|
|||
}
|
||||
|
||||
|
||||
def factor_screen(sym: str, start: str = None) -> dict | None:
|
||||
if start is None:
|
||||
start = decompose.FULL_WINDOW
|
||||
def factor_screen(sym: str, start: str = "1990-01-01") -> dict | None:
|
||||
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]
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
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
|
||||
|
|
@ -1,444 +0,0 @@
|
|||
"""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 +0,0 @@
|
|||
5847
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
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 ===
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
[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
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
"""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()
|
||||
|
|
@ -1,835 +0,0 @@
|
|||
"""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()
|
||||
|
|
@ -1,400 +0,0 @@
|
|||
"""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
File diff suppressed because one or more lines are too long
|
|
@ -1,4 +1,2 @@
|
|||
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
|
||||
|
|
|
|||
|
|
@ -1,257 +0,0 @@
|
|||
"""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
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
Date,Capital Gains
|
||||
2022-12-28,0.007000
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
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
|
||||
|
File diff suppressed because it is too large
Load Diff
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"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"
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
Date,Capital Gains
|
||||
2021-12-03,0.018000
|
||||
2016-12-07,0.040000
|
||||
2020-12-04,0.145000
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
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
|
||||
|
File diff suppressed because it is too large
Load Diff
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"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 +0,0 @@
|
|||
Date,Dividends,ctime
|
||||
|
|
|
@ -1,503 +0,0 @@
|
|||
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
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"symbol": "adusx",
|
||||
"longName": "?",
|
||||
"freeze_date": "2017-12-18",
|
||||
"created": "2026-08-31",
|
||||
"reason": "yahoo-empty"
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
Date,Capital Gains
|
||||
2021-12-21,1.204000
|
||||
2017-12-19,0.016000
|
||||
2018-12-18,0.414000
|
||||
2020-12-22,0.608000
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
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
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
Date,Open,High,Low,Close,Adj Close,Volume
|
||||
2025-09-23,14.420000,14.420000,14.420000,14.420000,14.420000,0
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"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"
|
||||
}
|
||||
|
|
@ -1,478 +0,0 @@
|
|||
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
|
||||
|
File diff suppressed because it is too large
Load Diff
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"symbol": "afxpx",
|
||||
"longName": "?",
|
||||
"freeze_date": "2018-12-11",
|
||||
"created": "2026-08-31",
|
||||
"reason": "yahoo-empty"
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
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
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
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
|
||||
|
File diff suppressed because it is too large
Load Diff
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"symbol": "agazx",
|
||||
"longName": "Allspring Funds Trust - Allspring Global Long/Short Equity Fund",
|
||||
"freeze_date": "2025-04-07",
|
||||
"created": "2026-08-31",
|
||||
"reason": "yahoo-empty"
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
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
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
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
|
||||
|
File diff suppressed because it is too large
Load Diff
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"symbol": "akrex",
|
||||
"longName": "Akre Focus Retail",
|
||||
"freeze_date": "2025-10-09",
|
||||
"created": "2026-08-31",
|
||||
"reason": "yahoo-empty"
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
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
|
||||
|
File diff suppressed because it is too large
Load Diff
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"symbol": "alasx",
|
||||
"longName": "?",
|
||||
"freeze_date": "2018-04-27",
|
||||
"created": "2026-08-31",
|
||||
"reason": "yahoo-empty"
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
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
|
||||
|
|
|
@ -1,573 +0,0 @@
|
|||
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
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"symbol": "amfzx",
|
||||
"longName": "Investment Managers Series Trust - 361 Managed Futures Strategy Fund",
|
||||
"freeze_date": "2021-04-09",
|
||||
"created": "2026-08-31",
|
||||
"reason": "yahoo-empty"
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
Date,Capital Gains
|
||||
2014-12-19,0.282000
|
||||
2017-12-20,0.015000
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
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
|
||||
|
File diff suppressed because it is too large
Load Diff
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"symbol": "andrx",
|
||||
"longName": "AQR Funds - AQR International Defensive Style Fund",
|
||||
"freeze_date": "2026-05-01",
|
||||
"created": "2026-08-31",
|
||||
"reason": "yahoo-empty"
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
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
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
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
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
Date,Open,High,Low,Close,Adj Close,Volume
|
||||
2025-09-23,8.650000,8.650000,8.650000,8.650000,8.650000,0
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"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"
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
Date,Capital Gains
|
||||
2021-12-07,17.691000
|
||||
2022-12-06,2.947000
|
||||
2024-12-10,11.705000
|
||||
2025-12-09,18.145000
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
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
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
Date,Open,High,Low,Close,Adj Close,Volume
|
||||
2026-07-17,137.520004,137.520004,137.520004,137.520004,137.520004,0
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"symbol": "atezx",
|
||||
"longName": "AB Sustainable Global Thematic Z",
|
||||
"freeze_date": "2026-07-17",
|
||||
"created": "2026-08-31",
|
||||
"reason": "yahoo-empty"
|
||||
}
|
||||
|
|
@ -1,491 +0,0 @@
|
|||
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
|
||||
|
File diff suppressed because it is too large
Load Diff
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"symbol": "atmdx",
|
||||
"longName": "?",
|
||||
"freeze_date": "2018-03-23",
|
||||
"created": "2026-08-31",
|
||||
"reason": "yahoo-empty"
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
Date,Capital Gains
|
||||
2021-12-20,2.743000
|
||||
2016-12-23,0.029000
|
||||
2017-12-22,0.817000
|
||||
2019-12-23,0.331000
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
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
|
||||
|
File diff suppressed because it is too large
Load Diff
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"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"
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
Date,Capital Gains
|
||||
2018-12-17,0.114000
|
||||
2019-12-16,0.036000
|
||||
2021-12-14,1.749000
|
||||
2022-12-13,0.814000
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
Date,Dividends
|
||||
2019-12-16,0.035660
|
||||
2021-12-14,1.749320
|
||||
2022-12-13,0.813930
|
||||
2025-12-15,7.440010
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
Date,Open,High,Low,Close,Adj Close,Volume
|
||||
2026-04-24,9.920400,9.920400,9.920400,9.920400,9.920400,0
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"symbol": "bafmx",
|
||||
"longName": "Brown Advisory Mid-Cap Growth Instl",
|
||||
"freeze_date": "2026-04-24",
|
||||
"created": "2026-08-31",
|
||||
"reason": "yahoo-empty"
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
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
|
||||
|
|
|
@ -1,284 +0,0 @@
|
|||
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
|
||||
|
File diff suppressed because it is too large
Load Diff
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"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"
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
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
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
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
|
||||
|
File diff suppressed because it is too large
Load Diff
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"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"
|
||||
}
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
Date,Dividends,ctime
|
||||
2014-12-02,0.191,2017-08-22
|
||||
|
File diff suppressed because it is too large
Load Diff
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"symbol": "bfslx",
|
||||
"longName": "?",
|
||||
"freeze_date": "2018-03-16",
|
||||
"created": "2026-08-31",
|
||||
"reason": "yahoo-empty"
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
Date,Dividends
|
||||
2017-12-06,0.007000
|
||||
2018-12-06,0.114000
|
||||
2019-12-04,0.724000
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
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
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"symbol": "bgaqx",
|
||||
"longName": "BMO Global Long/Short Equity Fund Class A",
|
||||
"freeze_date": "2020-03-30",
|
||||
"created": "2026-08-31",
|
||||
"reason": "yahoo-empty"
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
Date,Capital Gains
|
||||
2018-12-13,0.203000
|
||||
2024-09-19,1.467000
|
||||
2015-12-17,0.044000
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
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
|
||||
|
File diff suppressed because it is too large
Load Diff
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"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