예제 #1
0
def top_stocks(field, date, frequency="1d", count=5, market="cn"):
    """获取雪球舆情数据

    :param field: 如 'new_comments', 'total_comments', 'new_followers',
                 'total_followers', 'sell_actions', 'buy_actions'
    :param date: 如 '2015-05-21', 必须在2015年4月23日之后
    :param frequency: 如 '1d', '1w', '1M' (Default value = "1d")
    :param count: 如 5, 10, 100 (Default value = 5)
    :param market: 地区代码, 如 'cn' (Default value = "cn")
    :returns: 如果有数据,返回一个DataFrame,否则返回None

    """
    field = ensure_string(field, "field")
    frequency = ensure_string(frequency, "frequency")
    check_items_in_container([field], FIELDS, "field")
    check_items_in_container([frequency], {"1d", "1w", "1M"}, "frequency")
    d = {"1d": "d", "1M": "m", "1w": "w"}
    frequency = d[frequency]
    date = ensure_date_int(date)
    if date < 20150423 or date > ensure_date_int(datetime.datetime.today()):
        raise ValueError("date out of range, start_date "
                         "cannot be earlier than 2015-04-23")
    data = get_client().execute("xueqiu.top_stocks", field, date, frequency,
                                count, market)

    if not data:
        return
    df = pd.DataFrame(data)
    df = df[["order_book_id", field]]
    return df
예제 #2
0
def get_capital_flow_tickbar(order_book_id, start_date, end_date, fields,
                             market):
    ensure_string(order_book_id, "order_book_id")
    start_date, end_date = ensure_date_range(start_date, end_date,
                                             datetime.timedelta(days=3))
    history_permission_denied = realtime_permission_denied = False
    try:
        data = get_client().execute("get_capital_flow_tickbar",
                                    order_book_id,
                                    start_date,
                                    end_date,
                                    fields,
                                    market=market)
    except PermissionDenied:
        data = []
        history_permission_denied = True
    today = today_int()

    if data:
        data = [(obid, {k: np.frombuffer(*v)
                        for k, v in d.items()}) for obid, d in data]
        df_list = []
        for obid, d in data:
            df = pd.DataFrame(d)
            df_list.append(df)

        df = pd.concat(df_list)  # type: pd.DataFrame
        df["datetime"] = int17_to_datetime_v(df["datetime"].values)
        history_latest_date = date_to_int8(df.iloc[-1]["datetime"])
        df.set_index("datetime", inplace=True)
    else:
        df = None
        history_latest_date = date_to_int8(
            get_previous_trading_date(today, market=market))

    if history_latest_date >= end_date or start_date > today or history_latest_date >= today:
        return df

    try:
        live_df = get_today_capital_flow_tick(order_book_id,
                                              today,
                                              market=market)
    except PermissionDenied:
        live_df = None
        realtime_permission_denied = True
    except MarketNotSupportError:
        live_df = None

    if history_permission_denied and realtime_permission_denied:
        raise PermissionDenied("get_capital_flow_tick")

    if live_df is None:
        return df
    if df is None:
        return live_df
    return pd.concat([df, live_df])
예제 #3
0
    def data(order_book_id,
             start_date=None,
             end_date=None,
             frequency="1d",
             fields=None):
        """获取天猫电商销售额数据

        :param order_book_id: 股票名
        :param start_date: 开始日期,默认为结束日期前一个月,  必须在2016年6月30日之后 (Default value = None)
        :param end_date: 结束日期 (Default value = None)
        :param frequency: 如'1d', '1M' (Default value = "1d")
        :param fields: 如'sales' (Default value = None)
        :returns: 返回DataFrame

        """
        order_book_id = ensure_order_book_id(order_book_id)

        if not end_date:
            end_date = datetime.date.today()

        if not start_date:
            start_date = end_date - datetime.timedelta(days=30)

        end_date = to_datetime(end_date)
        start_date = to_datetime(start_date)

        if start_date < datetime.datetime(2016, 6, 30):
            raise ValueError("start_date cannot be earlier than 2016-06-30")

        if start_date > end_date:
            raise ValueError()

        ensure_string(frequency, "frequency")
        check_items_in_container([frequency], {"1d", "1M"}, "frequency")

        if fields is None:
            fields = "sales"
        else:
            fields = ensure_string(fields, "fields")
            check_items_in_container(fields, ["sales"], "fields")
        data = get_client().execute("tmall.data", order_book_id, start_date,
                                    end_date, frequency)
        if not data:
            return
        df = pd.DataFrame(data)
        df = df.set_index("date")
        df.sort_index(inplace=True)
        df.columns = ["sales"]
        return df
예제 #4
0
def get_bond_stru(order_book_id, date=None, market="cn"):
    """获取指定日期公募基金债券持仓券种明细信息

    :param order_book_id: 基金代码 str, 仅支持传入单个基金代码
    :param date: 日期,为空则返回所有时间段的数据 (Default value = None)
    :param market:  (Default value = "cn")
    :returns: DataFrame

    """
    order_book_id = ensure_string(order_book_id)
    order_book_id = ensure_fund(order_book_id, market)
    if date is not None:
        date = to_datetime(date)
        if date > datetime.datetime.today():
            return
        date = ensure_date_int(date)

    data = get_client().execute("fund.get_bond_stru", order_book_id, date, market=market)
    if not data:
        return
    df = pd.DataFrame(data)
    df.set_index(['date'], inplace=True)
    df.sort_index(inplace=True)
    df = df[['order_book_id', 'bond_type', 'weight_nv', 'weight_bond_mv', 'market_value']]
    return df
