Exemple #1
0
def test_mfundinfo():
    zogqb.bcmkset(xa.cashinfo())
    assert round(zogqb.total_annualized_returns('2018-08-01'), 3) == 0.036
    with pytest.raises(FundTypeError) as excinfo:
        xa.fundinfo("001211")
    assert str(excinfo.value
               ) == "This code seems to be a mfund, use mfundinfo instead"
Exemple #2
0
def test_customize_fee():
    df = pd.DataFrame(
        {"date": ["2020-05-28", "2020-06-01"], "519732": [500.005, -0.505]}
    )
    df["date"] = pd.to_datetime(df["date"])
    dqzf = xa.trade(xa.fundinfo("519732"), df)
    assert dqzf.dailyreport("2020-06-02")["基金分红与赎回"].iloc[0] == 2.22
    assert dqzf.dailyreport("2020-05-31")["持有份额"].iloc[0] == 116.5
    # issue 59
    df = pd.DataFrame(
        {"date": ["2020-05-28", "2020-06-01"], "519732": [10000.005, -0.505]}
    )
    df["date"] = pd.to_datetime(df["date"])
    dqzf = xa.trade(xa.fundinfo("519732"), df)
    assert round(dqzf.dailyreport("2020-05-28").iloc[0]["基金现值"], 0) == 10000.0
Exemple #3
0
def test_fund_update():
    zghl = xa.fundinfo("164906", **ioconf)
    len1 = len(zghl.price)
    delete_csvlines(path=ioconf["path"] + "164906.csv", lines=83)
    zghl = xa.fundinfo("164906", **ioconf)
    len2 = len(zghl.price)
    assert len1 == len2
    jxzl = xa.mfundinfo("002758", **ioconf)
    netvalue = jxzl.price.iloc[-1]["netvalue"]
    len3 = len(jxzl.price)
    delete_csvlines(path=ioconf["path"] + "002758.csv", lines=9)
    jxzl = xa.mfundinfo("002758", **ioconf)
    netvalue2 = jxzl.price.iloc[-1]["netvalue"]
    len4 = len(jxzl.price)
    assert len3 == len4
    assert round(netvalue, 4) == round(netvalue2, 4)
Exemple #4
0
def test_fund():
    assert hs300.round_label == 1
    assert hs300.name == "景顺长城沪深300指数增强"  ## "景顺长城沪深300增强", 蜜汁改名。。。
    assert hs300.fenhongdate[1] == pd.Timestamp("2017-08-15")
    assert hs300.get_holdings(2019, 4).iloc[0]["name"] == "中国平安"
    assert (
        float(hs300.special[hs300.special["date"] == "2017-08-04"]["comment"]) == 0.19
    )
    hs300.rate = 0.12
    hs300.segment = [[0, 7], [7, 365], [365, 730], [730]]
    with pytest.raises(Exception) as excinfo:
        hs300.shuhui(
            100,
            "2014-01-04",
            [[pd.Timestamp("2014-01-03"), 200], [pd.Timestamp("2017-01-03"), 200]],
        )
    assert str(excinfo.value) == "One cannot move share before the lastest operation"
    assert (
        hs300.shuhui(
            320,
            "2018-01-01",
            [[pd.Timestamp("2011-01-03"), 200], [pd.Timestamp("2017-12-29"), 200]],
        )[1]
        == 685.72
    )
    assert hs300.shengou(200, "2018-07-20")[2] == 105.24
    with pytest.raises(FundTypeError) as excinfo:
        xa.mfundinfo("000311")
    assert str(excinfo.value) == "This code seems to be a fund, use fundinfo instead"
    hs300.info()
    dax = xa.fundinfo("510030")  # test empty shuhuifei and shengoufei case
    assert dax.feeinfo == ["小于7天", "1.50%", "大于等于7天", "0.00%"]
