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
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])
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
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
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)
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
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)
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
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)
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
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)
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
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]
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
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
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()
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))
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