예제 #5
0
def get_commission_margin(order_book_ids=None,
                          fields=None,
                          hedge_flag="speculation"):
    """获取期货保证金和手续费数据

    :param order_book_ids: 期货合约, 支持 order_book_id 或 order_book_id list,
        若不指定则默认获取所有合约 (Default value = None)
    :param fields: str 或 list, 可选字段有: 'margin_type', 'long_margin_ratio', 'short_margin_ratio',
            'commission_type', 'open_commission_ratio', 'close_commission_ratio',
            'close_commission_today_ratio', 若不指定则默认获取所有字段 (Default value = None)
    :param hedge_flag: str, 账户对冲类型, 可选字段为: 'speculation', 'hedge',
            'arbitrage', 默认为'speculation', 目前仅支持'speculation' (Default value = "speculation")
    :returns: pandas.DataFrame

    """
    if order_book_ids:
        order_book_ids = ensure_list_of_string(order_book_ids)

    if fields is None:
        fields = _FIELDS
    else:
        fields = ensure_list_of_string(fields, "fields")
        check_items_in_container(fields, _FIELDS, "fields")

    hedge_flag = ensure_string(hedge_flag, "hedge_flag")
    if hedge_flag not in ["speculation", "hedge", "arbitrage"]:
        raise ValueError("invalid hedge_flag: {}".format(hedge_flag))

    ret = get_client().execute("futures.get_commission_margin", order_book_ids,
                               fields, hedge_flag)
    return pd.DataFrame(ret)
예제 #6
0
def get_factor_return(
    start_date,
    end_date,
    factors=None,
    universe="whole_market",
    method="implicit",
    industry_mapping=True,
    market="cn",
):
    """获取因子收益率数据

    :param start_date: 开始日期(例如:‘2017-03-03’)
    :param end_date: 结束日期(例如:‘2017-03-20’)
    :param factors: 因子。默认获取全部因子的因子收益率
        当 method 参数取值为'implicit' ,可返回全部因子(风格、行业、市场联动)的隐式因子收益率;
        当 method 参数取值为'explicit' , 只返回风格因子的显式因子收益率。具体因子名称见说明文档 (Default value = None)
    :param universe: 股票池。默认调用全市场收益率。可选沪深300(‘000300.XSHG’)、中证500('000905.XSHG')
        、以及中证800('000906.XSHG') (Default value = "whole_market")
    :param method: 计算方法。默认为'implicit'(隐式因子收益率),可选'explicit'(显式风格因子收益率) (Default value = "implicit")
    :param market: 地区代码, 现在仅支持 'cn' (Default value = "cn")
    :param industry_mapping(bool): 是否按 2014 年后的申万行业分类标 准计算行业收益率.默认为 True.
        若取值为 False,则 2014 年前的行业 收益率按旧行业分类标准计算
    :returns: pd.DataFrame. index 为日期,column 为因子字段名称。

    Usage example::
        # 获取介于2017-03-03 到 2017-03-20到隐式因子收益率数据
        get_factor_return('2017-03-03', '2017-03-20')

    """
    start_date, end_date = ensure_date_range(start_date, end_date)

    if factors:
        factors = ensure_list_of_string(factors)

    method = ensure_string(method)
    if method not in _METHOD_MAPPING:
        raise ValueError(
            "invalid method: {!r}, valid: explicit, implicit".format(method))
    method = _METHOD_MAPPING[method]

    if universe not in _UNIVERSE_MAPPING:
        raise ValueError("invalid universe: {!r}, valid: {}".format(
            universe, list(_UNIVERSE_MAPPING.keys())))
    universe = _UNIVERSE_MAPPING[universe]

    df = get_client().execute("get_factor_return",
                              start_date,
                              end_date,
                              factors,
                              universe,
                              method,
                              market=market,
                              industry_mapping=industry_mapping)
    if not df:
        return None
    df = pd.DataFrame(df)
    # convert to required format.
    df = df.pivot(index="date", columns="factor")[universe]
    df.sort_index(inplace=True)
    return df
예제 #7
0
def get_margin_stocks(date=None,
                      exchange=None,
                      margin_type='stock',
                      market="cn"):
    """获取融资融券信息

    :param date: 查询日期,默认返回今天上一交易日,支持 str, timestamp, datetime 类型
    :param exchange: 交易所信息,默认不填写则返回全部。
                    str类型,默认为 None,返回所有字段。可选字段包括:
                    'XSHE', 'sz' 代表深交所;'XSHG', 'sh' 代表上交所,不区分大小写
                    (Default value = None)
    :param margin_type: 'stock' 代表融券卖出,'cash',代表融资买入,默认为'stock'

    """
    if date:
        date = ensure_date_int(date)
    else:
        date = get_previous_trading_date(datetime.date.today())
        date = date.year * 10000 + date.month * 100 + date.day

    if exchange is None:
        exchange = EXCHANGE_CONTENT
    else:
        exchange = ensure_string(exchange, "exchange")
        if exchange in EXCHANGE_TYPE:
            exchange = EXCHANGE_TYPE[exchange]
        check_items_in_container(exchange, EXCHANGE_CONTENT, "exchange")
        exchange = [exchange]

    margin_type = ensure_string(margin_type, "margin_type")
    check_items_in_container(margin_type, MARGIN_TYPE, "margin_type")

    data = get_client().execute("get_margin_stocks",
                                date,
                                exchange,
                                margin_type,
                                market=market)

    if not data:
        return []
    else:
        return sorted(data)