Exemple #5
0
def index(request):
    code = request.GET.get('code')
    try:
        zzcm = xa.fundinfo(code)
    except Exception:
        return JsonResponse({'code': 500, 'msg': '基金代码错误'})
    # 分红再投入
    zzcm.dividend_label = 1
    orgin_start = request.GET.get('start')
    orgin_end = request.GET.get('end')
    amount = request.GET.get('amount')
    freq = request.GET.get('freq')
    offset = request.GET.get('offset')
    start = datetime.strptime(orgin_start, '%Y-%m-%d')
    end = datetime.strptime(orgin_end, '%Y-%m-%d')
    new_start = start - timedelta(days=100)
    new_end = end + timedelta(days=100)
    rng = pd.date_range(new_start, new_end, freq=freq) + \
        pd.DateOffset(days=int(offset))
    rng = rng[rng <= end]  # 过滤超出范围的日期
    rng = rng[rng >= start]
    price = zzcm.price[(zzcm.price["date"] >= start)
                       & (zzcm.price["date"] <= end)]
    # 有价格的起始日期
    priceStart = price.iloc[0].date
    priceEnd = price.iloc[-1].date
    # 需要判断rng的时间是否合法,是否都在有价格的区间
    datel = []
    isSmall = False
    for date in rng:
        if date >= priceStart and date <= priceEnd:
            datel.append(date)
        elif date < priceStart:
            isSmall = True
    if isSmall:
        try:
            thing_index = datel.index(priceStart)
        except ValueError:
            thing_index = -1
        if thing_index == -1:
            datel.insert(0, priceStart)
    status = pd.DataFrame(data={
        "date": datel,
        zzcm.code: [float(amount)] * len(datel)
    })
    cm_t3 = xa.trade(zzcm, status)
    dailyreport = cm_t3.dailyreport(orgin_end)
    cftable = cm_t3.cftable
    del cftable['share']
    cftable['date'] = cftable['date'].astype('datetime64[ns]')
    cash_flow = cftable.values.tolist()
    fv = dailyreport['基金现值'][0]
    cash_flow.append([end, fv])
    rate = xirr(cash_flow)

    return JsonResponse({
        'code': 0,
        'xirr': rate,
        'dailyreport': dailyreport.to_dict()
    })
Exemple #6
0
def f(trade_info, code):  #某个基金的交易信息
    fundinfo = xa.fundinfo(code)

    buy, sell = 0, 0
    fe = 0
    for index, row in trade_info.iterrows():
        date = row.get('date')
        dwjz = get_jz(code, date)

        v = row.get(code)
        if v > 0:
            # print('申购费率:{}'.format(fundinfo.rate))
            buy += v
            # buy += v
        else:
            sell += v

        fe += v * (1 - fundinfo.rate / 100.) / dwjz  #份额变动 要考虑申购费率

    last_trade_day = datetime.strftime(datetime.now() - timedelta(1),
                                       '%Y-%m-%d')
    dqjz = get_jz(code, last_trade_day)  #api接口到24点以后才更新净值,所以做多只能取到昨日净值
    # print(dqjz)
    dqye = fe * dqjz + sell  #包括当前持有金额以及已卖出金额之和
    syl = dqye / buy - 1  #收益率
    # print('{},{}--份额:{},昨日净值{},当前余额{},总投入{},收益率{},盈利{}'.format(fundinfo.name,last_trade_day,fe,dqjz,dqye,buy,syl,dqye-buy))
    print('{},当前余额{:.2f},总投入{:.2f},收益率{:.3f},盈利{:.2f}'.format(
        fundinfo.name, dqye, buy, syl, dqye - buy))
    return (fe, dqjz, dqye, buy, syl)
Exemple #7
0
def test_weekly_price():
    # see https://github.com/refraction-ray/xalpha/issues/27
    ryjh = xa.fundinfo("008969")
    bah = xa.policy.buyandhold(ryjh, start="2019-01-01", totmoney=100000)
    bah.sellout("2020-05-12")  # 选定日期全部卖出
    jshstrade = xa.trade(ryjh, bah.status)
    assert round(jshstrade.xirrrate("2020-05-01", startdate="2020-02-01"), 1) == 0.2
Exemple #8
0
def test_csvio():
    hs300 = xa.fundinfo('000311', **ioconf)
    len1 = len(hs300.price)
    hs300 = xa.fundinfo('000311', **ioconf)
    len2 = len(hs300.price)
    delete_csvlines(path=ioconf['path'] + '000311.csv')
    hs300 = xa.fundinfo('000311', **ioconf)
    len3 = len(hs300.price)
    assert len1 == len2
    assert len1 == len3
    delete_csvlines(path=ioconf['path'] + '001211.csv')
    zogqb2 = xa.mfundinfo('001211', **ioconf)
    assert round(zogqb.price.iloc[-1].netvalue,
                 5) == round(zogqb2.price.iloc[-1].netvalue, 5)
    delete_csvlines(path=ioconf['path'] + '0000827.csv')
    zzhb2 = xa.indexinfo('0000827', **ioconf)
    assert len(zzhb2.price) == len(zzhb.price)
