def test_remote_data_service_industry(): from quantos.data.align import align import pandas as pd ds = RemoteDataService() arr = ds.get_index_comp(index='000300.SH', start_date=20130101, end_date=20170505) df = ds.get_industry_raw(symbol=','.join(arr), type_='ZZ') df = df.astype(dtype={'in_date': int}) # df_ann = df.loc[:, ['in_date', 'symbol']] # df_ann = df_ann.set_index(['symbol', 'in_date']) # df_ann = df_ann.unstack(level='symbol') from quantos.data.dataview import DataView dic_sec = DataView._group_df_to_dict(df, by='symbol') dic_sec = {sec: df.reset_index() for sec, df in dic_sec.viewitems()} df_ann = pd.concat([df.loc[:, 'in_date'].rename(sec) for sec, df in dic_sec.viewitems()], axis=1) df_value = pd.concat([df.loc[:, 'industry1_code'].rename(sec) for sec, df in dic_sec.viewitems()], axis=1) dates_arr = ds.get_trade_date(20140101, 20170505) res = align(df_value, df_ann, dates_arr) print # df_ann = df.pivot(index='in_date', columns='symbol', values='in_date') # df_value = df.pivot(index=None, columns='symbol', values='industry1_code') def align_single_df(df_one_sec): df_value = df_one_sec.loc[:, ['industry1_code']] df_ann = df_one_sec.loc[:, ['in_date']] res = align(df_value, df_ann, dates_arr) return res # res_list = [align_single_df(df) for sec, df in dic_sec.viewitems()] res_list = [align_single_df(df) for sec, df in dic_sec.items()[:10]] res = pd.concat(res_list, axis=1) print res
def test_remote_data_service_inst_info(): ds = RemoteDataService() res, msg = ds.query_inst_info('000001.SZ', fields='status,selllot,buylot,pricetick,multiplier,product') assert res.loc[0, 'multiplier'] == 1 assert abs(res.loc[0, 'pricetick'] - 0.01) < 1e-2 assert res.loc[0, 'buylot'] == 100
def test_remote_data_service_components(): ds = RemoteDataService() res = ds.get_index_comp_df(index='000300.SH', start_date=20140101, end_date=20170505) assert res.shape == (814, 430) arr = ds.get_index_comp(index='000300.SH', start_date=20140101, end_date=20170505) assert len(arr) == 430
def test_remote_data_service_fin_indicator(): ds = RemoteDataService() symbol = '000008.SZ' filter_argument = ds._dic2url({'symbol': symbol}) df_raw, msg = ds.query("lb.finIndicator", fields="", filter=filter_argument, orderby="symbol") print
def test_remote_data_service_daily_quited(): ds = RemoteDataService() # test daily res, msg = ds.daily('600832.SH', fields="", start_date=20140828, end_date=20170831, adjust_mode=None) assert msg == '0,' assert res.shape == (175, 13)
def test_remote_data_service_adj_factor(): ds = RemoteDataService() arr = ds.get_index_comp(index='000300.SH', start_date=20130101, end_date=20170505) symbol_arr = ','.join(arr) res = ds.get_adj_factor_daily(symbol_arr, start_date=20130101, end_date=20170101, div=False) assert abs(res.loc[20160408, '300024.SZ'] - 10.735) < 1e-3 assert abs(res.loc[20160412, '300024.SZ'] - 23.658) < 1e-3 assert res.isnull().sum().sum() == 0
def test_align(): # ------------------------------------------------------------------------------------- # input and pre-process demo data ds = RemoteDataService() raw, msg = ds.query_lb_fin_stat('income', '600000.SH', 20151225, 20170501, 'oper_rev') assert msg == '0,' idx_list = ['report_date', 'symbol'] raw_idx = raw.set_index(idx_list) raw_idx.sort_index(axis=0, level=idx_list, inplace=True) df_ann = raw_idx.loc[pd.IndexSlice[:, :], 'ann_date'] df_ann = df_ann.unstack(level=1) df_value = raw_idx.loc[pd.IndexSlice[:, :], 'oper_rev'] df_value = df_value.unstack(level=1) date_arr = ds.get_trade_date(20160101, 20170501) df_close = pd.DataFrame(index=date_arr, columns=df_value.columns, data=1e3) # ------------------------------------------------------------------------------------- # demo usage of parser parser = Parser() parser.register_function( 'Myfunc', lambda x: x * 0 + 1) # simultaneously test register function and align expr_formula = 'revenue / Myfunc(close)' expression = parser.parse(expr_formula) for i in range(100): df_res = parser.evaluate({ 'revenue': df_value, 'close': df_close }, df_ann, date_arr) # ------------------------------------------------------------------------------------- sec = '600000.SH' """ # print to validate results print "\n======Expression Formula:\n{:s}".format(expr_formula) print "\n======Report date, ann_date and evaluation value:" tmp = pd.concat([df_ann.loc[:, sec], df_value.loc[:, sec]], axis=1) tmp.columns = ['df_ann', 'df_value'] print tmp print "\n======Selection of result of expansion:" print "20161028 {:.4f}".format(df_res.loc[20161028, sec]) print "20161031 {:.4f}".format(df_res.loc[20161031, sec]) print "20170427 {:.4f}".format(df_res.loc[20170427, sec]) """ assert abs(df_res.loc[20161028, sec] - 82172000000) < 1 assert abs(df_res.loc[20161031, sec] - 120928000000) < 1 assert abs(df_res.loc[20170427, sec] - 42360000000) < 1
def test_remote_data_service_daily_ind_performance(): ds = RemoteDataService() hs300 = ds.get_index_comp('000300.SH', 20140101, 20170101) hs300_str = ','.join(hs300) fields = "pb,pe,share_float_free,net_assets,limit_status" res, msg = ds.query("lb.secDailyIndicator", fields=fields, filter=("symbol=" + hs300_str + "&start_date=20160907&end_date=20170907"), orderby="trade_date") assert msg == '0,'
def test_double_ma(): prop_file_path = fileio.join_relative_path("etc/backtest.json") print prop_file_path prop_file = open(prop_file_path, 'r') props = json.load(prop_file) enum_props = {'bar_type': common.QUOTE_TYPE} for k, v in enum_props.iteritems(): props[k] = v.to_enum(props[k]) # strategy = CtaStrategy() strategy = DoubleMaStrategy() gateway = BarSimulatorGateway() data_service = RemoteDataService() context = model.Context() context.register_data_api(data_service) context.register_gateway(gateway) context.register_trade_api(gateway) backtest = EventBacktestInstance() backtest.init_from_config(props, strategy, context=context) # backtest.run() backtest.run() report = backtest.generate_report()
def save_dataview(): # total 130 seconds ds = RemoteDataService() dv = DataView() props = {'start_date': 20141114, 'end_date': 20170327, 'universe': '000300.SH', # 'symbol': 'rb1710.SHF,rb1801.SHF', 'fields': ('open,high,low,close,vwap,volume,turnover,' # + 'pb,net_assets,' + 'total_oper_rev,oper_exp,tot_profit,int_income' ), 'freq': 1} dv.init_from_config(props, ds) dv.prepare_data() factor_formula = '-1 * Rank(Ts_Max(Delta(vwap, 7), 11))' # GTJA factor_name = 'gtja' dv.add_formula(factor_name, factor_formula) dv.add_formula('eps_ret_wrong', 'Return(eps, 3)', is_quarterly=False) tmp = dv.get_ts('eps_ret_wrong') dv.add_formula('eps_ret', 'Return(eps, 3)', is_quarterly=True) tmp = dv.get_ts('eps_ret') dv.add_formula('look_ahead', 'Delay(Return(close_adj, 5), -5)') dv.add_formula('ret1', 'Return(close_adj, 1)') dv.add_formula('ret20', 'Delay(Return(close_adj, 20), -20)') dv.save_dataview(folder_path=fileio.join_relative_path('../output/prepared'))
def test_remote_data_service_daily(): ds = RemoteDataService() # test daily res, msg = ds.daily('rb1710.SHF,600662.SH', fields="", start_date=20170828, end_date=20170831, adjust_mode=None) assert msg == '0,' rb = res.loc[res.loc[:, 'symbol'] == 'rb1710.SHF', :] stk = res.loc[res.loc[:, 'symbol'] == '600662.SH', :] assert set(rb.columns) == {'close', 'code', 'high', 'low', 'oi', 'open', 'settle', 'symbol', 'trade_date', 'trade_status', 'turnover', 'volume', 'vwap'} assert rb.shape == (4, 13) assert rb.loc[:, 'volume'].values[0] == 189616 assert stk.loc[:, 'volume'].values[0] == 7174813
def test_remote_data_service_bar(): ds = RemoteDataService() # test bar res2, msg2 = ds.bar('rb1710.SHF,600662.SH', start_time=200000, end_time=160000, trade_date=20170831, fields="") assert msg2 == '0,' rb2 = res2.loc[res2.loc[:, 'symbol'] == 'rb1710.SHF', :] stk2 = res2.loc[res2.loc[:, 'symbol'] == '600662.SH', :] assert set(rb2.columns) == {u'close', u'code', u'date', u'freq', u'high', u'low', u'oi', u'open', u'settle', u'symbol', u'time', u'trade_date', u'turnover', u'volume', u'vwap'} assert abs(rb2.loc[:, 'settle'].values[0] - 0.0) < 1e-3 assert rb2.shape == (345, 15) assert stk2.shape == (240, 15) assert rb2.loc[:, 'volume'].values[344] == 3366
def test_add_field(): dv = DataView() folder_path = '../output/prepared/20160601_20170601_freq=1D' dv.load_dataview(folder=folder_path) nrows, ncols = dv.data_d.shape n_securities = len(dv.data_d.columns.levels[0]) from quantos.data.dataservice import RemoteDataService ds = RemoteDataService() dv.add_field('share_amount', ds) assert dv.data_d.shape == (nrows, ncols + 1 * n_securities)
def test_remote_data_service_industry_df(): from quantos.data.calendar import Calendar cal = Calendar() ds = RemoteDataService() arr = ds.get_index_comp(index='000300.SH', start_date=20130101, end_date=20170505) symbol_arr = ','.join(arr) sec = '000008.SZ' type_ = 'ZZ' df_raw = ds.get_industry_raw(symbol=sec, type_=type_) df = ds.get_industry_daily(symbol=symbol_arr, start_date=df_raw['in_date'].min(), end_date=20170505, type_=type_) for idx, row in df_raw.iterrows(): in_date = row['in_date'] value = row['industry1_code'] if in_date in df.index: assert df.loc[in_date, sec] == value else: idx = cal.get_next_trade_date(in_date) assert df.loc[idx, sec] == value
def my_globals(request): ds = RemoteDataService() df, msg = ds.daily("000001.SH, 600030.SH, 000300.SH", start_date=20170801, end_date=20170820, fields="open,high,low,close,vwap,preclose") ds.api.close() multi_index_names = ['trade_date', 'symbol'] df_multi = df.set_index(multi_index_names, drop=False) df_multi.sort_index(axis=0, level=multi_index_names, inplace=True) dfx = df_multi.loc[pd.IndexSlice[:, :], pd.IndexSlice['close']].unstack() dfy = df_multi.loc[pd.IndexSlice[:, :], pd.IndexSlice['open']].unstack() parser = Parser() request.function.func_globals.update({ 'parser': parser, 'dfx': dfx, 'dfy': dfy })
def test_alpha_strategy(): gateway = DailyStockSimGateway() remote_data_service = RemoteDataService() prop_file_path = fileio.join_relative_path('etc', 'alpha.json') props = read_props(prop_file_path) """ props = { "benchmark": "000300.SH", "universe": "600026.SH,600027.SH,600028.SH,600029.SH,600030.SH,600031.SH", "period": "week", "days_delay": 2, "init_balance": 1e7, "position_ratio": 0.7, "start_date": 20120101, "end_date": 20170601, } """ remote_data_service.init_from_config(props) remote_data_service.initialize() gateway.init_from_config(props) context = model.Context() context.register_data_api(remote_data_service) context.register_gateway(gateway) context.register_trade_api(gateway) risk_model = model.FactorRiskModel() signal_model = model.FactorRevenueModel() cost_model = model.SimpleCostModel() risk_model.register_context(context) signal_model.register_context(context) cost_model.register_context(context) signal_model.register_func('pb_factor', pb_factor) signal_model.activate_func({'pb_factor': {'coef': 3.27}}) cost_model.register_func('my_commission', my_commission) cost_model.activate_func({'my_commission': {'myrate': 1e-2}}) strategy = DemoAlphaStrategy(risk_model, signal_model, cost_model) # strategy.register_context(context) # strategy.active_pc_method = 'equal_weight' strategy.active_pc_method = 'mc' backtest = AlphaBacktestInstance() backtest.init_from_config(props, strategy, context=context) backtest.run_alpha() backtest.save_results('../output/')
def test_add_formula_directly(): from quantos.data.dataservice import RemoteDataService ds = RemoteDataService() dv = DataView() secs = '600030.SH,000063.SZ,000001.SZ' props = {'start_date': 20160601, 'end_date': 20170601, 'symbol': secs, 'fields': 'open,close', 'freq': 1} dv.init_from_config(props, data_api=ds) dv.prepare_data() dv.add_formula("myfactor", 'close / open', is_quarterly=False) assert dv.data_d.shape == (281, 33)
def test_add_field_quarterly(): dv = DataView() folder_path = '../output/prepared/20160609_20170601_freq=1D' dv.load_dataview(folder=folder_path) nrows, ncols = dv.data_q.shape n_securities = len(dv.data_d.columns.levels[0]) from quantos.data.dataservice import RemoteDataService ds = RemoteDataService() dv.add_field('net_inc_other_ops', ds) """ dv.add_field('oper_rev', ds) dv.add_field('turnover', ds) """ assert dv.data_q.shape == (nrows, ncols + 1 * n_securities)
def test_dataview_universe(): from quantos.data.dataservice import RemoteDataService ds = RemoteDataService() dv = DataView() props = {'start_date': 20170227, 'end_date': 20170327, 'universe': '000016.SH', # 'symbol': 'rb1710.SHF,rb1801.SHF', 'fields': ('open,high,low,close,vwap,volume,turnover,' + 'roe,net_assets,' + 'total_oper_rev,oper_exp,tot_profit,int_income' ), 'freq': 1} dv.init_from_config(props, ds) dv.prepare_data()
def _test_append_custom_data(): # -------------------------------------------------------------------------------- # get custom data ds = RemoteDataService() # lb.blablabla df_raw, msg = ds.api.query("lb.secRestricted", fields="symbol,list_date,lifted_shares,lifted_ratio", filter="start_date=20170325&end_date=20170525", orderby="", data_format='pandas') assert msg == '0,' gp = df_raw.groupby(by=['list_date', 'symbol']) df_multi = gp.agg({'lifted_ratio': np.sum}) df_value = df_multi.unstack(level=1) df_value.columns = df_value.columns.droplevel(level=0) # df_value = df_value.fillna(0.0) # -------------------------------------------------------------------------------- # Format df_custom dv = DataView() dv.load_dataview('../output/prepared/20160609_20170601_freq=1D') df_value = df_value.loc[:, dv.symbol] df_custom = pd.DataFrame(index=dv.dates, columns=dv.symbol, data=None) df_custom.loc[df_value.index, df_value.columns] = df_value df_custom.fillna(0.0, inplace=True) # -------------------------------------------------------------------------------- # append DataFrame to existed DataView dv.append_df(df_custom + 1e-3 * np.random.rand(df_custom.shape[1]), field_name='custom') dv.add_formula('myfactor', 'Rank(custom)') # -------------------------------------------------------------------------------- # test this factor factor = dv.get_ts('myfactor') trade_status = dv.get_ts('trade_status') close = dv.get_ts('close') mask_sus = trade_status != u'交易'.encode('utf-8') factor_data = alphalens.utils.get_clean_factor_and_forward_returns(factor, close, mask_sus=mask_sus, periods=[5]) alphalens.tears.create_full_tear_sheet(factor_data, output_format='pdf')
def save_dataview(): from quantos.data.dataservice import RemoteDataService ds = RemoteDataService() dv = DataView() props = { 'start_date': 20141114, 'end_date': 20161114, 'universe': '000300.SH', 'fields': 'open,close,high,low,volume,turnover,vwap,' + 'oper_rev,oper_exp', 'freq': 1 } dv.init_from_config(props, data_api=ds) dv.prepare_data() dv.save_dataview(folder_path='../output/prepared')
def test_quarterly(): from quantos.data.dataservice import RemoteDataService ds = RemoteDataService() dv = DataView() secs = '600030.SH,000063.SZ,000001.SZ' props = {'start_date': 20160609, 'end_date': 20170601, 'universe': '000300.SH', 'symbol': secs, 'fields': ('open,close,' + 'pb,net_assets,' + 'total_oper_rev,oper_exp,' + 'cash_paid_invest,' + 'capital_stk,' + 'roe'), 'freq': 1} dv.init_from_config(props, data_api=ds) dv.prepare_data() folder_path = '../output/prepared' dv.save_dataview(folder_path=folder_path)
class InstManager(object): def __init__(self): self.data_api = RemoteDataService() self.inst_map = {} self.load_instruments() def load_instruments(self): fields = ['symbol', 'inst_type', 'market', 'status', 'multiplier'] res, msg = self.data_api.query_inst_info(symbol='', fields=','.join(fields), inst_type="") for _, row in res.iterrows(): inst = Instrument() dic = row.to_dict() dic = {k: v for k, v in dic.iteritems() if k in fields} inst.__dict__.update(dic) self.inst_map[inst.symbol] = inst def get_intruments(self, code): return self.inst_map.get(code, None)
def test_backtest_analyze(): ta = ana.AlphaAnalyzer() data_service = RemoteDataService() out_folder = fileio.join_relative_path("../output") ta.initialize(data_service, out_folder) print "process trades..." ta.process_trades() print "get daily stats..." ta.get_daily() print "calc strategy return..." ta.get_returns() # print "get position change..." # ta.get_pos_change_info() selected_sec = [] # list(ta.universe)[:3] if len(selected_sec) > 0: print "Plot single securities PnL" for symbol in selected_sec: df_daily = ta.daily.get(symbol, None) if df_daily is not None: ana.plot_trades(df_daily, symbol=symbol, save_folder=out_folder) print "Plot strategy PnL..." ta.plot_pnl(out_folder) print "generate report..." static_folder = fileio.join_relative_path("backtest/analyze/static") ta.gen_report(source_dir=static_folder, template_fn='report_template.html', css_fn='blueprint.css', out_folder=out_folder, selected=selected_sec)
def test_write(): from quantos.data.dataservice import RemoteDataService ds = RemoteDataService() dv = DataView() secs = '600030.SH,000063.SZ,000001.SZ' props = {'start_date': 20160601, 'end_date': 20170601, 'symbol': secs, 'fields': 'open,close,high,low,volume,pb,net_assets,ncf', 'freq': 1} dv.init_from_config(props, data_api=ds) dv.prepare_data() assert dv.data_d.shape == (281, 42) assert dv.dates.shape == (281, ) # TODO """ PerformanceWarning: your performance may suffer as PyTables will pickle object types that it cannot map directly to c-types [inferred_type->mixed,key->block1_values] [items->[('000001.SZ', 'int_income'), ('000001.SZ', 'less_handling_chrg_comm_exp'), ('000001.SZ', 'net_int_income'), ('000001.SZ', 'oper_exp'), ('000001.SZ', 'symbol'), ('000063.SZ', 'int_income'), ('000063.SZ', 'less_handling_chrg_comm_exp'), ('000063.SZ', 'net_int_income'), ('000063.SZ', 'oper_exp'), ('000063.SZ', 'symbol'), ('600030.SH', 'int_income'), ('600030.SH', 'less_handling_chrg_comm_exp'), ('600030.SH', 'net_int_income'), ('600030.SH', 'oper_exp'), ('600030.SH', 'symbol')]] """ folder_path = '../output/prepared' dv.save_dataview(folder_path=folder_path)
def test_remote_data_service_lb(): ds = RemoteDataService() # test lb.secDailyIndicator fields = "pb,pe,share_float_free,net_assets,limit_status" for res3, msg3 in [ds.query("lb.secDailyIndicator", fields=fields, filter="symbol=600030.SH&start_date=20170907&end_date=20170907", orderby="trade_date"), ds.query_lb_dailyindicator('600030.SH', 20170907, 20170907, fields)]: assert msg3 == '0,' assert abs(res3.loc[0, 'pb'] - 1.5135) < 1e-4 assert abs(res3.loc[0, 'share_float_free'] - 781496.5954) < 1e-4 assert abs(res3.loc[0, 'net_assets'] - 1.437e11) < 1e8 assert res3.loc[0, 'limit_status'] == 0 # test lb.income for res4, msg4 in [ds.query("lb.income", fields="", filter="symbol=600000.SH&start_date=20150101&end_date=20170101&report_type=408001000", order_by="report_date"), ds.query_lb_fin_stat('income', '600000.SH', 20150101, 20170101, fields="")]: assert msg4 == '0,' assert res4.shape == (8, 12) assert abs(res4.loc[4, 'oper_rev'] - 120928000000) < 1
if __name__ == '__main__': props = {} props['jsh.addr'] = 'tcp://10.2.0.14:61616' props['start_date'] = 20170702 props['end_date'] = 20170712 props['future_commission_rate'] = 0.005 props['stock_commission_rate'] = 0.005 props['stock_tax_rate'] = 0.002 props['symbol'] = '600030.SH' pnlmgr = PnlManager() from quantos.data.dataservice import RemoteDataService ds = RemoteDataService() pnlmgr.initFromConfig(props, ds) trades = [] t1 = Trade() t1.symbol = '600030.SH' t1.action = common.ORDER_ACTION.BUY t1.fill_date = 20170704 t1.fill_size = 100 t1.fill_price = 16.72 t2 = Trade() t2.symbol = '600030.SH' t2.action = common.ORDER_ACTION.SELL t2.fill_date = 20170706 t2.fill_size = 50 t2.fill_price = 16.69 t3 = Trade()
class Calendar(object): """ A calendar for manage trade date. Attributes ---------- data_api : """ def __init__(self, data_api=None): if data_api is None: self.data_api = RemoteDataService() else: self.data_api = data_api def get_trade_date_range(self, begin, end): """ Get array of trade dates within given range. Return zero size array if no trade dates within range. Parameters ---------- begin : int YYmmdd end : int Returns ------- trade_dates_arr : np.ndarray dtype = int """ filter_argument = self.data_api._dic2url({ 'start_date': begin, 'end_date': end }) df_raw, msg = self.data_api.query("jz.secTradeCal", fields="trade_date", filter=filter_argument, orderby="") if df_raw.empty: return np.array([], dtype=int) trade_dates_arr = df_raw['trade_date'].values.astype(int) return trade_dates_arr def get_last_trade_date(self, date): """ Parameters ---------- date : int Returns ------- res : int """ dt = dtutil.convert_int_to_datetime(date) delta = pd.Timedelta(weeks=2) dt_old = dt - delta date_old = dtutil.convert_datetime_to_int(dt_old) dates = self.get_trade_date_range(date_old, date) mask = dates < date res = dates[mask][-1] return res def is_trade_date(self, date): """ Check whether date is a trade date. Parameters ---------- date : int Returns ------- bool """ dates = self.get_trade_date_range(date, date) return len(dates) > 0 def get_next_trade_date(self, date): """ Parameters ---------- date : int Returns ------- res : int """ dt = dtutil.convert_int_to_datetime(date) delta = pd.Timedelta(weeks=2) dt_new = dt + delta date_new = dtutil.convert_datetime_to_int(dt_new) dates = self.get_trade_date_range(date, date_new) mask = dates > date res = dates[mask][0] return res
def __init__(self, data_api=None): if data_api is None: self.data_api = RemoteDataService() else: self.data_api = data_api
def __init__(self): self.data_api = RemoteDataService() self.inst_map = {} self.load_instruments()