예제 #8
0
def history(
    order_book_ids,
    start_date="2015-05-21",
    end_date="2016-05-21",
    frequency="1d",
    fields=None,
    market="cn",
):
    """获取雪球历史舆情数据

    :param order_book_ids: 股票代码或代码列表
    :param start_date: 如 '2015-05-21', 必须在2015年4月23日之后 (Default value = "2015-05-21")
    :param end_date: 如 '2016-05-21' (Default value = "2016-05-21")
    :param frequency: 如 '1d' (Default value = "1d")
    :param fields: 如 'new_comments', 'total_comments', 'new_followers',
                 'total_followers', 'sell_actions', 'buy_actions' (Default value = None)
    :param market: 地区代码, 如 'cn' (Default value = "cn")
    :returns: 返回pd.Panel或pd.DataFrame或pd.Series

    """
    order_book_ids = ensure_order_book_ids(order_book_ids, market=market)
    if fields:
        fields = ensure_list_of_string(fields, "fields")
        check_items_in_container(fields, FIELDS, "fields")
    else:
        fields = FIELDS
    frequency = ensure_string(frequency, "frequency")
    check_items_in_container([frequency], {"1d"}, "frequency")
    start_date, end_date = ensure_date_range(start_date, end_date)

    if start_date < 20150423:
        raise ValueError("date out of range, start_date "
                         "cannot be earlier than 2015-04-23")
    data = get_client().execute("xueqiu.history", order_book_ids, start_date,
                                end_date, fields, market)
    if not data:
        return
    df = pd.DataFrame(data)
    df = df.set_index(["date", "order_book_id"])
    df.sort_index(inplace=True)
    pl = df.to_panel()
    if len(pl.minor_axis) == 1:
        pl = pl.minor_xs(pl.minor_axis[0])
    if len(fields) == 1:
        pl = pl[fields[0]]
    return pl
예제 #9
0
def get_industry(industry, source='sws', date=None, market="cn"):
    """获取行业股票列表

    :param industry: 行业名称或代码
    :param source: 分类来源。sws: 申万, citics: 中信, gildata: 聚源
    :param date: 查询日期,默认为当前最新日期
    :param market:  (Default value = "cn")
    :return: 所属目标行业的order_book_id list or None
    """
    industry = ensure_string(industry, "industry")
    source = ensure_string_in(source, ["sws", "citics", "gildata"], "source")
    date = ensure_date_or_today_int(date)

    res = get_client().execute("get_industry",
                               industry,
                               source,
                               date,
                               market=market)
    return sorted(res)
예제 #10
0
def get_irr_sensitivity(order_book_ids, start_date=None, end_date=None, market="cn"):
    """获取基金利率风险敏感性分析数据

    :param order_book_ids: 基金代码(str), 仅支持查询一个基金合约
    :param start_date: 开始日期, 如'2013-01-04'
    :param end_date: 结束日期, 如'2014-01-04';在 start_date 和 end_date 都不指定的情况下,默认为最近6个月
    :param market:  (Default value = "cn")
    :returns: DataFrame

    """
    order_book_ids = ensure_string(order_book_ids)
    start_date, end_date = ensure_date_range(start_date, end_date,delta=relativedelta(months=6))
    result = get_client().execute("fund.get_irr_sensitivity", order_book_ids, start_date, end_date, market=market)
    if not result:
        return

    df = pd.DataFrame(result).set_index(keys=['date'])
    df.sort_index(inplace=True)
    return df
예제 #11
0
def get_industry(industry, source='citics', date=None, market="cn"):
    """获取行业股票列表

    :param industry: 行业名称或代码
    :param source: 分类来源。citics 以及 citics_2019: 中信, gildata: 聚源
    :param date: 查询日期,默认为当前最新日期
    :param market:  (Default value = "cn")
    :return: 所属目标行业的order_book_id list or None
    """

    industry = ensure_string(industry, "industry")
    source = ensure_string_in(source,
                              ["sws", "citics", "gildata", "citics_2019"],
                              "source")
    date = ensure_date_or_today_int(date)

    res = get_client().execute("get_industry",
                               industry,
                               source,
                               date,
                               market=market)

    if not res:
        return res

    if res[-1] == "have_sector_name":
        # have_sector_name 代表 industry传入的是风格版块,产业板块或者上下游产业版块
        from rqdatac.services import basic
        res_list = basic.instruments(res[:-1])
        res = []
        date = to_date_str(date)
        for order_book in res_list:
            if order_book.de_listed_date == "0000-00-00" or order_book.de_listed_date is None:
                order_book.de_listed_date = "2099-12-31"
            if order_book.listed_date <= date <= order_book.de_listed_date:
                res.append(order_book.order_book_id)
    return sorted(res)
