<jupyter_start><jupyter_text>Data Analytics Project - Backtesting Model Predictions TATAMTRDVR STOCK MODELS EVALUATION---  1. Importing Required Modules<jupyter_code>import pandas as pd<jupyter_output><empty_output><jupyter_text>2. Get required datasets  2.1. Get the orders dataset of TATAMTRDVR<jupyter_code>orders_df = pd.read_csv('../Preprocess/Pair4/Pair4_orders.csv')
orders_df.head()
orders_df.tail()<jupyter_output><empty_output><jupyter_text>2.2. Visualize the orders<jupyter_code># Plotting the zscore of the Spread
orders_plt = orders_df.plot(x='Date', y='zscore', figsize=(30,15))

# Plotting the lines at mean, 1 and 2 std. dev.
orders_plt.axhline(0, c='black')
orders_plt.axhline(1, c='red', ls = "--")
orders_plt.axhline(-1, c='red', ls = "--")

# Extracting orders
Orders = orders_df['Orders']

# Plot vertical lines where orders are placed
for order in range(len(Orders)):
    
    if Orders[order] != "FLAT":
        
        # GREEN line for a long position
        if Orders[order] == "LONG":
            orders_plt.axvline(x=order, c = "green")
        
        # RED line for a short position
        elif Orders[order] == "SHORT":
            orders_plt.axvline(x=order, c = "red")
        
        # BLACK line for getting out of all positions at that point
        else:
            orders_plt.axvline(x=order, c = "black")

orders_plt.set_ylabel("zscore")<jupyter_output><empty_output><jupyter_text>__In the figure above:__- __Blue line__ - zscore of the Spread- __Black horizontal line__ at 0 - Mean- __Red dotted horizontal lines__ - at +1 and -1 standard deviations- __Green vertical line__ - represents long position taken on that day- __Red vertical line__ - represents short position taken on that day- __Black vertical line__ - represents getting out of all open positions till that point  2.3. Get the predicitions dataset of TATAMTRDVR<jupyter_code>predictions = pd.read_csv("../Models/Pair4/Tata_predicitions.csv")
predictions.head()
predictions = predictions.dropna()
predictions.head()<jupyter_output><empty_output><jupyter_text>2.4 Visualize the predictions by different models<jupyter_code>predictions.plot(x='Date', y=['Actual_Close', 'Linear_regression_Close', 'ARIMA_Close', 'LSTM_Close'], figsize=(30,15))<jupyter_output><empty_output><jupyter_text>__In the figure above:__- __x-axis__ - Date- __y-axis__ - Price in rupees- __Blue line__ - Actual data in the time period of correlation- __Orange line__ - Linear Regression predictions for the time period- __Red line__ - LSTM predictions for the time period- __Green line__ - ARIMA predictions for the time period ---  3. Set parameters of trading<jupyter_code>CAPITAL = 1000000
RISK = 20000 # Max risk allowed per trade (2% of capital)<jupyter_output><empty_output><jupyter_text>- CAPITAL - Total amout of money willing to be spent.- RISK - Amount to spend per trade (maximum).- OPEN POSITION - Buy/Short shares of stock worth 20000.- CLOSE POSITION - Buy/Sell shares to consolidate open positions and take profit/loss.- TRADE_BOOK - Keeps track of all open positions.- For the purpose of this experiment, we assume no brokerage costs, which is a fair assumption as many brokers (such as zerodha, robinhood, sharekhan, etc.) offer equity delivery at no cost. ---  4. Evaluate all individual orders  4.1. Display all orders which are not *FLAT*<jupyter_code>not_flat_orders = orders_df[orders_df['Orders'] != 'FLAT']
not_flat_orders
not_flat_orders = not_flat_orders.set_index('Date').reset_index()
not_flat_orders<jupyter_output><empty_output><jupyter_text>4.2 Flip all orders<jupyter_code>def flip_orders(orders):
    
    flipped_orders = []
    
    for order in orders:
        if order == 'SHORT':
            flipped_orders.append('LONG')
        elif order == 'LONG':
            flipped_orders.append('SHORT')
        else:
            flipped_orders.append(order)
    
    return flipped_orders

