Best Python code snippet using pandera_python
classes_backt_GAMMA_1.py
Source:classes_backt_GAMMA_1.py  
1import numpy as np2import pandas as pd3import matplotlib as mpl4import scipy5import matplotlib.pyplot as plt6import yfinance as yf7from scipy.stats import skew, kurtosis, chi28from datetime import datetime as dt9import datetime10import importlib11from scipy.stats import skew, kurtosis, chi2, linregress12from scipy.optimize import minimize13from numpy import linalg as LA14import random1516import classes_backt_GAMMA_117importlib.reload(classes_backt_GAMMA_1)1819import functions_backt_GAMMA_1 as functions20importlib.reload(functions)2122import tickers_backt_GAMMA_1 as tickers_list23importlib.reload(tickers_list)242526class backtest():27    28    def __init__(self, ticker, benchmark , length):29        self.ticker = ticker30        self.benchmark = benchmark31        self.length = length32        33        #load_time_series34        self.data_cut = 0.0035        self.data_type = None36        37        #Compute strategy38        self.pnl_mean = 0.0039        self.pnl_volatility = 0.0040        self.pnl_sharpe = 0.0041        self.nb_trades = 0.0042        43        44        #Risk merics45        self.win_rate = 0.0046        self.average_win = 0.0047        self.average_loose = 0.0048        49        self.nb_decimals = 350    51    52    def load_time_series(self, data_cut, data_type):53        self.data_cut = data_cut54        self.data_type = data_type55        56        #length - calculo57        hoy = dt.now()58        start = hoy - datetime.timedelta(days = self.length)59        60        61        #Get market data62        accion = yf.download(tickers = self.ticker, start = start , end = hoy )63        benchmark = yf.download(tickers = self.benchmark, start = start , end = hoy )64        65        66        # Create a table of returns - stock67        self.data = pd.DataFrame()68        self.data['Open'] = accion['Open']69        self.data['High'] = accion['High']70        self.data['Low'] = accion['Low']71        self.data['Close'] = accion['Adj Close']72        self.data['Close_prev'] = accion['Adj Close'].shift(1)73        self.data['Ret'] = accion['Adj Close'] / accion['Adj Close'].shift(1) - 174        self.data['Ret_cum'] = self.data['Ret'].cumsum()75        self.data['Date'] = pd.to_datetime(accion.index, dayfirst = True)76        self.data['Volume'] = accion['Volume']7778        self.data = self.data.dropna()79        self.data = self.data.reset_index(drop = True)80        81        self.data.index = self.data['Date']82        83        84        # Create a table of returns - benchmark85        self.dataB = pd.DataFrame()86        self.dataB['Open'] = benchmark['Open']87        self.dataB['High'] = benchmark['High']88        self.dataB['Low'] = benchmark['Low']89        self.dataB['Close'] = benchmark['Adj Close']90        self.dataB['Ret'] = benchmark['Adj Close'] / benchmark['Adj Close'].shift(1) - 191        self.dataB['Ret_cum'] = self.dataB['Ret'].cumsum()92        self.dataB['Date'] = pd.to_datetime(benchmark.index, dayfirst = True)93        self.dataB['Volume'] = benchmark['Volume']9495        self.dataB = self.dataB.dropna()96        self.dataB = self.dataB.reset_index(drop = True)97        98        self.dataB.index = self.dataB['Date']99        100        101        #Definiendo in_sample & out_of_sample para data102        cut = int(self.data_cut * self.data.shape[0])103        104        if self.data_type == 'in_sample':105            df = self.data.head(cut) #Me devuelve el 70% de los dias106       107        elif self.data_type == 'out_of_sample':108            df = self.data.tail(self.data.shape[0] - cut) #Me devuelve el 30% de los dias109        110        df = df.reset_index(drop = True)111        112        self.dataframe_data = df113        114        115        #Definiendo in_sample & out_of_sample para dataB116        cut = int(self.data_cut * self.dataB.shape[0])117        118        if self.data_type == 'in_sample':119            dfB = self.dataB.head(cut) #Me devuelve el 70% de los dias120       121        elif self.data_type == 'out_of_sample':122            dfB = self.dataB.tail(self.data.shape[0] - cut) #Me devuelve el 30% de los dias123        124        dfB = dfB.reset_index(drop = True)125        126        self.dataframe_dataB = dfB127        128    129        return  self.dataframe_data130    131    132    def synchronise_timeseries(self): 133        #Load time series134        t1 = self.dataframe_strategy135        t2 = self.dataframe_dataB136        137        138        #Sincronizar series de tiempo139        timestamp1 = list(t1['Date'].values)140        timestamp2 = list(t2['Date'].values)141        timestamps = list(set(timestamp1) & set(timestamp2)) #Que me agarre solo los dias que estan en ambos142        143        144        #Sincronizando la serie de tiempo para x1145        t1_sync = t1[t1['Date'].isin(timestamps)] #Le pido que filtre solo por los valores que esten en timestamps146        t1_sync.sort_values(by = 'Date', ascending = True) #Ordeno los valores por fechas de manera ascendente147        t1_sync = t1_sync.reset_index(drop = True)148        149        150        #Sincronizando la serie de tiempo para x2151        t2_sync = t2[t2['Date'].isin(timestamps)] #Le pido que filtre solo por los valores que esten en timestamps152        t2_sync.sort_values(by = 'Date', ascending = True) #Ordeno los valores por fechas de manera ascendente153        t2_sync = t2_sync.reset_index(drop = True)154        155        156        #Tabla de retornos para el ticker y el benchmark157        t = pd.DataFrame()158        159        t['Date'] = t1_sync['Date']160        161        t['Price_1'] = t1_sync['Cum_pnl_daily']162        t['Price_2'] = t2_sync['Close']163        164        t['Price_1_previous'] = t1_sync['Cum_pnl_daily'].shift(1)165        t['Price_2_previous'] = t2_sync['Close'].shift(1)166        167        t = t.drop(t.index[[0]])168        t = t.drop(t.index[[0]])169        170        171        t['Return_1'] = t1_sync['Returns_daily']172        t['Return_2'] = t2_sync['Ret']173        174        175        #Compute vectors of returns176        returns_ticker = t['Return_2'].values #Y177        returns_benchmark = t['Return_1'].values #X 178        179        return returns_ticker, returns_benchmark, t180    181    182    def compute_strategy(self, param_1, param_2, param_3, capital, k_position, strategy):183        self.capital = capital184        self.k_position = k_position185        self.strategy_used = strategy186        187        self.param_1 = param_1188        self.param_2 = param_2189        self.param_3 = param_3190        self.strategy = self.strategy_used(ticker = self.ticker, benchmark = self.benchmark, length = self.length,191                                            data_cut = self.data_cut, data_type = self.data_type,192                                            param_1 = param_1, param_2 = param_2, param_3 = param_3, k_position = self.k_position)193        194    195    196    def compute_account(self, bool_plot = False):197        _, mtx_backtest, columns = self.strategy_used(ticker = self.ticker, benchmark = self.benchmark,198                                                             length = self.length, data_cut = self.data_cut, 199                                                             data_type = self.data_type, param_1 = self.param_1, 200                                                             param_2 = self.param_2, param_3 = self.param_3, k_position = self.k_position)201        202        df1 = pd.DataFrame(data = mtx_backtest, columns = columns)203        df1 = df1.dropna()204        df1 = df1.reset_index(drop = True)205        df1['Cum_pnl_daily'] = np.cumsum(df1['Pnl_daily']) + self.capital206        self.dataframe_strategy = df1207        208        self.dataframe_strategy['Returns_daily'] = self.dataframe_strategy['Cum_pnl_daily'].pct_change()[1:]209        self.dataframe_strategy['Returns_daily'] = self.dataframe_strategy['Returns_daily']\210            .replace([np.inf, -np.inf], 0) #Le saco los valores infinitos211        212        self.dataframe_strategy['Cum_returns_daily'] = np.cumsum(self.dataframe_strategy['Returns_daily'])213        214        self.dataframe_strategy['Date'] = self.dataframe_data['Date']215        216        #Compute Sarpe ratio and numbers of trades217        vec_pnl = df1['Returns_daily'].values218        self.pnl_mean = np.round(np.mean(vec_pnl[1:]) * 252, 4)219        self.pnl_volatility = np.round(np.std(vec_pnl[1:]) * np.sqrt(252), 4)220        self.pnl_sharpe = np.round(self.pnl_mean / self.pnl_volatility, 4)221        self.resume = df1[df1['Trade'] == 1]222        self.nb_trades = len(self.resume)223        224225        226        if bool_plot == True:227            self.plot_pnl_strategy()228            self.plot_rdto_strategy()229        230        231        return self.dataframe_strategy, self.resume232    233        234    235    def plot_pnl_strategy(self):236        equity_curve = pd.DataFrame()237        window = 50238        239        equity_curve['Promedio cada ' + str(window)] = \240            self.dataframe_strategy['Cum_pnl_daily'].rolling(window = window).mean()241            242        equity_curve['Desviacion cada ' + str(window)] = \243            equity_curve['Promedio cada ' + str(window)].rolling(window = window).std()244        245        equity_curve['Desviacion cada ' + str(window) + '+'] = (equity_curve['Promedio cada ' + str(window)])\246            + (equity_curve['Desviacion cada ' + str(window)])247            248        equity_curve['Desviacion cada ' + str(window) + '-'] = equity_curve['Promedio cada ' + str(window)]\249            - equity_curve['Desviacion cada ' + str(window)]250        251        #Equity curve252        253        plt.figure()254        plt.title('Cumulative P&L of strategy with ' + self.ticker  + '\n' \255                  + 'Return(Y) ' + str(np.round(self.pnl_mean, 3))  + '\n' \256                  + 'Volatility(Y) ' + str(np.round(self.pnl_volatility, 3))  + '\n' \257                  + 'Sharpe(Y) ' + str(np.round(self.pnl_sharpe, 3))) 258            259        plt.xlabel('Time')260        plt.ylabel('Price')261        262        plt.plot(self.dataframe_strategy['Cum_pnl_daily'], 'k', label = 'Strategy')263        plt.plot(equity_curve['Promedio cada ' + str(window)], 'y', label = 'Promedio cada ' + str(window))264        plt.plot(equity_curve['Desviacion cada ' + str(window) + '+'], 'g', label = 'Desviacion cada ' + str(window) + ' +')265        plt.plot(equity_curve['Desviacion cada ' + str(window) + '-'], 'r', label = 'Desviacion cada ' + str(window) + ' -')266        267        268        plt.grid()269        plt.legend()270        plt.show()271272        273    274    def plot_rdto_strategy(self):275        #Equity curve rdto276        plt.figure()277        plt.title('Cumulative Return of strategy with ' + self.ticker  + '\n' \278                  + ' / K_position ' + str(np.round(self.k_position, 3))\279                  + ' / Nb trades ' + str(np.round(self.nb_trades, 3))  + '\n' \280                  + ' / Return(Y) ' + str(np.round(self.pnl_mean, 3))\281                  + ' / Volatility(Y) ' + str(np.round(self.pnl_volatility, 3))  + '\n' \282                  + ' / Sharpe(Y) ' + str(np.round(self.pnl_sharpe, 3))) 283            284        plt.xlabel('Time')285        plt.ylabel('Price')286        287        plt.plot(self.dataframe_strategy['Cum_returns_daily'], 'k', label = 'Strategy')288        289        plt.grid()290        plt.legend()291        plt.show()292        293    294295    296    297    def risk_metrics(self, nb_decimals = 3, bool_print = False, bool_plot = False):298        #Parameters299        total_win_trades_long = np.where((self.dataframe_strategy['Pnl_trade'] > 0) &\300                                              (self.dataframe_strategy['Position'].shift(1) == 1), 1, 0).sum()301302        total_trades_long = np.where((self.dataframe_strategy['Exit_signal'] == 1) &\303                                          (self.dataframe_strategy['Position'].shift(1) == 1), 1, 0).sum()304        305            306        total_win_trades_short = np.where((self.dataframe_strategy['Pnl_trade'] > 0) &\307                                              (self.dataframe_strategy['Position'].shift(1) == -1), 1, 0).sum()308309        total_trades_short = np.where((self.dataframe_strategy['Exit_signal'] == 1) &\310                                          (self.dataframe_strategy['Position'].shift(1) == -1), 1, 0).sum()        311        312        313        #Profits314        self.average_win = np.round(np.where(self.dataframe_strategy['Pnl_trade'] > 0, self.dataframe_strategy['Pnl_trade'], 0).sum()\315             / self.dataframe_strategy['Trade'].sum(), nb_decimals) #Dollars316            317        318        self.average_loose = np.round(np.where(self.dataframe_strategy['Pnl_trade'] < 0, self.dataframe_strategy['Pnl_trade'], 0).sum()\319             / self.dataframe_strategy['Trade'].sum(), nb_decimals) #Dollars320        321        322        self.best_trade = np.round(self.dataframe_strategy['Pnl_trade'].max(), nb_decimals)323        324        325        self.worst_trade = np.round(self.dataframe_strategy['Pnl_trade'].min(), nb_decimals)326        327        328        self.total_pnl = np.round(list(self.dataframe_strategy['Cum_pnl_daily'])[-1], nb_decimals)329        330        331        #vcont = Variation coefficient of net profit332        self.vcont = np.round(np.std(self.resume['Pnl_trade']) / self.average_win, nb_decimals)333        334        335        self.risk_benefit_ratio = np.round(self.average_win / abs(self.average_loose), nb_decimals)336        337        338        self.drawdown = pd.DataFrame()339        self.drawdown = (self.dataframe_strategy['Cum_pnl_daily'] - self.dataframe_strategy['Cum_pnl_daily'].cummax())\340            / self.dataframe_strategy['Cum_pnl_daily'].cummax()341        342        self.drawdown = self.drawdown.replace([np.inf, -np.inf], 0)343        344        self.drawdown_max = np.round(self.drawdown.min(), nb_decimals)345        self.drawdown_promedio = np.round(self.drawdown.mean(), nb_decimals)346        347        348        #Probabilities349        self.win_rate = np.round(np.where(self.dataframe_strategy['Pnl_trade'] > 0, 1, 0).sum()\350            / self.dataframe_strategy['Trade'].sum(), nb_decimals)351        352        353        self.win_rate_long = np.round(total_win_trades_long / total_trades_long, nb_decimals)354        355        356        self.win_rate_short = np.round(total_win_trades_short / total_trades_short, nb_decimals)357        358        359        self.average_win_p = np.round(np.where(self.dataframe_strategy['Pnl_trade'] >= self.average_win, 1, 0).sum()\360            / self.dataframe_strategy['Trade'].sum(), nb_decimals)361        362        363        self.average_loose_p = np.round(np.where(self.dataframe_strategy['Pnl_trade'] <= self.average_loose, 1, 0).sum()\364            / self.dataframe_strategy['Trade'].sum(), nb_decimals)365        366        367        #Linear regression368        self.x, self.y, self.t = self.synchronise_timeseries()369        370        slope, intercept, r_value, p_value, std_err = linregress(self.x,self.y) #slope = Beta371        372        self.beta = np.round(slope, nb_decimals)373        self.alpha = np.round(intercept, nb_decimals)374        self.p_value = np.round(p_value, nb_decimals)375        376        self.null_hypothesis = p_value > 0.05 377        #Si p_value < 0.05 reject null hypothesis 378        #La null hypothesis, si la puedo rechazar me sirve para saber si los datos son estadisticamente significativos379        380        self.correlation = np.round(r_value, nb_decimals)381        self.r_squared = np.round(r_value**2, nb_decimals) #pct de varianza de y explicada por x382        self.predictor_linreg = self.beta * self.x + self.alpha383        384        385        if bool_print:386            self.print_riskmetrics()387        388        if bool_plot:389            self.plot_riskmetrics()390    391    392    def print_riskmetrics(self):393        print('----------')394        print('Ticker: ' + str(self.ticker))395        print('Benchmark: ' + str(self.benchmark))396        print('Length: ' + str(len(self.dataframe_strategy)))397        print('Data cut: ' + str(self.data_cut))398        print('Data type: ' + str(self.data_type))399        print('Total trades: ' + str(self.nb_trades))400        print('Total P&L: ' + str(self.total_pnl))401        print('Dradown max: ' + str(self.drawdown_max))402        print('Dradown prom: ' + str(self.drawdown_promedio))403        print('Return: ' + str(self.pnl_mean))404        print('Volatility: ' + str(self.pnl_volatility))405        print('Sharpe: ' + str(self.pnl_sharpe))406        print('Win rate: ' + str(self.win_rate))407        print('Win rate long: ' + str(self.win_rate_long))408        print('Win rate short: ' + str(self.win_rate_short))409        print('Expected profit: ' + str(self.average_win))410        print('Expected profit probability: ' + str(self.average_win_p))411        print('Expected loose: ' + str(self.average_loose))412        print('Expected loose probability: ' + str(self.average_loose_p))413        print('Benefit/Risk ratio: ' + str(self.risk_benefit_ratio))414        print('Variation coefficient of net profit: ' + str(self.vcont))415        print('Correlation with benchmark: ' + str(self.correlation))416        print('Beta with benchmark: ' + str(self.beta))417        print('Best trade: ' + str(self.best_trade))418        print('Worst trade: ' + str(self.worst_trade))419    420421    def plot_riskmetrics(self):422        #Drawdown423        plt.figure()424        plt.title('Dradown ' + self.ticker)425            426        plt.xlabel('Time')427        plt.ylabel('Price')428        429        plt.plot(self.drawdown, 'r', label = 'Strategy_DD')430        431        plt.grid()432        plt.legend()433        plt.show()434        435        436        #Linear regression437        str_tittle = 'Scatterplot of returns' + '\n'\438            + 'Linear regression / ticker ' + self.ticker\439            + ' / benchmark ' + self.benchmark + '\n'\440            + 'alpha (intercept) ' + str(self.alpha)\441            + ' / beta (slope) ' +str(self.beta)\442            + ' / p_value ' + str(self.p_value)\443            + ' / null hypothesis ' + str(self.null_hypothesis) + '\n'\444            + 'Correlacion ' + str(self.correlation)\445            + ' / Informacion explicada (r_squared) ' + str(self.r_squared)446            447        plt.figure()448        plt.title(str_tittle)449        450        plt.scatter(self.x,self.y, color = 'k')451        plt.plot(self.x, self.predictor_linreg, color = 'r')452        453        plt.ylabel(self.ticker)454        plt.xlabel(self.benchmark)455        plt.grid()456        plt.show()457        458        459        #Rdto account & benchmark & accion(buy and hold)460        plt.figure()461        plt.title('Rdto account & benchmark')462        plt.xlabel('Time')463        plt.ylabel('%') 464        465        self.dataframe_strategy['Cum_returns_daily'].plot(color = 'k', label = self.ticker)466        467        self.dataframe_dataB['Ret_cum'].plot(color = 'b', label = self.benchmark)468        self.dataframe_data['Ret_cum'].plot(color = 'r', label = self.ticker + ' B&H')469        470        plt.legend()471        plt.show()472    473    474    475    def returns_distribution(self, nb_decimals, bool_print = False, bool_plot = False):476        self.nb_decimals = nb_decimals477        478        self.rdto_clean = pd.DataFrame(index = self.data['Date'])479        480        self.rdto_clean =self.dataframe_strategy['Returns_daily'].replace(0, np.nan)481        self.rdto_clean = self.rdto_clean.dropna()482        self.rdto_clean = self.rdto_clean.reset_index(drop = True)483        484        #Riskemtrics - returns distribution485        self.mean = np.mean(self.rdto_clean)486        self.std = np.std(self.rdto_clean)487        self.skew = skew(self.rdto_clean)488        self.kurtosis = kurtosis(self.rdto_clean)489        self.var_95 = np.percentile(self.rdto_clean, 5)490        self.cvar_95 = np.mean(self.rdto_clean[self.rdto_clean <= self.var_95])491        self.jb =  len(self.rdto_clean)/6*(self.skew**2 + 1/4*self.kurtosis**2)492        self.p_value = 1 - chi2.cdf(self.jb, df = 2)493        self.is_normal = (self.p_value > 0.05) 494        495        if bool_print == True:496            self.print_returns_distribution()497        498        if bool_plot == True:499            self.plot_returns_distribution()500    501    502    def print_returns_distribution(self):503        print('----------')504        print('Mean ' + str(round(self.mean,  self.nb_decimals)))505        print('Std ' + str(round(self.std,  self.nb_decimals)))506        print('Skewness ' + str(round(self.skew,  self.nb_decimals)))507        print('Kurtosis ' + str(round(self.kurtosis,  self.nb_decimals)))508        print('VaR ' + str(round(self.var_95,  self.nb_decimals)))509        print('CVar ' + str(round(self.cvar_95,  self.nb_decimals)))510        print('Is normal ' + str(self.is_normal))511    512    513    def plot_returns_distribution(self):514        #Drawdown515        plt.figure()516        plt.title('Returns ' + self.ticker)517            518        plt.xlabel('Time')519        plt.ylabel('%')520        521        plt.hist(self.rdto_clean, bins = 100, edgecolor='black')522        523        plt.grid()524        plt.show()525        526    527    def optimize(self, param_1_list, param_2_list, param_3_list, bool_plot = False, bool_print = False, optimize = '1&2'):528        self.param_1_list = param_1_list529        self.param_2_list = param_2_list530        self.param_3_list = param_3_list531        532        if optimize == '1&2':533            mtx_sharpe = np.zeros((len(self.param_1_list), len(self.param_2_list)))534            mtx_nb_trades = np.zeros((len(self.param_1_list), len(self.param_2_list)))535            mtx_returns = np.zeros((len(self.param_1_list), len(self.param_2_list)))536            mtx_volatility = np.zeros((len(self.param_1_list), len(self.param_2_list)))537            mtx_win_rate =  np.zeros((len(self.param_1_list), len(self.param_2_list)))538            mtx_win_rate_long = np.zeros((len(self.param_1_list), len(self.param_2_list)))539            mtx_win_rate_short = np.zeros((len(self.param_1_list), len(self.param_2_list)))540            mtx_max_dd = np.zeros((len(self.param_1_list), len(self.param_2_list)))541            mtx_benefit_risk_ratio = np.zeros((len(self.param_1_list), len(self.param_2_list)))542            mtx_variation_coefficient = np.zeros((len(self.param_1_list), len(self.param_2_list)))543            544            p1 = 0545            for i in self.param_1_list:546                p2 = 0547                for z in self.param_2_list:548                    if i > z:549                        #Load data550                        self.load_time_series(self.data_cut, self.data_type)551                        552                        #Compute indicator553                        self.compute_strategy(i, z, self.param_3_list[0], self.capital, self.k_position, self.strategy_used)                                   554                        555                        #Run backtest of traiding strategy556                        self.compute_account(bool_plot = bool_plot)557                        558                        #Risk metrics559                        self.risk_metrics(self.nb_decimals, bool_print = bool_print, bool_plot = bool_plot)560                        561                        #Save data in tables min 562                        mtx_sharpe[p1][p2] = self.pnl_sharpe563                        564                        mtx_nb_trades[p1][p2] = self.nb_trades565                        566                        mtx_returns[p1][p2]= self.pnl_mean567                        568                        mtx_volatility[p1][p2] = self.pnl_volatility569                        570                        mtx_win_rate[p1][p2] = self.win_rate571                        572                        mtx_win_rate_long[p1][p2] = self.win_rate_long573                        574                        mtx_win_rate_short[p1][p2] = self.win_rate_short575                        576                        mtx_max_dd[p1][p2] = self.drawdown_max577                        578                        mtx_benefit_risk_ratio[p1][p2] = self.risk_benefit_ratio579                        580                        mtx_variation_coefficient[p1][p2] = self.vcont581                            582                        p2 += 1583                    else:584                        continue585                p1 += 1586    587            588            #Df_Sharpe589            df1 = pd.DataFrame()590            df1['P1'] = param_1_list                                                         591            column_names = ['P2_' + str(z) for z in self.param_2_list]592            df2 = pd.DataFrame(data = mtx_sharpe, columns = column_names)593            self.df_sharpe = pd.concat([df1, df2], axis = 1) #Axis 0 for rows, axis = 1 for columns594            self.df_sharpe = self.df_sharpe.dropna()595            self.df_sharpe = self.df_sharpe.reset_index(drop = True)596            597            #Df_nb_trades598            df1 = pd.DataFrame()599            df1['P1'] = param_1_list                                                         600            column_names = ['P2_' + str(z) for z in self.param_2_list]601            df2 = pd.DataFrame(data = mtx_nb_trades, columns = column_names)602            self.df_nb_trades = pd.concat([df1, df2], axis = 1) #Axis 0 for rows, axis = 1 for columns603            self.df_nb_trades = self.df_nb_trades.dropna()604            self.df_nb_trades = self.df_nb_trades.reset_index(drop = True)605            606            #Df_returns607            df1 = pd.DataFrame()608            df1['P1'] = param_1_list                                                         609            column_names = ['P2_' + str(z) for z in self.param_2_list]610            df2 = pd.DataFrame(data = mtx_returns, columns = column_names)611            self.df_returns = pd.concat([df1, df2], axis = 1) #Axis 0 for rows, axis = 1 for columns612            self.df_returns = self.df_returns.dropna()613            self.df_returns = self.df_returns.reset_index(drop = True)614            615            #Df_volatility616            df1 = pd.DataFrame()617            df1['P1'] = param_1_list                                                         618            column_names = ['P2_' + str(z) for z in self.param_2_list]619            df2 = pd.DataFrame(data =  mtx_volatility, columns = column_names)620            self.df_volatility = pd.concat([df1, df2], axis = 1) #Axis 0 for rows, axis = 1 for columns621            self.df_volatility = self.df_volatility.dropna()622            self.df_volatility = self.df_volatility.reset_index(drop = True)623            624            #Df_win_rate625            df1 = pd.DataFrame()626            df1['P1'] = param_1_list                                                         627            column_names = ['P2_' + str(z) for z in self.param_2_list]628            df2 = pd.DataFrame(data = mtx_win_rate, columns = column_names)629            self.df_win_rate = pd.concat([df1, df2], axis = 1) #Axis 0 for rows, axis = 1 for columns630            self.df_win_rate = self.df_win_rate.dropna()631            self.df_win_rate = self.df_win_rate.reset_index(drop = True)632            633            #Df_win_rate_long634            df1 = pd.DataFrame()635            df1['P1'] = param_1_list                                                         636            column_names = ['P2_' + str(z) for z in self.param_2_list]637            df2 = pd.DataFrame(data = mtx_win_rate_long, columns = column_names)638            self.df_win_rate_long = pd.concat([df1, df2], axis = 1) #Axis 0 for rows, axis = 1 for columns639            self.df_win_rate_long = self.df_win_rate_long.dropna()640            self.df_win_rate_long = self.df_win_rate_long.reset_index(drop = True)641            642            #Df_win_rate_short643            df1 = pd.DataFrame()644            df1['P1'] = param_1_list                                                         645            column_names = ['P2_' + str(z) for z in self.param_2_list]646            df2 = pd.DataFrame(data = mtx_win_rate_short, columns = column_names)647            self.df_win_rate_short = pd.concat([df1, df2], axis = 1) #Axis 0 for rows, axis = 1 for columns648            self.df_win_rate_short = self.df_win_rate_short.dropna()649            self.df_win_rate_short = self.df_win_rate_short.reset_index(drop = True)650            651            #Df_max_dd652            df1 = pd.DataFrame()653            df1['P1'] = param_1_list                                                         654            column_names = ['P2_' + str(z) for z in self.param_2_list]655            df2 = pd.DataFrame(data = mtx_max_dd, columns = column_names)656            self.df_max_dd = pd.concat([df1, df2], axis = 1) #Axis 0 for rows, axis = 1 for columns657            self.df_max_dd = self.df_max_dd.dropna()658            self.df_max_dd = self.df_max_dd.reset_index(drop = True)659            660            #Df_benefit_risk_ratio661            df1 = pd.DataFrame()662            df1['P1'] = param_1_list                                                         663            column_names = ['P2_' + str(z) for z in self.param_2_list]664            df2 = pd.DataFrame(data = mtx_benefit_risk_ratio, columns = column_names)665            self.df_benefit_risk_ratio = pd.concat([df1, df2], axis = 1) #Axis 0 for rows, axis = 1 for columns666            self.df_benefit_risk_ratio = self.df_benefit_risk_ratio.dropna()667            self.df_benefit_risk_ratio = self.df_benefit_risk_ratio.reset_index(drop = True)668            669            #Df_variation_coefficient670            df1 = pd.DataFrame()671            df1['P1'] = param_1_list                                                         672            column_names = ['P2_' + str(z) for z in self.param_2_list]673            df2 = pd.DataFrame(data = mtx_variation_coefficient, columns = column_names)674            self.df_variation_coefficient = pd.concat([df1, df2], axis = 1) #Axis 0 for rows, axis = 1 for columns675            self.df_variation_coefficient = self.df_variation_coefficient.dropna()676            self.df_variation_coefficient = self.df_variation_coefficient.reset_index(drop = True)677        678        elif optimize == '1&3':679            mtx_sharpe = np.zeros((len(self.param_1_list), len(self.param_3_list)))680            mtx_nb_trades = np.zeros((len(self.param_1_list), len(self.param_3_list)))681            mtx_returns = np.zeros((len(self.param_1_list), len(self.param_3_list)))682            mtx_volatility = np.zeros((len(self.param_1_list), len(self.param_3_list)))683            mtx_win_rate =  np.zeros((len(self.param_1_list), len(self.param_3_list)))684            mtx_win_rate_long = np.zeros((len(self.param_1_list), len(self.param_3_list)))685            mtx_win_rate_short = np.zeros((len(self.param_1_list), len(self.param_3_list)))686            mtx_max_dd = np.zeros((len(self.param_1_list), len(self.param_3_list)))687            mtx_benefit_risk_ratio = np.zeros((len(self.param_1_list), len(self.param_3_list)))688            mtx_variation_coefficient = np.zeros((len(self.param_1_list), len(self.param_3_list)))689            690            p1 = 0691            for i in self.param_1_list:692                p2 = 0693                for z in self.param_3_list:694                    if i > z:695                        #Load data696                        self.load_time_series(self.data_cut, self.data_type)697                        698                        #Compute indicator699                        self.compute_strategy(i, self.param_2_list[0], z, self.capital, self.k_position, self.strategy_used)                                   700                        701                        #Run backtest of traiding strategy702                        self.compute_account(bool_plot = bool_plot)703                        704                        #Risk metrics705                        self.risk_metrics(self.nb_decimals, bool_print = bool_print, bool_plot = bool_plot)706                        707                        #Save data in tables min 708                        mtx_sharpe[p1][p2] = self.pnl_sharpe709                        710                        mtx_nb_trades[p1][p2] = self.nb_trades711                        712                        mtx_returns[p1][p2]= self.pnl_mean713                        714                        mtx_volatility[p1][p2] = self.pnl_volatility715                        716                        mtx_win_rate[p1][p2] = self.win_rate717                        718                        mtx_win_rate_long[p1][p2] = self.win_rate_long719                        720                        mtx_win_rate_short[p1][p2] = self.win_rate_short721                        722                        mtx_max_dd[p1][p2] = self.drawdown_max723                        724                        mtx_benefit_risk_ratio[p1][p2] = self.risk_benefit_ratio725                        726                        mtx_variation_coefficient[p1][p2] = self.vcont727                            728                        p2 += 1729                    else:730                        continue731                p1 += 1732                733            734            #Df_Sharpe735            df1 = pd.DataFrame()736            df1['P1'] = param_1_list                                                         737            column_names = ['P3_' + str(a) for a in self.param_3_list]738            df2 = pd.DataFrame(data = mtx_sharpe, columns = column_names)739            self.df_sharpe = pd.concat([df1, df2], axis = 1) #Axis 0 for rows, axis = 1 for columns740            self.df_sharpe = self.df_sharpe.dropna()741            self.df_sharpe = self.df_sharpe.reset_index(drop = True)742            743            #Df_nb_trades744            df1 = pd.DataFrame()745            df1['P1'] = param_1_list                                                         746            column_names = ['P3_' + str(a) for a in self.param_3_list]747            df2 = pd.DataFrame(data = mtx_nb_trades, columns = column_names)748            self.df_nb_trades = pd.concat([df1, df2], axis = 1) #Axis 0 for rows, axis = 1 for columns749            self.df_nb_trades = self.df_nb_trades.dropna()750            self.df_nb_trades = self.df_nb_trades.reset_index(drop = True)751            752            #Df_returns753            df1 = pd.DataFrame()754            df1['P1'] = param_1_list                                                         755            column_names = ['P3_' + str(a) for a in self.param_3_list]756            df2 = pd.DataFrame(data = mtx_returns, columns = column_names)757            self.df_returns = pd.concat([df1, df2], axis = 1) #Axis 0 for rows, axis = 1 for columns758            self.df_returns = self.df_returns.dropna()759            self.df_returns = self.df_returns.reset_index(drop = True)760            761            #Df_volatility762            df1 = pd.DataFrame()763            df1['P1'] = param_1_list                                                         764            column_names = ['P3_' + str(a) for a in self.param_3_list]765            df2 = pd.DataFrame(data =  mtx_volatility, columns = column_names)766            self.df_volatility = pd.concat([df1, df2], axis = 1) #Axis 0 for rows, axis = 1 for columns767            self.df_volatility = self.df_volatility.dropna()768            self.df_volatility = self.df_volatility.reset_index(drop = True)769            770            #Df_win_rate771            df1 = pd.DataFrame()772            df1['P1'] = param_1_list                                                         773            column_names = ['P3_' + str(a) for a in self.param_3_list]774            df2 = pd.DataFrame(data = mtx_win_rate, columns = column_names)775            self.df_win_rate = pd.concat([df1, df2], axis = 1) #Axis 0 for rows, axis = 1 for columns776            self.df_win_rate = self.df_win_rate.dropna()777            self.df_win_rate = self.df_win_rate.reset_index(drop = True)778            779            #Df_win_rate_long780            df1 = pd.DataFrame()781            df1['P1'] = param_1_list                                                         782            column_names = ['P3_' + str(a) for a in self.param_3_list]783            df2 = pd.DataFrame(data = mtx_win_rate_long, columns = column_names)784            self.df_win_rate_long = pd.concat([df1, df2], axis = 1) #Axis 0 for rows, axis = 1 for columns785            self.df_win_rate_long = self.df_win_rate_long.dropna()786            self.df_win_rate_long = self.df_win_rate_long.reset_index(drop = True)787            788            #Df_win_rate_short789            df1 = pd.DataFrame()790            df1['P1'] = param_1_list                                                         791            column_names = ['P3_' + str(a) for a in self.param_3_list]792            df2 = pd.DataFrame(data = mtx_win_rate_short, columns = column_names)793            self.df_win_rate_short = pd.concat([df1, df2], axis = 1) #Axis 0 for rows, axis = 1 for columns794            self.df_win_rate_short = self.df_win_rate_short.dropna()795            self.df_win_rate_short = self.df_win_rate_short.reset_index(drop = True)796            797            #Df_max_dd798            df1 = pd.DataFrame()799            df1['P1'] = param_1_list                                                         800            column_names = ['P3_' + str(a) for a in self.param_3_list]801            df2 = pd.DataFrame(data = mtx_max_dd, columns = column_names)802            self.df_max_dd = pd.concat([df1, df2], axis = 1) #Axis 0 for rows, axis = 1 for columns803            self.df_max_dd = self.df_max_dd.dropna()804            self.df_max_dd = self.df_max_dd.reset_index(drop = True)805            806            #Df_benefit_risk_ratio807            df1 = pd.DataFrame()808            df1['P1'] = param_1_list                                                         809            column_names = ['P3_' + str(a) for a in self.param_3_list]810            df2 = pd.DataFrame(data = mtx_benefit_risk_ratio, columns = column_names)811            self.df_benefit_risk_ratio = pd.concat([df1, df2], axis = 1) #Axis 0 for rows, axis = 1 for columns812            self.df_benefit_risk_ratio = self.df_benefit_risk_ratio.dropna()813            self.df_benefit_risk_ratio = self.df_benefit_risk_ratio.reset_index(drop = True)814            815            #Df_variation_coefficient816            df1 = pd.DataFrame()817            df1['P1'] = param_1_list                                                         818            column_names = ['P3_' + str(a) for a in self.param_3_list]819            df2 = pd.DataFrame(data = mtx_variation_coefficient, columns = column_names)820            self.df_variation_coefficient = pd.concat([df1, df2], axis = 1) #Axis 0 for rows, axis = 1 for columns821            self.df_variation_coefficient = self.df_variation_coefficient.dropna()822            self.df_variation_coefficient = self.df_variation_coefficient.reset_index(drop = True)823        824        825        826        return self.df_sharpe, self.df_nb_trades, self.df_returns, self.df_volatility, self.df_win_rate,\827            self.df_max_dd, self.df_benefit_risk_ratio, self.df_variation_coefficient, self.df_win_rate_long, self.df_win_rate_short828            829    830    def comparison(self, df, bool_print = False):831        #Compute Sarpe ratio, return and volatility832        vec_pnl = df['Ret'].values833        self.pnl_mean_comparison = np.round(np.mean(vec_pnl[1:]) * 252, self.nb_decimals)834        self.pnl_volatility_comparison = np.round(np.std(vec_pnl[1:]) * np.sqrt(252), self.nb_decimals)835        self.pnl_sharpe_comparison = np.round(self.pnl_mean_comparison / self.pnl_volatility_comparison, self.nb_decimals)836837        838        #Drawdown839        drawdown = pd.DataFrame()840        drawdown = (df['Close'] - df['Close'].cummax())\841            / df['Close'].cummax()842        843        drawdown = drawdown.replace([np.inf, -np.inf], 0)844        845        self.drawdown_max_comparison = np.round(drawdown.min(), self.nb_decimals)846        self.drawdown_promedio_comparison = np.round(drawdown.mean(), self.nb_decimals)847        848        if bool_print == True:849            self.print_comparison()850    851    852    def print_comparison(self):853        print('----------')854        print('Comparison You / Other')855        print('Return: ' + str(self.pnl_mean) + ' / ' + str(self.pnl_mean_comparison))856        print('Volatility: ' + str(self.pnl_volatility) + ' / ' + str(self.pnl_volatility_comparison))857        print('Sharpe: '  + str(self.pnl_sharpe) + ' / ' + str(self.pnl_sharpe_comparison))858        print('Drawdown max: '  + str(self.drawdown_max) + ' / ' + str(self.drawdown_max_comparison))859        print('Drawdown prom: '  + str(self.drawdown_promedio) + ' / ' + str(self.drawdown_promedio_comparison))860    861    862    def simulations(self, bool_print = False, bool_plot = False, sector = 'all'):863        tickers_list.simulations_initialize(self.benchmark, 864                                            self.length, 865                                            self.data_cut, 866                                            self.data_type, 867                                            self.param_1, 868                                            self.param_2, 869                                            self.param_3, 870                                            self.capital, 871                                            self.k_position, 872                                            self.strategy_used, 873                                            bool_plot, 874                                            bool_print, 875                                            self.nb_decimals, 876                                            sector)877878        879    #     if bool_print == True:880    #         self.print_simulations()881        882        883    # def print_simulations(self):884    #     print('----------')885    #     print('Mean market / Std market')886    #     print('Total trades: ' + str(round(self.nb_trades_list_mean, self.nb_decimals)) + ' / ' + str(round(self.nb_trades_list_std, self.nb_decimals)))887    #     print('Dradown max: ' + str(round(self.drawdown_max_list_mean, self.nb_decimals)) + ' / ' + str(round(self.drawdown_max_list_std, self.nb_decimals)))888    #     print('Dradown prom: ' + str(round(self.drawdown_promedio_list_mean, self.nb_decimals)) + ' / ' + str(round(self.drawdown_promedio_list_std, self.nb_decimals)))889    #     print('Return: ' + str(round(self.pnl_mean_list_mean, self.nb_decimals)) + ' / ' + str(round(self.pnl_mean_list_std, self.nb_decimals)))890    #     print('Volatility: ' + str(round(self.pnl_volatility_list_mean, self.nb_decimals)) + ' / ' + str(round(self.pnl_volatility_list_std, self.nb_decimals)))891    #     print('Sharpe: ' + str(round(self.pnl_sharpe_list_mean, self.nb_decimals)) + ' / ' + str(round(self.pnl_sharpe_list_std, self.nb_decimals)))892    #     print('Win rate: ' + str(round(self.win_rate_list_mean, self.nb_decimals)) + ' / ' + str(round(self.win_rate_list_std, self.nb_decimals)))893    #     print('Win rate long: ' + str(round(self.win_rate_long_list_mean, self.nb_decimals)) + ' / ' + str(round(self.win_rate_long_list_std, self.nb_decimals)))894    #     print('Win rate short: ' + str(round(self.win_rate_short_list_mean, self.nb_decimals)) + ' / ' + str(round(self.win_rate_short_list_std, self.nb_decimals)))895    #     print('Benefit/Risk ratio: ' + str(round(self.risk_benefit_ratio_list_mean, self.nb_decimals)) + ' / ' + str(round(self.risk_benefit_ratio_list_std, self.nb_decimals)))896    #     print('Variation coefficient of net profit: ' + str(round(self.vcont_list_mean, self.nb_decimals)) + ' / ' + str(round(self.vcont_list_std, self.nb_decimals)))897    #     print('VaR : ' + str(round(self.var_95_list_mean, self.nb_decimals)) + ' / ' + str(round(self.var_95_list_std, self.nb_decimals)))898    #     print('CVaR : ' + str(round(self.cvar_95_list_mean, self.nb_decimals)) + ' / ' + str(round(self.cvar_95_list_std, self.nb_decimals)))899900
...15_stat_arb_optimization.py
Source:15_stat_arb_optimization.py  
1import pandas as pd2import numpy as np3import matplotlib as mpl 4import scipy5import importlib6import matplotlib.pyplot as plt7from scipy.stats import skew, kurtosis, chi28# Import our own files and reload9import file_classes10importlib.reload(file_classes)11import file_functions12importlib.reload(file_functions)13# Inputs14backtest = file_classes.backtest()15backtest.ric_long = 'SAN.MC'16backtest.ric_short = 'BBVA.MC'17backtest.data_cut = 0.118backtest.data_type = 'in-sample' # in-sample out-of-sample19# First overview20list_rolling_days = [10,20,30,40,50,60]21list_level_1 = [0.25,0.5,0.75,1.0,1.25,1.5,1.75,2.0]22# We can play with these values and zoom in 23# list_rolling_days = [10,15,20,25,30,35]24# list_level_1 = [0.5,0.6,0.7,0.8,0.9,1.0,1.1,1.2,1.3,1.4]25# Third zoom to find the optimal parameters26# list_rolling_days = [15,16,17,18,19,20,21,22,23,24,25]27# list_level_1 = [0.5,0.6,0.7,0.8,0.9,1.0,1.1,1.2,1.3,1.4]28mtx_sharpe = np.zeros((len(list_rolling_days), len(list_level_1)))29mtx_nb_trades = np.zeros((len(list_rolling_days), len(list_level_1)))30rd = 031for rolling_days in list_rolling_days:32    l1 = 033    for level_1 in list_level_1:34        # Parameters to optimize35        backtest.rolling_days = rolling_days36        backtest.level_1 = level_137        backtest.level_2 = 2*level_1 # symmetric take profit and stop loss 38        # Load data39        backtest.load_data()40        # Compute indicator41        backtest.compute_indicator()42        # Run backtest of trading strategy43        backtest.run_strategy()44        # Get results in a dataframe format45        df_strategy = backtest.dataframe_strategy46        # Save data in tables47        mtx_sharpe[rd][l1] = backtest.pnl_sharpe48        mtx_nb_trades[rd][l1] = backtest.nb_trades49        l1 += 150    rd += 151# Show different levels for the Sharpe matrix52df1 = pd.DataFrame()53df1['rolling_days'] = list_rolling_days54column_names = ['level_1_' + str(level_1) for level_1 in list_level_1] 55df2 = pd.DataFrame(data=mtx_sharpe, columns=column_names)56df_sharpe = pd.concat([df1,df2], axis=1) # axis=0 for rows, axis=1 for columns57df_sharpe = df_sharpe.reset_index(drop=True)58# Table of the number of trades59df1 = pd.DataFrame()60df1['rolling_days'] = list_rolling_days61column_names = ['level_1_' + str(level_1) for level_1 in list_level_1] 62df2 = pd.DataFrame(data=mtx_nb_trades, columns=column_names)63df_trades = pd.concat([df1,df2], axis=1) # axis=0 for rows, axis=1 for columns...14_stat_arb_refac.py
Source:14_stat_arb_refac.py  
1import pandas as pd2import numpy as np3import matplotlib as mpl 4import scipy5import importlib6import matplotlib.pyplot as plt7from scipy.stats import skew, kurtosis, chi28# Import our own files and reload9import file_classes10importlib.reload(file_classes)11import file_functions12importlib.reload(file_functions)13# Inputs14backtest = file_classes.backtest()15backtest.ric_long = 'SAN.MC'16backtest.ric_short = 'BBVA.MC'17backtest.rolling_days = 2018backtest.level_1 = 1.19backtest.level_2 = 2.20backtest.data_cut = 0.721backtest.data_type = 'in-sample' # in-sample out-of-sample22# Load data23backtest.load_data()24# Compute indicator25backtest.compute_indicator(bool_plot=True)26# Run backtest of trading strategy27backtest.run_strategy(bool_plot=True)28# Get results in a dataframe format...Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