예제 #12
0
def get_stock_beta(order_book_ids,
                   start_date,
                   end_date,
                   benchmark="000300.XSHG",
                   market="cn"):
    """获取个股相对于基准的贝塔

    :param order_book_ids: 证券代码(例如:‘600705.XSHG’)
    :param start_date: 开始日期(例如:‘2017-03-03’)
    :param end_date: 结束日期(例如:‘2017-03-20’)
    :param benchmark: 基准指数。默认为沪深300(‘000300.XSHG’)
        可选上证50('000016.XSHG')、中证500('000905.XSHG')、
        中证800('000906.XSHG')以及中证全指('000985.XSHG') (Default value = "000300.XSHG")
    :param market:  (Default value = "cn")
    :returns: pandas.DataFrame,index 为日期,column 为个股的 order_book_id
    """
    order_book_ids = ensure_order_book_ids(order_book_ids)
    start_date, end_date = ensure_date_range(start_date, end_date)

    all_benchmark = ("000300.XSHG", "000016.XSHG", "000905.XSHG",
                     "000906.XSHG", "000985.XSHG")
    benchmark = ensure_string(benchmark, "benchmark")
    check_items_in_container(benchmark, all_benchmark, "benchmark")
    benchmark = benchmark.replace(".", "_")
    df = get_client().execute("get_stock_beta",
                              order_book_ids,
                              start_date,
                              end_date,
                              benchmark,
                              market=market)
    if not df:
        return
    df = pd.DataFrame(df)
    df = df.pivot(index="date", columns="order_book_id",
                  values=benchmark).sort_index()
    return df
예제 #13
0
def current_performance(
        order_book_id, info_date=None, quarter=None, interval="1q", fields=None, market="cn"
):
    """获取A股快报

    :param order_book_id: 股票代码, 如'000001.XSHE'
    :param info_date: 发布日期, 如'20180501', 默认为最近的交易日 (Default value = None)
    :param quarter: 发布季度, 如'2018q1' (Default value = None)
    :param interval: 数据区间, 发布日期, 如'2y', '4q' (Default value = "1q")
    :param fields: str 或 list 类型. 默认为 None, 返回所有字段 (Default value = None)
    :param market: 地区代码, 如'cn' (Default value = "cn")
    :returns: pd.DataFrame

    """
    order_book_id = ensure_order_book_id(order_book_id, market=market)
    end_date = None
    if info_date:
        info_date = ensure_date_int(info_date)
    elif quarter:
        splited = quarter.lower().split("q")
        if len(quarter) != 6 or len(splited) != 2:
            raise ValueError(
                "invalid argument {}: {}, valid parameter: {}".format(
                    "quarter", quarter, "string format like '2016q1'"
                )
            )

        year, quarter = int(splited[0]), int(splited[1])
        if not 1 <= quarter <= 4:
            raise ValueError(
                "invalid argument {}: {}, valid parameter: {}".format(
                    "quarter", quarter, "quarter should be in [1, 4]"
                )
            )
        month, day = QUARTER_DATE_MAP[quarter]
        end_date = ensure_date_int(datetime.datetime(year, month, day))
    else:
        info_date = ensure_date_int(datetime.date.today())
    ensure_string(interval, "interval")
    if interval[-1] not in ("y", "q", "Y", "Q"):
        raise ValueError(
            "invalid argument {}: {}, valid parameter: {}".format(
                "interval", interval, "interval unit should be q(quarter) or y(year)"
            )
        )

    try:
        int(interval[:-1])
    except ValueError:
        raise ValueError(
            "invalid argument {}: {}, valid parameter: {}".format(
                "interval", interval, "string like 4q, 2y"
            )
        )
    interval = interval.lower()

    if fields is not None:
        fields = ensure_list_of_string(fields, "fields")
        check_items_in_container(fields, PERFORMANCE_FIELDS, "fields")
    else:
        fields = PERFORMANCE_FIELDS

    data = get_client().execute(
        "current_performance", order_book_id, info_date, end_date, fields, market=market
    )
    if not data:
        return
    df = pd.DataFrame(data)
    sort_field = "info_date" if info_date else "end_date"
    df.sort_values(by=[sort_field, "mark"], ascending=[False, True], inplace=True)
    df.drop_duplicates(subset="end_date", keep="first", inplace=True)
    num = int(interval[:-1])
    unit = interval[-1]
    if unit == "y":
        latest_month = df.loc[0, "end_date"].month
        df["month"] = df.end_date.apply(lambda x: x.month)
        df = df[df.month == latest_month]
    df.reset_index(drop=True, inplace=True)
    return df.loc[: num - 1, ["end_date", "info_date"] + fields]
