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 datetime(self): if self._dt is not None: return self._dt if not self._isnan: dt = self._data["datetime"] return to_datetime(dt) return datetime.datetime.min
def is_suspended(order_book_ids, start_date=None, end_date=None): """获取停牌信息 :param order_book_ids: 可转债ID :param start_date: 开始日期, 如'2013-01-04' (Default value = None) :param end_date: 结束日期,如'2014-01-04' (Default value = None) :returns: DataFrame """ order_book_ids = ensure_order_book_ids(order_book_ids) if len(order_book_ids) == 1: instrument = instruments(order_book_ids[0], market="cn") start_date, end_date = ensure_dates_base_on_listed_date( instrument, start_date, end_date, "cn") if start_date is None: return start_date, end_date = ensure_date_range(start_date, end_date) trading_dates = pd.to_datetime( get_trading_dates(start_date, end_date, market="cn")) df = pd.DataFrame(data=False, columns=order_book_ids, index=trading_dates) data = get_client().execute("convertible.is_suspended", order_book_ids, start_date, end_date, market="cn") for (order_book_id, date) in data: date = to_datetime(date) df.at[date, order_book_id] = True return df
def get_ratings(order_book_id, date=None, market="cn"): """获取距离指定日期最近发布的基金评级信息 :param order_book_id: 基金代码 str or list :param date: 日期,为空则返回所有时间段的数据 (Default value = None) :param market: (Default value = "cn") :returns: DataFrame """ order_book_id = ensure_list_of_string(order_book_id) if date is not None: date = to_datetime(date) if date > datetime.datetime.today(): return date = ensure_date_int(date) df = get_client().execute("fund.get_ratings_v2", order_book_id, date, market=market) if not df: return df = pd.DataFrame(df, columns=["order_book_id", "datetime", "zs", "sh3", "sh5", "jajx"]) df.sort_values(["order_book_id", "datetime"], inplace=True) if date is not None: df.drop_duplicates(subset=['order_book_id'], keep='last', inplace=True) df.set_index(["order_book_id", "datetime"], inplace=True) df.fillna(np.nan, inplace=True) 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 is_st_stock(order_book_ids, start_date=None, end_date=None, market="cn"): """判断股票在给定的时间段是否是ST股, 返回值为一个DataFrame :param order_book_ids: 股票 id :param start_date: (Default value = None) :param end_date: (Default value = None) :param market: (Default value = "cn") """ order_book_ids = ensure_order_book_ids(order_book_ids, type="CS", market=market) if len(order_book_ids) == 1: instrument = instruments(order_book_ids[0], market=market) start_date, end_date = ensure_dates_base_on_listed_date( instrument, start_date, end_date, market) if start_date is None: return start_date, end_date = ensure_date_range(start_date, end_date) trading_dates = pd.to_datetime( get_trading_dates(start_date, end_date, market=market)) data = get_client().execute("get_st_days", order_book_ids, start_date=start_date, end_date=end_date) df = pd.DataFrame(data=False, columns=order_book_ids, index=trading_dates) for idx, dates in data.items(): for date in dates: date = to_datetime(date) df.at[date, idx] = True return df
def is_suspended(order_book_ids, start_date=None, end_date=None, market="cn"): """获取股票停牌信息 :param order_book_ids: 股票名称 :param start_date: 开始日期, 如'2013-01-04' (Default value = None) :param end_date: 结束日期,如'2014-01-04' (Default value = None) :param market: 地区代码, 如 'cn' (Default value = "cn") :returns: DataFrame """ order_book_ids = ensure_order_book_ids(order_book_ids, type="CS", market=market) if len(order_book_ids) == 1: instrument = instruments(order_book_ids[0], market=market) start_date, end_date = ensure_dates_base_on_listed_date(instrument, start_date, end_date, market) if start_date is None: return if end_date is None: end_date = datetime.date.today() start_date, end_date = ensure_date_range(start_date, end_date) trading_dates = pd.to_datetime(get_trading_dates(start_date, end_date, market=market)) df = pd.DataFrame(data=False, columns=order_book_ids, index=trading_dates) data = get_client().execute("get_suspended_days", order_book_ids, start_date, end_date, market=market) for idx, dates in data.items(): for date in dates: date = to_datetime(int(date)) df.at[date, idx] = True df.sort_index(inplace=True) return df
def all_instruments(date=None, market="cn"): """获取所有可转债详细信息 :param market: (Default value = "cn") :returns: DataFrame """ profile = lambda v: ( v.order_book_id, v.symbol, v.full_name, v.exchange, v.bond_type, v.trade_type, v.value_date, v.maturity_date, v.par_value, v.coupon_rate, v.coupon_frequency, v.coupon_method, v.compensation_rate, v.total_issue_size, v.de_listed_date, v.stock_code, v.conversion_start_date, v.conversion_end_date, v.redemption_price, v.issue_price, v.call_protection, v.listed_date, ) def judge(listed_date, de_listed_date): if listed_date and de_listed_date: return listed_date <= date and de_listed_date > date if listed_date: return listed_date <= date else: return False if date: date = to_datetime(date) data = [ profile(v) for v in _all_instruments_dict(market).values() if judge(v.listed_date, v.de_listed_date) ] else: data = [profile(v) for v in _all_instruments_dict(market).values()] df = pd.DataFrame( data, columns=INS_COLUMNS, ) df.sort_values('order_book_id', inplace=True) return df.reset_index(drop=True)
def get_units_change(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_fund(order_book_id, market) if date is not None: date = to_datetime(date) if date > datetime.datetime.today(): return None date = ensure_date_int(date) df = get_client().execute("fund.get_units_change", order_book_id, date, market=market) df = pd.DataFrame(df, columns=["subscribe_units", "redeem_units", "units", "datetime"]) df["datetime"] = pd.to_datetime(df["datetime"]) return df.set_index("datetime").sort_index()
def get_industry_allocation(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_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) df = get_client().execute("fund.get_industry_allocation", order_book_id, date, market=market) df = pd.DataFrame(df, columns=["industry", "weights", "market_value", "datetime"]) df["datetime"] = pd.to_datetime(df["datetime"]) return df.set_index("datetime").sort_index()
def get_asset_allocation(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_fund(order_book_id, market) if date is not None: date = to_datetime(date) if date > datetime.datetime.today(): return None date = ensure_date_int(date) df = get_client().execute("fund.get_asset_allocation", order_book_id, date, market=market) if not df: return df = pd.DataFrame(df, columns=["stock", "bond", "fund", "cash", 'other', 'nav', "net_asset", 'total_asset', "datetime"]) df["datetime"] = pd.to_datetime(df["datetime"]) warnings.warn("'nav' is deprecated. Please use 'net_asset' instead") return df.set_index("datetime").sort_index()
def get_fundamentals(query, entry_date, interval=None, report_quarter=False, expect_df=False, market="cn"): """获取财务数据 :param query: query 对象 :param entry_date: 日期 :param interval: (Default value = None) :param report_quarter: (Default value = False) :param expect_df: 返回 MultiIndex DataFrame (Default value = False) :param market: (Default value = "cn") """ if market != "cn": raise MarketNotSupportError("don't support market {} yet.", market) if not isinstance(query, Query): raise ValueError("a sqlalchemy's Query object expected: {}".format(type(query))) raise_for_no_panel(expect_df) entry_date = to_datetime(entry_date) delta = 0 duration = 0 if interval is not None: if not isinstance(interval, str): raise ValueError( "invalid interval: {} should be a string like 1d, 5y, 3m, 2q".format(interval) ) if interval[-1] not in __TIME_DELTA_MAP__: raise ValueError( "invalid interval: {}, interval unit should be d(day), " "m(month), q(quarter) or y(year)".format(interval) ) delta = __TIME_DELTA_MAP__[interval[-1]] try: duration = int(interval[:-1]) except ValueError: raise ValueError( "invalid interval: {}, should be a string like 1d, 5y, 3m, 2q".format(interval) ) trading_dates = [get_previous_trading_date(entry_date + __TIME_DELTA_MAP__["d"], market=market)] if duration > 0: current_date = trading_dates[0] one_day = __TIME_DELTA_MAP__["d"] for i in range(duration - 1): current_date = get_previous_trading_date(current_date - delta + one_day, market=market) trading_dates.append(current_date) query = _unsafe_apply_query_filter(query, trading_dates) sql = _compile_query(query) records = get_client().execute("get_fundamentals", sql, market=market) if not records: warnings.warn("No record found") return None base_fields = ["STOCKCODE", "TRADEDATE", "RPT_YEAR", "RPT_QUARTER"] field_names = base_fields + list(set(records[0].keys()) - set(base_fields)) items = ["report_quarter"] + field_names[4:] if report_quarter else field_names[4:] if expect_df: df = pd.DataFrame(records) df.rename(columns={"STOCKCODE": "order_book_id", "TRADEDATE": "date"}, inplace=True) df["report_quarter"] = df["RPT_YEAR"].map(str) + "q" + df["RPT_QUARTER"].map(str) df.sort_values(["order_book_id", "date"], ascending=[True, False], inplace=True) df.set_index(["order_book_id", "date"], inplace=True) for item in items: if item != "report_quarter": df[item] = df[item].astype(np.float64) return df[items] # 只有一个查询日期时, 保持顺序 if len(trading_dates) > 1: stocks = list(set([r[field_names[0]] for r in records])) else: stocks = [r[field_names[0]] for r in records] stock_index = {s: i for i, s in enumerate(stocks)} day_index = {d: i for i, d in enumerate(trading_dates)} removed_items_size = 3 if report_quarter else 4 array = np.ndarray( ((len(records[0]) - removed_items_size), len(trading_dates), len(stocks)), dtype=object ) array.fill(np.nan) for r in records: istock = stock_index[r[field_names[0]]] iday = day_index[int8_to_date(r[field_names[1]])] for i in range(4, len(r)): array[(i - removed_items_size, iday, istock)] = np.float64(r[field_names[i]]) if report_quarter: array[(0, iday, istock)] = ( np.nan if None in (r[field_names[2]], r[field_names[3]]) else str(r[field_names[2]]) + "q" + str(r[field_names[3]]) ) trading_dates = pd.to_datetime(trading_dates) warnings.warn("Panel is removed after pandas version 0.25.0." "the default value of 'expect_df' will change to True in the future.") return pd.Panel(data=array, items=items, major_axis=trading_dates, minor_axis=stocks)
def convert_history_tick_to_multi_df(data, dt_name, fields, convert_dt): line_no = 0 dt_set = set() obid_level = [] obid_slice_map = {} for i, (obid, d) in enumerate(data): dates = d.pop("date") if len(dates) == 0: continue times = d.pop("time") dts = d[dt_name] = [_convert_int_to_datetime(dt, tm) for dt, tm in zip(dates, times)] dts_len = len(dts) if not obid_level or obid_level[-1] != obid: obid_level.append(obid) obid_slice_map[(i, obid)] = slice(line_no, line_no + dts_len, None) dt_set.update(dts) line_no += dts_len if line_no == 0: return daybars = {} if set(fields) & RELATED_DABAR_FIELDS: for obid in obid_level: daybar = daybar_for_tick_price(obid) if daybar is not None: daybar['prev_close'] = daybar['close'].shift(1) daybars[obid] = daybar fields_ = list(set(fields) | {"last", "volume"}) else: fields_ = fields obid_idx_map = {o: i for i, o in enumerate(obid_level)} obid_label = np.empty(line_no, dtype=object) dt_label = np.empty(line_no, dtype=object) arr = np.full((line_no, len(fields_)), np.nan) r_map_fields = {f: i for i, f in enumerate(fields_)} dt_arr_sorted = np.array(sorted(dt_set)) dt_level = convert_dt(dt_arr_sorted) for i, (obid, d) in enumerate(data): if dt_name not in d: continue dts = d[dt_name] slice_ = obid_slice_map[(i, obid)] for f, value in d.items(): if f == dt_name: dt_label[slice_] = dt_arr_sorted.searchsorted(dts, side='left') else: arr[slice_, r_map_fields[f]] = value obid_label[slice_] = obid_idx_map[obid] trading_date = to_datetime(get_current_trading_date(int17_to_datetime(dts[-1]))) if "trading_date" in r_map_fields: trading_date_int = date_to_int8(trading_date) arr[slice_, r_map_fields["trading_date"]] = trading_date_int daybar = daybars.get(obid) if daybar is not None: try: last = daybar.loc[trading_date] except KeyError: continue day_open = last["open"] if "open" in r_map_fields: arr[slice_, r_map_fields["open"]] = [day_open if v > 0 else 0.0 for v in d["volume"]] if "prev_close" in r_map_fields: arr[slice_, r_map_fields["prev_close"]] = last["prev_close"] if instruments(obid).type in ("CS", "Future"): if "limit_up" in r_map_fields: arr[slice_, r_map_fields["limit_up"]] = last["limit_up"] if "limit_down" in r_map_fields: arr[slice_, r_map_fields["limit_down"]] = last["limit_down"] if instruments(obid).type in ("Future", "Option"): if "prev_settlement" in r_map_fields: arr[slice_, r_map_fields["prev_settlement"]] = last["prev_settlement"] if "change_rate" in r_map_fields: arr[slice_, r_map_fields["change_rate"]] = arr[slice_, r_map_fields["last"]] / last[ "prev_settlement"] - 1 elif "change_rate" in r_map_fields: arr[slice_, r_map_fields["change_rate"]] = arr[slice_, r_map_fields["last"]] / last["prev_close"] - 1 try: func_is_singletz = getattr(pd._libs.lib, 'is_datetime_with_singletz_array') setattr(pd._libs.lib, 'is_datetime_with_singletz_array', lambda *args: True) except AttributeError: func_is_singletz = None multi_idx = pd.MultiIndex( levels=[obid_level, dt_level], labels=[obid_label, dt_label], names=('order_book_id', dt_name) ) df = pd.DataFrame(data=arr, index=multi_idx, columns=fields_) if "trading_date" in r_map_fields: df["trading_date"] = df["trading_date"].astype(int).apply(int8_to_datetime) if func_is_singletz is not None: setattr(pd._libs.lib, 'is_datetime_with_singletz_array', func_is_singletz) return df[fields]