Exemple #9
0
def test_fund_update():
    zghl = xa.fundinfo(
        "501029", **ioconf)  # 164906 maybe possible remainning issue for qdii?
    len1 = len(zghl.price)
    delete_csvlines(path=ioconf["path"] + "501029.csv", lines=83)
    zghl = xa.fundinfo("501029", **ioconf)
    len2 = len(zghl.price)
    assert len1 == len2
    jxzl = xa.mfundinfo("002758", **ioconf)
    netvalue = jxzl.price.iloc[-1]["netvalue"]
    len3 = len(jxzl.price)
    delete_csvlines(path=ioconf["path"] + "002758.csv", lines=9)
    jxzl = xa.mfundinfo("002758", **ioconf)
    netvalue2 = jxzl.price.iloc[-1]["netvalue"]
    len4 = len(jxzl.price)
    assert len3 == len4
    assert round(netvalue, 4) == round(netvalue2, 4)
Exemple #10
0
def test_fund_holdings():
    f = xa.fundinfo("F519732")
    df = f.get_stock_holdings(2020, 2)
    assert df.iloc[0]["code"] == "300413"
    d = f.get_industry_holdings(2020, 2)
    assert d["交通运输"] == 5.48
    d = f.get_portfolio_holdings("20180101")
    assert d["stock_ratio"] == 68.62
    df = f.get_bond_holdings(2020, 2)
    assert df.iloc[0]["code"] == "190307"
    assert f.which_industry() == "宽基基金"
Exemple #11
0
def test_fund_update():
    zghl = xa.fundinfo(
        "501029", **ioconf)  # 164906 maybe possible remainning issue for qdii?
    len1 = len(zghl.price)
    delete_csvlines(path=ioconf["path"] + "501029.csv", lines=83)
    zghl = xa.fundinfo("501029", **ioconf)
    len2 = len(zghl.price)
    assert (len1 == len2) or (len1 - len2 == -1)  # similar fix up
    jxzl = xa.mfundinfo("002758", **ioconf)
    netvalue = jxzl.price.iloc[-1]["netvalue"]
    len3 = len(jxzl.price)
    delete_csvlines(path=ioconf["path"] + "002758.csv", lines=9)
    jxzl = xa.mfundinfo("002758", **ioconf)
    netvaluel = [
        round(jxzl.price.iloc[-1]["netvalue"], 4),
        round(jxzl.price.iloc[-2]["netvalue"], 4),
    ]
    len4 = len(jxzl.price)
    assert (len3 == len4) or (len3 - len4 == -1)
    assert round(netvalue, 4) in netvaluel  ##天天基金的总量 API 更新越来越慢了。。。
Exemple #12
0
def test_csvio():
    hs300 = xa.fundinfo("000311", **ioconf)
    len1 = len(hs300.price)
    hs300 = xa.fundinfo("000311", **ioconf)
    len2 = len(hs300.price)
    delete_csvlines(path=ioconf["path"] + "000311.csv")
    hs300 = xa.fundinfo("000311", **ioconf)
    len3 = len(hs300.price)
    assert (len1 == len2) or (len1 - len2 == -1)  # temp fixup
    # there may be time lag for update of .js API, i.e. 天天基金的该 API 不一定能保证更新昨天的净值,即使不是 QDII
    assert (len1 == len3) or (len1 - len3 == -1)
    delete_csvlines(path=ioconf["path"] + "001211.csv")
    zogqb2 = xa.mfundinfo("001211", **ioconf)
    assert round(zogqb.price.iloc[-1].netvalue, 5) in [
        round(zogqb2.price.iloc[-1].netvalue, 5),
        round(zogqb2.price.iloc[-2].netvalue, 5),
    ]
    delete_csvlines(path=ioconf["path"] + "0000827.csv")
    zzhb2 = xa.indexinfo("0000827", **ioconf)
    assert (len(zzhb2.price) == len(
        zzhb.price)) or ((len(zzhb2.price) - len(zzhb.price)) == 1)