예제 #14
0
def get_trading_hours(order_book_id,
                      date=None,
                      expected_fmt="str",
                      frequency="1m",
                      market="cn"):
    """获取合约指定日期交易时间
      :param order_book_id: 合约代码
      :param date: 日期,默认为今天
      :param expected_fmt: 返回格式,默认为str, 也支持datetime.time和datetime.datetime格式
      :param frequency: 频率,默认为1m, 对应米筐分钟线时间段的起始, tick和1m相比区别在于每个交易时间段开盘往前移一分钟
      :param market:  (Default value = "cn")

      :return: trading_hours str or list of datetime.time/datetime.datetime list or None
      """
    date = ensure_date_or_today_int(date)
    if not is_trading_date(date, market):
        warnings.warn(" %d is not a trading date" % date)
        return

    ensure_string(order_book_id, "order_book_id")
    ins = instruments(order_book_id)
    if ins is None:
        return

    ensure_string_in(expected_fmt, ("str", "time", "datetime"), "expected_fmt")
    ensure_string_in(frequency, ("1m", "tick"), "frequency")
    date_str = to_date_str(date)

    if ins.listed_date > date_str:
        return

    if ins.type in (
            "Future", "Option"
    ) and ins.de_listed_date < date_str and ins.de_listed_date != "0000-00-00":
        return

    if ins.type not in (
            "Future", "Option"
    ) and ins.de_listed_date <= date_str and ins.de_listed_date != "0000-00-00":
        return
    if ins.type == "Repo":
        trading_hours = "09:31-11:30,13:01-15:30"
    elif ins.type == "Spot":
        if has_night_trading(date, market):
            trading_hours = "20:01-02:30,09:01-15:30"
        else:
            trading_hours = "09:01-15:30"
    elif ins.type not in ("Future",
                          "Option") or (ins.type == "Option"
                                        and ins.exchange in ("XSHG", "XSHE")):
        trading_hours = "09:31-11:30,13:01-15:00"
    else:
        trading_hours = get_client().execute("get_trading_hours",
                                             ins.underlying_symbol,
                                             date,
                                             market=market)
        if trading_hours is None:
            return
        # 前一天放假或者该品种上市首日没有夜盘
        no_night_trading = (not has_night_trading(date, market)
                            or get_underlying_listed_date(
                                ins.underlying_symbol, ins.type) == date_str)

        if no_night_trading and not trading_hours.startswith("09"):
            trading_hours = trading_hours.split(",", 1)[-1]

    if frequency == "tick":
        trading_hours = ",".join([
            s[:4] + str(int(s[4]) - 1) + s[5:]
            for s in trading_hours.split(",")
        ])

    if expected_fmt != "str":
        trading_hours = [t.split("-", 1) for t in trading_hours.split(",")]
        for i, (start, end) in enumerate(trading_hours):
            trading_hours[i][0] = str_to_dt_time(start)
            trading_hours[i][1] = str_to_dt_time(end)

        if expected_fmt == "datetime":
            td = int8_to_date(date)
            prev_td = get_previous_trading_date(date)
            prev_td_next = prev_td + datetime.timedelta(days=1)

            for i, (start, end) in enumerate(trading_hours):
                if start.hour > 16:
                    start_dt = prev_td
                    end_dt = start_dt if end.hour > 16 else prev_td_next
                else:
                    start_dt = end_dt = td
                trading_hours[i][0] = datetime.datetime.combine(
                    start_dt, start)
                trading_hours[i][1] = datetime.datetime.combine(end_dt, end)

    return trading_hours
