def getTYData(self, code_list): # prices needed from tspy import ts prices = pd.DataFrame([]) codes = list(set(zcodeparse(code_list, 'SH600000'))) for group_idx, group in itertools.groupby(enumerate(codes), lambda it: it[0]//10): print('group: ' + str(group_idx)) _code = list(map(lambda it: it[1], group)) tsql = ''' Setsysparam(pn_cycle(),cy_1s()); Return Select datetimetostr(["date"]) as "time", ['StockID'] as 'ticker', ["price"] as "price", ["buy1"] as "buy1", ["sale1"] as "sale1" from MarketTable DateKey strtodate('{0}') to strtodate('{0}')+0.99 Of "{1}" end; '''.format(date, ",".join(_code)) _price = ts.calltsl(tsql, None, ['time', 'ticker']).squeeze() prices = pd.concat([prices, _price]) prices.sort_index(level=['time', 'ticker'], inplace=True) prices = prices.loc[prices.index.get_level_values('time') < (date + ' 14:57:00')] for col in prices: prices.loc[(prices[col] < 1e-6).values, col] = None prices.fillna(method='ffill', inplace=True) prices.index.set_levels(zcodeparse(prices.index.levels[1], '600000.SH'), level='ticker', inplace=True) # 存储prices saveData(prices, 'prices') return prices
def tsbeta(self, index, codes, start_date, end_date, params): codes = zlist(zcodeparse(codes, formatlike='SH600000')) index = zcodeparse(index, formatlike='SH600000') start_date = ztimeparse(start_date, '%Y-%m-%d') end_date = ztimeparse(end_date, '%Y-%m-%d') ns = {'1M': 21, '3M': 63, '6M': 126, '12M': 252}[params['window']] tsltemp = Template(''' stockarray:=array('{{codes}}'); begt:=strtodate('{{startdate}}'); endt:=strtodate('{{enddate}}'); datearray:= MarketTradeDayQk(begt, endt); total:=array(); SetSysParam(PN_Precision(),6); for j:=0 to length(datearray)-1 do begin SetSysParam(pn_cycle(), cy_day()); t1 := datearray[j]; setsysparam(pn_date(), t1); t0 := ref(sp_time(), {{ns}}); for i:=0 to length(stockarray)-1 do begin setsysparam(Pn_stock(), stockarray[i]); total union= ``array('ticker': stockarray[i], 'date': datetostr(datearray[j]), 'value': StockBeta('{{index}}', t0, t1)); end end return total; ''') tsl = tsltemp.render(codes="','".join(codes), startdate=start_date, enddate=end_date, index=index, ns=ns) return self.calltsl(tsl, None, ['date', 'ticker'])
def tsvolatility2(self, codes, start_date, end_date, params): codes = zlist(zcodeparse(codes, formatlike='SH600000')) start_date = ztimeparse(start_date, '%Y-%m-%d') end_date = ztimeparse(end_date, '%Y-%m-%d') ns = {'1M': 21, '3M': 63, '6M': 126, '12M': 252}[params['window']] tsql = ''' datearray:= MarketTradeDayQk(strtodate('2005-01-01'), strtodate('{0}')); results := array(); for i:=0 to length(datearray)-1 do begin results[i] := datetostr(datearray[i]); end return results; '''.format(start_date) calendar = zsqueeze(ts.calltsl(tsql)) calendar = calendar.apply(lambda t: t.decode('utf-8')).values calendar = np.sort(calendar) data_start_date = calendar[calendar < start_date][-ns] pri = self.price(codes, data_start_date, end_date, {'pn_rate': 1}) pri.loc[pri['amount'] < 1e-6, 'ret'] = None ret2 = pri['ret']**2 def _std(s): v = s.dropna().values if v.shape[0] < 2: return None return np.sqrt(v.sum() / (len(v) - 1)) results = ret2.groupby(level='ticker').apply(_std) return results
def tsfactor(self, codes, start_date, end_date, factor_tsql): codes = zlist(zcodeparse(codes, formatlike='SH600000')) start_date = ztimeparse(start_date, '%Y-%m-%d') end_date = ztimeparse(end_date, '%Y-%m-%d') tsltemp = Template(''' stockarray:=array('{{codes}}'); begt:=strtodate('{{startdate}}'); endt:=strtodate('{{enddate}}'); datearray:= MarketTradeDayQk(begt, endt); total:=array(); SetSysParam(PN_Precision(),6); setsysparam(Pn_rate(), 0); for i:=0 to length(stockarray)-1 do begin for j:=0 to length(datearray)-1 do begin setsysparam(Pn_stock(), stockarray[i]); setsysparam(pn_date(), datearray[j]); rdate := NewReportDateOfEndT2(datearray[j]); total union= ``array('ticker': stockarray[i], 'date': datetostr(datearray[j]), 'value': {{factor_tsql}}); end end return total; ''') tsl = tsltemp.render(codes="','".join(codes), startdate=start_date, enddate=end_date, factor_tsql=factor_tsql) return self.calltsl(tsl, None, ['date', 'ticker']).squeeze()
def shares(self, codes, start_date, end_date): codes = zlist(zcodeparse(codes, formatlike='SH600000')) start_date = ztimeparse(start_date, '%Y-%m-%d') end_date = ztimeparse(end_date, '%Y-%m-%d') tsltemp = Template(''' stockarray:=array('{{codes}}'); begt:=strtodate('{{startdate}}'); endt:=strtodate('{{enddate}}'); total:=array(); dates:=MarketTradeDayQk(begt,endt); for i:=0 to length(stockarray)-1 do begin for j:=0 to length(dates)-1 do begin total union= ``array( 'ticker':stockarray[i], 'date':datetostr(dates[j]), 'totalshares':Spec(StockTotalShares(dates[j]),stockarray[i]), 'floatshares':Spec(StockNegotiableShares(dates[j]),stockarray[i])); end end return total; ''') tsl = tsltemp.render(codes="','".join(codes), startdate=start_date, enddate=end_date) return self.calltsl(tsl, None, ['date', 'ticker'])
def statement(self, table_name, entries, codes, start_date, end_date): codes = zlist(zcodeparse(codes, formatlike='SH600000')) start_date = ztimeparse(start_date, '%Y-%m-%d') end_date = ztimeparse(end_date, '%Y-%m-%d') table_num = {'balance': '44', 'income': '46', 'cash': '48'} tsltemp = Template(''' SetSysParam('ReportMode',-1); Return select ['StockID'] as 'ticker', ['StockName'] as 'name', ['截止日'] as 'report_period', ['公布日'] as 'ann_date' {%- for tsk, myk in entries.items() -%} ,\n['{{tsk}}'] as '{{myk}}' {%- endfor %} from infotable {{tnum}} of array('{{codes}}') where ['截止日']>=DateToInt(strtodate('{{startdate}}')) and ['公布日']<=DateToInt(strtodate('{{enddate}}')) end; ''') tsl = tsltemp.render(entries=entries, codes="','".join(codes), startdate=start_date, enddate=end_date, tnum=table_num[table_name]) return self.calltsl(tsl, None, ['ann_date', 'ticker', 'report_period'])
def callfunc(self, func, args): fail, data, _ = self.ts.RemoteCallFunc(func, args, {}) if not fail: data["ticker"] = zcodeparse(data["ticker"], "600000.SH") return pd.DataFrame(data).set_index(["date", "ticker"]) else: raise Exception("Error when execute callfunc.")
def fsdata_ttm(self, entry, codes, start_date, end_date): codes = zlist(zcodeparse(codes, formatlike='SH600000')) start_date = ztimeparse(start_date, '%Y-%m-%d') end_date = ztimeparse(end_date, '%Y-%m-%d') entries = { 'revenue': 46002, 'net_income': 46033, 'net_income2major': 46078, 'cost': 46005, 'net_value2major': 44140, 'total_asset': 44059, 'total_debt': 44097, 'float_asset': 44028, 'float_debt': 44083, 'inventory': 44019, 'operating_cashflow': 48018 } tsltemp = Template(''' stockarray:=array('{{codes}}'); begt:=strtodate('{{startdate}}'); endt:=strtodate('{{enddate}}'); total:=array(); dates:=MarketTradeDayQk(begt,endt); for i:=0 to length(stockarray)-1 do begin for j:=0 to length(dates)-1 do begin setsysparam(pn_stock(),stockarray[i]); setsysparam(pn_date(), dates[j]); RDate:=NewReportDateOfEndT2(dates[j]); v:=Last12MData(RDate,{{entrynum}}); total union= ``array('ticker':stockarray[i], 'date':datetostr(dates[j]), '{{entry}}':v); end end return total; ''') tsl = tsltemp.render(codes="','".join(codes), startdate=start_date, enddate=end_date, entry=entry, entrynum=str(entries[entry])) return self.calltsl(tsl, None, ['date', 'ticker']).squeeze()
def tsmomentum(self, codes, start_date, end_date, params): codes = zlist(zcodeparse(codes, formatlike='SH600000')) start_date = ztimeparse(start_date, '%Y-%m-%d') end_date = ztimeparse(end_date, '%Y-%m-%d') ns = {'1M': 21, '3M': 63, '6M': 126, '12M': 252}[params['window']] tsltemp = Template(''' stockarray:=array('{{codes}}'); begt:=strtodate('{{startdate}}'); endt:=strtodate('{{enddate}}'); datearray:= MarketTradeDayQk(begt, endt); total:=array(); setsysparam(Pn_precision(), 6); t0 := array(); t1 := datearray; setsysparam(pn_stock(), 'SH000300'); for j:=0 to length(t1)-1 do begin setsysparam(pn_date(), t1[j]); t0 union= array(nday({{ns}}+1, 't0', strtodate(datetimetostr(sp_time())))[0]); end t0 := sselect ['t0'] from t0 end; for i:=0 to length(stockarray)-1 do begin for j:=0 to length(t1)-1 do begin setsysparam(Pn_stock(), stockarray[i]); setsysparam(Pn_rate(), 1); total union= ``array('ticker': stockarray[i], 'date': datetostr(t1[j]), 'momentum': stockzf(t0[j],t1[j])); end end return total; ''') tsl = tsltemp.render(codes="','".join(codes), startdate=start_date, enddate=end_date, ns=ns) return self.calltsl(tsl, None, ['date', 'ticker'])
def tsvolatility(self, codes, start_date, end_date, params): codes = zlist(zcodeparse(codes, formatlike='SH600000')) start_date = ztimeparse(start_date, '%Y-%m-%d') end_date = ztimeparse(end_date, '%Y-%m-%d') ns = {'1M': 21, '3M': 63, '6M': 126, '12M': 252}[params['window']] tsql = ''' datearray:= MarketTradeDayQk(strtodate('2005-01-01'), strtodate('{0}')); results := array(); for i:=0 to length(datearray)-1 do begin results[i] := datetostr(datearray[i]); end return results; '''.format(start_date) calendar = zsqueeze(ts.calltsl(tsql)) calendar = calendar.apply(lambda t: t.decode('utf-8')).values calendar = np.sort(calendar) data_start_date = calendar[calendar < start_date][-ns] pri = self.price(codes, data_start_date, end_date, {'pn_rate': 1}) pri.loc[pri['amount'] < 1e-6, 'ret'] = None ret = pri['ret'].sort_index(level=['ticker', 'date']) def _std(s): v = s[-ns:].dropna().values if v.shape[0] < 2: return None return np.std(v, ddof=1) results = ret.groupby(level='ticker').apply(_std) ''' results = pri.groupby(level='ticker', as_index=False)['ret']\ .rolling(ns, min_periods=2)\ .apply(_std, raw=False) results.index = results.index.droplevel(level=0) ''' return results
def price(self, codes, start_date, end_date, params={}): codes = zlist(zcodeparse(codes, formatlike='SH600000')) start_date = ztimeparse(start_date, '%Y-%m-%d') end_date = ztimeparse(end_date, '%Y-%m-%d') pn_rate = params.setdefault('pn_rate', 0) tsltemp = Template(''' stockarray:=array('{{codes}}'); begt:=strtodate('{{startdate}}'); endt:=strtodate('{{enddate}}'); datearray:= MarketTradeDayQk(begt, endt); total:=array(); for i:=0 to length(stockarray)-1 do begin for j:=0 to length(datearray)-1 do begin setsysparam(Pn_stock(), stockarray[i]); setsysparam(Pn_rate(), {{pn_rate}}); setsysparam(pn_date(), datearray[j]); total union= ``array('ticker': stockarray[i], 'date': datetostr(datearray[j]), 'open': open(), 'high': high(), 'low': low(), 'prevclose': StockPrevClose3(), 'close': close(), 'ret': stockzf3(), 'vol': vol(), 'amount': amount()); end end return total; ''') tsl = tsltemp.render(codes="','".join(codes), startdate=start_date, enddate=end_date, pn_rate=pn_rate) return self.calltsl(tsl, None, ['date', 'ticker'])
def analyze(self, date, acct, params={'assetclass': '股票', 'action': '买卖'}): # data to be analyzed ords = self.allorders[((self.allorders['资金帐号'] == acct.zfill(12)) & (self.allorders['日期'] == date)).values] knos = self.allknocks[((self.allknocks['资金帐号'] == acct.zfill(12)) & (self.allknocks['日期'] == date)).values] if params['assetclass'] == '股票': ords = ords[ords['证券类别'] == '股票'] knos = knos[knos['证券类别'] == '股票'] if params['action'] == '买卖': ords = ords[ords['交易类型'] == '正常买卖'] knos = knos[knos['交易类型'] == '正常买卖'] ords.index = range(ords.shape[0]) knos.index = range(knos.shape[0]) ords.loc[:, '证券代码'] = zcodeparse(ords['证券代码'], '600000.SH') knos.loc[:, '证券代码'] = zcodeparse(knos['证券代码'], '600000.SH') ords['消息类别'] = 'Order' knos['消息类别'] = 'Knock' # 天软获取证券市场价格 # prices = self.getTYData(ords['证券代码']) # 读取已存储的市场价格数据 store = pd.HDFStore('tradeanalyst_data.h5') prices = store['prices'] store.close() # analyze records = nested_dict() for _, order in ords.iterrows(): # 合并orders ticker, bs = order['证券代码'], order['委托方向'] if bs in {'买入', '卖出'}: records[ticker, bs][order['下单时间']] = order.squeeze() elif bs == '撤单': bs = ords.loc[((ords['委托方向'].isin({'买入', '卖出'})) & (ords['合同序号'] == order['合同序号'])).values, '委托方向'].squeeze() records[ticker, bs][order['下单时间']] = order.squeeze() else: raise Exception("unknown ord['委托方向']") for _, kno in knos.iterrows(): # 合并knocks ticker, bs = kno['证券代码'], kno['买卖方向'] records[ticker, bs][kno['成交时间']] = kno.squeeze() trade_intents = nested_dict() for ticker, bs in records: # 将委托及其成交、撤单信息合并 bs_astk = OrderedDict(sorted(records[ticker, bs].items(), key=lambda s: s[0])) for time in bs_astk: if bs_astk[time]['消息类别'] == 'Order' and bs_astk[time]['撤单标志'] != '撤单':#撤单时委托方向也可能是买入或卖出,为实现同合同号数据合并,以撤单标志判断该笔记录 trade_intents[ticker, bs][bs_astk[time]['合同序号']] = {'ticker': bs_astk[time]['证券代码'], 'bs': bs_astk[time]['委托方向'], 'date_time': time, 'pit_price': prices.loc[(time, ticker), 'price'], 'pit_b1': prices.loc[(time, ticker), 'buy1'], 'pit_s1': prices.loc[(time, ticker), 'sale1'], 'order_price': bs_astk[time]['委托价格'], 'order_qty': bs_astk[time]['委托数量'], 'status': bs_astk[time]['委托状态'], 'finished_qty': 0,#成交量 'finished_amt': 0#成交金额 } elif bs_astk[time]['消息类别'] == 'Knock': # 此合同号下完成成交量 trade_intents[ticker, bs][bs_astk[time]['合同序号']]['finished_qty'] = bs_astk[time]['成交数量'] # 此合同号下完成成交金额 trade_intents[ticker, bs][bs_astk[time]['合同序号']]['finished_amt'] = bs_astk[time]['成交金额'] # 合并报单数据 trade_result = defaultdict(dict) for ticker, bs in trade_intents: # 将相关委托合并 _qty = 0 # 剩余量 _bs = '' # 委托方向 _ckey = '' # 合同号 for key,value in trade_intents[ticker, bs].items(): if value['order_qty'] > _qty + 100 or value['bs'] != _bs: # 此次需求结束,开始下一次交易 _qty = value['order_qty'] - value['finished_qty'] _bs = value['bs'] _ckey = key trade_result[ticker, bs, _ckey] = {'ticker': value['ticker'], 'bs': value['bs'], 'con_list':[key], #合同号序列 'pit_price_list': [value['pit_price']], #最新价序列 'pit_b1_list': [value['pit_b1']], #买一价序列 'pit_s1_list': [value['pit_s1']], #卖一价序列 'order_price_list': [value['order_price']], #委托价序列 'order_qty_list': [value['order_qty']], #委托数量序列 'status_list': [value['status']], #委托状态序列 'finished_qty_list': [value['finished_qty']], #成交量序列 'finished_amt_list': [value['finished_amt']], #成交金额序列 're_qty': _qty,#未成交量 'time': [value['date_time']], # 订单发出时间 'num_order': 0, #撤补次数 'time_fee': 0, #花费时间 'ave_price': 0 #成交均价 } else: # 继续完成此次委托 trade_result[ticker, bs, _ckey]['con_list'].append(key) trade_result[ticker, bs, _ckey]['pit_price_list'].append(value['pit_price']) trade_result[ticker, bs, _ckey]['pit_b1_list'].append(value['pit_b1']) trade_result[ticker, bs, _ckey]['pit_s1_list'].append(value['pit_s1']) trade_result[ticker, bs, _ckey]['order_price_list'].append(value['order_price']) trade_result[ticker, bs, _ckey]['order_qty_list'].append(value['order_qty']) trade_result[ticker, bs, _ckey]['status_list'].append(value['status']) trade_result[ticker, bs, _ckey]['finished_qty_list'].append(value['finished_qty']) trade_result[ticker, bs, _ckey]['finished_amt_list'].append(value['finished_amt']) trade_result[ticker, bs, _ckey]['time'].append(value['date_time']) # 剩余未成交数量 _qty = _qty - value['finished_qty'] trade_result[ticker, bs, _ckey]['re_qty'] = _qty # 成本核算:时间、交易、撤补量 for key,value in trade_result.items(): if value['re_qty'] < 100: # 撤补次数 trade_result[key]['num_order'] = len(value['con_list']) - 1 # 花费时间 trade_result[key]['time_fee'] = 0 if len(value['con_list']) == 1 \ else (datetime.datetime.strptime(value['time'][-1], "%Y-%m-%d %H:%M:%S") - \ datetime.datetime.strptime(value['time'][0], "%Y-%m-%d %H:%M:%S")).seconds / 60 # 成交均价 trade_result[key]['ave_price'] = np.matmul(value['finished_qty_list'], value['order_price_list']) / np.sum(value['finished_qty_list']) else: trade_result[key]['num_order'] = len(value['con_list']) - 1 trade_result[key]['time_fee'] = '未完成' trade_result[key]['ave_price'] = '未成交' if np.sum(value['finished_qty_list']) == 0 else np.matmul(value['finished_qty_list'], value['order_price_list']) / np.sum(value['finished_qty_list']) return trade_result
def fsdata_raw(self, entry, codes, start_date, end_date): codes = zlist(zcodeparse(codes, formatlike='SH600000')) start_date = ztimeparse(start_date, '%Y-%m-%d') end_date = ztimeparse(end_date, '%Y-%m-%d') entries = { 'net_value2major': 44140, 'total_asset': 44059, 'inventory': 44019, 'receivable': 44009, 'revenue': 46002, 'operating_profit': 46015, 'cost': 46005, 'net_income2major': 46078 } tsltemp = Template(''' stockarray:=array('{{codes}}'); begt:=strtodate('{{startdate}}'); endt:=strtodate('{{enddate}}'); datearray:= MarketTradeDayQk(begt, endt); total:=array(); for i:=0 to length(stockarray)-1 do begin for j:=0 to length(datearray)-1 do begin setsysparam(pn_stock(),stockarray[i]); setsysparam(pn_date(), datearray[j]); RDate:=NewReportDateOfEndT2(datearray[j]); RtDate:=PreviousReportDate(RDate); Rt2Date:=PreviousReportDate(RtDate); RyDate:=strtoint(FormatDateTime('yyyy',inttodate(RtDate))+'1231'); Ry2Date:=strtoint(FormatDateTime('yyyy',inttodate(Rt2Date))+'1231'); RpDate:=PreviousReportDateOfQuarter(RDate,1); RptDate:=PreviousReportDate(RpDate); RpyDate:=strtoint(FormatDateTime('yyyy',inttodate(RptDate))+'1231'); v1:=ReportOfAll({{entrynum}},RDate); v2:=ReportOfAll({{entrynum}},RyDate); v3:=ReportOfAll({{entrynum}},RtDate); v4:=ReportOfAll({{entrynum}},RpDate); v5:=ReportOfAll({{entrynum}},RpyDate); v6:=ReportOfAll({{entrynum}},RptDate); v7:=ReportOfAll({{entrynum}},Rt2Date); v8:=ReportOfAll({{entrynum}},Ry2Date); total union= ``array('ticker':stockarray[i], 'date':datetostr(datearray[j]), 'latest_report':datetostr(inttodate(RDate)), 'latest_data':v1, 'latest_annual_report':datetostr(inttodate(RyDate)), 'latest_annual_data': v2, 'latest_lastyear_report':datetostr(inttodate(RtDate)), 'latest_lastyear_data': v3, 'latest_annual2_report': Ry2Date, 'latest_annual2_data': v8, 'latest_last2year_report': Rt2Date, 'latest_last2year_data': v7, 'latest_prev_report':datetostr(inttodate(RpDate)), 'latest_prev_data': v4, 'latest_prev_annual_report':datetostr(inttodate(RpyDate)), 'latest_prev_annual_data': v5, 'latest_prev_lastyear_report':datetostr(inttodate(RptDate)), 'latest_prev_lastyear_data': v6 ); end end return total; ''') tsl = tsltemp.render(codes="','".join(codes), startdate=start_date, enddate=end_date, entrynum=entries[entry]) return self.calltsl(tsl, None, ['date', 'ticker'])