Exemple #13
0
def get_jz(code, date):
    fundinfo = xa.fundinfo(code)
    df = fundinfo.price
    # print(df)

    #获取某一日期净值 如果没有则返回最后一个交易日净值
    if df[df['date'] == date].empty:
        dwjz = df.tail(1)['netvalue']
    else:
        dwjz = df[df['date'] == date]['netvalue']

    for index in dwjz.index:
        # print('{},date:{}单位净值为:{}'.format(fundinfo.name,date,dwjz.get(index)))
        return dwjz.get(index)
Exemple #14
0
    def get_fund_history(self):
        '''下载历史数据
        '''
        now = datetime.datetime.now()
        fund_day_start = now + datetime.timedelta(days=-60)
        fund_day_start = fund_day_start.strftime('%Y-%m-%d')

        # 获取数据
        groups = []
        for fund_code in tqdm(self.load(self.SELECT_FUND_LIST_CODE_FILE)):
            try:
                fund_data = xa.fundinfo(fund_code, fetch=False, save=False)
                fund_data.price.reset_index(drop=True, inplace=True)
                fund_data.rsi(30)
                fund_data = fund_data.price
                fund_data.loc[:, "code"] = fund_code
                fund_data = fund_data.loc[fund_data["date"] >= fund_day_start]
                group = fund_data
                group.sort_values("date", inplace=True)
                group.loc[:, "netvalue"] = (group["netvalue"] - group["netvalue"].shift(periods=1)) / group[
                    "netvalue"].shift(periods=1)
                group.dropna(axis=0, inplace=True)
                group.loc[:, 'MA3'] = group["netvalue"].rolling(window=3).mean()
                group.sort_values('date', ascending=False, inplace=True)
                down_count = 0
                for ele in group["MA3"]:
                    if ele < 0:
                        down_count += 1
                    else:
                        break
                groups.append(
                    (fund_code, down_count, group.loc[group.index[0], "MA3"], group.loc[group.index[0], "RSI30"]))
            except Exception as e:
                continue
        fund_history = pd.DataFrame(groups, columns=['code', 'down_count', 'MA3', 'RSI30'])
        fund_history.sort_values("down_count", ascending=False, inplace=True)
        fund_em_fund_name_df = task.load(task.ALL_MARKET_FUND_INFO_FILE)
        fund_history = fund_history.merge(fund_em_fund_name_df, left_on='code', right_on='基金代码')
        fund_history = fund_history.loc[:, ['基金代码', '基金简称', '基金类型', 'down_count', 'MA3', 'RSI30']]
        fund_history = fund_history.loc[
            (~fund_history['基金类型'].isin(["债券型", '定开债券'])) & (~fund_history['基金简称'].str.contains("债|年|月|量化"))]
        joblib.dump(fund_history, self.FUND_HISTORY_DATA_FILE)
        return self
Exemple #15
0
def get_year_rate(code):
    last_trade_day = datetime.strftime(datetime.now() - timedelta(1),
                                       '%Y-%m-%d')
    first_day_of_year = '2020-01-02'
    fake_buy = 10000  #假设买入10000元
    b_jz = get_jz(code, first_day_of_year)
    e_jz = get_jz(code, last_trade_day)

    buy_fe = fake_buy / b_jz

    current_money = e_jz * buy_fe

    fundinfo = xa.fundinfo(code)
    #考虑分红情况
    fenghong = get_fenhong(code)
    fenghong_zonge = fenghong * buy_fe
    add = (fenghong_zonge + current_money - fake_buy) / fake_buy
    # print('{},{},add={}',b_jz,e_jz,add)

    return add
Exemple #16
0
def cal_fenhong(code):
    fundinfo = xa.fundinfo(code)

    total_fenhong = 0
    # print(fundinfo.fenhongdate)
    if (fundinfo.fenhongdate):
        s = fundinfo.special
        dates = s[s.date > np.datetime64('2020-01-01 00:00:00')]['date']  #
        fenhongs = s[s.date > np.datetime64('2020-01-01 00:00:00')]['comment']
        # print(tmp.date)

        for index, date in dates.items():
            # print(type(date))
            # print(str(date)[:10])
            fener = get_fener(date, code)  #计算分红日持有份额
            fenhong_per_fener = fenhongs[index]  #分红日每一份额分红金额

            total_fenhong += fenhong_per_fener * fener

    print('总计分红{}'.format(total_fenhong))
    return total_fenhong