예제 #15
0
def get_price(
    order_book_ids,
    start_date=None,
    end_date=None,
    frequency="1d",
    fields=None,
    adjust_type="pre",
    skip_suspended=False,
    expect_df=False,
    market="cn",
    **kwargs
):
    """获取证券的历史数据

    :param order_book_ids: 股票列表
    :param market: 地区代码, 如 'cn' (Default value = "cn")
    :param start_date: 开始日期, 如 '2013-01-04' (Default value = None)
    :param end_date: 结束日期, 如 '2014-01-04' (Default value = None)
    :param frequency: 可选参数, 默认为日线。日线使用 '1d', 分钟线 '1m' (Default value = "1d")
    :param fields: 可选参数。默认为所有字段。 (Default value = None)
    :param adjust_type: 可选参数, 默认为'pre', 返回前复权数据。设置为'none'将返回原始数据,
        'post'返回后复权数据,
        'internal'返回只包含拆分的前复权数据。 (Default value = "pre")
    :param skip_suspended: 可选参数,默认为False;当设置为True时,返回的数据会过滤掉停牌期间,
                    此时order_book_ids只能设置为一只股票 (Default value = False)
    :param expect_df: 返回 MultiIndex DataFrame (Default value = False)
    :returns: 如果仅传入一只股票, 返回一个 pandas.DataFrame
        如果传入多只股票, 则返回一个 pandas.Panel

    """
    if frequency == "tick":
        return get_tick_price(order_book_ids, start_date, end_date, fields, expect_df, market)
    elif frequency.endswith(("d", "m")):
        duration = int(frequency[:-1])
        frequency = frequency[-1]
        assert 1 <= duration <= 240, "frequency should in range [1, 240]"
        if market == "hk" and frequency == "m" and duration not in (1, 5, 15, 30, 60):
            raise ValueError("frequency should be str like 1m, 5m, 15m 30m,or 60m")
    else:
        raise ValueError("frequency should be str like 1d, 1m, 5m or tick")
    if "adjusted" in kwargs:
        adjusted = kwargs.pop("adjusted")
        adjust_type = "pre" if adjusted else "none"

    if kwargs:
        raise ValueError('unknown kwargs: {}'.format(kwargs))

    valid_adjust = ["pre", "post", "none"]
    ensure_string(adjust_type, "adjust_type")
    check_items_in_container(adjust_type, valid_adjust, "adjust_type")
    order_book_ids = ensure_list_of_string(order_book_ids, "order_book_ids")
    if skip_suspended and len(order_book_ids) > 1:
        raise ValueError("only accept one order_book_id or symbol if skip_suspended is True")

    assert isinstance(skip_suspended, bool), "'skip_suspended' should be a bool"
    assert isinstance(expect_df, bool), "'expect_df' should be a bool"

    order_book_ids, stocks, funds, indexes, futures, futures888, spots, options, convertibles, repos = classify_order_book_ids(
        order_book_ids, market
    )
    if not order_book_ids:
        warnings.warn("no valid instrument")
        return
    start_date, end_date = _ensure_date(
        start_date, end_date, stocks, funds, indexes, futures, spots, options, convertibles, repos
    )

    if expect_df:
        from rqdatac.services.detail.get_price_df import get_price_df
        return get_price_df(
            order_book_ids, start_date, end_date, frequency, duration, fields, adjust_type, skip_suspended,
            stocks, funds, indexes, futures, futures888, spots, options, convertibles, repos, market
        )

    if frequency == "d":
        fields, has_dominant_id = _ensure_fields(fields, DAYBAR_FIELDS, stocks, funds, futures, spots, options, convertibles, indexes, repos)
        pf = get_daybar(order_book_ids, start_date, end_date, fields, duration, market)
        if pf is None:
            return
    else:
        fields, has_dominant_id = _ensure_fields(fields, MINBAR_FIELDS, stocks, funds, futures, spots, options, convertibles, indexes, repos)
        history_permission_denied, today_permission_denied = False, False
        try:
            pf = get_minbar(order_book_ids, start_date, end_date, fields, duration, market)
        except (PermissionDenied, MarketNotSupportError):
            pf = None
            history_permission_denied = True
        history_latest_day = 0 if pf is None else date_to_int8(pf.iloc[-1].index[-1])
        if history_latest_day < end_date and end_date >= today_int():
            try:
                today_pf = get_today_minbar(order_book_ids, fields, duration, market)
            except (PermissionDenied, MarketNotSupportError):
                today_pf = None
                today_permission_denied = True
            if today_pf is None:
                today_pf_latest_day = 0
            else:
                today_pf_latest_day = date_to_int8(get_current_trading_date(today_pf.iloc[-1].index[-1]))
            if today_pf_latest_day > history_latest_day and today_pf_latest_day >= start_date:
                if history_latest_day == 0:
                    pf = today_pf
                else:
                    pf = pd.concat([pf, today_pf], axis=1)
        if pf is None:
            if history_permission_denied and today_permission_denied:
                raise PermissionDenied("Not permit to get minbar price ")
            elif history_permission_denied:
                warnings.warn("Not permit to get history minbar price")
            elif today_permission_denied:
                warnings.warn("Not permit to get realtime minbar price")
            return

    result = _adjust_pf(
        pf,
        order_book_ids,
        stocks,
        funds,
        futures888,
        start_date,
        end_date,
        frequency,
        fields,
        has_dominant_id,
        adjust_type,
        skip_suspended,
        market,
    )
    return result
예제 #16
0
def get_contracts(
    underlying,
    option_type=None,
    maturity=None,
    strike=None,
    trading_date=None
):
    """返回符合条件的期权

    :param underlying: 标的合约, 可以填写'M'代表期货品种的字母;也可填写'M1901'这种具体 order_book_id
    :param option_type: 期权类型, 'C'代表认购期权, 'P'代表认沽期权合约, 默认返回全部
    :param maturity: 到期月份, 如'1811'代表期权18年11月到期, 默认返回全部到期月份
    :param strike: 行权价, 向左靠档, 默认返回全部行权价
    :param trading_date: 查询日期, 仅针对50ETF期权行权有效, 默认返回当前全部

    :returns
        返回order_book_id list;如果无符合条件期权则返回空list[]
    """
    underlying = ensure_string(underlying, "underlying").upper()
    instruments_df = all_instruments(type='Option')
    underlying_symbols = instruments_df.underlying_symbol.unique()
    underlying_order_book_ids = instruments_df.underlying_order_book_id.unique()
    if underlying in underlying_symbols:
        instruments_df = instruments_df[instruments_df.underlying_symbol == underlying]
    elif underlying in underlying_order_book_ids:
        instruments_df = instruments_df[instruments_df.underlying_order_book_id == underlying]
    else:
        raise ValueError("Unknown underlying")
    if instruments_df.empty:
        return []

    if instruments_df.iloc[0].underlying_symbol != '510050.XSHG' and trading_date:
        warnings.warn(
            "Underlying symbol is not 510050.XSHG, trading_date ignored"
        )
    elif instruments_df.iloc[0].underlying_symbol == '510050.XSHG' and trading_date:
        instruments_df = all_instruments(type='Option', date=trading_date)
        instruments_df = instruments_df[instruments_df.underlying_symbol == '510050.XSHG']
        if instruments_df.empty:
            return []

    if option_type is not None:
        option_type = ensure_string(option_type, "option_type").upper()
        ensure_string_in(option_type, {'P', 'C'}, "option_type")
        instruments_df = instruments_df[instruments_df.option_type == option_type]

    if maturity is not None:
        maturity = int(maturity)
        month = maturity % 100
        if month not in range(1, 13):
            raise ValueError("Unknown month")
        year = maturity // 100 + 2000
        str_month = str(month)
        if len(str_month) == 1:
            str_month = '0' + str_month
        date_str = str(year) + '-' + str_month
        # instruments_df.set_index(instruments_df.maturity_date, inplace=True)
        # instruments_df = instruments_df.filter(like=date_str, axis=0)
        instruments_df = instruments_df[instruments_df.maturity_date.str.startswith(date_str)]
        if instruments_df.empty:
            return []

    if strike:
        order_book_ids = instruments_df.order_book_id.tolist()
        if instruments_df.iloc[0].underlying_symbol == '510050.XSHG' and trading_date:
            strikes = get_price(order_book_ids, start_date=trading_date, end_date=trading_date, fields='strike_price')
            if strikes.empty:
                return []
            instruments_df.set_index(instruments_df.order_book_id, inplace=True)
            strikes = strikes.T
            instruments_df['strike_price'] = strikes[strikes.columns[0]]
            instruments_df = instruments_df[instruments_df.strike_price.notnull()]
            if instruments_df.empty:
                return []
        l = []
        for date in instruments_df.maturity_date.unique():
            df = instruments_df[instruments_df.maturity_date == date]
            df = df[df.strike_price <= strike]
            if df.empty:
                continue
            df = df[df.strike_price.rank(method='min', ascending=False) == 1]
            l += df.order_book_id.tolist()
        return l
    else:
        return instruments_df.order_book_id.tolist()
