{
  "version": 3,
  "sources": ["ssg:https://framerusercontent.com/modules/lIxmgfkoUrdKnvgWKSyx/i9mBqLZ9xraeOU5uwWVQ/tNQezPB3C.js"],
  "sourcesContent": ["import{jsx as e,jsxs as t}from\"react/jsx-runtime\";import{addPropertyControls as a,ControlType as r,Link as i}from\"framer\";import*as o from\"react\";let n=\"mGfwEW8kL\",s=\"uN4uNF8Hw\",l=\"fm9xNGFNa\",c=\"NaBBy2qZQ\",d=\"LmkFXFAof\",h=(e,t)=>{if(e&&\"object\"==typeof e)return{...e,alt:t};},p=[{id:\"uL561_k7d\",[n]:\"Dynamic Hedge Ratio: Rolling Regression for Pairs Trading\",[s]:\"dynamic-hedge-ratio-rolling-regression-for-pairs-trading\",[l]:\"2022-04-08T00:00:00.000Z\",[c]:h({src:\"https://framerusercontent.com/images/82J3LMfh5DFPTY3MsmrIdQdxKuw.jpg\"},\"Blue Flower\"),[d]:/*#__PURE__*/t(o.Fragment,{children:[/*#__PURE__*/t(\"p\",{children:[\"This discussion article is a continuation of \u2014 \u201C\",/*#__PURE__*/e(i,{href:\"https://medium.com/analytics-vidhya/statistical-arbitrage-with-pairs-trading-and-backtesting-ec657b25a368?sk=467d90ba6c83d1e8e6e15716a52626e0\",openInNewTab:!1,smoothScroll:!1,children:/*#__PURE__*/e(\"a\",{children:\"Statistical Arbitrage with Pairs Trading and Backtesting\"})}),\"\u201D.\"]}),/*#__PURE__*/e(\"p\",{children:\"Let us recap what we have discussed:\"}),/*#__PURE__*/e(\"p\",{children:\"a. Analyzed historical data of NSE stocks in the \u201CFinancial Services\u201D sector to identify co-integrated pairs of stocks i.e., stocks that move together.\"}),/*#__PURE__*/e(\"p\",{children:\"b. Based on statistical tests, identified two stocks \u2014 Bank of Baroda (BANKBARODA) and State Bank of India (SBIN) as the right candidates for the analysis.\"}),/*#__PURE__*/e(\"p\",{children:\"c. Generated trading signals based on the mean-reversion principle of Pairs Trading and calculated profit and loss.\"}),/*#__PURE__*/e(\"p\",{children:\"The focus of the earlier article was to explain the Pairs Trading Strategy and show its working. One of the important steps in the analysis, though not quite evident then, was to calculate the ratio of the number of bought/sold stocks of SBI and Bank of Baroda. In financial jargons, this ratio is called the hedge ratio. Calculation of hedge ratio is done using a simple proven statistical technique called \u2014 OLS linear regression analysis. The slope of the regression line is the hedge ratio, which was assumed to be constant over time. Thereby the ratio of the two stocks bought/ sold remains the same whenever a trading signal is generated. In other words, it is assumed that the strength of the correlation is a non-evolving function of time.\"}),/*#__PURE__*/e(\"p\",{children:\"This article challenges this assumption and presents an improved version of the hedge ratio calculation. Looking at the price correlation chart below for the two stocks considered, it is quite evident that the degree of correlation is not the same over time. Hence, the constant hedge ratio assumption is not valid.\"}),/*#__PURE__*/e(\"p\",{children:\"Logically, our fundamental objective should then be to calculate the revised hedge ratio whenever a trading signal is generated. This will provide us with the appropriate hedge ratio as a function of time.\"}),/*#__PURE__*/e(\"p\",{children:\"Before we do this calculation, let us go back to the OLS linear regression model and try to understand where and how we can make this improvement. Linear regression model had two parameters \u2014 slope (\u03B2) and intercept (\u03B1) as defined below:\"}),/*#__PURE__*/e(\"p\",{children:\"Y= \u03B2 * X +\u03B1\"}),/*#__PURE__*/e(\"p\",{children:\"Where \u2014 Y and X are daily price time series of SBI and BoB\"}),/*#__PURE__*/e(\"p\",{children:\"In this method, slope and intercept are calculated using the frequentist approach and assumed to be constant over time. In the improved model, we want to factor in the changes in slope and intercept given observed values.\"}),/*#__PURE__*/e(\"p\",{children:\"This concept is a central idea of Bayesian Linear Regression or Rolling regression. The aim of Bayesian Linear Regression is not to find the \u201Csingle best\u201D value of the model parameters, but rather to determine the distribution for the model parameters based on the observed values at any given point. These observed values are called priors and model parameter distribution is called \u2014 posterior distribution. The approach used in this article follows the rolling regression example by Stefan Jansen and Thomas Wiecki.\"}),/*#__PURE__*/e(\"p\",{children:\"Let us assume slope and intercept follow a random walk through time i.e.,\"}),/*#__PURE__*/e(\"p\",{children:\"Also, let us assume the standard deviation of the above distribution i.e., \u03C3\u03B1 and \u03C3\u03B2 follow an exponential distribution.\"}),/*#__PURE__*/e(\"p\",{children:\"With these specifications of the probabilistic model (distribution of \u03B1 and \u03B2), we can define the regression line the way we did earlier. Post the definition, as per the Bayesian probabilistic model, we need to run a sampler that generates the posterior distribution of model parameters. In the current discussion, we have used the NUTS sampler (No U-Turn Sampler) which is based on the Markov Chain Monte Carlo (MCMC) sampling process.\"}),/*#__PURE__*/e(\"p\",{children:\"Below schematic represents our model parameters and assumptions:\"}),/*#__PURE__*/e(\"p\",{children:\"The below picture depicts how the intercept and slope coefficients have changed over the years, underlining the evolving correlations:\"}),/*#__PURE__*/e(\"p\",{children:\"The following plot combines the prices series and the regression lines with hue indicating the timeline.\"}),/*#__PURE__*/t(\"p\",{children:[\"Details of the Python code and analysis process can be found at the GitHub \",/*#__PURE__*/e(i,{href:\"https://github.com/sabirjana/blog/tree/master/Bayesian_rolling_reg\",openInNewTab:!0,smoothScroll:!1,children:/*#__PURE__*/e(\"a\",{children:\"link\"})}),\".\"]}),/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/t(\"em\",{children:[\"By Team\",/*#__PURE__*/e(\"br\",{})]}),/*#__PURE__*/e(i,{href:\"https://www.linkedin.com/in/vimal-mishra-2b28a4a/\",openInNewTab:!0,smoothScroll:!1,children:/*#__PURE__*/e(\"a\",{children:/*#__PURE__*/e(\"em\",{children:\"Vimal Mishra\"})})}),/*#__PURE__*/e(\"em\",{children:/*#__PURE__*/e(\"br\",{})}),/*#__PURE__*/e(i,{href:\"https://www.linkedin.com/in/sabirjana/\",openInNewTab:!0,smoothScroll:!1,children:/*#__PURE__*/e(\"a\",{children:/*#__PURE__*/e(\"em\",{children:\"Sabir Jana\"})})})]}),/*#__PURE__*/t(\"p\",{children:[\"Reference:\",/*#__PURE__*/e(\"br\",{}),\"1. \",/*#__PURE__*/e(i,{href:\"https://www.amazon.in/Machine-Learning-Algorithmic-Trading-alternative/dp/1839217715\",openInNewTab:!0,smoothScroll:!1,children:/*#__PURE__*/e(\"a\",{children:\"Machine Learning for Algorithmic Trading: Predictive models to extract signals from market and alternative data for systematic trading strategies with Python, 2nd Edition\"})}),\" by Stefan Jansen\",/*#__PURE__*/e(\"br\",{}),\"2. \",/*#__PURE__*/e(i,{href:\"https://docs.pymc.io/notebooks/GLM-rolling-regression.html\",openInNewTab:!0,smoothScroll:!1,children:/*#__PURE__*/e(\"a\",{children:\"Rolling Regression Example\"})}),\" by Thomas Wiecki\",/*#__PURE__*/e(\"br\",{}),\"3. Introduction to Bayesian Linear Regression \",/*#__PURE__*/e(i,{href:\"https://towardsdatascience.com/introduction-to-bayesian-linear-regression-e66e60791ea7\",openInNewTab:!0,smoothScroll:!1,children:/*#__PURE__*/e(\"a\",{children:\"link\"})}),/*#__PURE__*/e(\"br\",{}),/*#__PURE__*/e(\"br\",{className:\"trailing-break\"})]})]})},{id:\"jJH3mRvID\",[n]:\"ML Classification Algorithms to Predict Market Movements and Backtesting\",[s]:\"ml-classification-algorithms-to-predict-market-movements-and-backtesting\",[l]:\"2022-03-15T00:00:00.000Z\",[c]:h({src:\"https://framerusercontent.com/images/4HPhWVlQyFOTlWQ7tMMaCQrA8.jpg\"},\"Teal Flower\"),[d]:/*#__PURE__*/t(o.Fragment,{children:[/*#__PURE__*/t(\"p\",{children:[\"In this article, we will use the stock trading strategies based on multiple machine learning classification algorithms to predict the market movement. To analyze the performance we will perform simple vectorized backtesting and then test the best performing strategy using Backtrader to get a more realistic picture. You can find the relevant Jupyter notebook used in this article on my \",/*#__PURE__*/e(i,{href:\"https://github.com/sabirjana/blog/tree/master/Classification_ML\",openInNewTab:!0,smoothScroll:!1,children:/*#__PURE__*/e(\"a\",{children:\"Github\"})}),\" page. The overall approach is as follows:\"]}),/*#__PURE__*/t(\"ol\",{style:{\"--framer-text-alignment\":\"start\",\"--framer-text-color\":\"rgba(0, 0, 0, 0.8)\",\"--framer-text-transform\":\"none\"},children:[/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Gathering Historical Pricing Data.\"})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Feature Engineering.\"})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Build and Apply Classification Machine Learning Algorithms.\"})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Backtesting of Selected Strategy using Backtrader.\"})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Performance Analysis of Backtesting.\"})})]}),/*#__PURE__*/t(\"h6\",{children:[/*#__PURE__*/e(\"br\",{}),\"Gathering Historical Pricing Data\"]}),/*#__PURE__*/t(\"p\",{children:[\"We are going to use the Nifty-50 index for this analysis. We will download the daily closing pricing data with the help of \",/*#__PURE__*/e(\"code\",{children:/*#__PURE__*/e(i,{href:\"https://github.com/ranaroussi/yfinance\",openInNewTab:!0,smoothScroll:!1,children:/*#__PURE__*/e(\"a\",{children:\"yfinance\"})})}),\" python library, calculate daily log returns, and derive market direction based on that. We will visualize the closing prices and daily returns to quickly check our data. Let\u2019s go through the code:\"]}),/*#__PURE__*/t(\"p\",{children:[\"# make the necessary imports \",/*#__PURE__*/e(\"br\",{}),\"import numpy as np \",/*#__PURE__*/e(\"br\",{}),\"from matplotlib import pyplot as plt \",/*#__PURE__*/e(\"br\",{}),\"import pandas as pd \",/*#__PURE__*/e(\"br\",{}),\"import seaborn as sns \",/*#__PURE__*/e(\"br\",{}),\"import yfinance as yf \",/*#__PURE__*/e(\"br\",{}),\"import warnings \",/*#__PURE__*/e(\"br\",{}),\"from sklearn import linear_model \",/*#__PURE__*/e(\"br\",{}),\"from sklearn.naive_bayes import GaussianNB \",/*#__PURE__*/e(\"br\",{}),\"from sklearn.svm import SVC \",/*#__PURE__*/e(\"br\",{}),\"from sklearn.ensemble import RandomForestClassifier \",/*#__PURE__*/e(\"br\",{}),\"from sklearn.neural_network import MLPClassifier \",/*#__PURE__*/e(\"br\",{}),\"import datetime \",/*#__PURE__*/e(\"br\",{}),\"import pyfolio as pf \",/*#__PURE__*/e(\"br\",{}),\"import backtrader as bt \",/*#__PURE__*/e(\"br\",{}),\"from backtrader.feeds \",/*#__PURE__*/e(\"br\",{}),\"import PandasData \",/*#__PURE__*/e(\"br\",{}),\"import warnings \"]}),/*#__PURE__*/t(\"p\",{children:[\"# set the style and ignore warnings \",/*#__PURE__*/e(\"br\",{}),\"plt.style.use(\u2018seaborn-colorblind\u2019) \",/*#__PURE__*/e(\"br\",{}),\"warnings.simplefilter(action=\u2019ignore\u2019, category=FutureWarning) \",/*#__PURE__*/e(\"br\",{}),\"warnings.filterwarnings(\u2018ignore\u2019) \"]}),/*#__PURE__*/t(\"p\",{children:[\"# this is to display images in notebook \",/*#__PURE__*/e(\"br\",{}),\"%matplotlib inline \",/*#__PURE__*/e(\"br\",{}),\"%config InlineBackend.figure_format = 'retina' \"]}),/*#__PURE__*/t(\"p\",{children:[\"# ticker and the start and end dates for testing \",/*#__PURE__*/e(\"br\",{}),\"ticker =  '^NSEI' # Nifty 50 benchmark \",/*#__PURE__*/e(\"br\",{}),\"start = datetime.datetime(2010, 1, 1) \",/*#__PURE__*/e(\"br\",{}),\"end = datetime.datetime(2020, 7, 31) \"]}),/*#__PURE__*/t(\"p\",{children:[\"# download ticker \u2018Adj Close\u2019 price from yahoo finance \",/*#__PURE__*/e(\"br\",{}),\"stock =  yf.download(ticker, progress=True, actions=True,start=start, \",/*#__PURE__*/e(\"br\",{}),\"end=end)['Adj Close'] \",/*#__PURE__*/e(\"br\",{}),\"stock = pd.DataFrame(stock) \",/*#__PURE__*/e(\"br\",{}),\"stock.rename(columns = {'Adj Close':ticker}, inplace=True) \",/*#__PURE__*/e(\"br\",{}),\"stock.head(2) \"]}),/*#__PURE__*/t(\"p\",{children:[\"# calculate daily log returns and market direction \",/*#__PURE__*/e(\"br\",{}),\"stock['returns'] = np.log(stock / stock.shift(1)) \",/*#__PURE__*/e(\"br\",{}),\"stock.dropna(inplace=True) \",/*#__PURE__*/e(\"br\",{}),\"stock['direction'] = np.sign(stock['returns']).astype(int) \",/*#__PURE__*/e(\"br\",{}),\"stock.head(3) \"]}),/*#__PURE__*/t(\"p\",{children:[\"# visualize the closing price and daily returns \",/*#__PURE__*/e(\"br\",{}),\"fig, ax = plt.subplots(2, 1, sharex=True, figsize = (12,6)) \",/*#__PURE__*/e(\"br\",{}),\"ax[0].plot(stock[ticker], label = f'{ticker} Adj Close') \",/*#__PURE__*/e(\"br\",{}),\"ax[0].set(title = f'{ticker} Closing Price', ylabel = 'Price') \",/*#__PURE__*/e(\"br\",{}),\"ax[0].grid(True) ax[0].legend() \",/*#__PURE__*/e(\"br\",{}),\"ax[1].plot(stock['returns'], label = 'Daily Returns') \",/*#__PURE__*/e(\"br\",{}),\"ax[1].set(title = f'{ticker} Daily Retunrs', ylabel = 'Returns') \",/*#__PURE__*/e(\"br\",{}),\"ax[1].grid(True) \",/*#__PURE__*/e(\"br\",{}),\"plt.legend() \",/*#__PURE__*/e(\"br\",{}),\"plt.tight_layout(); \",/*#__PURE__*/e(\"br\",{}),\"plt.savefig('images/chart1', dpi=300)\"]}),/*#__PURE__*/e(\"p\",{children:\"Code commentary:\"}),/*#__PURE__*/t(\"ol\",{style:{\"--framer-text-alignment\":\"start\",\"--framer-text-color\":\"rgba(0, 0, 0, 0.8)\",\"--framer-text-transform\":\"none\"},children:[/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Make the necessary imports.\"})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Set the ticker as index Nifty-50 with start and end dates as 2010\u201301\u201301 and 2020\u201307\u201331.\"})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[\"Download daily \",/*#__PURE__*/e(\"code\",{children:\"Adj Close\"}),\" data with the help of \",/*#__PURE__*/e(\"code\",{children:\"yfinance\"}),\" from Yahoo Finance.\"]})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[\"Calculate daily log returns and market direction using \",/*#__PURE__*/e(\"code\",{children:\"np.sign().astype(int)\"}),\".\"]})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Visualize daily closing prices and log returns.\"})})]}),/*#__PURE__*/t(\"h6\",{children:[/*#__PURE__*/e(\"br\",{}),\"Feature Engineering\"]}),/*#__PURE__*/e(\"p\",{children:\"In this section, we will create feature variables to predict the market direction. As a first step, we will use five lags of the log-returns series and then digitize them as binary (0, 1) to predict the probability of an upward and a downward market movement as (+1, -1). The python code is as follows:\"}),/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"br\",{}),\"# define the number of lags \",/*#__PURE__*/e(\"br\",{}),\"lags = [1, 2, 3, 4, 5]\"]}),/*#__PURE__*/t(\"p\",{children:[\" # compute lagged log returns \",/*#__PURE__*/e(\"br\",{}),\"cols = [] \",/*#__PURE__*/e(\"br\",{}),\"for lag in lags: \",/*#__PURE__*/e(\"br\",{}),\"      col = f'rtn_lag{lag}' \",/*#__PURE__*/e(\"br\",{}),\"      stock[col] = stock['returns'].shift(lag) \",/*#__PURE__*/e(\"br\",{}),\"      cols.append(col) \",/*#__PURE__*/e(\"br\",{}),\"stock.dropna(inplace=True) \",/*#__PURE__*/e(\"br\",{}),\"stock.head(2) \"]}),/*#__PURE__*/t(\"p\",{children:[\"# function to transform the lag returns to binary values (0,+1) \",/*#__PURE__*/e(\"br\",{}),\"def create_bins(data, bins=[0]): \",/*#__PURE__*/e(\"br\",{}),\"      global cols_bin \",/*#__PURE__*/e(\"br\",{}),\"      cols_bin = [] \",/*#__PURE__*/e(\"br\",{}),\"      for col in cols: \",/*#__PURE__*/e(\"br\",{}),\"            col_bin = col + '_bin' \",/*#__PURE__*/e(\"br\",{}),\"            data[col_bin] = np.digitize(data[col], bins=bins) \",/*#__PURE__*/e(\"br\",{}),\"            cols_bin.append(col_bin)\"]}),/*#__PURE__*/t(\"p\",{children:[\"create_bins(stock) \",/*#__PURE__*/e(\"br\",{}),\"stock[cols+cols_bin].head(2)\"]}),/*#__PURE__*/e(\"p\",{children:\"Code commentary:\"}),/*#__PURE__*/e(\"ol\",{style:{\"--framer-text-alignment\":\"start\",\"--framer-text-color\":\"rgba(0, 0, 0, 0.8)\",\"--framer-text-transform\":\"none\"},children:/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Compute five days lagged returns and shift the returns series to the number of lags to align them with one day forward return.\"})})}),/*#__PURE__*/t(\"p\",{children:[\"Define the function to transform the lag returns to binary values (0,1) using the function \",/*#__PURE__*/e(\"code\",{children:\"np.digitize().\"})]}),/*#__PURE__*/t(\"h6\",{children:[/*#__PURE__*/e(\"br\",{}),\"Build and Apply Classification Machine Learning Algorithms\"]}),/*#__PURE__*/t(\"p\",{children:[\"Now we are going to use Logistic regression, Gaussian Naive Bayes, Support Vector Machine (SVM), Random Forest, and MLP Classifier approach to predict the market direction as (+1, -1). Please refer to \",/*#__PURE__*/e(i,{href:\"https://scikit-learn.org/stable/index.html\",openInNewTab:!0,smoothScroll:!1,children:/*#__PURE__*/e(\"a\",{children:\"sklearn documentation\"})}),\" for detail on these and other algorithms. We will then evaluate the performance of each of these models using vectorized backtesting and visualize the cumulative returns. Let\u2019s go through the python code:\"]}),/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"br\",{}),\"# create a dictionary of selected algorithms models = { \u2018log_reg\u2019: linear_model.LogisticRegression(), \u2018gauss_nb\u2019: GaussianNB(), \u2018svm\u2019: SVC(), \u2018random_forest\u2019: RandomForestClassifier(max_depth=10, n_estimators=100), \u2018MLP\u2019 : MLPClassifier(max_iter=500), } # function that fits all models. def fit_models(data): mfit = {model: models[model].fit(data[cols_bin], data['direction']) for model in models.keys()} # function that predicts (derives all position values) from the fitted models def derive_positions(data): for model in models.keys(): data['pos_' + model] = models[model].predict(data[cols_bin]) # function to evaluate all trading strategies def evaluate_strats(data): global strategy_rtn strategy_rtn = [] for model in models.keys(): col = 'strategy_' + model data[col] = data['pos_' + model] * data['returns'] strategy_rtn.append(col) strategy_rtn.insert(0, 'returns') # fit the models fit_models(stock) # derives all position values derive_positions(stock) # evaluate all trading strategies by multiplying predicted directions to actual daily returns evaluate_strats(stock) # calculate total return and std. deviation of each strategy print('\\\\nTotal Returns: \\\\n') print(stock[strategy_rtn].sum().apply(np.exp)) print('\\\\nAnnual Volitility:') stock[strategy_rtn].std() * 252 ** 0.5 # number of trades over time for highest and second highest return strategy print('Number of trades SVM = ', (stock['pos_svm'].diff()!=0).sum()) print('Number of trades Ramdom Forest = ',(stock['pos_random_forest'].diff()!=0).sum()) # vectorized backtesting of the resulting trading strategies and visualize the performance over time ax = stock[strategy_rtn].cumsum().apply(np.exp).plot(figsize=(12, 6), title = 'Machine Learning Classifiers Return Comparison') ax.set_ylabel(\\\"Cumulative Returns\\\") ax.grid(True); plt.tight_layout(); plt.savefig('images/chart2', dpi=300)\"]}),/*#__PURE__*/e(\"p\",{children:\"Code commentary:\"}),/*#__PURE__*/t(\"ol\",{style:{\"--framer-text-alignment\":\"start\",\"--framer-text-color\":\"rgba(0, 0, 0, 0.8)\",\"--framer-text-transform\":\"none\"},children:[/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Create a dictionary of selected algorithms.\"})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[\"Define a function that fits all models with \",/*#__PURE__*/e(\"code\",{children:\"direction \"}),\"column as the dependent variable and \",/*#__PURE__*/e(\"code\",{children:\"_bin \"}),\"columns as feature variables.\"]})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Define a function that predicts all position values from the fitted models.\"})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Define a function to evaluate all trading strategies.\"})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Next, we fit the models, predict positions, and evaluate all trading strategies by multiplying predicted directions to actual daily returns.\"})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Calculate the total return and standard deviation of each strategy.\"})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Calculate the number of trades overtime for the highest and second-highest return strategies.\"})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Vectorize backtesting of the resulting trading strategies and visualize the performance over time.\"})})]}),/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"br\",{}),\"We can see that the support vector machine model has given the maximum total returns over time with comparable annual volatility with other models. However, it will be quite immature to deploy any such strategy based on vectorized backtesting results. Some of the reason are listed below:\"]}),/*#__PURE__*/t(\"ol\",{style:{\"--framer-text-alignment\":\"start\",\"--framer-text-color\":\"rgba(0, 0, 0, 0.8)\",\"--framer-text-transform\":\"none\"},children:[/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"The number of trades is quite high and vectorized backtesting doesn\u2019t account for costs such as trading and market slippage.\"})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"The strategy accounts for both long and short positions however short selling may not be feasible due to multiple reasons.\"})})]}),/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"br\",{}),\"Hence, our backtesting needs to be more realistic and event-driven to address the above gaps.\"]}),/*#__PURE__*/e(\"h6\",{children:\"Backtesting of Selected Strategy using Backtrader\"}),/*#__PURE__*/t(\"p\",{children:[\"In this section, we will take our best performing model, i.e. support vector machine (SVM), and perform the backtesting using the python library \",/*#__PURE__*/e(i,{href:\"https://www.backtrader.com/docu/\",openInNewTab:!0,smoothScroll:!1,children:/*#__PURE__*/e(\"a\",{children:\"Backtrader\"})}),\". The backtesting strategy will be as follows:\"]}),/*#__PURE__*/t(\"ol\",{style:{\"--framer-text-alignment\":\"start\",\"--framer-text-color\":\"rgba(0, 0, 0, 0.8)\",\"--framer-text-transform\":\"none\"},children:[/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"We start with the initial capital of 100, 000 and trading commission as 0.1%.\"})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[\"We buy when the \",/*#__PURE__*/e(\"code\",{children:\"predicted\"}),\" value is +1 and sell (only if stock is in possession) when the predicted value is -1.\"]})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"All-in strategy \u2014 when creating a buy order, buy as many shares as possible.\"})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Short selling is not allowed.\"})})]}),/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"br\",{}),\"Let\u2019s go through the python code:\"]}),/*#__PURE__*/t(\"p\",{children:[\"# fetch the daily pricing data from yahoo finance prices = yf.download(ticker, progress=True, actions=True, start=start, end=end) prices.head(2) # rename the columns as needed for Backtrader prices.drop(['Close','Dividends','Stock Splits'], inplace=True, axis=1) prices.rename(columns = {'Open':'open','High':'high','Low':'low','Adj Close':'close','Volume':'volume', }, inplace=True) prices.head(3) # add the predicted column to prices dataframe. This will be used as signal for buy or sell predictions = stock['strategy_svm'] predictions = pd.DataFrame(predictions) predictions.rename(columns = {'strategy_svm':'predicted'}, inplace=True) prices = predictions.join(prices, how='right').dropna() prices.head(2) OHLCV = ['open', 'high', 'low', 'close', 'volume'] # class to define the columns we will provide class SignalData(PandasData): \\\"\\\"\\\" Define pandas DataFrame structure \\\"\\\"\\\" cols = OHLCV + ['predicted'] # create lines lines = tuple(cols) # define parameters params = {c: -1 for c in cols} params.update({'datetime': None}) params = tuple(params.items())\",/*#__PURE__*/e(\"br\",{}),/*#__PURE__*/e(\"br\",{className:\"trailing-break\"})]}),/*#__PURE__*/e(\"p\",{children:\"Code commentary:\"}),/*#__PURE__*/t(\"ol\",{style:{\"--framer-text-alignment\":\"start\",\"--framer-text-color\":\"rgba(0, 0, 0, 0.8)\",\"--framer-text-transform\":\"none\"},children:[/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Fetch the daily pricing data from yahoo finance and rename the columns as OHLCV format needed for Backtrader.\"})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[\"Take the SVM strategy returns from the \",/*#__PURE__*/e(\"code\",{children:\"stock \"}),\"dataframe and join it to the \",/*#__PURE__*/e(\"code\",{children:\"prices \"}),\"dataframe. This column\u2019s value will be a signal to buy or sell while placing the order.\"]})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[\"Define a custom \",/*#__PURE__*/e(\"code\",{children:\"SignalData\"}),\" class for dataframe columns to be fed to Backtrader.\"]})})]}),/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"br\",{}),\"Now, we define the \",/*#__PURE__*/e(\"code\",{children:\"MLStrategy\"}),\" class for the backtesting strategy. It needs to be inherited from \",/*#__PURE__*/e(\"code\",{children:\"bt.Strategy\"}),\". As we have predicted the market direction on the day\u2019s closing price, hence we will use \",/*#__PURE__*/e(\"code\",{children:\"cheat_on_open=True \"}),\"when creating the \",/*#__PURE__*/e(\"code\",{children:\"bt.Cerebro\"}),\" object. This means the number of shares we want to buy will be based on day t+1\u2019s open price. As a result, we also define the \",/*#__PURE__*/e(\"code\",{children:\"next_open\"}),\" method instead of \",/*#__PURE__*/e(\"code\",{children:\"next\"}),\" within the Strategy class.\"]}),/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"br\",{}),\"# define backtesting strategy class class MLStrategy(bt.Strategy): params = dict( ) def __init__(self): # keep track of open, close prices and predicted value in the series self.data_predicted = self.datas[0].predicted self.data_open = self.datas[0].open self.data_close = self.datas[0].close # keep track of pending orders/buy price/buy commission self.order = None self.price = None self.comm = None # logging function def log(self, txt): '''Logging function''' dt = self.datas[0].datetime.date(0).isoformat() print(f'{dt}, {txt}') def notify_order(self, order): if order.status in [order.Submitted, order.Accepted]: # order already submitted/accepted - no action required return # report executed order if order.status in [order.Completed]: if order.isbuy(): self.log(f'BUY EXECUTED --- Price: {order.executed.price:.2f}, Cost: {order.executed.value:.2f},Commission: {order.executed.comm:.2f}' ) self.price = order.executed.price self.comm = order.executed.comm else: self.log(f'SELL EXECUTED --- Price: {order.executed.price:.2f}, Cost: {order.executed.value:.2f},Commission: {order.executed.comm:.2f}' ) # report failed order elif order.status in [order.Canceled, order.Margin, order.Rejected]: self.log('Order Failed') # set no pending order self.order = None def notify_trade(self, trade): if not trade.isclosed: return self.log(f'OPERATION RESULT --- Gross: {trade.pnl:.2f}, Net: {trade.pnlcomm:.2f}') # We have set cheat_on_open = True.This means that we calculated the signals on day t's close price, # but calculated the number of shares we wanted to buy based on day t+1's open price. def next_open(self): if not self.position: if self.data_predicted > 0: # calculate the max number of shares ('all-in') size = int(self.broker.getcash() / self.datas[0].open) # buy order self.log(f'BUY CREATED --- Size: {size}, Cash: {self.broker.getcash():.2f}, Open: {self.data_open[0]}, Close: {self.data_close[0]}') self.buy(size=size) else: if self.data_predicted < 0: # sell order self.log(f'SELL CREATED --- Size: {self.position.size}') self.sell(size=self.position.size)\"]}),/*#__PURE__*/e(\"p\",{children:\"Code commentary:\"}),/*#__PURE__*/t(\"ol\",{style:{\"--framer-text-alignment\":\"start\",\"--framer-text-color\":\"rgba(0, 0, 0, 0.8)\",\"--framer-text-transform\":\"none\"},children:[/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[\"The function \",/*#__PURE__*/e(\"code\",{children:\"__init__\"}),\" tracks open, close, predicted, and pending orders.\"]})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[\"The function \",/*#__PURE__*/e(\"code\",{children:\"notify_order\"}),\" tracks the order status.\"]})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[\"The function \",/*#__PURE__*/e(\"code\",{children:\"notify_trade\"}),\" is triggered if the order is complete and logs profit and loss for the trade.\"]})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[\"The function \",/*#__PURE__*/e(\"code\",{children:\"next_open\"}),\" checks the available cash and calculates the maximum number of shares that can be bought. It places the buy order if we don\u2019t hold any position and the\",/*#__PURE__*/e(\"code\",{children:\"predicted \"}),\"value is greater than zero. Else, it places the sell order if the \",/*#__PURE__*/e(\"code\",{children:\"predicted\"}),\" value is less than zero.\"]})})]}),/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"br\",{}),\"Next, we instantiate \",/*#__PURE__*/e(\"code\",{children:\"SignalData \"}),\"and \",/*#__PURE__*/e(\"code\",{children:\"Cerebro\"}),\" objects and add \",/*#__PURE__*/e(\"code\",{children:\"prices\"}),\" dataframe, \",/*#__PURE__*/e(\"code\",{children:\"MLStrategy\"}),\", initial capital, commission, and \",/*#__PURE__*/e(\"code\",{children:\"pyfolio \"}),\"analyzer. Finally, we run the backtest and capture the results.\"]}),/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"br\",{}),\"# instantiate SignalData class\",/*#__PURE__*/e(\"br\",{}),\"data = SignalData(dataname=prices)# instantiate Cerebro, add strategy, data, initial cash, commission and pyfolio for performance analysis\",/*#__PURE__*/e(\"br\",{}),\"cerebro = bt.Cerebro(stdstats = False, cheat_on_open=True)\",/*#__PURE__*/e(\"br\",{}),\"cerebro.addstrategy(MLStrategy)\",/*#__PURE__*/e(\"br\",{}),\"cerebro.adddata(data, name=ticker)\",/*#__PURE__*/e(\"br\",{}),\"cerebro.broker.setcash(100000.0)\",/*#__PURE__*/e(\"br\",{}),\"cerebro.broker.setcommission(commission=0.001)\",/*#__PURE__*/e(\"br\",{}),\"cerebro.addanalyzer(bt.analyzers.PyFolio, _name='pyfolio')# run the backtest\",/*#__PURE__*/e(\"br\",{}),\"print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())\",/*#__PURE__*/e(\"br\",{}),\"backtest_result = cerebro.run()\",/*#__PURE__*/e(\"br\",{}),\"print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())\"]}),/*#__PURE__*/e(\"h6\",{children:\"Performance Analysis of Backtesting\"}),/*#__PURE__*/t(\"p\",{children:[\"We will analyze the performance statistics using \",/*#__PURE__*/e(\"code\",{children:/*#__PURE__*/e(i,{href:\"https://github.com/quantopian/pyfolio\",openInNewTab:!0,smoothScroll:!1,children:/*#__PURE__*/e(\"a\",{children:\"pyfolio\"})})}),\" . pyfolio is a Python library for performance and risk analysis of financial portfolios developed by \",/*#__PURE__*/e(i,{href:\"https://www.quantopian.com/\",openInNewTab:!0,smoothScroll:!1,children:/*#__PURE__*/e(\"a\",{children:\"Quantopian Inc\"})}),\".\"]}),/*#__PURE__*/e(\"p\",{children:\"# Extract inputs for pyfolio strat = backtest_result[0] pyfoliozer = strat.analyzers.getbyname(\u2018pyfolio\u2019) returns, positions, transactions, gross_lev = pyfoliozer.get_pf_items() returns.name = \u2018Strategy\u2019 returns.head(2) # get benchmark returns benchmark_rets= stock['returns'] benchmark_rets.index = benchmark_rets.index.tz_localize('UTC') benchmark_rets = benchmark_rets.filter(returns.index) benchmark_rets.name = 'Nifty-50' benchmark_rets.head(2) # get performance statistics for strategy pf.show_perf_stats(returns) # plot performance for strategy vs benchmark fig, ax = plt.subplots(nrows=2, ncols=2, figsize=(16, 9),constrained_layout=True) axes = ax.flatten() pf.plot_drawdown_periods(returns=returns, ax=axes[0]) axes[0].grid(True) pf.plot_rolling_returns(returns=returns, factor_returns=benchmark_rets, ax=axes[1], title='Strategy vs Nifty-50') axes[1].grid(True) pf.plot_drawdown_underwater(returns=returns, ax=axes[2]) axes[2].grid(True) pf.plot_rolling_sharpe(returns=returns, ax=axes[3]) axes[3].grid(True) # fig.suptitle('Strategy vs Nifty-50 (Buy and Hold)', fontsize=16, y=0.990) plt.grid(True) plt.legend() plt.tight_layout() plt.savefig('images/chart3', dpi=300)\"}),/*#__PURE__*/e(\"p\",{children:\"Code commentary:\"}),/*#__PURE__*/t(\"ol\",{style:{\"--framer-text-alignment\":\"start\",\"--framer-text-color\":\"rgba(0, 0, 0, 0.8)\",\"--framer-text-transform\":\"none\"},children:[/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"We extract inputs needed for pyfolio from the backtesting result.\"})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Get the benchmark daily returns to compare and contrast with the strategy.\"})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[\"Get performance statistics for the strategy using pyfolio \",/*#__PURE__*/e(\"code\",{children:\"show_perf_stats\"}),\".\"]})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:\"Visualize drawdowns, cumulative returns, underwater plot, and rolling Sharpe ratio.\"})})]}),/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"br\",{}),\"Let\u2019s analyze the performance of our strategy. The annual return is just 3.9% and the cumulative return is 48% as compared to 8.86 times total return we observed during vectorized backtesting. If we visualize a few other performance parameters in comparison to the benchmark, we can see our strategy is not able to beat the performance of the simple buy and hold strategy.\"]}),/*#__PURE__*/e(\"p\",{children:\"So the obvious question is why? This is due to the fact that we paid a huge commission for a high number of trades. The second reason; we allowed no short selling while performing backtesting with Backtrader.\"}),/*#__PURE__*/e(\"p\",{children:\"In conclusion, often the vectorized backtesting results may look great on paper however we need to consider all aspects of implementation shortfall and feasibility before we decide to implement such a strategy. Also, keep in mind that the capital market is not just about machine learning otherwise all data scientists would have become super-rich by now.\"}),/*#__PURE__*/e(\"h6\",{children:\"Happy investing and do leave your comments on the article!\"}),/*#__PURE__*/e(\"p\",{children:/*#__PURE__*/e(\"em\",{children:\"Please Note: This analysis is only for educational purposes and the author is not liable for any of your investment decisions.\"})}),/*#__PURE__*/e(\"p\",{children:\"References:\"}),/*#__PURE__*/t(\"ol\",{style:{\"--framer-text-alignment\":\"start\",\"--framer-text-color\":\"rgba(0, 0, 0, 0.8)\",\"--framer-text-transform\":\"none\"},children:[/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(i,{href:\"https://www.amazon.in/Python-Finance-2e-Yves-Hilpisch/dp/1492024333\",openInNewTab:!0,smoothScroll:!1,children:/*#__PURE__*/e(\"a\",{children:\"Python for Finance 2e: Mastering Data-Driven Finance\"})}),\" by Yves Hilpisch\"]})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(i,{href:\"https://www.amazon.in/Python-Finance-Cookbook-libraries-financial-ebook/dp/B083KG9DC7/ref=sr_1_2?dchild=1&keywords=Python+for+Finance+Cookbook&qid=1597938216&s=books&sr=1-2\",openInNewTab:!0,smoothScroll:!1,children:/*#__PURE__*/e(\"a\",{children:\"Python for Finance Cookbook: Over 50 recipes for applying modern Python libraries to financial data analysis\"})}),\" by Eryk Lewinson\"]})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(i,{href:\"https://www.amazon.in/gp/product/B08D9SP6MB/ref=dbs_a_def_rwt_bibl_vppi_i1\",openInNewTab:!0,smoothScroll:!1,children:/*#__PURE__*/e(\"a\",{children:\"Machine Learning for Algorithmic Trading\"})}),\" by Stefan Jansen\"]})}),/*#__PURE__*/t(\"li\",{\"data-preset-tag\":\"p\",children:[/*#__PURE__*/t(\"p\",{children:[\"Please check out my other articles/ posts on quantitative finance at my \",/*#__PURE__*/e(i,{href:\"https://www.linkedin.com/in/sabirjana/detail/recent-activity/shares/\",openInNewTab:!0,smoothScroll:!1,children:/*#__PURE__*/e(\"a\",{children:\"Linkedin\"})}),\" page or on \",/*#__PURE__*/e(i,{href:\"https://medium.com/@sabirh.jana\",openInNewTab:!1,smoothScroll:!1,children:/*#__PURE__*/e(\"a\",{children:\"Medium\"})}),\".\"]}),/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(i,{href:\"https://medium.com/tag/investing?source=post_page-----2382fdaf7a32---------------investing-----------------\",openInNewTab:!1,smoothScroll:!1,children:/*#__PURE__*/e(\"a\",{children:/*#__PURE__*/e(\"br\",{})})}),/*#__PURE__*/e(\"br\",{}),/*#__PURE__*/e(\"br\",{}),/*#__PURE__*/e(\"br\",{}),/*#__PURE__*/e(\"br\",{}),/*#__PURE__*/e(\"br\",{}),/*#__PURE__*/e(\"br\",{}),/*#__PURE__*/e(\"br\",{}),/*#__PURE__*/e(\"br\",{className:\"trailing-break\"})]})]})]})]})},{id:\"NSkq79_Go\",[n]:\"Statistical Arbitrage with Pairs Trading and Backtesting\",[s]:\"statistical-arbitrage-with-pairs-trading-and-backtesting\",[l]:\"2023-10-27T00:00:00.000Z\",[c]:h({src:\"https://framerusercontent.com/images/C4XZ5kqe64SRjV3GPNHJmArYDdU.jpg\"},\"Pink Flower\"),[d]:/*#__PURE__*/t(o.Fragment,{children:[/*#__PURE__*/t(\"p\",{children:[\"Statistical Arbitrage (Stat Arb) are trading strategies that typically take advantage of either mean reversion in share prices or opportunities created by market microstructure anomalies. It is a highly quantitative analytical approach involving a well-diversified portfolio of securities. However, to illustrate the concept I will take the example of pairs trading involving only two cointegrated securities.Pairs trading is a market-neutral strategy where we use statistical techniques to identify two stocks that are historically highly correlated with each other. When there is a deviation in the price relationship of these stocks, we expect this to be mean reverting and buy the underperforming stock and simultaneously sell the outperforming one. If our mean-reversion assumption is valid then prices should converge to long term average and trade should benefit. However, if the price divergence is not temporary and it is due to structural reasons then there is a high risk of losing the money. You can find the Python Notebook and data used in this article on my \",/*#__PURE__*/e(i,{href:\"https://github.com/sabirjana/blog/tree/master/Pair_Trading\",openInNewTab:!0,smoothScroll:!1,children:/*#__PURE__*/t(\"a\",{children:[/*#__PURE__*/e(\"strong\",{children:\"Github\"}),\" \"]})}),\"page. The overall approach followed in this article is mentioned below:Stock Universe and Identification of Cointegrated Pairs of Stocks.Perform Stationary test for the Selected Pair.Generate Trading Signals using z-score.Portfolio Profit and Loss Calculation.\"]}),/*#__PURE__*/e(\"p\",{children:/*#__PURE__*/e(\"br\",{className:\"trailing-break\"})}),/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"strong\",{children:\"Stock Universe and Identification of Cointegrated Pairs of Stocks\"}),\"Our first step is to decide the stock universe and identify the pairs with high correlation. It is very important that this is based on economic relationships such as companies with similar businesses, else it might be spurious. I have taken all constituents of NSE-100 which are categorized as \u2018FINANCIAL SERVICES\u2019 companies. This gives us a list of 25 companies to start with. However, we filter out companies with less than 10 years of daily pricing data and are left with only the final 15 stocks. We take the daily closing price for these 15 stocks and split the dataframe into test and training sets. This is to ensure that our decision to select a cointegrated pair is based on the training dataset and backtesting is done using out of sample test dataset. As a first step, we will use the \",/*#__PURE__*/e(i,{href:\"https://en.wikipedia.org/wiki/Pearson_correlation_coefficient\",openInNewTab:!0,smoothScroll:!1,children:/*#__PURE__*/e(\"a\",{children:\"Pearson correlation coefficient\"})}),\" to get the basic idea about the relationship between these stocks and then work to identify cointegrated stocks using the function \",/*#__PURE__*/e(\"code\",{children:\"coint\"}),\" form \",/*#__PURE__*/e(\"code\",{children:\"statsmodels.tsa.stattools \"}),\". The function \",/*#__PURE__*/e(\"code\",{children:\"coint,\"}),\" will return p-values of the cointegration test for each pair. We will store these p-values in an array and visualize it as a heatmap. If a p-value is lower than 0.05, this means that we can reject the null hypothesis and the two time series of different symbols can be cointegrated.Let\u2019s jump right to the code:# make the necessary imports\",/*#__PURE__*/e(\"br\",{}),\"import pandas as pd\",/*#__PURE__*/e(\"br\",{}),\"import numpy as np\",/*#__PURE__*/e(\"br\",{}),\"import matplotlib.pyplot as plt\",/*#__PURE__*/e(\"br\",{}),\"import seaborn as sns\",/*#__PURE__*/e(\"br\",{}),\"import datetime\",/*#__PURE__*/e(\"br\",{}),\"idx = pd.IndexSlice\",/*#__PURE__*/e(\"br\",{}),\"import statsmodels.api as smfrom statsmodels.regression.linear_model import OLS\",/*#__PURE__*/e(\"br\",{}),\"from statsmodels.tsa.stattools import adfuller\",/*#__PURE__*/e(\"br\",{}),\"from statsmodels.tsa.stattools import coint\",/*#__PURE__*/e(\"br\",{}),\"from sklearn.model_selection import train_test_split%matplotlib inline\",/*#__PURE__*/e(\"br\",{}),\"%config InlineBackend.figure_format = \u2018retina\u2019# read the matadata csv\",/*#__PURE__*/e(\"br\",{}),\"nifty_meta = pd.read_csv('data/nifty_meta.csv')\",/*#__PURE__*/e(\"br\",{}),\"nifty_meta.head(2)# get the ticker list with industry is equal to FINANCIAL SERVICES\",/*#__PURE__*/e(\"br\",{}),\"tickers = list(nifty_meta[nifty_meta.Industry=='FINANCIAL SERVICES'].Symbol)\",/*#__PURE__*/e(\"br\",{}),\"print(tickers)\",/*#__PURE__*/e(\"br\",{}),\"print(len(tickers))# start and end dates for backtesting\",/*#__PURE__*/e(\"br\",{}),\"fromdate = datetime.datetime(2010, 1, 1)\",/*#__PURE__*/e(\"br\",{}),\"todate = datetime.datetime(2020, 6, 15)# read back the pricing data\",/*#__PURE__*/e(\"br\",{}),\"prices = pd.read_csv('data/prices.csv', index_col=['ticker','date'], parse_dates=True)\",/*#__PURE__*/e(\"br\",{}),\"prices.head(2)# remove tickers where we have less than 10 years of data.\",/*#__PURE__*/e(\"br\",{}),\"min_obs = 2520\",/*#__PURE__*/e(\"br\",{}),\"nobs = prices.groupby(level='ticker').size()\",/*#__PURE__*/e(\"br\",{}),\"keep = nobs[nobs>min_obs].indexprices = prices.loc[idx[keep,:], :]\",/*#__PURE__*/e(\"br\",{}),\"prices.info()# final tickers list\",/*#__PURE__*/e(\"br\",{}),\"TICKERS = list(prices.index.get_level_values('ticker').unique())\",/*#__PURE__*/e(\"br\",{}),\"print(len(TICKERS))\",/*#__PURE__*/e(\"br\",{}),\"print(TICKERS)# unstack and take close price\",/*#__PURE__*/e(\"br\",{}),\"close = prices.unstack('ticker')['close'].sort_index()\",/*#__PURE__*/e(\"br\",{}),\"close = close.dropna()\",/*#__PURE__*/e(\"br\",{}),\"close.head(2)# train test split \",/*#__PURE__*/e(\"br\",{}),\"train_close, test_close = train_test_split(close, test_size=0.5, shuffle=False)# quick view of head and tail of train set\",/*#__PURE__*/e(\"br\",{}),\"train_close.head(2).append(train_close.tail(2))# Pearson correlation to get the basic idea about the relationship\",/*#__PURE__*/e(\"br\",{}),\"fig, ax = plt.subplots(figsize=(10,7))\",/*#__PURE__*/e(\"br\",{}),\"sns.heatmap(train_close.pct_change().corr(method ='pearson'), ax=ax, cmap='coolwarm', annot=True, fmt=\\\".2f\\\") #spearman\",/*#__PURE__*/e(\"br\",{}),\"ax.set_title('Assets Correlation Matrix')\",/*#__PURE__*/e(\"br\",{}),\"plt.savefig('images/chart1', dpi=300)# function to find cointegrated pairs\",/*#__PURE__*/e(\"br\",{}),\"def find_cointegrated_pairs(data):\",/*#__PURE__*/e(\"br\",{}),\"n = data.shape[1]\",/*#__PURE__*/e(\"br\",{}),\"pvalue_matrix = np.ones((n, n))\",/*#__PURE__*/e(\"br\",{}),\"keys = data.keys()\",/*#__PURE__*/e(\"br\",{}),\"pairs = []\",/*#__PURE__*/e(\"br\",{}),\"for i in range(n):\",/*#__PURE__*/e(\"br\",{}),\"for j in range(i+1, n):\",/*#__PURE__*/e(\"br\",{}),\"result = coint(data[keys[i]], data[keys[j]])\",/*#__PURE__*/e(\"br\",{}),\"pvalue_matrix[i, j] = result[1]\",/*#__PURE__*/e(\"br\",{}),\"if result[1] < 0.05:\",/*#__PURE__*/e(\"br\",{}),\"pairs.append((keys[i], keys[j]))\",/*#__PURE__*/e(\"br\",{}),\"return pvalue_matrix, pairs# calculate p-values and plot as a heatmap\",/*#__PURE__*/e(\"br\",{}),\"pvalues, pairs = find_cointegrated_pairs(train_close)\",/*#__PURE__*/e(\"br\",{}),\"print(pairs)\",/*#__PURE__*/e(\"br\",{}),\"fig, ax = plt.subplots(figsize=(10,7))\",/*#__PURE__*/e(\"br\",{}),\"sns.heatmap(pvalues, xticklabels = train_close.columns,\",/*#__PURE__*/e(\"br\",{}),\"yticklabels = train_close.columns, cmap = 'RdYlGn_r', annot = True, fmt=\\\".2f\\\",\",/*#__PURE__*/e(\"br\",{}),\"mask = (pvalues >= 0.99))\",/*#__PURE__*/e(\"br\",{}),\"ax.set_title('Assets Cointregration Matrix p-values Between Pairs')\",/*#__PURE__*/e(\"br\",{}),\"plt.tight_layout()\",/*#__PURE__*/e(\"br\",{}),\"plt.savefig('images/chart2', dpi=300)Code commentary:We make the necessary imports of python libraries.Next, we read \",/*#__PURE__*/e(\"code\",{children:\"nifty_meta.csv\"}),\" and create a list of tickers where the industry is \u2018FINANCIAL SERVICES\u2019 and set start and end dates.Read daily pricing data from \",/*#__PURE__*/e(\"code\",{children:\"prices.csv\"}),\" and remove tickers where we have less than 10 years of data.Unstack the pricing dataframe to have only daily closing data and split into 50% each into the train and test datasets.Plot Pearson correlation of daily returns to get the basic idea about the relationship.Define a function \",/*#__PURE__*/e(\"code\",{children:\"find_cointegrated_pairs\"}),\" to find cointegrated pairs and corresponding p-values.Plot the heatmap of p-values.Pearson Correlation of Daily ReturnsPearson correlation coefficient varies between +1 to -1 and is a linear measure of the relationship between two variables. The value +1 indicates a strong positive correlation, zero indicates no relationship, and -1 indicates a strong negative relationship. We can see in the above heatmap that there are multiple pairs with a strong positive correlation.Assets Cointegration Matrix p-values Between PairsLet\u2019s also analyze the result of the cointegration test. We can see in the above heatmap that there are many pairs with a p-value of less than 0.05. This means that for these pairs we can reject the null hypothesis and they can be cointegrated.\"]}),/*#__PURE__*/e(\"p\",{children:/*#__PURE__*/e(\"br\",{className:\"trailing-break\"})}),/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"strong\",{children:\"Perform Stationary test for the Selected Pair\"}),\"Now, we have many candidates of pairs for the strategy where the p-value is less than 0.05. Selecting the right pair is of the utmost importance as the strategy will not work well if the prices are moving exactly together. They need to be diverging and mean-reverting for our strategy to be profitable.Let\u2019s go with tickers BANKBARODA and SBIN and further test the stationarity of spread using the Augmented Dickey-Fuller test. It is important that the spread is stationary. A time series is considered stationary if parameters such as mean and variance do not change over time and there is no \",/*#__PURE__*/e(i,{href:\"https://en.wikipedia.org/wiki/Unit_root\",openInNewTab:!0,smoothScroll:!1,children:/*#__PURE__*/e(\"a\",{children:\"unit root\"})}),\". We will first calculate the hedge ratio between these two tickers using OLS regression. Then, using the hedge ratio, we will calculate the spread and run the Augmented Dickey-Fuller test.Let\u2019s go through the code:# final pair to test strategy\",/*#__PURE__*/e(\"br\",{}),\"asset1 = \u2018BANKBARODA\u2019\",/*#__PURE__*/e(\"br\",{}),\"asset2 = \u2018SBIN\u2019# create a train dataframe of 2 assets\",/*#__PURE__*/e(\"br\",{}),\"train = pd.DataFrame()\",/*#__PURE__*/e(\"br\",{}),\"train['asset1'] = train_close[asset1]\",/*#__PURE__*/e(\"br\",{}),\"train['asset2'] = train_close[asset2]# visualize closing prices\",/*#__PURE__*/e(\"br\",{}),\"ax = train[['asset1','asset2']].plot(figsize=(12, 6), title = 'Daily Closing Prices for {} and {}'.format(asset1,asset2))\",/*#__PURE__*/e(\"br\",{}),'ax.set_ylabel(\"Closing Price\")',/*#__PURE__*/e(\"br\",{}),\"ax.grid(True);\",/*#__PURE__*/e(\"br\",{}),\"plt.savefig('images/chart3', dpi=300)# run OLS regression\",/*#__PURE__*/e(\"br\",{}),\"model=sm.OLS(train.asset2, train.asset1).fit()# print regression summary results\",/*#__PURE__*/e(\"br\",{}),\"plt.rc('figure', figsize=(12, 7))\",/*#__PURE__*/e(\"br\",{}),\"plt.text(0.01, 0.05, str(model.summary()), {'fontsize': 16}, fontproperties = 'monospace')\",/*#__PURE__*/e(\"br\",{}),\"plt.axis('off')\",/*#__PURE__*/e(\"br\",{}),\"plt.tight_layout()\",/*#__PURE__*/e(\"br\",{}),\"plt.subplots_adjust(left=0.2, right=0.8, top=0.7, bottom=0.1)\",/*#__PURE__*/e(\"br\",{}),\"plt.savefig('images/chart4', dpi=300);print('Hedge Ratio = ', model.params[0])# calculate spread\",/*#__PURE__*/e(\"br\",{}),\"spread = train.asset2 - model.params[0] * train.asset1# Plot the spread\",/*#__PURE__*/e(\"br\",{}),'ax = spread.plot(figsize=(12, 6), title = \"Pair\\'s Spread\")',/*#__PURE__*/e(\"br\",{}),'ax.set_ylabel(\"Spread\")',/*#__PURE__*/e(\"br\",{}),\"ax.grid(True);# conduct Augmented Dickey-Fuller test\",/*#__PURE__*/e(\"br\",{}),\"adf = adfuller(spread, maxlag = 1)\",/*#__PURE__*/e(\"br\",{}),\"print('Critical Value = ', adf[0])# probablity critical values\",/*#__PURE__*/e(\"br\",{}),\"print(adf[4])Code commentary:Select asset1 as BANKBARODA and asset2 as SBIN.Create a dataframe of the above two stock\u2019s closing prices using the training dataset and visualize it.Run OLS regression and get the slope coefficient which is also our hedge ratio.Calculate the spread and plot it for visualization.Run the Augmented Dickey-Fuller test to check the stationarity of the spread and presence of unit root.Daily Closing Prices for the PairWe can see from the above plot that closing prices between these two stocks move quite together.OLS Regression ResultsPair\u2019s SpreadA high value of R-square and near-zero p-value from OLS regression suggest a very high correlation between these two stocks. The spread looks stationary and the critical value from the Augmented Dickey-Fuller test is -3.459 which is less than the value at 1% (-3.435) significance level. Hence, we are able to reject the null hypothesis that spread has a unit root and can conclude that it is stationarity in nature.\"]}),/*#__PURE__*/e(\"p\",{children:/*#__PURE__*/e(\"br\",{className:\"trailing-break\"})}),/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"strong\",{children:\"Generate Trading Signals using z-score\"}),\"We have used the training dataset until this point to finalize the stock pair for our strategy. Now onward we will be using the test dataset to ensure trading signal generation and backtesting is using out of sample dataset. We will use the z-score of the ratio between the two stock prices to generate trading signals and set the upper and lower thresholds. This will tell us how far a price is from the population mean value. If it is positive and the value is above the upper thresholds then the stock price is higher than the average price value. Therefore, its price is expected to go down hence we want to short (sell) this stock and long (buy) the other one.Let\u2019s go through the code:# calculate z-score\",/*#__PURE__*/e(\"br\",{}),\"def zscore(series):\",/*#__PURE__*/e(\"br\",{}),\"return (series \u2014 series.mean()) / np.std(series)# create a dataframe for trading signals\",/*#__PURE__*/e(\"br\",{}),\"signals = pd.DataFrame()\",/*#__PURE__*/e(\"br\",{}),\"signals['asset1'] = test_close[asset1] \",/*#__PURE__*/e(\"br\",{}),\"signals['asset2'] = test_close[asset2]\",/*#__PURE__*/e(\"br\",{}),\"ratios = signals.asset1 / signals.asset2# calculate z-score and define upper and lower thresholds\",/*#__PURE__*/e(\"br\",{}),\"signals['z'] = zscore(ratios)\",/*#__PURE__*/e(\"br\",{}),\"signals['z upper limit'] = np.mean(signals['z']) + np.std(signals['z'])\",/*#__PURE__*/e(\"br\",{}),\"signals['z lower limit'] = np.mean(signals['z']) - np.std(signals['z'])# create signal - short if z-score is greater than upper limit else long\",/*#__PURE__*/e(\"br\",{}),\"signals['signals1'] = 0\",/*#__PURE__*/e(\"br\",{}),\"signals['signals1'] = np.select([signals['z'] > \\\\\",/*#__PURE__*/e(\"br\",{}),\"signals['z upper limit'], signals['z'] < signals['z lower limit']], [-1, 1], default=0)# we take the first order difference to obtain portfolio position in that stock\",/*#__PURE__*/e(\"br\",{}),\"signals['positions1'] = signals['signals1'].diff()\",/*#__PURE__*/e(\"br\",{}),\"signals['signals2'] = -signals['signals1']\",/*#__PURE__*/e(\"br\",{}),\"signals['positions2'] = signals['signals2'].diff()# verify datafame head and tail\",/*#__PURE__*/e(\"br\",{}),\"signals.head(3).append(signals.tail(3))# visualize trading signals and position\",/*#__PURE__*/e(\"br\",{}),\"fig=plt.figure(figsize=(14,6))\",/*#__PURE__*/e(\"br\",{}),\"bx = fig.add_subplot(111) \",/*#__PURE__*/e(\"br\",{}),\"bx2 = bx.twinx()#plot two different assets\",/*#__PURE__*/e(\"br\",{}),\"l1, = bx.plot(signals['asset1'], c='#4abdac')\",/*#__PURE__*/e(\"br\",{}),\"l2, = bx2.plot(signals['asset2'], c='#907163')u1, = bx.plot(signals['asset1'][signals['positions1'] == 1], lw=0, marker='^', markersize=8, c='g',alpha=0.7)Code commentary:Define the function \",/*#__PURE__*/e(\"code\",{children:\"zscore \"}),\"to calculate z-score.Create a signals dataframe of our two stocks with the closing price from the testing dataset and calculate their price ratio.Calculate z-score for the ratio and define upper and lower thresholds with plus and minus one standard deviation.Create a signal column with the following logic \u2014 If z-score is greater than the upper threshold than we will have -1 (short signal) however if z-score is less than the lower threshold than +1 (long signal) and the default is zero for no signal.Take the first-order difference of the signal column to obtain the stock position. If it is +1 then we are long, -1 then short and 0 if no position.The second signal will be just opposite to first which means we go long on one stock and simultaneously short on the other one. Similarly, take the first-order difference for the second signal and calculate the second position column.Next, we visualize both the stock prices along with its long and short positions in the portfolio.Pair Trading \u2014 Trading Signals and Position\",/*#__PURE__*/e(\"strong\",{children:\"Portfolio Profit and Loss Calculation\"}),\"We will start with an initial capital of 100,000 and calculate the maximum number of shares position for each stock using the initial capital. On any given day, total profit and loss from the first stock will be total holding in that stock and cash position for that stock. Similarly, profit and loss for the second stock will be total holding in the stock and cash for that stock. You need to keep in mind that we have a market neutral position which means we go long and short simultaneously with approximately the same capital. Finally, to get the total profit and loss we have to aggregate these two. Based on the position for the stock 1 and 2, we calculate their respective daily returns. We will also add a z-score column with upper and lower threshold columns to the final portfolio dataframe for visualization purposes.Let\u2019s jump to the code:# initial capital to calculate the actual pnl\",/*#__PURE__*/e(\"br\",{}),\"initial_capital = 100000\",/*#__PURE__*/e(\"br\",{}),/*#__PURE__*/e(\"br\",{}),\"# shares to buy for each position\",/*#__PURE__*/e(\"br\",{}),\"positions1 = initial_capital// max(signals['asset1'])\",/*#__PURE__*/e(\"br\",{}),\"positions2 = initial_capital// max(signals['asset2'])\",/*#__PURE__*/e(\"br\",{}),/*#__PURE__*/e(\"br\",{}),\"# since there are two assets, we calculate each asset Pnl \",/*#__PURE__*/e(\"br\",{}),\"# separately and in the end we aggregate them into one portfolio\",/*#__PURE__*/e(\"br\",{}),\"portfolio = pd.DataFrame()\",/*#__PURE__*/e(\"br\",{}),\"portfolio['asset1'] = signals['asset1']\",/*#__PURE__*/e(\"br\",{}),\"portfolio['holdings1'] = signals['positions1'].cumsum() * signals['asset1'] * positions1\",/*#__PURE__*/e(\"br\",{}),\"portfolio['cash1'] = initial_capital - (signals['positions1'] * signals['asset1'] * positions1).cumsum()\",/*#__PURE__*/e(\"br\",{}),\"portfolio['total asset1'] = portfolio['holdings1'] + portfolio['cash1']\",/*#__PURE__*/e(\"br\",{}),\"portfolio['return1'] = portfolio['total asset1'].pct_change()\",/*#__PURE__*/e(\"br\",{}),\"portfolio['positions1'] = signals['positions1']# pnl for the 2nd asset\",/*#__PURE__*/e(\"br\",{}),\"portfolio['asset2'] = signals['asset2']\",/*#__PURE__*/e(\"br\",{}),\"portfolio['holdings2'] = signals['positions2'].cumsum() * signals['asset2'] * positions2\",/*#__PURE__*/e(\"br\",{}),\"portfolio['cash2'] = initial_capital - (signals['positions2'] * signals['asset2'] * positions2).cumsum()\",/*#__PURE__*/e(\"br\",{}),\"portfolio['total asset2'] = portfolio['holdings2'] + portfolio['cash2']\",/*#__PURE__*/e(\"br\",{}),\"portfolio['return2'] = portfolio['total asset2'].pct_change()\",/*#__PURE__*/e(\"br\",{}),\"portfolio['positions2'] = signals['positions2']\",/*#__PURE__*/e(\"br\",{}),/*#__PURE__*/e(\"br\",{}),\"# total pnl and z-score\",/*#__PURE__*/e(\"br\",{}),\"portfolio['z'] = signals['z']\",/*#__PURE__*/e(\"br\",{}),\"portfolio['total asset'] = portfolio['total asset1'] + portfolio['total asset2']\",/*#__PURE__*/e(\"br\",{}),\"portfolio['z upper limit'] = signals['z upper limit']\",/*#__PURE__*/e(\"br\",{}),\"portfolio['z lower limit'] = signals['z lower limit']\",/*#__PURE__*/e(\"br\",{}),\"portfolio = portfolio.dropna()\",/*#__PURE__*/e(\"br\",{}),/*#__PURE__*/e(\"br\",{}),\"# plot the asset value change of the portfolio and pnl along with z-score\",/*#__PURE__*/e(\"br\",{}),\"fig = plt.figure(figsize=(14,6),)\",/*#__PURE__*/e(\"br\",{}),\"ax = fig.add_subplot(111)\",/*#__PURE__*/e(\"br\",{}),\"ax2 = ax.twinx()\",/*#__PURE__*/e(\"br\",{}),\"l1, = ax.plot(portfolio['total asset'], c='g')\",/*#__PURE__*/e(\"br\",{}),\"l2, = ax2.plot(portfolio['z'], c='black', alpha=0.3)\",/*#__PURE__*/e(\"br\",{}),\"b = ax2.fill_between(portfolio.index,portfolio['z upper limit'],\\\\\",/*#__PURE__*/e(\"br\",{}),\"portfolio['z lower limit'], \\\\\",/*#__PURE__*/e(\"br\",{}),\"alpha=0.2,color='#ffb48f')\",/*#__PURE__*/e(\"br\",{}),\"ax.set_ylabel('Asset Value')\",/*#__PURE__*/e(\"br\",{}),\"ax2.set_ylabel('Z Statistics',rotation=270)\",/*#__PURE__*/e(\"br\",{}),\"ax.yaxis.labelpad=15\",/*#__PURE__*/e(\"br\",{}),\"ax2.yaxis.labelpad=15\",/*#__PURE__*/e(\"br\",{}),\"ax.set_xlabel('Date')\",/*#__PURE__*/e(\"br\",{}),\"ax.xaxis.labelpad=15\",/*#__PURE__*/e(\"br\",{}),\"plt.title('Portfolio Performance with Profit and Loss')\",/*#__PURE__*/e(\"br\",{}),\"plt.legend([l2,b,l1],['Z Statistics',\",/*#__PURE__*/e(\"br\",{}),\"'Z Statistics +-1 Sigma',\",/*#__PURE__*/e(\"br\",{}),\"'Total Portfolio Value'],loc='upper left');\",/*#__PURE__*/e(\"br\",{}),\"plt.savefig('images/chart8', dpi=300);\",/*#__PURE__*/e(\"br\",{}),/*#__PURE__*/e(\"br\",{}),\"# calculate CAGR\",/*#__PURE__*/e(\"br\",{}),\"final_portfolio = portfolio['total asset'].iloc[-1]\",/*#__PURE__*/e(\"br\",{}),\"delta = (portfolio.index[-1] - portfolio.index[0]).days\",/*#__PURE__*/e(\"br\",{}),\"print('Number of days = ', delta)\",/*#__PURE__*/e(\"br\",{}),\"YEAR_DAYS = 365\",/*#__PURE__*/e(\"br\",{}),\"returns = (final_portfolio/initial_capital) ** (YEAR_DAYS/delta) - 1print('CAGR = {:.3f}%' .format(returns * 100))Code commentary:We start with the initial capital of 100,000 and calculate the number of shares to buy for each stock.Next, we calculate holding in the first stock by taking the cumulative sum of its position multiplied by stock price and the total number of shares.We then calculate the cash position by subtracting holding from the initial cash position. The total position of stock in the portfolio is the sum of cash plus holding.Calculate daily returns using total stock position.Next, we follow the steps 1 to 4 for the second stock and sum up two asset\u2019s positions for the total portfolio value.Add the z-score with upper and lower thresholds for visualization.Visualize the portfolio performance along with z-score, upper, and lower thresholds.Calculate portfolio CAGR.Portfolio Performance with Profit and LossThe Compounded Annual Growth Rate (CAGR) for the strategy is 16.5% which looks promising however there are many things to consider before we draw any conclusion. Few important factors to account for are as follows:As this is a market-neutral approach a lot depends on our ability to short sell which may be limited due to various reasons including regulations.We have not accounted for costs related to trading, market slippage, and security borrowing. Normally, a market-neutral strategy results in a high number of trades.There is always a limitation of using historical data to forecast the future.Let\u2019s keep in mind that any decision to implement a strategy should be based only after considering all the critical performance parameters including its feasibility and returns net of fee and charges.Happy investing and do leave your comments on the article!\",/*#__PURE__*/e(\"em\",{children:\"Please Note: This analysis is only for educational purposes and the author is not liable for any of your investment decisions.\"}),\"References:\",/*#__PURE__*/e(i,{href:\"https://www.amazon.com/Learn-Algorithmic-Trading-algorithmic-strategies/dp/178934834X\",openInNewTab:!0,smoothScroll:!1,children:/*#__PURE__*/e(\"a\",{children:\"Learn Algorithmic Trading: Build and deploy algorithmic trading systems and strategies using Python and advanced data analysis\"})}),\" by Sebastien Donadio and Sourav Ghosh.\",/*#__PURE__*/e(i,{href:\"https://je-suis-tm.github.io/quant-trading/\",openInNewTab:!0,smoothScroll:!1,children:/*#__PURE__*/e(\"a\",{children:\"https://je-suis-tm.github.io/quant-trading/\"})}),\".Please check out my other articles/ posts on quantitative finance at my \",/*#__PURE__*/e(i,{href:\"https://www.linkedin.com/in/sabirjana/detail/recent-activity/shares/\",openInNewTab:!0,smoothScroll:!1,children:/*#__PURE__*/e(\"a\",{children:\"Linkedin\"})}),\" page or on \",/*#__PURE__*/e(i,{href:\"https://medium.com/@sabirh.jana\",openInNewTab:!1,smoothScroll:!1,children:/*#__PURE__*/e(\"a\",{children:\"Medium\"})}),\".\"]})]})},{id:\"xH0Uv4aoU\",[n]:\"Markets & Mind Games\",[s]:\"markets-mind-games\",[l]:\"2022-02-06T00:00:00.000Z\",[c]:h({src:\"https://framerusercontent.com/images/y6cX4dzArhF9QmqBtlOsSJqX0jA.jpg\",srcSet:\"https://framerusercontent.com/images/y6cX4dzArhF9QmqBtlOsSJqX0jA.jpg?scale-down-to=512 512w, https://framerusercontent.com/images/y6cX4dzArhF9QmqBtlOsSJqX0jA.jpg 828w\"},\"Yellow Flower\"),[d]:/*#__PURE__*/t(o.Fragment,{children:[/*#__PURE__*/e(\"p\",{children:\"Would you willingly allow a certifiable lunatic to come by at least five times a week to tell you that you should feel exactly the way he feels?\"}),/*#__PURE__*/e(\"p\",{children:\"Would you ever agree to be euphoric just because he is or, miserable just because he thinks you should be?\"}),/*#__PURE__*/e(\"p\",{children:\"Of-course not!\"}),/*#__PURE__*/e(\"p\",{children:\"You\u2019d insist on your right to take control of your own emotional life, based on your experiences and your beliefs. But, when it comes to their financial lives, millions of people let Mr. Market tell them how to feel and what to do despite, the obvious fact that, from time to time, he can get nuttier than a fruitcake.\"}),/*#__PURE__*/e(\"p\",{children:\"Why, then, do investors find Mr. Market so seductive?\"}),/*#__PURE__*/e(\"p\",{children:\"Let us find the psychological connection between -\"}),/*#__PURE__*/e(\"h5\",{children:\"The Market and Your Mind\"}),/*#__PURE__*/t(\"p\",{children:[\"It turns out that our brains are hardwired to get us into investing trouble. Humans are \",/*#__PURE__*/e(\"strong\",{children:\"pattern-seeking animals\"}),\". Psychologists have shown that if you present people with a random sequence-and tell them that it\u2019s unpredictable-they will nevertheless insist on trying to guess what\u2019s coming next.\"]}),/*#__PURE__*/t(\"p\",{children:[\"Take this experiment explaining pattern confirmation conducted by the psychologist \",/*#__PURE__*/e(\"strong\",{children:\"P. C. Wason \"}),\"illustrated by\",/*#__PURE__*/e(\"strong\",{children:\" N.N.Taleb \"}),\"in his book\",/*#__PURE__*/e(\"strong\",{children:\" Black Swan\"})]}),/*#__PURE__*/e(\"p\",{children:/*#__PURE__*/e(\"strong\",{children:\"The Task :\"})}),/*#__PURE__*/e(\"p\",{children:\"Wason presented subjects with the three-number sequence 2, 4, 6, and asked them to try to guess the rule generating it. Their method of guessing was to produce other three-number sequences, to which the experimenter would respond \u201Cyes\u201D or \u201Cno\u201D depending on whether the new sequences were consistent with the rule. Once confident with their answers, the subjects would formulate the rule.\"}),/*#__PURE__*/e(\"p\",{children:\"After tinkering for hours and giving numerous complex combinations the subjects could not give the right answer.\"}),/*#__PURE__*/e(\"p\",{children:/*#__PURE__*/e(\"strong\",{children:\"The Answer :\"})}),/*#__PURE__*/e(\"p\",{children:\"The correct rule was \u201Cnumbers in ascending order,\u201D nothing more. Very few subjects discovered it because in order to do so they had to offer a series in descending order (that the experimenter would say \u201Cno\u201D to).\"}),/*#__PURE__*/t(\"p\",{children:[\"Wason noticed that the subjects had a rule in mind, but gave him examples aimed at confirming it instead of trying to supply series that were inconsistent with their hypothesis. Subjects tenaciously kept trying to \",/*#__PURE__*/e(\"strong\",{children:\"confirm the rules that they had made up.\"})]}),/*#__PURE__*/e(\"p\",{children:/*#__PURE__*/e(\"em\",{children:\"Once your mind is inhabited with a certain view of the world , you will tend to only consider instances proving you to be right. Paradoxically, the more information you have, the more justified you will feel in your views\"})}),/*#__PURE__*/t(\"p\",{children:[\"Ground-breaking research in neuroscience shows that our brains are designed to perceive trends even where they might not exist. After an event occurs just two or three times in a row, regions of the human brain called the \",/*#__PURE__*/e(\"strong\",{children:\"anterior cingulate\"}),\" and \",/*#__PURE__*/e(\"strong\",{children:\"nucleus accumbens\"}),\" automatically anticipate that it will happen again. If it does repeat, a natural chemical called \",/*#__PURE__*/e(\"strong\",{children:\"dopamine\"}),\" is released, flooding your brain with a soft euphoria.\"]}),/*#__PURE__*/t(\"p\",{children:[\"Thus, if a stock goes up a few times in a row, you reflexively expect it to keep going and your brain chemistry changes as the stock rises, giving you a \u2018natural high\u2019. You effectively become \",/*#__PURE__*/e(\"strong\",{children:\"addicted to your own predictions.\"})]}),/*#__PURE__*/t(\"p\",{children:[\"But when stocks drop, that financial loss fires up your \",/*#__PURE__*/e(\"strong\",{children:\"amygdala \"}),\"- the part of the brain that processes fear and anxiety and generates the famous \",/*#__PURE__*/e(\"strong\",{children:\"\u2018fight or flight\u2019\"}),\" response that is common to all cornered animals.\"]}),/*#__PURE__*/e(\"p\",{children:\"Just as you can\u2019t keep your heart rate from rising if a fire alarm goes off, just as you can\u2019t avoid flinching if a rattlesnake slithers onto your hiking path, you can\u2019t help feeling fearful when stock prices are plunging.\"}),/*#__PURE__*/t(\"p\",{children:[\"In fact, the brilliant psychologists \",/*#__PURE__*/e(\"strong\",{children:\"Daniel Kahneman and Amos Tversky \"}),\"have shown that the pain of financial loss is more than twice as intense as the pleasure of an equivalent gain. Making $1,000 on a stock feels great-but a $1,000 loss wields an emotional wallop more than twice as powerful.\"]}),/*#__PURE__*/e(\"p\",{children:\"Losing money is so painful that many people, terrified at the prospect of any further loss, sell out near the bottom or refuse to buy more.\"}),/*#__PURE__*/t(\"p\",{children:[\"That helps explain why we fixate on the raw magnitude of a market decline and forget to put the loss in proportion. So, if a TV reporter hollers, \",/*#__PURE__*/e(\"strong\",{children:\"\u201CThe market is plunging-the Dow is down 100 points!\u201D\"}),\" most people instinctively shudder. But, at the Dow\u2019s level of 8,000, that\u2019s a drop of \",/*#__PURE__*/e(\"strong\",{children:\"just 1.2%\"}),\".\"]}),/*#__PURE__*/e(\"p\",{children:\"Now think how ridiculous it would sound if, on a day when it\u2019s 81 degrees outside, the TV weatherman shrieked, \u201CThe temperature is plunging-it\u2019s dropped from 81 degrees to 80 degrees\u201D That, too, is a 1.2% drop. When you forget to view changing market prices in percentage terms, it\u2019s all too easy to panic over minor vibrations.\"}),/*#__PURE__*/e(\"p\",{children:\"What then must one do to tackle these psychological biases?\"}),/*#__PURE__*/e(\"p\",{children:/*#__PURE__*/e(\"strong\",{children:\"Recognize that investing intelligently is about controlling the controllable.\"})}),/*#__PURE__*/e(\"h5\",{children:\"Things you cannot control -\"}),/*#__PURE__*/t(\"ol\",{style:{\"--framer-text-alignment\":\"start\",\"--framer-text-color\":\"rgba(0, 0, 0, 0.8)\",\"--framer-text-transform\":\"none\"},children:[/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"strong\",{children:\"Market volatility:\"}),\" Stock prices can fluctuate rapidly due to various economic and geopolitical factors, and no one can predict or control these fluctuations.\"]})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"strong\",{children:\"Interest rates:\"}),\" Interest rates set by central banks can have a significant impact on the stock market. However, individuals cannot control these rates.\"]})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"strong\",{children:\"Global events:\"}),\" Wars, natural disasters, pandemics, and other global events can affect the stock market in unpredictable ways, and individuals have no control over these events.\"]})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"strong\",{children:\"Company-specific news:\"}),\" A company\u2019s stock price can be affected by news about its earnings, management changes, and other internal factors. Again, individuals cannot control these factors.\"]})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"strong\",{children:\"Investor sentiment:\"}),\" The mood of the market can be influenced by investor sentiment, which is largely driven by emotions rather than rational analysis. This sentiment can cause stock prices to rise or fall, and individuals cannot control it.\"]})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"strong\",{children:\"Market regulations:\"}),\" Governments and regulatory bodies can impose rules and regulations that can affect the stock market. These regulations are beyond an individual\u2019s control.\"]})})]}),/*#__PURE__*/e(\"p\",{children:\"In summary, while there are many factors that can impact the stock market, there are several things that individuals cannot control. It is important to understand these factors and their potential impact on investments.\"}),/*#__PURE__*/t(\"p\",{children:[\"The points below are backed by \",/*#__PURE__*/e(i,{href:\"https://www.finsharpe.com/\",openInNewTab:!0,smoothScroll:!1,children:/*#__PURE__*/e(\"a\",{children:/*#__PURE__*/e(\"strong\",{children:\"FinSharpe\u2019s\"})})}),\" data analytics. Click on the sub-headings to see the research articles.\"]}),/*#__PURE__*/e(\"p\",{children:/*#__PURE__*/e(\"strong\",{children:\"Things you can control -\"})}),/*#__PURE__*/t(\"ol\",{style:{\"--framer-text-alignment\":\"start\",\"--framer-text-color\":\"rgba(0, 0, 0, 0.8)\",\"--framer-text-transform\":\"none\"},children:[/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(i,{href:\"https://www.linkedin.com/posts/sabirjana_investment-strategy-quantitativefinance-activity-7017077525474385921-svYs?utm_source=share&utm_medium=member_desktop\",openInNewTab:!0,smoothScroll:!1,children:/*#__PURE__*/e(\"a\",{children:\"Investment Strategy\"})}),\": Individuals can choose an investment strategy that aligns with their goals and risk tolerance. They can select from various asset classes, such as stocks, bonds, and real estate, and decide on their asset allocation.\"]})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(i,{href:\"https://www.linkedin.com/posts/sabirjana_investment-realestate-quantitativefinance-activity-7018846593638383616-ZQ5B?utm_source=share&utm_medium=member_desktop\",openInNewTab:!0,smoothScroll:!1,children:/*#__PURE__*/e(\"a\",{children:\"Investment Timeframe\"})}),\": Individuals can decide on their investment timeframe, whether it is short-term or long-term. This can help them choose investments that are appropriate for their goals.\"]})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(i,{href:\"https://www.linkedin.com/posts/sabirjana_finance-markets-investment-activity-7024629173239308288-3e2h?utm_source=share&utm_medium=member_desktop\",openInNewTab:!0,smoothScroll:!1,children:/*#__PURE__*/e(\"a\",{children:\"Diversification\"})}),\": Individuals can diversify their investments by spreading their money across various asset classes, industries, and geographies. This can help reduce the risk of loss in the portfolio.\"]})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(i,{href:\"https://www.linkedin.com/posts/sabirjana_investing-strategy-trading-activity-7018479714637877248-hfJF?utm_source=share&utm_medium=member_desktop\",openInNewTab:!0,smoothScroll:!1,children:/*#__PURE__*/e(\"a\",{children:\"Investment Fees & Brokerage\"})}),\": Individuals can control the fees they pay for investing. They can research and choose low-cost investment options to maximize their returns. Reduce excessive trading costs by trading infrequently and buy mutual funds or strategies with a low expense ratio.\"]})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(i,{href:\"https://www.linkedin.com/posts/sabirjana_finance-quantitativefinance-quant-activity-7019194290476068864-7adN?utm_source=share&utm_medium=member_desktop\",openInNewTab:!0,smoothScroll:!1,children:/*#__PURE__*/e(\"a\",{children:\"Monitoring and Rebalancing\"})}),\": Individuals can monitor their investments regularly and rebalance their portfolio if necessary. This can help ensure that their investments remain aligned with their goals and risk tolerance.\"]})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(i,{href:\"https://www.linkedin.com/posts/sabirjana_money-investing-quantitativefinance-activity-6978385626068918272-ZpLN?utm_source=share&utm_medium=member_desktop\",openInNewTab:!0,smoothScroll:!1,children:/*#__PURE__*/e(\"a\",{children:\"Emotional Reactions\"})}),\": Individuals can control their emotional reactions to market fluctuations by avoiding impulsive decisions based on fear or greed. One way to deal with this is to structure investments automatically spread out over different dates in a month.\"]})})]}),/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"br\",{}),\"In summary, while there are many factors that individuals cannot control when it comes to investing, there are several things that they can control. By focusing on these controllable factors, individuals can make informed investment decisions and maximize their returns over time.\"]}),/*#__PURE__*/e(\"h5\",{children:\"Apply the Real Estate Investing Mindset to Equity Investing\"}),/*#__PURE__*/e(\"p\",{children:\"If, after checking the value of your investment portfolio at 1:24pm , you feel compelled to check it all over again at 1:37pm , ask yourself these questions:\"}),/*#__PURE__*/e(\"p\",{children:\"Did I call a real-estate agent to check the market price of my house today at 1:24 P.M.?\"}),/*#__PURE__*/e(\"p\",{children:\"Did I call back at 1:37 P.M.?\"}),/*#__PURE__*/e(\"p\",{children:\"If I had, would the price have changed?\"}),/*#__PURE__*/e(\"p\",{children:\"If it did, would I have rushed to sell my house?\"}),/*#__PURE__*/e(\"p\",{children:\"By not checking, or even knowing, the market price of my house from minute to minute, do I prevent its value from rising over time ?\"}),/*#__PURE__*/e(\"p\",{children:\"The only possible answer to these questions is Of-course not! And you should view your long term portfolio the same way. Over a long term investment horizon, Mr. Market\u2019s daily dipsy-doodles simply do not matter.\"}),/*#__PURE__*/e(\"p\",{children:\"In any case, for anyone who will be investing for years to come, falling stock prices are good news, not bad, since they enable you to buy more for less money.\"}),/*#__PURE__*/e(\"p\",{children:\"The longer and further stocks fall, and the more steadily you keep buying as they drop, the more money you will make in the end-if you remain steadfast until the end.\"}),/*#__PURE__*/e(\"p\",{children:\"Instead of fearing a bear market, you should embrace it.\"}),/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"strong\",{children:\"The Intelligent Investor\"}),\" should be perfectly comfortable owning a stock or mutual fund even if the stock market stopped supplying daily prices for the next 10 years.\"]}),/*#__PURE__*/e(\"p\",{children:\"Paradoxically, \u201Cyou will be much more in control, explains neuroscientist Antonio Damasio, \u201Cif you realize how much you are not in control\u201D.\"}),/*#__PURE__*/t(\"p\",{children:[\"By acknowledging your biological tendency to buy high and sell low, you can admit the need to \",/*#__PURE__*/e(i,{href:\"https://www.investopedia.com/terms/d/dollarcostaveraging.asp\",openInNewTab:!0,smoothScroll:!1,children:/*#__PURE__*/e(\"a\",{children:\"dollar-cost average\"})}),\", \",/*#__PURE__*/e(i,{href:\"https://www.investopedia.com/terms/r/rebalancing.asp#:~:text=our%20editorial%20policies-,What%20Is%20Rebalancing%3F,risk%20and%20desire%20for%20reward.\",openInNewTab:!0,smoothScroll:!1,children:/*#__PURE__*/e(\"a\",{children:\"rebalance\"})}),\", and follow a \",/*#__PURE__*/e(i,{href:\"https://www.investopedia.com/articles/investing/062714/100-minus-your-age-outdated.asp\",openInNewTab:!0,smoothScroll:!1,children:/*#__PURE__*/e(\"a\",{children:\"disciplined investment process\"})}),\".\"]}),/*#__PURE__*/e(\"p\",{children:\"By putting much of your portfolio on permanent autopilot, you can fight the prediction addiction, focus on your long-term financial goals, and tune out Mr. Market\u2019s mood swings.\"}),/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(\"br\",{}),\"The source of information for this article is from the following books which I highly recommend :\"]}),/*#__PURE__*/t(\"ol\",{style:{\"--framer-text-alignment\":\"start\",\"--framer-text-color\":\"rgba(0, 0, 0, 0.8)\",\"--framer-text-transform\":\"none\"},children:[/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:/*#__PURE__*/e(\"strong\",{children:\"The Intelligent Investor by Benjamin Graham\"})})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:/*#__PURE__*/e(\"strong\",{children:\"The Black Swan by Nassim Nicholas Taleb\"})})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:/*#__PURE__*/e(\"strong\",{children:\"Thinking Fast and Slow by Daniel Kahneman\"})})}),/*#__PURE__*/e(\"li\",{\"data-preset-tag\":\"p\",children:/*#__PURE__*/e(\"p\",{children:/*#__PURE__*/e(\"strong\",{children:\"The Molecule of More by Daniel Z. Lieberman and Michael E. Long\"})})})]}),/*#__PURE__*/t(\"p\",{children:[\"I am a \",/*#__PURE__*/e(\"strong\",{children:\"SEBI Registered Investment Advisor\"}),\". If you would like to structure your investment portfolio or invest in long term equity strategies, connect with me on rohan@finsharpe.com\"]}),/*#__PURE__*/t(\"p\",{children:[/*#__PURE__*/e(i,{href:\"https://medium.com/tag/stock-market?source=post_page-----6000ea5aaf73---------------stock_market-----------------\",openInNewTab:!1,smoothScroll:!1,children:/*#__PURE__*/e(\"a\",{children:/*#__PURE__*/e(\"br\",{})})}),/*#__PURE__*/e(\"br\",{}),/*#__PURE__*/e(\"br\",{}),/*#__PURE__*/e(\"br\",{}),/*#__PURE__*/e(\"br\",{}),/*#__PURE__*/e(\"br\",{}),/*#__PURE__*/e(\"br\",{}),/*#__PURE__*/e(\"br\",{className:\"trailing-break\"})]})]})},{id:\"PALZDKXIj\",[n]:\"How to Create an Effective Design Portfolio\",[s]:\"how-to-create-an-effective-design-portfolio\",[l]:\"2022-01-12T00:00:00.000Z\",[c]:h({src:\"https://framerusercontent.com/images/8yfgC6RHF3rdJakSSJjblRQVM.jpg\",srcSet:\"https://framerusercontent.com/images/8yfgC6RHF3rdJakSSJjblRQVM.jpg?scale-down-to=512 334w, https://framerusercontent.com/images/8yfgC6RHF3rdJakSSJjblRQVM.jpg?scale-down-to=1024 668w, https://framerusercontent.com/images/8yfgC6RHF3rdJakSSJjblRQVM.jpg 914w\"},\"Purple Flower\"),[d]:/*#__PURE__*/t(o.Fragment,{children:[/*#__PURE__*/e(\"h2\",{children:\"What is a portfolio?\"}),/*#__PURE__*/e(\"p\",{children:\"A portfolio is any method used to showcase your best work. No matter the industry, fashion, architecture, or design, there are tons of ways to display your work in order to get a new job or expand your audience or customers.\"}),/*#__PURE__*/e(\"h2\",{children:\"Types of design portfolios\"}),/*#__PURE__*/e(\"p\",{children:\"Depending on the type of design work that you do, there are different portfolio formats that will be best suited for your needs. A design portfolio can be digital in the form of a website, slideshow, or PDF but it can also be analog in the form of a print book or poster.\"}),/*#__PURE__*/e(\"h3\",{children:\"Graphic design portfolio\"}),/*#__PURE__*/e(\"p\",{children:\"When it comes to graphic design, designing a PDF as your portfolio is becoming more and more popular to highlight your work and PDF design skills. Using tools like InDesign and Photoshop you can create multi-page PDFs that can be fine-tuned and formatted any way you like. With new software, like Framer, it's becoming even easier to create a PDF online and share it in no time.\\xa0The result of your PDF portfolio will be a brochure or one-pager piece that shows off examples of your best work along with the descriptions of each project and more related information.\"}),/*#__PURE__*/e(\"h3\",{children:\"UX design portfolio\"}),/*#__PURE__*/e(\"p\",{children:\"For UX designers, online portfolios are probably the most popular type today. This can be in the form of a simple one-page website with your contact information or a more thorough online gallery site. If your main discipline is web design, a portfolio website is the choice for you. It serves as an example itself of your web design skills, as well as highlighting your best work where it\u2019s meant to be seen.Portfolio websites come with many benefits, especially as most of our work is done online. First, they can show off design properties like animation and interactivity.\"}),/*#__PURE__*/e(\"p\",{children:\"As an important part of UX design, it\u2019s important to show these aspects so viewers get the full experience of your designs. Next, website portfolios are super easy to share. You can include the link in your social media bios as well as send the link to anyone at any time. Your work will become more readily available this way. Finally, online portfolios are a great way to show off your personality. As the more new-age mention of displaying your work, you are less constrained by the rules of the classic print portfolio.\"}),/*#__PURE__*/e(\"p\",{children:\"When going the online portfolio route there are some drawbacks. First, website portfolios often require knowledge of code to create. This can be a blocker for many UX designers. However, there are increasingly more tools like Framer that allow you to create a design portfolio without code. Next, you have to keep in mind the constraints of the web. Things like breakpoints, different browsers, and rendering issues that you wouldn\u2019t have to think about in print portfolios. Finally, website portfolios can be more time-consuming to create depending on how many site pages you need.\"})]})}];for(let e of p)Object.freeze(e);a(p,{mGfwEW8kL:{defaultValue:\"\",title:\"Title\",type:r.String},uN4uNF8Hw:{title:\"Slug\",type:r.String},fm9xNGFNa:{defaultValue:\"\",title:\"Date\",type:r.Date},NaBBy2qZQ:{title:\"Image\",type:r.ResponsiveImage},LmkFXFAof:{defaultValue:\"\",title:\"Content\",type:r.RichText}}),p.displayName=\"Blog\";export default p;export const enumToDisplayNameFunctions={};\nexport const __FramerMetadata__ = {\"exports\":{\"enumToDisplayNameFunctions\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"default\":{\"type\":\"data\",\"name\":\"data\",\"annotations\":{\"framerContractVersion\":\"1\",\"framerEnumToDisplayNameUtils\":\"2\",\"framerSlug\":\"uN4uNF8Hw\",\"framerRecordIdKey\":\"id\",\"framerData\":\"\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}"],
  "mappings": "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",
  "names": ["e", "t", "u", "x", "p", "Link", "addPropertyControls", "ControlType", "tNQezPB3C_default", "enumToDisplayNameFunctions", "__FramerMetadata__"]
}