Exemple #17
0
def get_fenhong(code):
    fundinfo = xa.fundinfo(code)
    # print(fundinfo.fenhongdate)
    if (fundinfo.fenhongdate):
        # print(fundinfo.special.loc[])
        s = fundinfo.special
        # print(s.dtypes)
        # print(s[s['date']])
        tmp = s[s.date > np.datetime64('2020-01-01 00:00:00')]
        # print(tmp)

        comment = tmp['comment']
        fenhong = comment.sum()
        print('分红总额为{}'.format(fenhong))
        for _, value in comment.items():
            print(value)

        return fenhong
    else:
        print('分红总额为{}'.format(0))
        return 0
Exemple #18
0
def fake_trade_300(fake_code):
    read = xa.record("./tests/fund_2020.csv", skiprows=1)
    jjcode_list = list(read.status.columns.values)[1:]  #持有的全部基金列表
    t_buy, t_get = 0, 0  #总计买入,总计剩余(包括当前剩余及赎回)
    for code in jjcode_list:
        trade_info = read.status.loc[:, ['date', code]]
        # print(trade_info)

        buy, sell = 0, 0
        fe = 0
        fundinfo = xa.fundinfo(fake_code)
        shengoufeilv = fundinfo.rate / 100.

        for index, row in trade_info.iterrows():
            date = row.get('date')
            dwjz = get_jz(fake_code, date)  #假设买的全是hs300

            v = row.get(code)
            if v > 0:
                buy += v
            else:
                sell += v

            fe += v * (1 - shengoufeilv) / dwjz  #份额变动

        last_trade_day = datetime.strftime(datetime.now() - timedelta(1),
                                           '%Y-%m-%d')
        dqjz = get_jz(fake_code, last_trade_day)
        # print(dqjz)
        dqye = fe * dqjz + sell  #包括当前持有金额以及已卖出金额之和
        syl = dqye / buy - 1  #收益率
        # print('{},{}--份额:{},昨日净值{},当前余额{},总投入{},收益率{},盈利{}'.format(fundinfo.name,last_trade_day,fe,dqjz,dqye,buy,syl,dqye-buy))
        print('{},当前余额{},总投入{},收益率{},盈利{}'.format(fake_code, dqye, buy, syl,
                                                  dqye - buy))

        t_buy += buy
        t_get += dqye
    print('假设全部买入{},总投入:{},总回报:{},整体收益率:{:.3f},盈利{}\n'.format(
        fake_code, t_buy, t_get, t_get / t_buy - 1, t_get - t_buy))
Exemple #19
0
def get_fener(deadline_date, code):
    read = xa.record("./tests/fund_2020.csv", skiprows=1)
    trade_info = read.status.loc[:, ['date', code]]
    trade_info = trade_info[trade_info.date < np.datetime64(deadline_date)]
    # print(trade_info)

    fundinfo = xa.fundinfo(code)

    #计算份额变动
    fe = 0
    for _, row in trade_info.iterrows():
        date = row.get('date')
        dwjz = get_jz(code, date)

        v = row.get(code)  #买入或者卖出金额
        if v > 0:
            # print('申购费率:{}'.format(fundinfo.rate))
            fe += v * (1 - fundinfo.rate / 100.) / dwjz
        else:
            fe += v / dwjz  #这里没有考虑赎回的费率 注意这里不是减法 卖出的话v为负值

    print('截止{}持有份额{}'.format(deadline_date, fe))
    return fe
Exemple #20
0
import sys

sys.path.insert(0, "../")
import xalpha as xa
import pytest
import pandas as pd

path = 'demo.csv'
path1 = 'demo1.csv'
cm = xa.fundinfo('164818')
statb = xa.record(path).status
statl = xa.record(path1, format="list").status
cm_t = xa.trade(cm, statb)
ioconf = {'save': True, 'fetch': True, 'path': 'pytest', 'form': 'csv'}