예제 #17
0
def get_price(
        order_book_ids,
        start_date=None,
        end_date=None,
        frequency="1d",
        fields=None,
        adjust_type="pre",
        skip_suspended=False,
        expect_df=False,
        market="cn",
        **kwargs
):
    """获取证券的历史数据

    :param order_book_ids: 股票列表
    :param market: 地区代码, 如 'cn' (Default value = "cn")
    :param start_date: 开始日期, 如 '2013-01-04' (Default value = None)
    :param end_date: 结束日期, 如 '2014-01-04' (Default value = None)
    :param frequency: 可选参数, 默认为日线。日线使用 '1d', 分钟线 '1m' (Default value = "1d")
    :param fields: 可选参数。默认为所有字段。 (Default value = None)
    :param adjust_type: 可选参数,默认为‘pre', 返回开盘价,收盘价,最高价,最低价依据get_ex_factor 复权因子(包含分红,拆分),volume依据get_split 复权因子(仅涵盖拆分)计算的前复权数据
            'none'将返回原始数据
            'post'返回开盘价,收盘价,最高价,最低价依据get_ex_factor 复权因子(包含分红,拆分),volume依据get_split 复权因子(仅涵盖拆分)计算的后复权数据
            'pre_volume'返回开盘价,收盘价,最高价,最低价,成交量依据get_ex_factor 复权因子(包含分红,拆分)计算的前复权数据
            'post_volume'返回开盘价,收盘价,最高价,最低价,成交量依据get_ex_factor 复权因子(包含分红,拆分)计算的后复权数据
            'internal'返回只包含拆分的前复权数据。 (Default value = "pre")
    :param skip_suspended: 可选参数,默认为False;当设置为True时,返回的数据会过滤掉停牌期间,
                    此时order_book_ids只能设置为一只股票 (Default value = False)
    :param expect_df: 返回 MultiIndex DataFrame (Default value = False)
    :returns: 如果仅传入一只股票, 返回一个 pandas.DataFrame
        如果传入多只股票, 则返回一个 pandas.Panel

    """
    # tick数据
    if frequency == "tick":
        return get_tick_price(order_book_ids, start_date, end_date, fields, expect_df, market)
    elif frequency.endswith(("d", "m", "w")):
        duration = int(frequency[:-1])
        frequency = frequency[-1]
        assert 1 <= duration <= 240, "frequency should in range [1, 240]"
        if market == "hk" and frequency == "m" and duration not in (1, 5, 15, 30, 60):
            raise ValueError("frequency should be str like 1m, 5m, 15m 30m,or 60m")
        elif frequency == 'w' and duration not in (1,):
            raise ValueError("Weekly frequency should be str '1w'")
    else:
        raise ValueError("frequency should be str like 1d, 1m, 5m or tick")
    # 验证adjust_type
    if "adjusted" in kwargs:
        adjusted = kwargs.pop("adjusted")
        adjust_type = "pre" if adjusted else "none"

    if kwargs:
        raise ValueError('unknown kwargs: {}'.format(kwargs))

    valid_adjust = ["pre", "post", "none", "pre_volume", "post_volume"]
    ensure_string(adjust_type, "adjust_type")
    check_items_in_container(adjust_type, valid_adjust, "adjust_type")
    order_book_ids = ensure_list_of_string(order_book_ids, "order_book_ids")
    if skip_suspended and len(order_book_ids) > 1:
        raise ValueError("only accept one order_book_id or symbol if skip_suspended is True")

    assert isinstance(skip_suspended, bool), "'skip_suspended' should be a bool"
    assert isinstance(expect_df, bool), "'expect_df' should be a bool"

    order_book_ids, stocks, funds, indexes, futures, futures888, spots, options, convertibles, repos = classify_order_book_ids(
        order_book_ids, market
    )
    if not order_book_ids:
        warnings.warn("no valid instrument")
        return
    start_date, end_date = _ensure_date(
        start_date, end_date, stocks, funds, indexes, futures, spots, options, convertibles, repos
    )
    from rqdatac.services.detail.get_price_df import get_price_df, get_week_df
    if frequency != 'w':
        df = get_price_df(
            order_book_ids, start_date, end_date, frequency, duration, fields, adjust_type, skip_suspended,
            stocks, funds, indexes, futures, futures888, spots, options, convertibles, repos, market
        )
        if df is None or expect_df:
            return df
        # 单个合约
        if len(df.index.get_level_values(0).unique()) == 1:
            df.reset_index(level=0, inplace=True, drop=True)
            # df.index.name = None
            if len(df.columns) == 1:
                df = df[df.columns[0]]
            return df
        # 单个字段
        elif len(df.columns) == 1:
            field = df.columns[0]
            df = df.unstack(0)[field]
            # df.index.name = None
            df.columns.name = None
            return df
        raise_for_no_panel(False)
        # 交换index的顺序,以制作panel
        return df.swaplevel().to_panel()
    else:
        if not expect_df:
            raise ValueError(
                "Weekly frequency can only return a DataFrame object, set 'expect_df' to True to resolve this")
        if skip_suspended:
            raise ValueError(
                "Weekly frequency does not support skipping suspended trading days, set 'skip_suspended' to False to resolve this")
        start_date, end_date = _weekly_start_end_date_handler(start_date, end_date)
        if start_date > end_date:
            # 如果*当周没有结束*
            # 或者start date 和 end date 不能涵盖当周所有的交易日,查询该周的数据时返回为空。
            return None
        return get_week_df(order_book_ids, start_date, end_date, fields, adjust_type, market,
                           *(stocks, funds, indexes, futures, futures888, spots, options, convertibles, repos))
