def test_get_investing(): df1 = xa.get_daily(code="indices/germany-30") df2 = xa.get_daily(code="172") assert (df1.iloc[-2]["close"] == df2.iloc[-2]["close"] ) ## never try -1, today's data is unpredictable df = xa.get_daily(code="/currencies/usd-cny", end="20200307") assert round(df.iloc[-1]["close"], 4) == 6.9321
def test_get_rmb(): df = xa.get_daily(start="20180101", end="2020-03-07", code="USD/CNY") assert len(df) == 528 df = xa.get_daily(code="EUR/CNY", end="20200306") assert round(df.iloc[-1]["close"], 4) == 7.7747 df = xa.get_daily("CNY/EUR", end="20200306", prev=5) assert round(df.iloc[-1]["close"], 3) == round(1 / 7.7747, 3)
def test_cache_mm(): df = xa.get_daily("SH501018", prev=100) l1 = len(df) xa.set_backend(backend="memory") xa.get_daily("SH501018", prev=50) df = xa.get_daily("SH501018", prev=100) l2 = len(df) assert l1 == l2
def test_get_investing(): df1 = xa.get_daily(code="indices/germany-30") df2 = xa.get_daily(code="172") assert (df1.iloc[-2]["close"] == df2.iloc[-2]["close"] ) ## never try -1, today's data is unpredictable df = xa.get_daily(code="/currencies/usd-cny", end="20200307", prev=20) assert round(df.iloc[-1]["close"], 4) == 6.9321 df.v_kline(ucolor="#ffffff", ucolorborder="#ef232a")
def test_cache_mm(): df = xa.get_daily("SH501018", prev=100) l1 = len(df) # xa.set_backend(backend="memory", prefix="pytestm-") xa.get_daily("SH501018", prev=50) df = xa.get_daily("SH501018", prev=100) l2 = len(df) assert l1 == l2 xa.universal.check_cache("SH501018", start="2018/09/01", omit_lines=1)
def test_get_xueqiu(): df = xa.get_daily(start="20200302", end="2020-03-07", code="HK01810") assert round(df.iloc[-1]["close"], 2) == 12.98 df = xa.get_daily(start="2020/03/02", end="20200307", code="PDD") assert round(df.iloc[0]["close"], 2) == 37.51 df = xa.get_daily(start="20200301", end="20200307", code="SZ112517") # note how this test would fail when the bond is matured assert round(df.iloc[0]["close"], 2) == 98 df = xa.get_daily(start="20200222", end="20200301", code="SH501018") assert round(df.iloc[-1]["close"], 3) == 0.965
def get_qdii_t(code, ttdict, tdict, positions=True, percent=False): # predict realtime netvalue for d day, only possible for oil related lof nettt = get_qdii_tt(code, ttdict, positions=positions) t = 0 n = 0 today_str = dt.datetime.now(tz=tz_bj).strftime("%Y%m%d") for k, v in tdict.items(): t += v if infos.get(k): url = infos[k].url else: url = k r = xa.get_rt(url) if percent or (not percent and not future_now.get(k)): c = v / 100 * (1 + r["percent"] / 100) else: print("use close to compare instead of directly percent for %s" % k) funddf = xa.get_daily(future_now[k]) last_line = funddf[funddf["date"] < today_str].iloc[ -1 ] # TODO: check it is indeed date of last_on(today) c = v / 100 * r["current"] / last_line["close"] if r.get("currency") and r.get("currency") != "CNY": c = c * daily_increment(r["currency"] + "/CNY", today_str) n += c n += (100 - t) / 100 nett = n * nettt return nettt, nett
def test_iw(csv_cache): df = xa.get_daily("iw-SZ399006", end="20200226") assert (df[(df["date"] == "2019-04-01") & (df["code"] == "300271.XSHE")].iloc[0].weight == 0.9835) df = xa.universal.get_index_weight_range("SZ399006", start="2018-01-01", end="2020-02-01") assert (df[(df["date"] == "2019-04-01") & (df["code"] == "300271.XSHE")].iloc[0].weight == 0.9835)
def get_nonqdii_t(code, tdict, date=None): if not date: # 今日实时净值 last_value, last_date = get_newest_netvalue("F" + code[2:]) today = dt.datetime.now(tz=tz_bj).replace(tzinfo=None) today_str = today.strftime("%Y-%m-%d") yesterday = last_onday(today) yesterday_str = yesterday.strftime("%Y-%m-%d") last_value, last_date = get_newest_netvalue("F" + code[2:]) if last_date != yesterday_str: raise DateMismatch( code, "%s netvalue has not been updated to yesterday" % code) t = 0 r = 100 for k, v in tdict.items(): if infos.get(k): url = infos[k].url else: url = k aim_current = xa.get_rt(url) delta1 = aim_current["percent"] / 100 currency = aim_current["currency"] ## 关于当日货币换算的部分,1. 当日中间价涨幅 2. 当日汇率市价实时涨幅 3.1+2 哪个更合适待研究 if currency == "JPY": delta2 = daily_increment("100JPY/CNY", today_str, yesterday_str, _check=yesterday_str) # delta2 = xa.get_rt("currencies/jpy-cny")["percent"] / 100 elif currency == "USD": delta2 = daily_increment("USD/CNY", today_str, yesterday_str, _check=yesterday_str) # delta2 = xa.get_rt("currencies/usd-cny")["percent"] / 100 elif currency == "EUR": delta2 = daily_increment("EUR/CNY", today_str, yesterday_str, _check=yesterday_str) elif currency == "CNY": delta2 = 0 else: raise NonAccurate( "%s transformation have not been implemented" % currency) r -= v t += v * (1 + delta1) * delta2 / 100 t += r / 100 return last_value * t # 过去净值同日预测 date 日, date 日一定是交易日 date_str = date.replace("-", "").replace("/", "") funddf = xa.get_daily("F" + code[2:]) last_value = funddf[funddf["date"] < date_str].iloc[-1]["close"] net = last_value * (1 + evaluate_fluctuation(tdict, date_str) / 100) return net
def test_get_ycharts(): # ycharts 可能有时也需要代理了。。。。 d = xa.get_daily(code="yc-companies/DBP", start="20200401", end="20200402") assert d.iloc[0]["close"] == 41.04 d = xa.get_daily( code="yc-companies/DBP/net_asset_value", start="20200401", end="20200402" ) assert d.iloc[0]["close"] == 40.7144 d = xa.get_daily(code="yc-indices/^SPGSCICO", start="20200401", end="20200402") assert d.iloc[0]["close"] == 111.312 d = xa.get_daily( code="yc-indices/^SPGSCICO/total_return_forward_adjusted_price", start="20200401", end="20200402", ) assert d.iloc[0]["close"] == 169.821 assert xa.get_rt("yc-companies/DBO")["currency"] == "USD"
def get_qdii_tt(code, hdict, date=None, positions=True, usecache=True): # predict d-1 netvalue of qdii funds if date is None: today = ( dt.datetime.now(tz=tz_bj) .replace(tzinfo=None) .replace(hour=0, minute=0, second=0, microsecond=0) ) yesterday = last_onday(today) datekey = yesterday.strftime("%Y%m%d") else: datekey = date.replace("/", "").replace("-", "") key = code + datekey if usecache: if key in tt_cache: return tt_cache[key] if positions: current_pos = position_predict(code, hdict, datekey) hdict = scale_dict(hdict.copy(), aim=current_pos * 100) print(current_pos) print(sum([v for _, v in hdict.items()])) if date is None: # 此时预测上个交易日净值 yesterday_str = datekey last_value, last_date = get_newest_netvalue("F" + code[2:]) last_date_obj = dt.datetime.strptime(last_date, "%Y-%m-%d") if last_date_obj < last_onday(yesterday): # 前天净值数据还没更新 raise DateMismatch( code, reason="%s netvalue has not been updated to the day before yesterday" % code, ) elif last_date_obj > last_onday(yesterday): # 昨天数据已出,不需要再预测了 print( "no need to predict t-1 value since it has been out for %s" % code ) return last_value else: yesterday_str = datekey fund_price = xa.get_daily("F" + code[2:]) fund_last = fund_price[fund_price["date"] < date].iloc[-1] # 注意实时更新应用 date=None 传入,否则此处无法保证此数据是前天的而不是大前天的 last_value = fund_last["close"] last_date = fund_last["date"].strftime("%Y-%m-%d") net = last_value * ( 1 + evaluate_fluctuation(hdict, yesterday_str, _check=last_date) / 100 ) tt_cache[key] = net return net
def test_iw(): xa.set_backend(backend="csv", path="./") df = xa.get_daily("iw-399006.XSHE", end="20200226") assert ( df[(df["date"] == "2019-04-01") & (df["code"] == "300271.XSHE")].iloc[0].weight == 0.9835 ) df = xa.universal.get_index_weight_range( "399006.XSHE", start="2018-01-01", end="2020-02-01" ) assert ( df[(df["date"] == "2019-04-01") & (df["code"] == "300271.XSHE")].iloc[0].weight == 0.9835 )
def get_nonqdii_t(code, tdict, date=None): if not date: # 今日实时净值 last_value, last_date = get_newest_netvalue("F" + code[2:]) tz_bj = dt.timezone(dt.timedelta(hours=8)) today = dt.datetime.now(tz=tz_bj) yesterday = last_onday(today) yesterday_str = yesterday.strftime("%Y-%m-%d") last_value, last_date = get_newest_netvalue("F" + code[2:]) if last_date != yesterday_str: raise DateMismatch( "%s netvalue has not been updated to the day before yesterday" % code) t = 0 r = 100 for k, v in tdict.items(): if infos.get(k): url = infos[k].url else: url = k print(url) aim_current = xa.get_rt(url) delta1 = aim_current["percent"] / 100 currency = aim_current["currency"] if currency == "JPY": delta2 = xa.get_rt("currencies/jpy-cny")["percent"] / 100 elif currency == "USD": delta2 = xa.get_rt("currencies/usd-cny")["percent"] / 100 elif currency == "CNY": delta2 = 0 else: raise NonAccurate( "%s transformation have not been implemented" % currency) r -= v t += v * (1 + delta1) * (1 + delta2) / 100 t += r / 100 return last_value * t # 过去净值同日预测 date 日, date 日一定是交易日 date_str = date.replace("-", "").replace("/", "") funddf = xa.get_daily("F" + code[2:]) last_value = funddf[funddf["date"] < date_str].iloc[-1]["close"] net = last_value * (1 + evaluate_fluctuation(tdict, date_str) / 100) return net
def daily_increment(code, date, lastday=None, _check=None): tds = xa.get_daily(code=code, end=date, prev=20) tds = tds[tds["date"] <= date] if _check: _check_obj = dt.datetime.strptime(_check, "%Y-%m-%d") if tds.iloc[-1]["date"] <= _check_obj: # in case data is not up to date # 但是存在日本市场休市时间不一致的情况,估计美股也存在 if next_onday(_check_obj).strftime( "%Y-%m-%d" ) in no_trading_days.get(get_currency(code), []): # 注意有时计价货币无法和市场保持一致,暂时不处理,遇到再说 print("%s is closed that day" % code) else: raise DateMismatch( code, reason="%s has no data newer than %s" % (code, _check) ) if not lastday: ratio = tds.iloc[-1]["close"] / tds.iloc[-2]["close"] else: tds2 = tds[tds["date"] <= lastday] ratio = tds.iloc[-1]["close"] / tds2.iloc[-1]["close"] return ratio
def replace_text(otext, code=None, est_holdings=None, rt_holdings=None): print(otext) dtstr = otext.split(":")[1].split(";")[0] dtobj = dt.datetime.strptime(dtstr, "%Y-%m-%d-%H-%M") now = dt.datetime.now(tz=tz_bj) now = now.replace(tzinfo=None) if now >= dtobj: v = otext.split(">")[0].split(";")[1].split("-")[-3] vdtstr = otext.split(";")[1][:10] # - if not est_holdings: est_holdings = holdings[code[2:]] ## 动态仓位调整切入点 today = now.strftime("%Y-%m-%d") if v == "value1": if not rt_holdings and not holdings.get(code[2:] + "rt"): rt_holdings = holdings["oil_rt"] # 默认石油基金预测 elif not rt_holdings: rt_holdings = holdings[code[2:] + "rt"] # 实时净值 if today == vdtstr: try: _, rtvalue = get_qdii_t(code, est_holdings, rt_holdings) ntext = str(round(rtvalue, 3)) now_value = xa.get_rt(code)["current"] prate = round((now_value / rtvalue - 1) * 100, 1) ntext += f" ({now.strftime('%H:%M')})" if prate > 0: ntext += f'<p style="color: red;display: inline"> [{prate}%]</p>' else: ntext += f'<p style="color: green;display: inline"> [{prate}%]</p>' ntext = (otext.split(">")[0] + ">" + ntext + "<" + otext.split("<")[-1]) except NonAccurate as e: print(e.reason) ntext = otext else: # 新的一天,不再预测实时 # ntext = otext.split(">")[1].split("<")[0] ntext = "<".join(">".join( otext.split(">")[1:]).split("<")[:-1]) elif v == "value2": try: if last_onday(now).strftime("%Y-%m-%d") == vdtstr: ntext = str(round(get_qdii_tt(code, est_holdings), 3)) else: ntext = str( round(get_qdii_tt(code, est_holdings, date=vdtstr), 3)) except NonAccurate as e: print(e.reason) ntext = otext elif v == "value3": # 真实净值 fund_price = xa.get_daily(code="F" + code[2:], end=vdtstr) fund_line = fund_price[fund_price["date"] == vdtstr] if len(fund_line) == 0: value, date = get_newest_netvalue( "F" + code[2:]) # incase get_daily -1 didn't get timely update else: value = fund_line.iloc[0]["close"] date = fund_line.iloc[0]["date"].strftime("%Y-%m-%d") if date != vdtstr: ntext = otext else: ntext = str(value) elif v == "value4": # non qdii 同日 qdii lof 的实时净值 try: if today == vdtstr: if now.hour > 9 and now.hour < 15: v = get_nonqdii_t(code, est_holdings) ntext = str(round(v, 3)) ntext += f" ({now.strftime('%H:%M')})" ntext = (otext.split(">")[0] + ">" + ntext + "<" + otext.split("<")[-1]) else: ntext = otext else: v = get_nonqdii_t(code, est_holdings, date=vdtstr) ntext = str(round(v, 3)) except NonAccurate as e: print(e.reason) ntext = otext elif v == "4c": ntext = f"""<!--update:{next_onday(dtobj).strftime("%Y-%m-%d-%H-%M")};{next_onday(dtobj).strftime("%Y-%m-%d")}-4c--><!--end--> <tr> <td style='text-align:center;' >{dtobj.strftime("%Y-%m-%d")}</td> <td style='text-align:center;' ><!--update:{(dtobj + dt.timedelta(hours=1)).strftime("%Y-%m-%d-%H-%M")};{dtobj.strftime("%Y-%m-%d")}-value1--> <!--end--></td> <td style='text-align:center;' ><!--update:{(dtobj + dt.timedelta(days=1, hours=1)).strftime( "%Y-%m-%d-%H-%M" )};{dtobj.strftime("%Y-%m-%d")}-value2--> <!--end--></td> <td style='text-align:center;' ><!--update:{(dtobj + dt.timedelta(days=1, hours=12)).strftime("%Y-%m-%d-%H-%M")};{dtobj.strftime("%Y-%m-%d")}-value3--> <!--end--></td> </tr> """ elif v == "3c": ntext = f"""<!--update:{next_onday(dtobj).strftime("%Y-%m-%d-%H-%M")};{next_onday(dtobj).strftime("%Y-%m-%d")}-3c--><!--end--> <tr> <td style='text-align:center;' >{dtobj.strftime("%Y-%m-%d")}</td> <td style='text-align:center;' ><!--update:{(dtobj + dt.timedelta(days=1, hours=1)).strftime( "%Y-%m-%d-%H-%M" )};{dtobj.strftime("%Y-%m-%d")}-value2--> <!--end--></td> <td style='text-align:center;' ><!--update:{(dtobj + dt.timedelta(days=1, hours=12)).strftime("%Y-%m-%d-%H-%M")};{dtobj.strftime("%Y-%m-%d")}-value3--> <!--end--></td> </tr> """ elif v == "3crt": ntext = f"""<!--update:{next_onday(dtobj).strftime("%Y-%m-%d-%H-%M")};{next_onday(dtobj).strftime("%Y-%m-%d")}-3crt--><!--end--> <tr> <td style='text-align:center;' >{dtobj.strftime("%Y-%m-%d")}</td> <td style='text-align:center;' ><!--update:{(dtobj + dt.timedelta(hours=1, minutes=30)).strftime( "%Y-%m-%d-%H-%M" )};{dtobj.strftime("%Y-%m-%d")}-value4--> <!--end--></td> <td style='text-align:center;' ><!--update:{next_onday(dtobj).strftime("%Y-%m-%d-%H-%M")};{dtobj.strftime("%Y-%m-%d")}-value3--> <!--end--></td> </tr> """ else: ntext = otext print("replaced as %s" % ntext) return ntext
def test_ttjj_oversea_daily(): df = xa.get_daily("F968054", start="2019-05-01", end="20190606") assert df.iloc[-1]["close"] == 10.18
def test_get_bond_rates(): df = xa.get_daily("B-AA+.3", end="2020-05-17") assert df.iloc[-1]["close"] == 2.7743
def test_get_es(): df = xa.get_daily("ESCI000302", start="20190419", end="2019/04/22") assert round(df.iloc[-1]["settlement"], 2) == 1074.80
def test_get_hzindex(): assert len(xa.get_daily("HZ999002")) > 100
def test_get_gzindex(): df = xa.get_daily("GZB30018", start="20200202", end="20200204") assert round(df.iloc[-1]["close"], 1) == 107.4
def test_get_zzindex(): assert len(xa.get_daily("ZZH30533")) > 100
def test_get_futu(): df = xa.get_daily("fu-03690.HK", start="2021-01-01") assert df.iloc[0]["open"] == 293.4 df = xa.get_daily("fu-BNO.US", start="2021-01-01")
def test_get_ft_daily(): df = xa.get_daily("FT-22065529", start="20190101", end="20200323") assert len(df) == 306 df = xa.get_daily("FT-AUCHAH:SWX:CHF", prev=10, end="20200327") assert round(df.iloc[-1]["close"], 2) == 66.37 xa.get_daily("FTE-DVN:NYQ", prev=10)
def test_get_yahoo_daily(): df = xa.get_daily("YH-CSGOLD.SW", end="20200323") assert round(df.iloc[-1]["close"], 1) == 149.4
def test_set_display(): xa.set_display("notebook") df = xa.get_daily("PDD", prev=30) df._repr_javascript_() xa.set_display() assert getattr(df, "_repre_javascript_", None) is None
def test_get_fund(): df = xa.get_daily(code="F100032") assert round(df[df["date"] == "2020-03-06"].iloc[0]["close"], 3) == 1.036 df = xa.get_daily(code="M002758", start="20200201") assert round(df.iloc[1]["close"], 3) == 1.134
def test_get_fund_pt(): df = xa.get_daily("pt-F100032") assert round(df[df["date"] < "2020-01-01"].iloc[-1]["bond_ratio"], 2) == 0.08
def test_get_sp_daily(): df = xa.get_daily("SP5475707.2", start="20200202", end="20200303") assert round(df.iloc[-1]["close"], 3) == 1349.31 df = xa.get_daily("SP5475707.2", prev=100, end="20200303") assert round(df.iloc[-1]["close"], 3) == 1349.31
def test_get_investng_app(): df = xa.get_daily(code="INA-currencies/usd-cny", end="20200307", prev=30) # 似乎外网链接有问题? assert round(df.iloc[-1]["close"], 4) == 6.9321 assert xa.get_rt("INA-indices/germany-30")["name"] == "德国DAX30指数 (GDAXI)"
def test_get_bb_daily(proxy): df = xa.get_daily("BB-FGERBIU:ID", prev=10)