def test_trade():
    assert cm_t.cftable.loc[2, 'share'] == -129.14
    assert round(cm_t.xirrrate('2018-03-03'), 3) == -0.24
    assert cm_t.dailyreport('2018-07-29').iloc[0]['单位成本'] == 1.346
    cm_t.v_tradecost('2018-08-01')
    cm_t.v_totvalue('2018-07-31')
    cm_t.v_tradevolume(freq='M')


def test_mul():
    with pytest.raises(Exception) as excinfo:
        cm_m = xa.mulfix(cm_t, totmoney=200)
    assert str(excinfo.value) == 'You cannot sell first when you never buy'
    with pytest.raises(Exception) as excinfo:
        cm_m = xa.mulfix(cm_t, totmoney=300)
Exemple #21
0
import sys

sys.path.insert(0, "../")
import xalpha as xa
from xalpha.exceptions import FundTypeError
import pandas as pd
import pytest

ioconf = {"save": True, "fetch": True, "path": "pytest", "form": "csv"}
ca = xa.cashinfo(interest=0.0002, start="2015-01-01")
zzhb = xa.indexinfo("0000827", **ioconf)
hs300 = xa.fundinfo("000311")
zogqb = xa.mfundinfo("001211", **ioconf)


def test_fundreport():
    # somehow fragile, to be checked
    r = xa.FundReport("000827")
    assert r.get_report()[0][:2] == "广发"
    assert r.analyse_report(1)["bank"][:2] == "兴业"
    assert r.show_report_list(type_=0)[0]["FUNDCODE"] == "000827"
    assert r.get_report(id_="AN202003171376532533")[0][:2] == "广发"


def test_cash():
    assert (
        round(ca.price[ca.price["date"] == "2018-01-02"].iloc[0].netvalue, 4) == 1.2453
    )
    assert ca.code == "mf"
    date, value, share = ca.shuhui(
        300, "2018-01-01", [[pd.Timestamp("2017-01-03"), 200]]
Exemple #22
0
import sys

sys.path.insert(0, "../")
import xalpha as xa
import pytest
import pandas as pd

path = "demo.csv"
path1 = "demo1.csv"
cm = xa.fundinfo("164818")
statb = xa.record(path).status
statl = xa.record(path1, format="list").status
cm_t = xa.trade(cm, statb)
ioconf = {"save": True, "fetch": True, "path": "pytest", "form": "csv"}


def test_trade():
    assert cm_t.cftable.loc[2, "share"] == -129.14
    assert round(cm_t.xirrrate("2018-03-03"), 3) == -0.24
    assert cm_t.dailyreport("2018-07-29").iloc[0]["单位成本"] == 1.346
    cm_t.v_tradecost("2018-08-01")
    cm_t.v_totvalue("2018-07-31")
    cm_t.v_tradevolume(freq="M")


def test_mul():
    with pytest.raises(Exception) as excinfo:
        cm_m = xa.mulfix(cm_t, totmoney=200)
    assert str(excinfo.value) == "You cannot sell first when you never buy"
    with pytest.raises(Exception) as excinfo:
        cm_m = xa.mulfix(cm_t, totmoney=300)
Exemple #23
0
import sys

sys.path.insert(0, "../")
import xalpha as xa
from xalpha.exceptions import FundTypeError
import pandas as pd
import pytest

ioconf = {'save': True, 'fetch': True, 'path': 'pytest', 'form': 'csv'}
ca = xa.cashinfo(interest=0.0002, start='2015-01-01')
zzhb = xa.indexinfo('0000827', **ioconf)
hs300 = xa.fundinfo('000311')
zogqb = xa.mfundinfo('001211', **ioconf)


def test_cash():
    assert round(ca.price[ca.price['date'] == '2018-01-02'].iloc[0].netvalue,
                 4) == 1.2453
    assert ca.code == 'mf'
    date, value, share = ca.shuhui(300, '2018-01-01',
                                   [[pd.Timestamp('2017-01-03'), 200]])
    assert date == pd.Timestamp('2018-01-02')
    assert value == 249.06
    assert share == -200
    ca.bcmkset(ca)
    assert ca.alpha() == 0
    assert round(ca.total_annualized_returns('2018-01-01'), 4) == 0.0757


def test_index():
    assert round(