def test_jq_603220_kdata(): df = get_kdata(entity_id='stock_sh_603220', session=day_k_session, level=IntervalLevel.LEVEL_1DAY, provider='joinquant') print(df) df = get_kdata(entity_id='stock_sh_603220', session=day_1h_session, level=IntervalLevel.LEVEL_1HOUR, provider='joinquant') print(df)
def test_single_trader(): trader = SingleTrader(codes=['000338'], level=IntervalLevel.LEVEL_1DAY, start_timestamp='2019-01-01', end_timestamp='2020-01-10', trader_name='000338_single_trader', draw_result=False, adjust_type=AdjustType.qfq) trader.run() positions = trader.get_current_account().positions print(positions) account = trader.get_current_account() print(account) buy_price = get_kdata(entity_id='stock_sz_000338', start_timestamp=buy_timestamp, end_timestamp=buy_timestamp, return_type='domain')[0] sell_price = get_kdata(entity_id='stock_sz_000338', start_timestamp=sell_timestamp, end_timestamp=sell_timestamp, return_type='domain')[0] sell_lost = trader.account_service.slippage + trader.account_service.sell_cost buy_lost = trader.account_service.slippage + trader.account_service.buy_cost pct = (sell_price.close * (1 - sell_lost) - buy_price.close * (1 + buy_lost)) / buy_price.close * (1 + buy_lost) profit_rate = (account.all_value - account.input_money) / account.input_money assert round(profit_rate, 2) == round(pct, 2)
def test_multiple_trader(): trader = MultipleTrader( codes=["000338", "601318"], level=IntervalLevel.LEVEL_1DAY, start_timestamp="2019-01-01", end_timestamp="2020-01-10", trader_name="multiple_trader", draw_result=False, adjust_type=AdjustType.qfq, ) trader.run() positions = trader.get_current_account().positions print(positions) account = trader.get_current_account() print(account) # 000338 buy_price = get_kdata(entity_id="stock_sz_000338", start_timestamp=buy_timestamp, end_timestamp=buy_timestamp, return_type="domain")[0] sell_price = get_kdata(entity_id="stock_sz_000338", start_timestamp=sell_timestamp, end_timestamp=sell_timestamp, return_type="domain")[0] sell_lost = trader.account_service.slippage + trader.account_service.sell_cost buy_lost = trader.account_service.slippage + trader.account_service.buy_cost pct1 = (sell_price.close * (1 - sell_lost) - buy_price.close * (1 + buy_lost)) / buy_price.close * (1 + buy_lost) # 601318 buy_price = get_kdata(entity_id="stock_sh_601318", start_timestamp=buy_timestamp, end_timestamp=buy_timestamp, return_type="domain")[0] sell_price = get_kdata(entity_id="stock_sh_601318", start_timestamp=sell_timestamp, end_timestamp=sell_timestamp, return_type="domain")[0] pct2 = (sell_price.close * (1 - sell_lost) - buy_price.close * (1 + buy_lost)) / buy_price.close * (1 + buy_lost) profit_rate = (account.all_value - account.input_money) / account.input_money assert profit_rate - (pct1 + pct2) / 2 <= 0.2
def filter_selector_long_targets(self, timestamp, selector: TargetSelector, long_targets: List[str]) -> List[str]: # 选择器选出的个股,再做进一步处理 if selector.level == IntervalLevel.LEVEL_1DAY: if not long_targets: return None entity_ids = [] for entity_id in long_targets: # 获取最近3k线 df = get_kdata( entity_id=entity_id, start_timestamp=timestamp - datetime.timedelta(20), end_timestamp=timestamp, columns=['entity_id', 'close', 'open', 'high', 'low']) if pd_is_not_null(df) and len(df) >= 3: df = df.iloc[-3:] # 收阳 se = df['close'] > df['open'] positive = np.all(se) # 高点比高点高 trending = df['high'][0] < df['high'][1] < df['high'][2] if positive and trending: entity_ids.append(entity_id) return entity_ids return long_targets
def run(self): from zvt.api import get_kdata bond_data = get_kdata(entity_id='bond_cn_EMM00166466') now_date = to_time_str(now_pd_timestamp()) if bond_data.empty: # 初始时间定在2007年 start = '2007-01-01' else: start = to_time_str(bond_data.timestamp.max()) # EMM00166466 中债国债到期收益率:10年 df = c.edb("EMM00166466", f"IsLatest=0,StartDate={start},EndDate={now_date},ispandas=1") if pd_is_not_null(df): df['name'] = "中债国债到期收益率:10年" df.rename(columns={'RESULT': 'data_value', 'DATES': 'timestamp'}, inplace=True) df['entity_id'] = 'bond_cn_EMM00166466' df['timestamp'] = pd.to_datetime(df['timestamp']) df['provider'] = 'emquantapi' df['exchange'] = 'cn' df['level'] = '1d' df['code'] = "EMM00166466" def generate_kdata_id(se): return "{}_{}".format(se['entity_id'], to_time_str(se['timestamp'], fmt=TIME_FORMAT_DAY)) df['id'] = df[['entity_id', 'timestamp']].apply(generate_kdata_id, axis=1) df_to_db(df=df, data_schema=self.data_schema, provider=self.provider, force_update=self.force_update)
def select_short_targets_from_levels(self, timestamp): positions = self.get_current_positions() if positions: entity_ids = [position.entity_id for position in positions] # 有效跌破5日线,卖出 input_df = get_kdata(region=region, entity_ids=entity_ids, start_timestamp=timestamp - datetime.timedelta(20), end_timestamp=timestamp, columns=['entity_id', 'close'], index=['entity_id', 'timestamp']) ma_df = input_df['close'].groupby(level=0).rolling( window=10, min_periods=10).mean() ma_df = ma_df.reset_index(level=0, drop=True) input_df['ma10'] = ma_df s = input_df['close'] < input_df['ma10'] input_df = s.to_frame(name='score') # 连续3日收在5日线下 df = input_df['score'].groupby(level=0).rolling( window=3, min_periods=3).apply(lambda x: np.logical_and.reduce(x)) df = df.reset_index(level=0, drop=True) input_df['score'] = df result_df = input_df[input_df['score'] == 1.0] if pd_is_not_null(result_df): short_df = result_df.loc[(slice(None), slice(timestamp, timestamp)), :] if pd_is_not_null(short_df): return short_df.index.get_level_values(0).tolist()
def test_to_high_level_kdata(): day_df = get_kdata(provider='joinquant', level=IntervalLevel.LEVEL_1DAY, entity_id='stock_sz_000338') print(day_df) df = to_high_level_kdata(kdata_df=day_df.loc[:'2019-09-01', :], to_level=IntervalLevel.LEVEL_1WEEK) print(df)
def on_trading_signal(self, trading_signal: TradingSignal): entity_id = trading_signal.entity_id happen_timestamp = trading_signal.happen_timestamp order_type = AccountService.trading_signal_to_order_type(trading_signal.trading_signal_type) trading_level = trading_signal.trading_level.value if order_type: try: kdata = get_kdata(provider=self.provider, entity_id=entity_id, level=trading_level, start_timestamp=happen_timestamp, end_timestamp=happen_timestamp, limit=1, adjust_type=self.adjust_type) except Exception as e: self.logger.error(e) raise WrongKdataError("could not get kdata") if pd_is_not_null(kdata): entity_type, _, _ = decode_entity_id(kdata['entity_id'][0]) the_price = kdata['close'][0] if the_price: self.order(entity_id=entity_id, current_price=the_price, current_timestamp=happen_timestamp, order_pct=trading_signal.position_pct, order_money=trading_signal.order_money, order_type=order_type) else: self.logger.warning( 'ignore trading signal,wrong kdata,entity_id:{},timestamp:{},kdata:{}'.format(entity_id, happen_timestamp, kdata.to_dict( orient='records'))) else: self.logger.warning( 'ignore trading signal,could not get kdata,entity_id:{},timestamp:{}'.format(entity_id, happen_timestamp))
def __init__(self, region: Region, entity_id, timestamp, window=100, level=IntervalLevel.LEVEL_1DAY, entity_schema=Stock, range=0.3, std=1) -> None: self.entity_id = entity_id self.window = window data_schema = get_kdata_schema(EntityType( entity_schema.__name__.lower()), level=level) self.df = get_kdata(region=region, entity_id=entity_id, level=level, end_timestamp=timestamp, order=data_schema.timestamp.desc(), limit=window, columns=['volume', 'open', 'close', 'high', 'low']) self.range = range self.std = std
def on_finish_entity(self, entity, http_session): kdatas = get_kdata(region=self.region, entity_id=entity.id, level=IntervalLevel.LEVEL_1DAY.value, order=Etf1dKdata.timestamp.asc(), return_type='domain', session=self.session, filters=[Etf1dKdata.cumulative_net_value.is_(None)]) if kdatas and len(kdatas) > 0: start = kdatas[0].timestamp end = kdatas[-1].timestamp # 从东方财富获取基金累计净值 df = self.fetch_cumulative_net_value(entity, start, end, http_session) if pd_is_not_null(df): for kdata in kdatas: if kdata.timestamp in df.index: kdata.cumulative_net_value = df.loc[kdata.timestamp, 'LJJZ'] kdata.change_pct = df.loc[kdata.timestamp, 'JZZZL'] self.session.commit() self.logger.info(f'{entity.code} - {entity.name}累计净值更新完成...')
def record(self, entity, start, end, size, timestamps): if self.adjust_type == AdjustType.hfq: fq_ref_date = '2000-01-01' else: fq_ref_date = to_time_str(now_pd_timestamp()) if not self.end_timestamp: df = get_bars(to_jq_entity_id(entity), count=size, unit=self.jq_trading_level, fields=['date', 'open', 'close', 'low', 'high', 'volume', 'money'], fq_ref_date=fq_ref_date, include_now=self.real_time) else: end_timestamp = to_time_str(self.end_timestamp) df = get_bars(to_jq_entity_id(entity), count=size, unit=self.jq_trading_level, fields=['date', 'open', 'close', 'low', 'high', 'volume', 'money'], end_dt=end_timestamp, fq_ref_date=fq_ref_date, include_now=False) if pd_is_not_null(df): df['name'] = entity.name df.rename(columns={'money': 'turnover', 'date': 'timestamp'}, inplace=True) df['entity_id'] = entity.id df['timestamp'] = pd.to_datetime(df['timestamp']) df['provider'] = 'joinquant' df['level'] = self.level.value df['code'] = entity.code # 判断是否需要重新计算之前保存的前复权数据 if self.adjust_type == AdjustType.qfq: check_df = df.head(1) check_date = check_df['timestamp'][0] current_df = get_kdata(entity_id=entity.id, provider=self.provider, start_timestamp=check_date, end_timestamp=check_date, limit=1, level=self.level, adjust_type=self.adjust_type) if pd_is_not_null(current_df): old = current_df.iloc[0, :]['close'] new = check_df['close'][0] # 相同时间的close不同,表明前复权需要重新计算 if round(old, 2) != round(new, 2): qfq_factor = new / old last_timestamp = pd.Timestamp(check_date) self.recompute_qfq(entity, qfq_factor=qfq_factor, last_timestamp=last_timestamp) def generate_kdata_id(se): if self.level >= IntervalLevel.LEVEL_1DAY: return "{}_{}".format(se['entity_id'], to_time_str(se['timestamp'], fmt=TIME_FORMAT_DAY)) else: return "{}_{}".format(se['entity_id'], to_time_str(se['timestamp'], fmt=TIME_FORMAT_ISO8601)) df['id'] = df[['entity_id', 'timestamp']].apply(generate_kdata_id, axis=1) df_to_db(df=df, data_schema=self.data_schema, provider=self.provider, force_update=self.force_update) return None
def test_jq_1mon_kdata(): df = get_kdata(entity_id='stock_sz_000338', provider='joinquant', level=IntervalLevel.LEVEL_1MON) se = df.loc['2010-01-29'] # make sure our fq is ok assert round(se['open'], 2) <= 5.44 assert round(se['high'], 2) <= 6.43 assert round(se['low'], 2) <= 5.2 assert round(se['close'], 2) <= 5.45
def test_ma_transformer(): df = get_kdata(entity_id='stock_sz_000338', start_timestamp='2019-01-01', provider='joinquant') t = MaTransformer(windows=[5, 10]) result_df = t.transform(df) print(result_df)
def test_jq_1d_hfq_kdata(): df = get_kdata(entity_id='stock_sz_000338', provider='joinquant', level=IntervalLevel.LEVEL_1DAY, adjust_type='hfq') se = df.loc['2019-04-08'] print(se) assert round(se['open'], 2) == 249.29 assert round(se['high'], 2) == 273.68 assert round(se['low'], 2) == 249.29 assert round(se['close'], 2) == 272.18
def test_MacdTransformer(): df = get_kdata(entity_id='stock_sz_000338', start_timestamp='2019-01-01', provider='joinquant', index=['entity_id', 'timestamp']) t = MacdTransformer() result_df = t.transform(df) print(result_df)
def test_jq_1d_kdata(): df = get_kdata(entity_id='stock_sz_000338', provider='joinquant', level=IntervalLevel.LEVEL_1DAY) print(df) se = df.loc['2019-04-08'] # make sure our fq is ok assert round(se['open'], 2) <= 12.86 assert round(se['high'], 2) <= 14.16 assert round(se['low'], 2) <= 12.86 assert round(se['close'], 2) <= 14.08
def get_ref_vector(entity_id, end, window=100, level=IntervalLevel.LEVEL_1DAY, entity_schema=Stock): data_schema = get_kdata_schema(entity_schema.__name__, level=level) df = get_kdata(entity_id=entity_id, level=level, end_timestamp=end, order=data_schema.timestamp.desc(), limit=window, columns=['close', 'volume']) exp_data = np.zeros((window, 2)) exp_data[:, 0] = df['close'] exp_data[:, 1] = df['volume'] return exp_data
def on_trading_close(self, timestamp): self.logger.debug('on_trading_close:{}'.format(timestamp)) self.account.value = 0 self.account.all_value = 0 for position in self.account.positions: entity_type, _, _ = decode_entity_id(position.entity_id) data_schema = get_kdata_schema(entity_type, level=IntervalLevel.LEVEL_1DAY, adjust_type=self.adjust_type) kdata = get_kdata(provider=self.provider, level=IntervalLevel.LEVEL_1DAY, entity_id=position.entity_id, order=data_schema.timestamp.desc(), end_timestamp=timestamp, limit=1, adjust_type=self.adjust_type) closing_price = kdata['close'][0] position.available_long = position.long_amount position.available_short = position.short_amount if closing_price: if (position.long_amount is not None) and position.long_amount > 0: position.value = position.long_amount * closing_price self.account.value += position.value elif (position.short_amount is not None) and position.short_amount > 0: position.value = 2 * (position.short_amount * position.average_short_price) position.value -= position.short_amount * closing_price self.account.value += position.value else: self.logger.warning( 'could not refresh close value for position:{},timestamp:{}' .format(position['entity_id'], timestamp)) # remove the empty position self.account.positions = [ position for position in self.account.positions if position.long_amount > 0 or position.short_amount > 0 ] self.account.all_value = self.account.value + self.account.cash self.account.closing = True self.account.timestamp = to_pd_timestamp(timestamp) self.logger.debug('on_trading_close:{},latest_account:{}'.format( timestamp, self.account)) self.persist_account(timestamp)
def on_trading_close(self, timestamp): self.logger.info('on_trading_close:{}'.format(timestamp)) self.latest_account['value'] = 0 self.latest_account['all_value'] = 0 for position in self.latest_account['positions']: entity_type, _, _ = decode_entity_id(position['entity_id']) data_schema = get_kdata_schema(entity_type, level=self.level) kdata = get_kdata(provider=self.provider, level=IntervalLevel.LEVEL_1DAY, entity_id=position['entity_id'], order=data_schema.timestamp.desc(), end_timestamp=timestamp, limit=1) closing_price = kdata['close'][0] position['available_long'] = position['long_amount'] position['available_short'] = position['short_amount'] if closing_price: if (position['long_amount'] is not None) and position['long_amount'] > 0: position['value'] = position['long_amount'] * closing_price self.latest_account['value'] += position['value'] elif (position['short_amount'] is not None) and position['short_amount'] > 0: position['value'] = 2 * (position['short_amount'] * position['average_short_price']) position[ 'value'] -= position['short_amount'] * closing_price self.latest_account['value'] += position['value'] else: self.logger.warning( 'could not refresh close value for position:{},timestamp:{}' .format(position['entity_id'], timestamp)) # remove the empty position self.latest_account['positions'] = [ position for position in self.latest_account['positions'] if position['long_amount'] > 0 or position['short_amount'] > 0 ] self.latest_account['all_value'] = self.latest_account[ 'value'] + self.latest_account['cash'] self.latest_account['closing'] = True self.latest_account['timestamp'] = to_pd_timestamp(timestamp) self.logger.info('on_trading_close:{},latest_account:{}'.format( timestamp, self.latest_account)) self.persist_account(timestamp)
def filter_selector_long_targets(self, timestamp, selector: TargetSelector, long_targets: List[str]) -> List[str]: # 选择器选出的个股,再做进一步处理 if selector.level == IntervalLevel.LEVEL_1DAY: if not long_targets: return None df = get_kdata(entity_ids=long_targets, start_timestamp=timestamp, end_timestamp=timestamp, columns=['entity_id', 'turnover']) if pd_is_not_null(df): df.sort_values(by=['turnover']) return df['entity_id'].iloc[:10].tolist() return None return long_targets
def test_ma_transformer(): df = get_kdata( entity_id="stock_sz_000338", start_timestamp="2019-01-01", provider="joinquant", index=["entity_id", "timestamp"], ) t = MaTransformer(windows=[5, 10]) result_df = t.transform(df) print(result_df)
def select_long_targets_from_levels(self, timestamp): # self.level_map_long_targets里面是各级别选中的标的,默认是各级别都选中才要 long_targets = super().select_long_targets_from_levels(timestamp) if self.level >= IntervalLevel.LEVEL_1DAY: if not long_targets: return None df = get_kdata(entity_ids=list(long_targets), start_timestamp=timestamp, end_timestamp=timestamp, columns=['entity_id', 'turnover']) if pd_is_not_null(df): df.sort_values(by=['turnover']) if len(df['entity_id']) > 5: return df['entity_id'].iloc[5:10].tolist() return df['entity_id'].tolist() return None return long_targets
def recompute_qfq(self, entity, qfq_factor, last_timestamp): # 重新计算前复权数据 if qfq_factor != 0: kdatas = get_kdata(provider=self.provider, entity_id=entity.id, level=self.level.value, order=self.data_schema.timestamp.asc(), return_type='domain', session=self.session, filters=[self.data_schema.timestamp < last_timestamp]) if kdatas: self.logger.info('recomputing {} qfq kdata,factor is:{}'.format(entity.code, qfq_factor)) for kdata in kdatas: kdata.open = round(kdata.open * qfq_factor, 2) kdata.close = round(kdata.close * qfq_factor, 2) kdata.high = round(kdata.high * qfq_factor, 2) kdata.low = round(kdata.low * qfq_factor, 2) self.session.add_all(kdatas) self.session.commit()
def generate_kdata_id(se): if self.level >= IntervalLevel.LEVEL_1DAY: return "{}_{}".format(se['entity_id'], to_time_str(se['timestamp'], fmt=TIME_FORMAT_DAY)) else: return "{}_{}".format(se['entity_id'], to_time_str(se['timestamp'], fmt=TIME_FORMAT_ISO8601)) df['id'] = df[['entity_id', 'timestamp']].apply(generate_kdata_id, axis=1) df_to_db(df=df, data_schema=self.data_schema, provider=self.provider, force_update=self.force_update) return None if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('--level', help='trading level', default='1d', choices=[item.value for item in IntervalLevel]) parser.add_argument('--codes', help='codes', default=['000001'], nargs='+') args = parser.parse_args() level = IntervalLevel(args.level) codes = args.codes init_log('jq_china_stock_{}_kdata.log'.format(args.level)) EmChinaStockKdataRecorder(level=level, sleeping_time=0, codes=codes, real_time=False, adjust_type=AdjustType.hfq).run() print(get_kdata(entity_id='stock_sz_000001', limit=10, order=Stock1dHfqKdata.timestamp.desc(), adjust_type=AdjustType.hfq)) # the __all__ is generated __all__ = ['EmChinaStockKdataRecorder']
end_timestamp: Union[str, pd.Timestamp] = None, columns: List = None, filters: List = None, order: object = None, limit: int = None, level: Union[str, IntervalLevel] = IntervalLevel.LEVEL_1DAY, category_field: str = 'entity_id', time_field: str = 'timestamp', computing_window: int = None, keep_all_timestamp: bool = False, fill_method: str = 'ffill', effective_number: int = None, transformer: Transformer = ZenTransformer(), accumulator: Accumulator = None, need_persist: bool = False, dry_run: bool = False, adjust_type: Union[AdjustType, str] = None) -> None: super().__init__(entity_schema, provider, entity_provider, entity_ids, exchanges, codes, the_timestamp, start_timestamp, end_timestamp, columns, filters, order, limit, level, category_field, time_field, computing_window, keep_all_timestamp, fill_method, effective_number, transformer, accumulator, need_persist, dry_run, adjust_type) if __name__ == '__main__': from zvt.drawer.drawer import Drawer df = get_kdata(entity_ids=['stock_sz_000338'], columns=['entity_id', 'timestamp', 'high', 'low', 'open', 'close'], index=['entity_id', 'timestamp'], end_timestamp='2009-01-01') one_df = df[['high', 'low']] t = ZenTransformer() one_df = t.transform_one('stock_sz_000338', one_df) print(one_df) # annotation_df format: # value flag color # entity_id timestamp # 处理分型 bi_ding = one_df[one_df.bi_ding][['timestamp', 'high']] bi_di = one_df[one_df.bi_di][['timestamp', 'low']] df1 = bi_ding.rename(columns={"high": "value"})
def on_trading_close(self, timestamp): self.logger.info('on_trading_close:{}'.format(timestamp)) # remove the empty position self.account.positions = [ position for position in self.account.positions if position.long_amount > 0 or position.short_amount > 0 ] # clear the data which need recomputing the_id = '{}_{}'.format(self.trader_name, to_time_str(timestamp, TIME_FORMAT_ISO8601)) self.account.value = 0 self.account.all_value = 0 for position in self.account.positions: entity_type, _, _ = decode_entity_id(position.entity_id) data_schema = get_kdata_schema(entity_type, level=IntervalLevel.LEVEL_1DAY, adjust_type=self.adjust_type) kdata = get_kdata(provider=self.provider, level=IntervalLevel.LEVEL_1DAY, entity_id=position.entity_id, order=data_schema.timestamp.desc(), end_timestamp=timestamp, limit=1, adjust_type=self.adjust_type) closing_price = kdata['close'][0] position.available_long = position.long_amount position.available_short = position.short_amount if closing_price: if (position.long_amount is not None) and position.long_amount > 0: position.value = position.long_amount * closing_price self.account.value += position.value elif (position.short_amount is not None) and position.short_amount > 0: position.value = 2 * (position.short_amount * position.average_short_price) position.value -= position.short_amount * closing_price self.account.value += position.value # refresh profit position.profit = (closing_price - position.average_long_price) \ * position.long_amount position.profit_rate = position.profit / ( position.average_long_price * position.long_amount) else: self.logger.warning( 'could not refresh close value for position:{},timestamp:{}' .format(position.entity_id, timestamp)) position.id = '{}_{}_{}'.format( self.trader_name, position.entity_id, to_time_str(timestamp, TIME_FORMAT_ISO8601)) position.timestamp = to_pd_timestamp(timestamp) position.account_stats_id = the_id self.account.id = the_id self.account.all_value = self.account.value + self.account.cash self.account.closing = True self.account.timestamp = to_pd_timestamp(timestamp) self.account.profit = ( self.account.all_value - self.account.input_money) / self.account.input_money self.session.add(self.account) self.session.commit() account_info = f'on_trading_close,holding size:{len(self.account.positions)} profit:{self.account.profit} input_money:{self.account.input_money} ' \ f'cash:{self.account.cash} value:{self.account.value} all_value:{self.account.all_value}' self.logger.info(account_info)
def record(self, entity, start, end, size, timestamps): if self.adjust_type == AdjustType.hfq: # 1 不复权 # 2 后复权 # 3 前复权 adjustflag = 2 elif self.adjust_type == AdjustType.qfq: adjustflag = 3 elif self.adjust_type == AdjustType.bfq: adjustflag = 1 start_timestamp = to_time_str(start) # if start_timestamp > '2020-06-01': # start_timestamp = '2019-01-01' end_timestamp = to_time_str(self.end_timestamp) # end_timestamp = to_time_str('2020-06-01') if self.jq_trading_level == '1d': period = 1 df = c.csd(str(entity.code + '.' + entity.exchange).upper(), "OPEN,CLOSE,HIGH,LOW,VOLUME,AMOUNT", start_timestamp, end_timestamp, f"period={period},adjustflag={adjustflag},curtype=1,order=1,market=HKSE00,ispandas=1") try: df.dropna(subset=['CLOSE'],inplace=True) except: return None if pd_is_not_null(df): df['name'] = entity.name df.rename(columns={ "OPEN": "open", "CLOSE": "close", "HIGH": "high", "LOW": "low", "VOLUME": "volume", 'AMOUNT': 'turnover', 'DATES': 'timestamp' }, inplace=True) df['entity_id'] = entity.id df['timestamp'] = pd.to_datetime(df['timestamp']) df['provider'] = 'emquantapi' df['level'] = self.level.value df['code'] = entity.code # 判断是否需要重新计算之前保存的前复权数据 if self.adjust_type == AdjustType.qfq: check_df = df.head(1) check_date = check_df['timestamp'][0] current_df = get_kdata(entity_id=entity.id, provider=self.provider, start_timestamp=check_date, end_timestamp=check_date, limit=1, level=self.level, adjust_type=self.adjust_type) if pd_is_not_null(current_df): old = current_df.iloc[0, :]['close'] new = check_df['close'][0] # 相同时间的close不同,表明前复权需要重新计算 if round(old, 2) != round(new, 2): qfq_factor = new / old last_timestamp = pd.Timestamp(check_date) self.recompute_qfq(entity, qfq_factor=qfq_factor, last_timestamp=last_timestamp) def generate_kdata_id(se): if self.level >= IntervalLevel.LEVEL_1DAY: return "{}_{}".format(se['entity_id'], to_time_str(se['timestamp'], fmt=TIME_FORMAT_DAY)) else: return "{}_{}".format(se['entity_id'], to_time_str(se['timestamp'], fmt=TIME_FORMAT_ISO8601)) df['id'] = df[['entity_id', 'timestamp']].apply(generate_kdata_id, axis=1) df_to_db(df=df, data_schema=self.data_schema, provider=self.provider, force_update=self.force_update) return None
def get_trade_dates(self, conn, start, end, order="ESC"): """ 获取start到end(包括start、end)之间的交易日期列表 start所表示的日期在end之前 :param end: :param order: :return: """ pass __all__ = ['TlChinaStockKdataRecorder'] if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('--level', help='trading level', default='1d', choices=[item.value for item in IntervalLevel]) parser.add_argument('--codes', help='codes', default=['600118'], nargs='+') args = parser.parse_args() level = IntervalLevel(args.level) codes = args.codes init_log('tl_china_stock_{}_kdata.log'.format(args.level)) TlChinaStockKdataRecorder(level=level, sleeping_time=0, codes=codes, real_time=False, adjust_type=AdjustType.hfq).run() print(get_kdata(entity_id=china_stock_code_to_id(args.codes[0]), limit=10, order=Stock1dHfqKdata.timestamp.desc(),adjust_type=AdjustType.hfq))
__all__ = ['YahooUsStockKdataRecorder'] if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('--level', help='trading level', default='1d', choices=[item.value for item in IntervalLevel]) parser.add_argument('--codes', help='codes', default=['000001'], nargs='+') args = parser.parse_args() level = IntervalLevel(args.level) codes = args.codes init_log('yahoo_us_stock_{}_kdata.log'.format(args.level)) YahooUsStockKdataRecorder(level=level, sleeping_time=0, codes=codes, real_time=False, adjust_type=AdjustType.hfq).run() print( get_kdata(region=Region.US, entity_id='stock_nyse_a', limit=10, order=Stock1dKdata.timestamp.desc(), adjust_type=AdjustType.hfq))
def test_jq_1wk_kdata(): df = get_kdata(entity_id='stock_sz_000338', provider='joinquant', level=IntervalLevel.LEVEL_1WEEK) print(df)