async def analysis(self): self.proforma = await self.portfolio.calc_proforma(self.db, self.start_time, folioPerformance=False) self.coins = self.portfolio.coins self.coins_ts = [f.Performance for f in self.coins] self.weights = [float(a['weight']) for a in self.allocs] self.regs = [SimpleReg(fts,self.proforma)[0] for fts in self.coins_ts] self.tot_beta = sum([b * w for b,w in zip(self.regs, self.weights)]) #contribition to risk crisks = [b * w / self.tot_beta for b,w in zip(self.regs, self.weights)] self.crisk = [toDecimal(crisk) for crisk in crisks] self.port_mean, self.port_std, self.port_var = self.calc_port_stats(self.proforma) #marginal var self.marginal_vars = [] for i in range(len(self.coins)): var = await self.marginal_var(i) self.marginal_vars.append(toDecimal(var)) #return contributions self.coin_returns = [mean(ts) for ts in self.coins_ts] self.coin_ret_contrib = [r * w for r,w in zip(self.coin_returns, self.weights)] self.port_er = sum(self.coin_ret_contrib) c_rets = [r / self.port_er for r in self.coin_ret_contrib] self.c_ret = [toDecimal(ret) for ret in c_rets] self.N = len(self.coins)
def calculate_stats(self): self.basicStats = BasicStats(self.perf) n = len(self.data_frame.columns) self.n_benchmarks = n - 1 self.mddser = self.basicStats.mdd_ser self.mdd_dates = self.mddser.index self.mdds = self.mddser.values styleTime = (datetime.utcfromtimestamp(int( self.start_at))) if self.start_at else "" def day_date(date_str): if len(str(date_str)) == 1: return "0%s" % str(date_str) else: return str(date_str) def compare_date(d): return ( int(str(d.year) + day_date(d.month) + day_date(d.day)) >= int( str(styleTime.year) + day_date(styleTime.month) + day_date(styleTime.day))) if styleTime else False if n > 1: bench_values = self.data_frame[self.data_frame.columns[1]].values bench_series = Series(data=bench_values, index=self.data_frame.index) self.bench_stats = BasicStats(bench_series) self.bench_mdd = self.bench_stats.mdd_ser self.mdd_res = sorted([ (d, m, b) for d, m, b in zip(self.mdd_dates, self.mdds, self.bench_mdd) ]) self.mdd_reses = [[{ "year": str(d.year), "month": day_date(d.month), "day": day_date(d.day) }, m, b, compare_date(d)] for d, m, b in self.mdd_res] else: self.mdd_res = sorted([(d, m) for d, m in zip(self.mdd_dates, self.mdds)]) self.mdd_reses = [[{ "year": str(d.year), "month": day_date(d.month), "day": day_date(d.day) }, toDecimal(m), compare_date(d)] for d, m in self.mdd_res] self.var = toDecimal(self.basicStats.var)
def __init__(self, y, x): self.ts_y = y if type(x) is list: self.ts_x = x else: self.ts_x = [x] self.all_series = self.ts_x.copy() self.all_series.insert(0, self.ts_y) self.common_data = align_series(self.all_series) self.columns = self.common_data.columns self.Y = self.common_data[self.columns[0]].values self.X = self.common_data[self.columns[1:]].values self.X = sm.add_constant(self.X) self.model = sm.OLS(self.Y, self.X) self.reg_results = self.model.fit() betas = list(self.reg_results.params)[1:] self.betas = [toDecimal(b) for b in betas] self.pvalues = self.reg_results.pvalues[1:] self.alpha = self.reg_results.params[0] self.rsq_adj = self.reg_results.rsquared_adj self.rsq = self.reg_results.rsquared self.coin_vol = var(self.Y) if len(self.ts_x) > 1: self.factor_cov = cov(self.X[:, 1:], rowvar=False) betas = [float(betas) for betas in self.betas] self.fcmtr = matmul(self.factor_cov, betas) self.crisk = [ b * v / self.coin_vol for (b, v) in zip(betas, self.fcmtr) ] else: self.factor_cov = [cov(self.X[:, 1])] self.crisk = [self.rsq] self.crisk.append(1 - sum(self.crisk)) self.crisk_cum = cumsum(self.crisk)
def get_histogram(self): """ Calculate Histogram """ cnt, bins = histogram(self.values, bins='sqrt') self.histogram_data = list([toDecimal(b), int(c)] for b, c in zip(bins[1:], cnt))
def get_histogram(values, gt=True, val=10): """ Calculate Histogram """ cnt, bins = histogram(values, bins='sqrt') datas = list([toDecimal(b), int(c)] for b, c in zip(bins[1:], cnt)) data_list = [] val_num = 0 per = 0 for d in datas: if gt: if val < float(d[0]): per = 9.999 val_num += int(d[1]) else: data_list.append(d) else: if val > float(d[0]): per = -0.9999 val_num += int(d[1]) else: data_list.append(d) data_list.append([toDecimal(per), int(val_num)]) return data_list
async def analysis(self): if self.isPortfolio: self.item = await self.db.get_portfolio(self.item_id, modify_num=30) if self.item: performance_data = self.item.folio_ts modify_at = self.item.modify_at else: performance_data = Series() modify_at = None else: self.item = await self.db.get_coin(self.item_id) modify_at = None if self.item: performance_data = self.item.Performance else: performance_data = Series() self.risk_factors = await self.db.get_risk_factors( self.tickers, modify_at, self.isPortfolio) self.factor_ts = [r.Performance for r in self.risk_factors] self.coin_ts = performance_data self.reg_analysis = RegressionAnalysis(self.coin_ts, self.factor_ts) self.factor_names = [r.Name for r in self.risk_factors] self.factor_names.append("Unexplained") self.common_data = self.reg_analysis.common_data self.N = len(self.factor_names) self.T = len(self.common_data) self.rolling_reg = [] self.IsPortfolio = self.isPortfolio if self.T >= 12: window = 12 if self.T >= 36: window = 24 dates = self.common_data.index def day_date(date_str): if len(str(date_str)) == 1: return "0%s" % str(date_str) else: return str(date_str) styleTime = (datetime.utcfromtimestamp(int( self.started_at))) if self.started_at else "" if styleTime: month = day_date(styleTime.month) day = day_date(styleTime.day) styleDate = str(styleTime.year) + month + day else: styleDate = "" def compare_date(d): return (int(str(d["year"]) + str(d["month"]) + str(d["day"])) >= int(styleDate)) if styleDate else False for t0 in range(window, self.T): idx = range(t0 - window, t0) rolldates = dates[idx] ser = lambda c: Series(data=self.common_data.iloc[idx, c], index=rolldates) y_ts = ser(0) x_ts = [ser(c + 1) for c in range(self.N - 1)] rollreg = RegressionAnalysis(y_ts, x_ts) rollreg_dict = { "betas": rollreg.betas, "crisk": [toDecimal(crisk) for crisk in rollreg.crisk] } d = rolldates[-1] rolldate = { "year": str(d.year), "month": day_date(d.month), "day": day_date(d.day) } self.rolling_reg.append( [rolldate, rollreg_dict, compare_date(rolldate)]) self.rolling_window = window self.RollingT = len(self.rolling_reg)
def calculate_vami_chart(self): self.cum_values = (self.data_frame + 1).cumprod().values data = [] T = len(self.data_frame) for t in range(T): arr = [] cum_list = self.cum_values[t, :].tolist() cum_list = [toDecimal(cu) for cu in cum_list] for cum in cum_list: arr.append(cum) data.append(arr) dates = self.data_frame.index pydate_array = dates.to_pydatetime() date_only_array = np.vectorize(lambda s: s.strftime('%Y-%m-%d'))( pydate_array) date_only_series = pd.Series(date_only_array) dates = date_only_series.to_dict().values() dates = [{ "year": date.split("-")[0], "month": date.split("-")[1], "day": date.split("-")[2] } for date in dates] self.vami_cols = self.data_frame.columns.values.tolist() self.vami_data = list(zip(dates, data)) def day_date(date_str): if len(str(date_str)) == 1: return "0%s" % str(date_str) else: return str(date_str) styleTime = (datetime.utcfromtimestamp(int( self.start_at))) if self.start_at else "" if styleTime: month = day_date(styleTime.month) day = day_date(styleTime.day) styleDate = str(styleTime.year) + month + day else: styleDate = "" info_data = {"isStart": True, "start_val": None} def compare_date(d, infoData): try: time_str = str(d[0]["year"]) + str(d[0]["month"]) + str( d[0]["day"]) val = (int(time_str) >= int(styleDate)) if styleDate else False if val and infoData["isStart"]: infoData["isStart"] = False infoData["start_val"] = d[1] val = True if int(time_str) == int(styleDate) else val compare_data = [d[0], d[1], val] except: compare_data = d return compare_data self.vami_data = [ compare_date(list(item), info_data) for item in self.vami_data ] if info_data["start_val"] and float(info_data["start_val"][0]): self.vami_data_rate = [[ item[0], [ toDecimal(float(item[1][0]) / float(info_data["start_val"][0]), style="0.000") ], item[2] ] for item in self.vami_data] else: self.vami_data_rate = self.vami_data values = [toDecimal(val) for val in self.values] self.hist_chart_items = list(zip(dates, values)) self.hist_chart_data = [ compare_date(list(item), info_data) for item in self.hist_chart_items ]
from analytics.basicstats import BasicStats from analytics.capture_ratios import CaptureRatios from analytics.correlation_analysis import CorrelationAnalysis from analytics.helper import StatsHelper from analytics.regression_analysis import RegressionAnalysis from analytics.time_series import align_series from coin_application.portfolios import dao as folios_dao from coin_application.reports import dao as report_dao from datalib.coin import CoinPerformance from datalib.datalib import Connection from lib.utils import toDecimal, getErrorMsg, toPreTimestamp, _ from logger.client import error from settings import windows f2d = lambda a: [round(toDecimal(x), 4) for x in a] """ Calculate non-linear sensitivity / convexity regression """ def calc_tmy(fts, benchts): common_data = align_series([fts, benchts]) common_data.columns = ['Y', 'X'] common_data['XY'] = common_data['X']**2 y = common_data.iloc[:, 0].values x = common_data.iloc[:, 1:].values x = sm.add_constant(x) model = sm.OLS(y, x) res = model.fit()