not_flat_orders['Orders'] = flip_orders(not_flat_orders['Orders'])
not_flat_orders<jupyter_output><empty_output><jupyter_text>- As TATAMTRDVR is the stock with the lower price value, in pair trading we need to take the position opposite to the one we take on the larger stock. Hence the positions to take are flipped.  4.3. Get predictions of dates where orders are placed  4.3.1. Filter rows in predictions to only include dates where orders are placed<jupyter_code>not_flat_orders = not_flat_orders.set_index('Date')
not_flat_orders
predicitions = predictions.set_index('Date')
predicitions
orders_predictions = predicitions.join(not_flat_orders)
orders_predictions = orders_predictions.dropna()
orders_predictions<jupyter_output><empty_output><jupyter_text>4.3.2 Remove columns in orders and predictions dataframe<jupyter_code>orders_predictions = orders_predictions.drop(columns=['ASHOKLEY_Close', 'TATAMTRDVR_Close', 'Spread', 'zscore'])
orders_predictions<jupyter_output><empty_output><jupyter_text>4.3.3 Create function to evaluate orders<jupyter_code>def evaluate_orders(orders_df):
    
    actual_profits = []
    LR_profits = []
    ARIMA_profits = []
    LSTM_profits = []
    shares = []
    
    num_orders = len(orders_df["Orders"])
    
    for i in range(num_orders):
        
        if i == num_orders - 1:
            actual_profits.append(0)
            LR_profits.append(0)
            ARIMA_profits.append(0)
            LSTM_profits.append(0)
            shares.append(0)
            break
        
        position = orders_df['Orders'][i]
        close = orders_df['Actual_Close'][i]
        LR_close = orders_df['Linear_regression_Close'][i]
        ARIMA_close = orders_df['ARIMA_Close'][i]
        LSTM_close = orders_df['LSTM_Close'][i]
        
        print()
        
        print("ORDER: ", i, close, LR_close, ARIMA_close, LSTM_close, position)
        
        if position == 'LONG' or position == 'SHORT':
            
            no_of_shares = 20000//close
            
            for j in range(i+1, num_orders):
                
                if (j == num_orders - 1) or orders_df['Orders'][j] == 'GET_OUT_OF_POSITION':
                    
                    actual_profit = orders_df['Actual_Close'][j] - orders_df['Actual_Close'][i]
                    LR_profit = orders_df['Linear_regression_Close'][j] - orders_df['Linear_regression_Close'][i]
                    ARIMA_profit = orders_df['ARIMA_Close'][j] - orders_df['ARIMA_Close'][i]
                    LSTM_profit = orders_df['LSTM_Close'][j] - orders_df['LSTM_Close'][i]
                    
                    actual_profit *= no_of_shares
                    LR_profit *= no_of_shares
                    ARIMA_profit *= no_of_shares
                    LSTM_profit  *= no_of_shares
                    
                    if position == 'SHORT':
                        actual_profit *= -1
                        LR_profit *= -1
                        ARIMA_profit *= -1
                        LSTM_profit *= -1
                    
                    print('number of shares: ', no_of_shares)
                    print('actual profit: ', actual_profit)
                    print('LR profit: ', LR_profit)
                    print('ARIMA profit: ', ARIMA_profit)
                    print('LSTM profit: ', LSTM_profit)
                    
                    shares.append(no_of_shares)
                    actual_profits.append(actual_profit)
                    LR_profits.append(LR_profit)
                    ARIMA_profits.append(ARIMA_profit)
                    LSTM_profits.append(LSTM_profit)
                    
                    break
        else:
            actual_profits.append(0)
            LR_profits.append(0)
            ARIMA_profits.append(0)
            LSTM_profits.append(0)
            shares.append(0)
        
        print()
    
    return actual_profits, LR_profits, ARIMA_profits, LSTM_profits, shares
                    
actual_profits, LR_profits, ARIMA_profits, LSTM_profits, shares = evaluate_orders(orders_predictions)
actual_profits
LR_profits
LSTM_profits
shares
ARIMA_profits<jupyter_output><empty_output><jupyter_text>4.3.4 Adding evaluated orders to dataframe<jupyter_code>orders_predictions
orders_predictions['Shares'] = shares
orders_predictions['Actual_profit'] = actual_profits
orders_predictions['Linear_regression_profit'] = LR_profits
orders_predictions['ARIMA_profit'] = ARIMA_profits
orders_predictions['LSTM_profit'] = LSTM_profits
orders_predictions<jupyter_output><empty_output><jupyter_text>4.3.5 Visualizing the profits<jupyter_code>orders_predictions = orders_predictions.reset_index()
orders_predictions
orders_predictions.plot(x='Date', y=['Actual_profit', 'Linear_regression_profit', 'ARIMA_profit', 'LSTM_profit'], figsize=(30,15))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.09604390578550194, 'fraction_numerical': 0.010976446375485937, 'mean_word_length': 3.0290188853063102, 'pattern_counts': {'":': 3, '<': 53, '<?xml version=': 0, '>': 53, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '13', 'dir': 'jupyter-structured-clean-dedup', 'id': '19912', 'license': 'MIT', 'n_tokens_mistral': 2820, 'n_tokens_neox': 2717, 'n_words': 625, 'path': 'Backtester/TATAMTRDVR_BACKTESTING.ipynb', 'repo_name': 'Varun487/PairTradingModels', 'size': '8746'}