예제 #18
0
def get_factor(order_book_ids,
               factor,
               start_date=None,
               end_date=None,
               universe=None,
               expect_df=False,
               **kwargs):
    """获取因子

    :param order_book_ids: 股票代码或代码列表
    :param factor: 如 'total_income'
    :param date: 如 date='2015-01-05', 默认为前一交易日
    :param start_date: 开始日期'2015-01-05', 默认为前一交易日, 最小起始日期为'2000-01-04'
    :param end_date: 结束日期
    :param universe: 股票池,默认为全A股
    :param expect_df: 返回 MultiIndex DataFrame (Default value = False)
    :returns: pd.DataFrame
    """

    order_book_ids = ensure_order_book_ids(order_book_ids, type="CS")
    order_book_ids = list(set(order_book_ids))

    factor = ensure_list_of_string(factor)
    factor = list(OrderedDict.fromkeys(factor))

    if start_date and end_date:
        start_date, end_date = ensure_date_range(start_date, end_date,
                                                 datetime.timedelta(days=15))
        if start_date < 20000104:
            warnings.warn(
                "start_date is earlier than 2000-01-04, adjusted to 2000-01-04"
            )
            start_date = 20000104
    elif start_date:
        raise ValueError("Expect end_date")
    elif end_date:
        raise ValueError("Expect start_date")
    else:
        date = kwargs.pop("date", None)
        date = ensure_date_int(
            date or get_previous_trading_date(datetime.date.today()))
        start_date = end_date = date

    if kwargs:
        raise ValueError('unknown kwargs: {}'.format(kwargs))

    if universe is not None:
        universe = ensure_string(universe, "universe")
        if universe != "all":
            universe = ensure_order_book_id(universe, type="INDX")
            from rqdatac import index_components
            allowed_order_book_ids = set(
                index_components(universe, date=end_date) or [])
            not_permit_order_book_ids = [
                order_book_id for order_book_id in order_book_ids
                if order_book_id not in allowed_order_book_ids
            ]
            if not_permit_order_book_ids:
                warnings.warn(
                    "%s not in universe pool, value of those order_book_ids will always be NaN"
                    % not_permit_order_book_ids)

    data = get_client().execute("get_factor_from_store",
                                order_book_ids,
                                factor,
                                start_date,
                                end_date,
                                universe=universe)

    if not data:
        return

    factor_value_length = len(data[0][2])
    if factor_value_length == 0:
        return

    dates = pd.to_datetime(get_trading_dates(start_date, end_date))
    if len(dates) > factor_value_length:
        _get_factor_warning_msg(dates[factor_value_length], dates[-1])
        dates = dates[0:factor_value_length]

    if expect_df or len(factor) > 1:
        order_book_id_index_map = {o: i for i, o in enumerate(order_book_ids)}
        factor_index_map = {f: i for i, f in enumerate(factor)}
        arr = np.full((len(order_book_ids) * len(dates), len(factor)), np.nan)

        for order_book_id, factor_name, values in data:
            order_book_id_index = order_book_id_index_map[order_book_id]
            factor_index = factor_index_map[factor_name]
            slice_ = slice(order_book_id_index * len(dates),
                           (order_book_id_index + 1) * len(dates), None)
            arr[slice_, factor_index] = values

        multi_index = pd.MultiIndex.from_product(
            [order_book_ids, dates], names=["order_book_id", "date"])
        df = pd.DataFrame(index=multi_index, columns=factor, data=arr)
        return df

    order_book_id_index_map = {o: i for i, o in enumerate(order_book_ids)}
    arr = np.full((len(dates), len(order_book_ids)), np.nan)
    for order_book_id, _, values in data:
        arr[:, order_book_id_index_map[order_book_id]] = values
    df = pd.DataFrame(index=dates, columns=order_book_ids, data=arr)

    if len(df.index) == 1:
        return df.iloc[0]
    if len(df.columns) == 1:
        return df[df.columns[0]]
    return df