avatarConnor Roberts

Summarize

Mastering Stock Market Predictions: Machine Learning, LSTM, and Statistical Analysis

In this article, we will delve into the cutting-edge techniques being used for stock market predictions. From visually representing technical indicators to enhance our understanding of market behavior, to implementing machine learning projects specifically designed for stock market prediction, we leave no stone unturned. We will explore the application of Long Short-Term Memory (LSTM) networks, a type of recurrent neural network renowned for remembering past information, perfect for the temporal nature of stock market data.

# Import Modules

import numpy as np
import pandas as pd
import os
import random
import copy
import matplotlib.pyplot as plt
import pandas

You imported the following modules in your code snippet:

Python’s numpy library is used for scientific computations. In addition to arrays, matrices, and related routines, it contains a high-level interface to these objects.

Python’s pandas library is used to analyze data. Data structures and analysis tools are provided in an easy-to-use, high-performance package.

Operating system functions are provided by OS, which is a module.

The random module provides functions for generating random numbers.

The copy module provides functions for copying objects.

Python plots can be created using matplotlib.pyplot.

Python’s pandas library allows you to analyze data. A high-level data structure and data analysis tools are provided.

In the current namespace, a module is imported using the import statement. By using this approach, you don’t have to specify the full path to the module to use its functions and variables. To create an array, for instance, you can use the np.array() function after importing the numpy module.

Choose 8 random stock data for analysis

#filenames = [x for x in os.listdir("./Stocks/") if x.endswith('.txt') and os.path.getsize(x) > 0]
filenames = random.sample([x for x in os.listdir() if x.endswith('.txt') 
                           and os.path.getsize(os.path.join('',x)) > 0], 8)
print(filenames)

In the code snippet, a variable called filenames is defined and a list of file names is assigned to it. To find these file names, use the os.listdir() function to list all the files in the ./Stocks/ directory. File names ending in .txt and with a file size greater than 0 are included in the list. Due to the fact that it begins with a #, the line is currently commented out.

Following that, the code snippet assigns a list of 8 random file names to another variable called filenames. In the current directory (where the script is running), all files that end with .txt and have a file size greater than 0 are selected. We randomly select 8 file names from the list using random.sample().

Lastly, the code snippet prints the list of 8 randomly selected filenames.

The code retrieves a list of file names that meet certain criteria (ending with .txt and having a non-zero file size) from a specific directory or the current directory, and then selects 8 random file names from it. The selected file names are then printed.

Read data into dataframes

data = []
for filename in filenames:
    df = pd.read_csv(os.path.join('',filename), sep=',')
    label, _, _ = filename.split(sep='.')
    df['Label'] = label
    df['Date'] = pd.to_datetime(df['Date'])

    data.append(df)

Data is extracted from a collection of files using the provided code.

To store the data from the files, it first creates an empty list called “data”.

In the next step, it iterates over each file name listed in the “filenames” list.

Using the read_csv() function from the pandas library, it reads the contents of each file as a CSV file. To construct the full file path, the os.path.join() function joins an empty string with the current file name.

With the separator set to “….”, the file name is split using the split() function. This splits the file name into two parts, and the first part is assigned to the variable “label”. A “label” is a label or identifier that identifies the data in the file.

A new column named “Label” is added to the DataFrame (df) obtained from the file, and its values are set to the “label” variable. DataFrame rows are labelled accordingly in this column.

A new column, “Date”, is added to the DataFrame, and the existing “Date” column is converted to datetime using the pandas function pd.to_datetime().

Lastly, all DataFrames created from the files are added to the “data” list.

This code reads multiple files, extracts relevant data, assigns labels and converts dates to datetime format, and stores the resulting DataFrames in a list.

data[0].head()

Data[0].head() retrieves the first few rows of data from the DataFrame at index 0 of the “data” list.

What it does is as follows:

The element at index 0 of the “data” list is accessed by data[0]. DataFrames are contained in the “data” list, so data[0] refers to the first DataFrame.

A DataFrame can be called with .head(). The first few rows of the DataFrame are retrieved. The first five rows are returned by default.

The data[0].head() method retrieves the first 5 rows of data from the first DataFrame in the “data” list.

Add various Technical Indicators in the dataframe

def rsi(values):
    up = values[values>0].mean()
    down = -1*values[values<0].mean()
    return 100 * up / (up + down)

Your code defines a function called rsi that calculates the Relative Strength Index (RSI) based on a given set of parameters.

We can calculate the RSI for all input values by passing a single argument called values.

Following are the steps taken by the function:

Only values greater than zero are included in the values array. The mean (average) of these filtered values is assigned to the variable up. Values changed on average positively.

Only values less than zero are included in the values array. The mean (average) of these filtered values is calculated and assigned to the variable down. By multiplying it by -1, negative values become positive. The average negative change in values is shown here.

RSI is calculated by dividing average positive change (up) by average negative change (down). The result is then multiplied by 100 to get a percentage. RSI is an indicator used in technical analysis to assess the strength or weakness of a trend.

# Add Momentum_1D column for all 15 stocks.
# Momentum_1D = P(t) - P(t-1)
for stock in range(len(TechIndicator)):
    TechIndicator[stock]['Momentum_1D'] = (TechIndicator[stock]['Close']-TechIndicator[stock]['Close'].shift(1)).fillna(0)
    TechIndicator[stock]['RSI_14D'] = TechIndicator[stock]['Momentum_1D'].rolling(center=False, window=14).apply(rsi).fillna(0)
TechIndicator[0].tail(5)

A number of steps are performed by the provided code. Firstly, it adds two new columns, “Momentum_1D” and “RSI_14D,” to each DataFrame in the “TechIndicator” list. The one-day momentum indicator and the 14-day RSI indicator will be stored in these columns. Each DataFrame in the “TechIndicator” list is then iterated over and calculations are performed. It calculates one-day momentum by subtracting the previous day’s closing price from the current day’s closing price, and stores the result in the “Momentum_1D” column. This column is filled with 0 if there are any missing values. Furthermore, it calculates the 14-day RSI by applying a custom function called “rsi” to the values in the “Momentum_1D” column over a rolling window of size 14. In the “RSI_14D” column, the result is stored, and any missing values in this column are also filled with 0. In the “TechIndicator” list, the code prints the last 5 rows of data from the first DataFrame. This code adds and populates columns for momentum and RSI indicators for each stock’s closing price, providing additional insights.

for stock in range(len(TechIndicator)):
    TechIndicator[stock]['Volume_plain'] = TechIndicator[stock]['Volume'].fillna(0)
TechIndicator[0].tail()

Following are the steps performed by the code you provided:

The TechIndicator list is looped over using the stock variable in a for loop. TechIndicator list length is included in the loop.

A DataFrame at each index stock in the TechIndicator list is added to the loop as follows:

In the DataFrame, it creates a new column called Volume_plain.

Volume_plain contains the values from the Volume column, but any missing values (NaN) are replaced with 0.

By using the .tail() function, it prints the last 5 rows of data from the first DataFrame in the TechIndicator list (TechIndicator[0]).

A new column called Volume_plain is added to each DataFrame, and it is filled with Volume values, leaving any missing values as 0. The code iterates over the TechIndicator list. After that, it displays the last 5 rows of data from the first DataFrame in the TechIndicator list. By adding a new column and providing a summary view of the data, this code essentially modifies the DataFrames.

Calculation of Bollinger Bands

def bbands(price, length=30, numsd=2):
    """ returns average, upper band, and lower band"""
    #ave = pd.stats.moments.rolling_mean(price,length)
    ave = price.rolling(window = length, center = False).mean()
    #sd = pd.stats.moments.rolling_std(price,length)
    sd = price.rolling(window = length, center = False).std()
    upband = ave + (sd*numsd)
    dnband = ave - (sd*numsd)
    return np.round(ave,3), np.round(upband,3), np.round(dnband,3)

Your code defines a function called “bbands” that calculates Bollinger Bands for a given price series.

What it does is as follows:

Bollinger Bands can be calculated using three arguments: “price” (the price series), “length” (the window length for calculating the average and standard deviation), and “numsd” (the number of standard deviations to use for calculating the upper and lower bands).

The docstring indicates that the function returns the average, upper band, and lower band.

Using price.rolling(window=length, center=False).mean(), the code calculates the rolling average (mean) of the price series and assigns it to the variable “ave”. In the price series, this calculates the average value for each window of length “length”.

Using price.rolling(window=length, center=False).std(), it calculates the rolling standard deviation of the price series and assigns it to the variable “sd”. In this example, we calculate the standard deviation for each window of length “length” in the price series.

The upper band is calculated by adding “numsd” times the standard deviation to the average: ave + (sd * numsd). Bollinger Bands’ upper boundary is represented by this line.

A lower band is calculated by subtracting “numsd” times the standard deviation from the average: ave — (sd * numsd). Bollinger Bands’ lower boundary is represented by this line.

As a final step, it returns the average, upper band, and lower band as tuples, each rounded to three decimal places using np.round().

In summary, the code calculates Bollinger Bands based on a price series. Upper and lower bands are calculated using the rolling average and standard deviation, and the average, upper band, and lower band are returned rounded. An overbought or oversold condition in financial markets can be identified using Bollinger Bands, a popular technical analysis tool.

for stock in range(len(TechIndicator)):
    TechIndicator[stock]['BB_Middle_Band'], TechIndicator[stock]['BB_Upper_Band'], TechIndicator[stock]['BB_Lower_Band'] = bbands(TechIndicator[stock]['Close'], length=20, numsd=1)
    TechIndicator[stock]['BB_Middle_Band'] = TechIndicator[stock]['BB_Middle_Band'].fillna(0)
    TechIndicator[stock]['BB_Upper_Band'] = TechIndicator[stock]['BB_Upper_Band'].fillna(0)
    TechIndicator[stock]['BB_Lower_Band'] = TechIndicator[stock]['BB_Lower_Band'].fillna(0)
TechIndicator[0].tail()

In a for loop with the variable “stock”, it iterates over the range of numbers from 0 to the length of the “TechIndicator” list. Using this loop, we can operate on each stock on the “TechIndicator” list.

Using the “TechIndicator” loop, for each stock at index “stock”:

The function “bbands” calculates Bollinger Bands for the stock’s closing prices (“TechIndicator[stock][‘Close’]”) with a length of 20 and a standard deviation of 1. In the DataFrame of the current stock, three new columns are created: “BB_Middle_Band,” “BB_Upper_Band,” and “BB_Lower_Band.”.

With .fillna(0), it fills any missing values (NaNs) in the “BB_Middle_Band,” “BB_Upper_Band,” and “BB_Lower_Band” columns with 0.

Using the .tail() function, it prints the last few rows of data from the first DataFrame in the “TechIndicator” list (TechIndicator[0]).

For each stock in the “TechIndicator” list, Bollinger Bands are calculated and added. As it iterates through each stock, it calls the “bbands” function to calculate Bollinger Bands based on its closing price, and stores the results in new columns. A value of 0 is substituted for any missing values in the Bollinger Bands columns. Following that, the code prints the last few rows of data for the first stock on the “TechIndicator” list.

Calculation of Aroon Oscillator

def aroon(df, tf=25):
    aroonup = []
    aroondown = []
    x = tf
    while x< len(df['Date']):
        aroon_up = ((df['High'][x-tf:x].tolist().index(max(df['High'][x-tf:x])))/float(tf))*100
        aroon_down = ((df['Low'][x-tf:x].tolist().index(min(df['Low'][x-tf:x])))/float(tf))*100
        aroonup.append(aroon_up)
        aroondown.append(aroon_down)
        x+=1
    return aroonup, aroondown

This code introduces a function named “aroon” which computes the Aroon indicators for a DataFrame that contains financial data. Indicators help analyze the strength and direction of trends in financial markets.

In order to calculate the Aroon indicators, the function requires two arguments: the DataFrame containing the financial data and the time period (with a default value of 25).

The function initializes two empty lists, “aroonup” and “aroondown.” The values computed by this function will be stored in these lists.

Iterating through the DataFrame while calculating the Aroon indicators requires the variable named “x” to be set to the value of “tf.” The while loop continues until “x” reaches the length of the ‘Date’ column in the DataFrame. In this way, data ranges are taken into account when performing calculations.

In each iteration of the loop, the Aroon Up value is computed by finding the index of the highest value in the ‘High’ column within the previous “tf” number of periods. A percentage value is calculated by dividing this index by “tf” and multiplying it by 100.

Similarly, the Aroon Down value is calculated based on the lowest value in the ‘Low’ column over the previous “tf” period. Additionally, this index is divided by “tf” and multiplied by 100.

Calculated Aroon Up and Aroon Down values are appended to the “aroonup” and “aroondown” lists, respectively. The variable “x” is incremented after each iteration, enabling the loop to progress to the next period.Finally, the function returns the lists “aroonup” and “aroondown,” which contain the computed Aroon Up and Aroon Down values.

A given DataFrame of financial data is used to calculate Aroon indicators in the provided code. Each time the DataFrame is iterated over, the Aroon Up and Aroon Down values are computed, and separate lists are produced for each period. By returning these lists, the function is able to assess the strength and direction of financial markets’ trends.

for stock in range(len(TechIndicator)):
    listofzeros = [0] * 25
    up, down = aroon(TechIndicator[stock])
    aroon_list = [x - y for x, y in zip(up,down)]
    if len(aroon_list)==0:
        aroon_list = [0] * TechIndicator[stock].shape[0]
        TechIndicator[stock]['Aroon_Oscillator'] = aroon_list
    else:
        TechIndicator[stock]['Aroon_Oscillator'] = listofzeros+aroon_list

The code calculates and assigns Aroon Oscillator values for each stock in the “TechIndicator” list. Its functionality is as follows:

The code initiates a for loop that loops through the range of numbers from 0 to the length of the “TechIndicator” list. The following steps can be performed individually on each stock using this loop.

In the loop, for each stock in the “TechIndicator” list at the current index “stock”:

A list of 25 zeros is created, named “listofzeros”. The code will use this list later.

As an argument, the current stock’s data is passed to the function “aroon”. Assigned to the variables “up” and “down”, this function calculates the Aroon Up and Aroon Down values specific to the stock.

By using a list comprehension, we create a new list called “aroon_list”. The Aroon Oscillator values are calculated by subtracting the corresponding elements in the “up” and “down” lists.

A check is then made to determine if “aroon_list” has a length of zero. Then the stock has no Aroon values. This creates a new list consisting of zeros with the same length as the stock’s data (TechIndicator[stock]). The new list is assigned to “aroon_list”.

Alternatively, if “aroon_list” is not zero, Aroon values have been calculated successfully. The code proceeds to the next step without modifying “aroon_list”.

Lastly, the code assigns the values of “aroon_list” to a new column called “Aroon_Oscillator” in the DataFrame specific to the current stock (TechIndicator[stock]). Using list concatenation, if “aroon_list” is not empty, its values are appended to the beginning of “listofzeros”. “Aroon_Oscillator” is assigned the values of “aroon_list” if “aroon_list” is empty, meaning no Aroon values were calculated.

Calculation of Price Volume Trend

for stock in range(len(TechIndicator)):
    TechIndicator[stock]["PVT"] = (TechIndicator[stock]['Momentum_1D']/ TechIndicator[stock]['Close'].shift(1))*TechIndicator[stock]['Volume']
    TechIndicator[stock]["PVT"] = TechIndicator[stock]["PVT"]-TechIndicator[stock]["PVT"].shift(1)
    TechIndicator[stock]["PVT"] = TechIndicator[stock]["PVT"].fillna(0)
TechIndicator[0].tail()

The code calculates and populates the Price Volume Trend (PVT) values for each stock in the “TechIndicator” list. The following are some of its features:

A for loop is used to iterate through the range of numbers from 0 to the length of the “TechIndicator” list. Using this loop, each stock can be processed individually.

For each stock in the current index “stock” of the “TechIndicator” list:

In the DataFrame, a new column called “PVT” is created. Calculated PVT values will be stored in this column.

In order to calculate the PVT value, we divide the one-day momentum (“Momentum_1D”) by the previous day’s closing price (“Close” column at time t-1). Multiply the result by the current trading volume (“Volume”). The purpose of this calculation is to assess the relationship between price changes and trading volume.

By subtracting the obtained PVT value from the previous day’s PVT value, the change in PVT is determined. Tracking PVT trends over time is enabled by this step.

Using the .fillna(0) function, any missing values (NaNs) are filled with 0. By doing so, all data points are represented numerically in the column.

The code prints the last few rows of data from the first DataFrame in the “TechIndicator” list (TechIndicator[0]) using the .tail() function. As a result, we can see the PVT values for the first stock.

Overall, the code calculates and adds the Price Volume Trend (PVT) values to the DataFrames of each stock in the “TechIndicator” list. In order to calculate PVT values, the one-day momentum, previous closing prices, and trading volume are taken into account. If any values are missing, they are filled with 0. In the DataFrame for the first stock, the code displays the last few rows of PVT data. In financial analysis, PVT is used to analyze the interaction between price movements and trading volumes.

Calculation of Acceleration Bands

def abands(df):
    #df['AB_Middle_Band'] = pd.rolling_mean(df['Close'], 20)
    df['AB_Middle_Band'] = df['Close'].rolling(window = 20, center=False).mean()
    # High * ( 1 + 4 * (High - Low) / (High + Low))
    df['aupband'] = df['High'] * (1 + 4 * (df['High']-df['Low'])/(df['High']+df['Low']))
    df['AB_Upper_Band'] = df['aupband'].rolling(window=20, center=False).mean()
    # Low *(1 - 4 * (High - Low)/ (High + Low))
    df['adownband'] = df['Low'] * (1 - 4 * (df['High']-df['Low'])/(df['High']+df['Low']))
    df['AB_Lower_Band'] = df['adownband'].rolling(window=20, center=False).mean()

his code accomplishes the following:

DataFrame containing financial data is represented by the argument “df” in the function.

The first thing it does is introduce a new column in the DataFrame called “AB_Middle_Band.” This column’s values are determined by computing the rolling mean (average) of the “Close” column over a window of 20 periods. Using .rolling(window=20, center=False).mean() simplifies this calculation.

The code calculates the upper band values by multiplying the values in the “High” column by a factor derived from the difference between the corresponding values in the “High” and “Low” columns. A one-time increment is applied to the multiplication factor. A column called “aupband” contains the computed values.

By using the .rolling(window=20, center=False).mean() function, a new column titled “AB_Upper_Band” is created in the DataFrame. This column calculates the rolling mean using a window of 20 periods.

The code calculates the lower band values by multiplying the values in the “Low” column by the difference between the corresponding values in the “High” and “Low” columns. Subtracting this factor from 1 results in the multiplication factor. An “adownband” column is used to temporarily store the obtained values.

The DataFrame also includes a column named “AB_Lower_Band”. Using the .rolling(window=20, center=False).mean() function, this column calculates the rolling mean over a window of 20 periods.

Abands is a function defined in the provided code that calculates Acceleration Bands for a given DataFrame. In this function, three columns are added to the DataFrame: “AB_Middle_Band,” “AB_Upper_Band,” and “AB_Lower_Band.” The middle band represents the rolling average of the closing prices, while the upper and lower bands are determined by multiplying the high and low prices, respectively, with appropriate factors derived from their differences. A rolling mean calculation is used to smooth these bands’ values over a 20-period period. In technical analysis, acceleration bands are widely used to identify potential price levels and market trends.

for stock in range(len(TechIndicator)):
    abands(TechIndicator[stock])
    TechIndicator[stock] = TechIndicator[stock].fillna(0)
TechIndicator[0].tail()

This code, the Acceleration Bands are calculated and processed for each stock on the “TechIndicator” list as follows:

A for loop iterates over the stocks in the “TechIndicator” list, with the loop variable “stock” representing the index of each stock.

For each stock within the loop:

As an argument to the “abands” function, the current stock’s DataFrame (TechIndicator[stock]) is passed. By adding middle, upper, and lower columns to the DataFrame, this function calculates Acceleration Bands.

A DataFrame of the current stock is then filled with zeros after the bands have been calculated for each stock. As a result, the DataFrame contains only numerical data points.

Lastly, the code prints the last few rows of data from the first DataFrame (TechIndicator[0]) using the .tail() function. In this example, we see a snapshot of the DataFrame after processing and calculating the recent data.

As a result, the code efficiently calculates Acceleration Bands for each stock in the “TechIndicator” list by using the “abands” function. DataFrames with missing values are filled with zeros. The code displays the recent data for the first stock in the “TechIndicator” list. This code ensures that the Acceleration Bands are consistently calculated and processed for each stock, which is used as a technical analysis tool to analyze potential price levels and market trends.

Drop unwanted columns

columns2Drop = ['Momentum_1D', 'aupband', 'adownband']
for stock in range(len(TechIndicator)):
    TechIndicator[stock] = TechIndicator[stock].drop(labels = columns2Drop, axis=1)
TechIndicator[0].head()

In the first step, the list “columns2Drop” is initialized with three columns: ‘Momentum_1D’, ‘aupband’, and ‘adownband’. In the DataFrame of each stock, these columns must be removed.

After that, a for loop is used to iterate through the range of numbers from 0 to the length of the “TechIndicator” list. As a result of this loop, every stock on the list can be operated upon.

In the loop, for each stock in the “TechIndicator” list at the current index “stock”:

In this code, the specified columns are removed using the .drop() function on the DataFrame corresponding to the current stock (TechIndicator[stock]). In the labels parameter, “columns2Drop” is set to the list of columns to drop. In addition, the axis parameter is set to 1, meaning that the columns will be dropped rather than the rows.

A DataFrame is then updated to reflect the removal of the specified columns from the current stock.

Lastly, the code prints the first few rows from the DataFrame of the first stock in the “TechIndicator” list (TechIndicator[0]) using the .head() function. This shows the modified DataFrame after removing the specified columns.

The code sequentially traverses each stock in the “TechIndicator” list and eliminates specific columns from their DataFrames. “Columns2Drop” lists the columns to be removed. As a result of the column removal process, the code prints the initial rows of data from the DataFrame of the first stock.

Calculation of Stochastic Oscillator (%K and %D)

def STOK(df, n):
    df['STOK'] = ((df['Close'] - df['Low'].rolling(window=n, center=False).mean()) / (df['High'].rolling(window=n, center=False).max() - df['Low'].rolling(window=n, center=False).min())) * 100
    df['STOD'] = df['STOK'].rolling(window = 3, center=False).mean()

The code defines a function named “STOK” that is responsible for calculating the Stochastic Oscillator for a given DataFrame of financial data.

Here’s a detailed breakdown of what the code does:

The function takes two arguments: “df,” which represents the DataFrame containing the financial data, and “n,” which specifies the number of periods to consider for the calculations.

Within the function, a new column called “STOK” is added to the DataFrame. This column represents the Stochastic Oscillator %K value. The %K value is calculated as follows:

The rolling mean of the “Low” column over a window of “n” periods is subtracted from the corresponding values in the “Close” column. The result of step 1 is divided by the difference between the rolling maximum of the “High” column and the rolling minimum of the “Low” column, both calculated over a window of “n” periods. Finally, the obtained value is multiplied by 100 to express it as a percentage. Additionally, the code introduces another column called “STOD” in the DataFrame. This column represents the Stochastic Oscillator %D value, which is computed as the simple moving average of the “STOK” column over a window of 3 periods.

for stock in range(len(TechIndicator)):
    STOK(TechIndicator[stock], 4)
    TechIndicator[stock] = TechIndicator[stock].fillna(0)
TechIndicator[0].tail()

The provided code performs the following steps:

It utilizes a for loop to iterate through the range of numbers from 0 to the length of the “TechIndicator” list. This loop enables operations to be executed on each stock within the “TechIndicator” list.

Within the loop, for each stock located at index “stock” within the “TechIndicator” list:

The code invokes the “STOK” function, passing the DataFrame of the current stock (TechIndicator[stock]) and the value 4 as arguments. This function calculates the Stochastic Oscillator %K values for the specified DataFrame, considering a window of 4 periods. After computing the Stochastic Oscillator %K values for each stock, the code proceeds to further process the DataFrame of each stock:

It uses the .fillna(0) function to replace any missing values (NaN) within the DataFrame with zeros. This step ensures that all data points within the DataFrame contain numerical values. Finally, the code employs the .tail() function to print the last few rows of data from the DataFrame of the first stock within the “TechIndicator” list (TechIndicator[0]). This provides a glimpse of the modified DataFrame following the calculations and processing.

Calculation of Chaikin Money Flow

def CMFlow(df, tf):
    CHMF = []
    MFMs = []
    MFVs = []
    x = tf
    
    while x < len(df['Date']):
        PeriodVolume = 0
        volRange = df['Volume'][x-tf:x]
        for eachVol in volRange:
            PeriodVolume += eachVol
        
        MFM = ((df['Close'][x] - df['Low'][x]) - (df['High'][x] - df['Close'][x])) / (df['High'][x] - df['Low'][x])
        MFV = MFM*PeriodVolume
        
        MFMs.append(MFM)
        MFVs.append(MFV)
        x+=1
    
    y = tf
    while y < len(MFVs):
        PeriodVolume = 0
        volRange = df['Volume'][x-tf:x]
        for eachVol in volRange:
            PeriodVolume += eachVol
        consider = MFVs[y-tf:y]
        tfsMFV = 0
        
        for eachMFV in consider:
            tfsMFV += eachMFV
        
        tfsCMF = tfsMFV/PeriodVolume
        CHMF.append(tfsCMF)
        y+=1
    return CHMF

The code defines a function called CMFlow, which calculates the Chaikin Money Flow (CMF) indicator for a given DataFrame of financial data. The CMF indicator is a volume-based metric used in technical analysis to evaluate the flow of money into or out of a security, indicating buying or selling pressure.

The function begins by initializing three empty lists: CHMF, MFMs, and MFVs. CHMF will store the CMF values, while MFMs and MFVs will store the Money Flow Multiplier and Money Flow Volume values, respectively.

Next, the function takes two arguments: df, representing the DataFrame containing the financial data, and tf, representing the time frame or period over which to calculate the CMF.

The function then enters a while loop, which continues until a variable x reaches the length of the Date column in the DataFrame. Within each iteration of the loop, several calculations are performed.

First, the function calculates the PeriodVolume by summing up the volume values from the Volume column within the previous tf number of periods. This value represents the total volume within the specified time frame.

Next, the Money Flow Multiplier (MFM) is calculated. It is determined by taking the difference between the closing price and the midpoint of the high and low prices, divided by the difference between the high and low prices. The MFM indicates the strength of the price movement within the given period.

The Money Flow Volume (MFV) is then calculated by multiplying the Money Flow Multiplier (MFM) with the PeriodVolume. This value represents the volume adjusted by the price movement.

The calculated MFM is appended to the MFMs list, and the calculated MFV is appended to the MFVs list.

After each iteration, the variable x is incremented by 1 to move to the next period.

Once the first while loop completes, the function initializes another variable y to the value of tf. It then enters a second while loop, which continues until y reaches the length of the MFVs list.

Within this loop, the function performs similar calculations to those in the previous loop. It calculates the PeriodVolume by summing up the volume values from the Volume column within the previous tf number of periods. It also considers a range of MFV values within the previous tf number of periods.

The total Money Flow Volume (tfsMFV) is calculated by summing up the values in the considered range. This represents the cumulative Money Flow Volume within the specified time frame.

Finally, the Chaikin Money Flow (CMF) is calculated by dividing the total Money Flow Volume (tfsMFV) by the PeriodVolume. The CMF value indicates the buying or selling pressure over the given time frame.

The calculated CMF is appended to the CHMF list, and the variable y is incremented by 1 to move to the next period.

Once the second while loop completes, the function returns the list of CMF values (CHMF).

for stock in range(len(TechIndicator)):
    listofzeros = [0] * 40
    CHMF = CMFlow(TechIndicator[stock], 20)
    if len(CHMF)==0:
        CHMF = [0] * TechIndicator[stock].shape[0]
        TechIndicator[stock]['Chaikin_MF'] = CHMF
    else:
        TechIndicator[stock]['Chaikin_MF'] = listofzeros+CHMF
TechIndicator[0].tail()

This code snippet performs a series of operations to calculate and assign the Chaikin Money Flow (CMF) values to the TechIndicator DataFrame.

First, the code iterates over a range of values based on the length of the TechIndicator list, which represents different stocks.

Within each iteration, a list named “listofzeros” is created, consisting of 40 zeros.

The CMF values for the current stock are then calculated using the CMFlow function, with a time frame of 20.

Next, the code checks the length of the CMF list. If it is 0, indicating that no CMF values were calculated, a list of zeros is assigned to the ‘Chaikin_MF’ column of the TechIndicator[stock] DataFrame. The length of this list matches the data in the TechIndicator[stock] DataFrame.

On the other hand, if the CMF list is not empty, the code concatenates the listofzeros with the CMF list and assigns the resulting list to the ‘Chaikin_MF’ column of the TechIndicator[stock] DataFrame.

Finally, the code displays the last few rows of the TechIndicator[0] DataFrame.

Calculation of Parabolic SAR

def psar(df, iaf = 0.02, maxaf = 0.2):
    length = len(df)
    dates = (df['Date'])
    high = (df['High'])
    low = (df['Low'])
    close = (df['Close'])
    psar = df['Close'][0:len(df['Close'])]
    psarbull = [None] * length
    psarbear = [None] * length
    bull = True
    af = iaf
    ep = df['Low'][0]
    hp = df['High'][0]
    lp = df['Low'][0]
    for i in range(2,length):
        if bull:
            psar[i] = psar[i - 1] + af * (hp - psar[i - 1])
        else:
            psar[i] = psar[i - 1] + af * (lp - psar[i - 1])
        reverse = False
        if bull:
            if df['Low'][i] < psar[i]:
                bull = False
                reverse = True
                psar[i] = hp
                lp = df['Low'][i]
                af = iaf
        else:
            if df['High'][i] > psar[i]:
                bull = True
                reverse = True
                psar[i] = lp
                hp = df['High'][i]
                af = iaf
        if not reverse:
            if bull:
                if df['High'][i] > hp:
                    hp = df['High'][i]
                    af = min(af + iaf, maxaf)
                if df['Low'][i - 1] < psar[i]:
                    psar[i] = df['Low'][i - 1]
                if df['Low'][i - 2] < psar[i]:
                    psar[i] = df['Low'][i - 2]
            else:
                if df['Low'][i] < lp:
                    lp = df['Low'][i]
                    af = min(af + iaf, maxaf)
                if df['High'][i - 1] > psar[i]:
                    psar[i] = df['High'][i - 1]
                if df['High'][i - 2] > psar[i]:
                    psar[i] = df['High'][i - 2]
        if bull:
            psarbull[i] = psar[i]
        else:
            psarbear[i] = psar[i]
    #return {"dates":dates, "high":high, "low":low, "close":close, "psar":psar, "psarbear":psarbear, "psarbull":psarbull}
    #return psar, psarbear, psarbull
    df['psar'] = psar
    #df['psarbear'] = psarbear
    #df['psarbull'] = psarbull

This code defines a function called “psar” that calculates the Parabolic Stop and Reverse (PSAR) indicator for a given DataFrame of financial data. The PSAR is a trend-following indicator used in technical analysis to determine potential reversal points in the price trend of a security.

The function takes three arguments: df (the DataFrame containing the financial data), iaf (the initial acceleration factor, set to 0.02 by default), and maxaf (the maximum acceleration factor, set to 0.2 by default).

The function initializes several variables and lists based on the input DataFrame. It extracts the ‘Date’, ‘High’, ‘Low’, and ‘Close’ columns from the DataFrame and assigns them to respective variables for convenience. It also initializes the ‘psar’ list with the same values as the ‘Close’ column.

The function then enters a for loop that iterates from the index 2 to the length of the DataFrame. Within each iteration, the PSAR values are calculated based on the current trend (bullish or bearish).

If the current trend is bullish, the PSAR value is updated by adding the acceleration factor (af) multiplied by the difference between the highest price (hp) and the previous PSAR value. If the trend is bearish, the PSAR value is updated by adding the af multiplied by the difference between the lowest price (lp) and the previous PSAR value.

The function checks for potential trend reversals. If the trend changes from bullish to bearish or vice versa, the PSAR value is adjusted accordingly, and the relevant variables are updated.

The function also adjusts the acceleration factor based on certain conditions. If the trend is bullish and the current high price is higher than the previous highest price (hp), the hp is updated, and the af is increased up to the maximum acceleration factor (maxaf). Similar adjustments are made for bearish trends.

Furthermore, the function takes into account recent price movements to update the PSAR values accordingly.

The PSAR values for each iteration are stored in the ‘psar’ list, while separate lists (‘psarbear’ and ‘psarbull’) are created to track the PSAR values for bearish and bullish trends, respectively.

Finally, the function assigns the ‘psar’ list as a new column (‘psar’) in the input DataFrame (‘df’).

Calculation of Volume Weighted Average Price

for stock in range(len(TechIndicator)):
    TechIndicator[stock]['VWAP'] = np.cumsum(TechIndicator[stock]['Volume'] * (TechIndicator[stock]['High'] + TechIndicator[stock]['Low'])/2) / np.cumsum(TechIndicator[stock]['Volume'])
    TechIndicator[stock] = TechIndicator[stock].fillna(0)
TechIndicator[0].tail()

This code calculates the Volume Weighted Average Price (VWAP) for each stock in the TechIndicator list. VWAP is a technical analysis indicator used to assess the average price at which a stock is traded throughout the day, taking into account the volume of each trade.

The code iterates over the range of stock indices in the TechIndicator list. Within each iteration, it calculates the VWAP values for the corresponding stock using the following formula:

It multiplies the volume of each trade by the average of the high and low prices of that trade. It computes the cumulative sum of these values. It divides the cumulative sum of the volume-weighted prices by the cumulative sum of the volume to obtain the VWAP values. The calculated VWAP values are then assigned to a new column named ‘VWAP’ in the TechIndicator[stock] DataFrame.

After calculating the VWAP for each stock, the code fills any missing or NaN (Not a Number) values in the DataFrame with 0.

Finally, the code displays the last few rows of the data for the first stock in the TechIndicator list (TechIndicator[0]), including the newly added ‘VWAP’ column.

Calculation of Momentum

for stock in range(len(TechIndicator)):
    TechIndicator[stock]['Momentum'] = TechIndicator[stock]['Close'] - TechIndicator[stock]['Close'].shift(4)
    TechIndicator[stock] = TechIndicator[stock].fillna(0)
TechIndicator[0].tail()

this code calculates the Momentum indicator for each stock in the TechIndicator list. Momentum is a technical analysis tool used to measure the rate of change in a stock’s price over a specified number of periods.

The code iterates over the range of stock indices in the TechIndicator list. Within each iteration, it calculates the Momentum values for the corresponding stock using the following formula:

It subtracts the closing price of the current period from the closing price of the period four periods ago. This difference represents the rate of change or momentum in the stock’s price over the specified period. The calculated Momentum values are then assigned to a new column named ‘Momentum’ in the TechIndicator[stock] DataFrame.

After calculating the Momentum for each stock, the code fills any missing or NaN (Not a Number) values in the DataFrame with 0.

Finally, the code displays the last few rows of the data for the first stock in the TechIndicator list (TechIndicator[0]), including the newly added ‘Momentum’ column.

Calculation of Commodity Channel Index

def CCI(df, n, constant):
    TP = (df['High'] + df['Low'] + df['Close']) / 3
    CCI = pd.Series((TP - TP.rolling(window=n, center=False).mean()) / (constant * TP.rolling(window=n, center=False).std())) #, name = 'CCI_' + str(n))
    return CCI

this code defines a function called CCI (Commodity Channel Index) that calculates the CCI indicator for a given DataFrame of financial data. The CCI is a popular technical analysis tool used to identify potential overbought or oversold conditions in a security.

The function takes three arguments: df (the DataFrame containing the financial data), n (the number of periods to consider for calculating the CCI), and constant (a constant value used in the CCI formula).

Within the function, the True Price (TP) is calculated as the average of the high, low, and close prices for each period.

The CCI values are then calculated using the CCI formula: CCI = (TP — Rolling Mean of TP over n periods) / (constant * Rolling Standard Deviation of TP over n periods)

Here, the rolling mean and rolling standard deviation are computed using the rolling() function in pandas, with a window size of n periods.

The resulting CCI values are stored in a pandas Series object.

Finally, the function returns the CCI series.

To summarize, this code defines a function that calculates the Commodity Channel Index (CCI) for a given DataFrame of financial data. It computes the True Price (average of high, low, and close prices), and then calculates the CCI using the rolling mean and standard deviation of the True Price over a specified number of periods. The function returns the CCI values as a pandas Series.

Calculation of On Balance Volume

for stock in range(len(TechIndicator)):
    new = (TechIndicator[stock]['Volume'] * (~TechIndicator[stock]['Close'].diff().le(0) * 2 -1)).cumsum()
    TechIndicator[stock]['OBV'] = new
TechIndicator[5].tail()

this code calculates the On-Balance Volume (OBV) indicator for each stock in the TechIndicator list. OBV is a technical analysis tool used to assess the cumulative buying or selling pressure of a security based on volume.

The code iterates over the range of stock indices in the TechIndicator list. Within each iteration, it performs the following operations:

It calculates a new series called “new” by multiplying the volume of each period by a binary value that represents whether the price change from the previous period is positive or negative. If the price change is positive, the binary value is 1, and if the price change is negative or zero, the binary value is -1. This is achieved by evaluating the condition ~TechIndicator[stock][‘Close’].diff().le(0) * 2 -1. It applies the cumulative sum (cumsum()) operation to the “new” series. It assigns the calculated values of the “new” series to a new column named ‘OBV’ in the TechIndicator[stock] DataFrame. After calculating the OBV for each stock, the code displays the last few rows of the data for the sixth stock in the TechIndicator list (TechIndicator[5]), including the newly added ‘OBV’ column.

In summary, this code calculates the On-Balance Volume (OBV) indicator for each stock in the TechIndicator list by accumulating volume values based on the direction of price changes. It assigns the calculated OBV values to the respective DataFrame, and then displays the last few rows of data for the sixth stock.

Calcualtion of Keltner Channels

#Keltner Channel  
def KELCH(df, n):  
    KelChM = pd.Series(((df['High'] + df['Low'] + df['Close']) / 3).rolling(window =n, center=False).mean(), name = 'KelChM_' + str(n))  
    KelChU = pd.Series(((4 * df['High'] - 2 * df['Low'] + df['Close']) / 3).rolling(window =n, center=False).mean(), name = 'KelChU_' + str(n))  
    KelChD = pd.Series(((-2 * df['High'] + 4 * df['Low'] + df['Close']) / 3).rolling(window =n, center=False).mean(), name = 'KelChD_' + str(n))    
    return KelChM, KelChD, KelChU

this code defines a function called KELCH (Keltner Channel) that calculates the Keltner Channel indicator for a given DataFrame of financial data. The Keltner Channel is a technical analysis tool used to identify potential price breakouts and determine overbought or oversold conditions.

The function takes two arguments: df (the DataFrame containing the financial data) and n (the number of periods to consider for calculating the Keltner Channel).

Within the function, the Keltner Channel values are calculated using the following formulas:

KelChM: It is calculated as the rolling mean of the average of the high, low, and close prices of each period. KelChU: It is calculated as the rolling mean of a modified formula based on the high, low, and close prices. KelChD: It is calculated as the rolling mean of another modified formula based on the high, low, and close prices. The rolling mean is computed using the rolling() function in pandas, with a window size of n periods.

The calculated Keltner Channel values are stored in pandas Series objects named ‘KelChM’, ‘KelChD’, and ‘KelChU’.

Finally, the function returns the three Series objects representing the Keltner Channel values: KelChM, KelChD, and KelChU.

for stock in range(len(TechIndicator)):
    KelchM, KelchD, KelchU = KELCH(TechIndicator[stock], 14)
    TechIndicator[stock]['Kelch_Upper'] = KelchU
    TechIndicator[stock]['Kelch_Middle'] = KelchM
    TechIndicator[stock]['Kelch_Down'] = KelchD
    TechIndicator[stock] = TechIndicator[stock].fillna(0)
TechIndicator[5].tail()

this code calculates the Keltner Channel indicator for each stock in the TechIndicator list and adds the calculated values to the DataFrame.

The code iterates over the range of stock indices in the TechIndicator list. Within each iteration, it performs the following operations:

It calls the KELCH() function with the current stock’s data (TechIndicator[stock]) and a period of 14. The KELCH() function returns three pandas Series objects representing the Keltner Channel values: KelchM, KelchD, and KelchU. The code assigns the values from KelchU to a new column named ‘Kelch_Upper’ in the TechIndicator[stock] DataFrame. Similarly, it assigns the values from KelchM to a new column named ‘Kelch_Middle’ and the values from KelchD to a new column named ‘Kelch_Down’ in the same DataFrame. It fills any missing or NaN (Not a Number) values in the DataFrame with 0. The process repeats for each stock in the TechIndicator list. Finally, the code displays the last few rows of the data for the sixth stock in the TechIndicator list (TechIndicator[5]), which now includes the newly added ‘Kelch_Upper’, ‘Kelch_Middle’, and ‘Kelch_Down’ columns.

In summary, this code calculates the Keltner Channel indicator for each stock in the TechIndicator list. It adds the upper, middle, and lower lines of the Keltner Channel to the respective DataFrames. The code then fills any missing values in the DataFrames and displays the last few rows of the data for the sixth stock.

Calculation of Average Directional Movement Index (ADX)

def DMI(df, period):
    df['UpMove'] = df['High'] - df['High'].shift(1)
    df['DownMove'] = df['Low'].shift(1) - df['Low']
    df['Zero'] = 0

    df['PlusDM'] = np.where((df['UpMove'] > df['DownMove']) & (df['UpMove'] > df['Zero']), df['UpMove'], 0)
    df['MinusDM'] = np.where((df['UpMove'] < df['DownMove']) & (df['DownMove'] > df['Zero']), df['DownMove'], 0)

    df['plusDI'] = 100 * (df['PlusDM']/df['ATR']).ewm(span=period,min_periods=0,adjust=True,ignore_na=False).mean()
    df['minusDI'] = 100 * (df['MinusDM']/df['ATR']).ewm(span=period,min_periods=0,adjust=True,ignore_na=False).mean()

    df['ADX'] = 100 * (abs((df['plusDI'] - df['minusDI'])/(df['plusDI'] + df['minusDI']))).ewm(span=period,min_periods=0,adjust=True,ignore_na=False).mean()

The code defines a function called DMI (Directional Movement Index) that calculates several indicators related to directional movement for a given DataFrame of financial data.

The function takes two arguments: df, which represents the DataFrame containing the financial data, and period, which indicates the period over which the indicators should be calculated.

Inside the function, the code performs the following steps:

It calculates the difference between the current period’s highest price (High) and the previous period’s highest price, storing the result in the ‘UpMove’ column. It calculates the difference between the previous period’s lowest price (Low) and the current period’s lowest price, storing the result in the ‘DownMove’ column. It creates a new column named ‘Zero’ with all values set to 0. It determines the values for the ‘PlusDM’ column based on conditions. If the ‘UpMove’ is greater than both the ‘DownMove’ and ‘Zero’, the ‘PlusDM’ column is assigned the value of ‘UpMove’; otherwise, it is set to 0. It determines the values for the ‘MinusDM’ column in a similar manner. If the ‘UpMove’ is less than both the ‘DownMove’ and ‘Zero’, the ‘MinusDM’ column is assigned the value of ‘DownMove’; otherwise, it is set to 0. It calculates the ‘plusDI’ column by taking the exponentially weighted moving average (ewm) of the ratio of ‘PlusDM’ to ‘ATR’ (Average True Range). The ewm is computed with a span equal to the specified period. It calculates the ‘minusDI’ column in a similar manner, using the ewm of the ratio of ‘MinusDM’ to ‘ATR’. It calculates the ‘ADX’ column as the exponentially weighted moving average of the absolute value of the difference between ‘plusDI’ and ‘minusDI’, divided by the sum of ‘plusDI’ and ‘minusDI’. The ewm is computed with a span equal to the specified period. In summary, the code defines a function that calculates several indicators related to the Directional Movement Index (DMI) for a given DataFrame. These indicators include the Plus Directional Indicator (+DI), Minus Directional Indicator (-DI), and Average Directional Index (ADX). The calculations are based on the ‘High’, ‘Low’, ‘ATR’, and previously calculated movement values.

for stock in range(len(TechIndicator)):
    DMI(TechIndicator[stock], 14)
    TechIndicator[stock] = TechIndicator[stock].fillna(0)
TechIndicator[5].tail()

The code iterates over the range of stock indices in the TechIndicator list. Within each iteration, it applies the DMI function to calculate the Directional Movement Index (DMI) indicators for the corresponding stock in the TechIndicator list. The period for calculating the DMI indicators is set to 14. The calculated DMI indicators are not directly assigned or stored because the DMI function modifies the DataFrame in-place. After calculating the DMI indicators for each stock, the code fills any missing values in each DataFrame with 0. Finally, the code displays the last few rows of the data for the sixth stock in the TechIndicator list (TechIndicator[5]), which now includes the calculated DMI indicators.

In summary, this code calculates the Directional Movement Index (DMI) indicators for each stock in the TechIndicator list. It modifies the DataFrames in-place to add the DMI indicators. Any missing values are filled with 0. The code then displays the last few rows of the data for the sixth stock, including the calculated DMI indicators.

Visualization of technical indicators

for stock in range(len(TechIndicator)):
    TechIndicator[stock].index = TechIndicator[stock]['Date']
    TechIndicator[stock] = TechIndicator[stock].drop(labels = ['Date'], axis = 1)

the provided code iterates over the range of stock indices in the TechIndicator list. Within each iteration, it performs the following operations:

It assigns the ‘Date’ column of the DataFrame TechIndicator[stock] as the new index for that DataFrame. This means that the index of the DataFrame will be set to the values in the ‘Date’ column. It drops the ‘Date’ column from the DataFrame TechIndicator[stock] using the drop() function. The labels parameter is set to ‘Date’, and the axis parameter is set to 1 to indicate that a column is being dropped. By setting the index to the ‘Date’ column and removing the ‘Date’ column itself, this code essentially transforms the DataFrame so that the ‘Date’ column is no longer a separate column but instead serves as the index for the DataFrame.

%matplotlib inline

# RSI Plot

fig = plt.figure(figsize=(20,25))
for i in range(8):
    ax = plt.subplot(4,2,i+1)
    ax.plot(TechIndicator[i].index, TechIndicator[i]['RSI_14D'])
    ax.set_title(str(TechIndicator[i]['Label'][0]))
    ax.set_xlabel("Date")
    ax.set_ylabel("Relative Strength Index")
    plt.xticks(rotation=30)
fig.tight_layout()

this code generates a plot of the Relative Strength Index (RSI) for multiple stocks using the TechIndicator data.

First, %matplotlib inline is a directive that allows the plots to be displayed within the Jupyter notebook environment.

The code then creates a figure object fig with a specified size. Within this figure, a loop iterates over a range of 8, indicating the number of subplots to be created.

For each iteration, a subplot is created using the plt.subplot() function, and the RSI values (TechIndicator[i][‘RSI_14D’]) of the corresponding stock are plotted against the corresponding dates (TechIndicator[i].index).

The title of each subplot is set to the first value of the ‘Label’ column for the respective stock. The x-axis label is set to “Date”, and the y-axis label is set to “Relative Strength Index”. The x-axis tick labels are rotated by 30 degrees for better readability.

Finally, fig.tight_layout() is used to optimize the layout of the subplots within the figure.

Overall, this code generates a visualization of the RSI for multiple stocks, allowing for a comparison of the RSI trends across different stocks over time.

# Volume Plain plot
fig = plt.figure(figsize=(20,25))
for i in range(8):
    ax = plt.subplot(8,1,i+1)
    ax.plot(TechIndicator[i].index, TechIndicator[i]['Volume_plain'], 'b')
    ax.set_title(str(TechIndicator[i]['Label'][0]))
    ax.set_xlabel("Date")
    ax.set_ylabel("Volume")
    plt.xticks(rotation=30)
fig.tight_layout()

his code generates a plot of the volume data for multiple stocks using the TechIndicator dataset.

The code starts by creating a figure object fig with a specified size. Within this figure, a loop iterates over a range of 8, indicating the number of subplots to be created.

For each iteration, a subplot is created using the plt.subplot() function. The volume data (TechIndicator[i][‘Volume_plain’]) of the corresponding stock is plotted against the corresponding dates (TechIndicator[i].index) using a blue line.

The title of each subplot is set to the first value of the ‘Label’ column for the respective stock. The x-axis label is set to “Date”, and the y-axis label is set to “Volume”. The x-axis tick labels are rotated by 30 degrees for better readability.

Finally, fig.tight_layout() is used to optimize the layout of the subplots within the figure.

Overall, this code generates a visualization of the volume data for multiple stocks, allowing for a comparison of the volume trends across different stocks over time.

plt.style.use('fivethirtyeight')

fig = plt.figure(figsize=(20,25))
for i in range(8):
    ax = plt.subplot(4,2,i+1)
    ax.fill_between(TechIndicator[i].index, TechIndicator[i]['BB_Upper_Band'], TechIndicator[i]['BB_Lower_Band'], color='grey', label="Band Range")
    # Plot Adjust Closing Price and Moving Averages
    ax.plot(TechIndicator[i].index, TechIndicator[i]['Close'], color='red', lw=2, label="Close")
    ax.plot(TechIndicator[i].index, TechIndicator[i]['BB_Middle_Band'], color='black', lw=2, label="Middle Band")
    ax.set_title("Bollinger Bands for " + str(TechIndicator[i]['Label'][0]))
    ax.legend()
    ax.set_xlabel("Date")
    ax.set_ylabel("Close Prices")
    plt.xticks(rotation=30)
fig.tight_layout()
#.dt.to_pydatetime()

this code generates a plot of Bollinger Bands for multiple stocks using the TechIndicator dataset.

The code begins by setting the plot style to ‘fivethirtyeight’, which gives the plot a specific visual appearance.

A figure object fig is created with a specified size. Within this figure, a loop iterates over a range of 8, indicating the number of subplots to be created.

For each iteration, a subplot is created using the plt.subplot() function. The Bollinger Bands are plotted in the background as a filled area using the fill_between() function. The upper band values are taken from the ‘BB_Upper_Band’ column, and the lower band values are taken from the ‘BB_Lower_Band’ column. The color is set to grey, and the label is specified as “Band Range”.

The closing prices (Close) for the corresponding stock are plotted as a line graph in red, indicating the price movement over time. The middle band values (BB_Middle_Band) are also plotted as a line graph in black, representing the average price trend.

The title of each subplot is set to “Bollinger Bands for [stock label]”, where the stock label is extracted from the ‘Label’ column for the respective stock. A legend is added to the plot to differentiate the lines.

The x-axis label is set to “Date”, and the y-axis label is set to “Close Prices”. The x-axis tick labels are rotated by 30 degrees for better readability.

Finally, fig.tight_layout() is used to optimize the layout of the subplots within the figure.

Overall, this code generates a visualization of Bollinger Bands for multiple stocks, allowing for a comparison of the price movements within the bands and identifying potential trends and volatility.

# Aroon Oscillator Plot
plt.style.use('seaborn-whitegrid')
fig = plt.figure(figsize=(20,25))
for i in range(8):
    ax = plt.subplot(4,2,i+1)
    ax.fill(TechIndicator[i].index, TechIndicator[i]['Aroon_Oscillator'],'g', alpha = 0.5, label = "Aroon Oscillator")
    ax.plot(TechIndicator[i].index, TechIndicator[i]['Close'], 'r', label="Close")
    ax.set_title("Aroon Oscillator for " +str(TechIndicator[i]['Label'][0]))
    ax.legend()
    ax.set_xlabel("Date")
    ax.set_ylabel("Close Prices")
    plt.xticks(rotation=30)
fig.tight_layout()

this code generates a plot of the Aroon Oscillator for multiple stocks using the TechIndicator dataset.

The code begins by setting the plot style to ‘seaborn-whitegrid’, which gives the plot a specific visual appearance with a white grid background.

A figure object fig is created with a specified size. Within this figure, a loop iterates over a range of 8, indicating the number of subplots to be created.

For each iteration, a subplot is created using the plt.subplot() function. The Aroon Oscillator values (Aroon_Oscillator) are filled with green color using the fill() function. The transparency is set to 0.5 to allow for better visibility of underlying data. The label is specified as “Aroon Oscillator”.

The closing prices (Close) for the corresponding stock are plotted as a line graph in red, indicating the price movement over time.

The title of each subplot is set to “Aroon Oscillator for [stock label]”, where the stock label is extracted from the ‘Label’ column for the respective stock. A legend is added to the plot to differentiate the lines.

The x-axis label is set to “Date”, and the y-axis label is set to “Close Prices”. The x-axis tick labels are rotated by 30 degrees for better readability.

Finally, fig.tight_layout() is used to optimize the layout of the subplots within the figure.

Overall, this code generates a visualization of the Aroon Oscillator for multiple stocks, allowing for a comparison of the oscillator values and the corresponding stock prices. It helps in identifying potential trends and the strength of those trends in the market.

# PRice Volume Trend Plot
fig = plt.figure(figsize=(20,25))
for i in range(8):
    ax = plt.subplot(8,1,i+1)
    ax.plot(TechIndicator[i].index, TechIndicator[i]['PVT'], 'black')
    ax.set_title("Price Volume Trend of " +str(TechIndicator[i]['Label'][0]))
    ax.set_xlabel("Date")
    ax.set_ylabel("Price Volume trend")
    plt.xticks(rotation=30)
fig.tight_layout()

this code generates a plot of the Price Volume Trend (PVT) for multiple stocks using the TechIndicator dataset.

The code begins by creating a figure object fig with a specified size. Within this figure, a loop iterates over a range of 8, indicating the number of subplots to be created.

For each iteration, a subplot is created using the plt.subplot() function. The PVT values (PVT) for the corresponding stock are plotted as a line graph in black color using the plot() function.

The title of each subplot is set to “Price Volume Trend of [stock label]”, where the stock label is extracted from the ‘Label’ column for the respective stock.

The x-axis label is set to “Date”, and the y-axis label is set to “Price Volume Trend”. The x-axis tick labels are rotated by 30 degrees for better readability.

Finally, fig.tight_layout() is used to optimize the layout of the subplots within the figure.

Overall, this code generates a visualization of the Price Volume Trend for multiple stocks, allowing for a comparison of the trend values and their relationship with the corresponding stock prices and trading volumes. The PVT helps in assessing the strength of price movements in relation to trading volume, which can provide insights into market trends and potential buying or selling signals.

# Stochastic Oscillator plots
plt.style.use('seaborn-whitegrid')
fig = plt.figure(figsize=(20,25))
for i in range(8):
    ax = plt.subplot(4,2,i+1)
    ax.plot(TechIndicator[i].index, TechIndicator[i]['STOK'], 'blue', label="%K")
    ax.plot(TechIndicator[i].index, TechIndicator[i]['STOD'], 'red', label="%D")
    ax.plot(TechIndicator[i].index, TechIndicator[i]['Close'], color='black', lw=2, label = "Close")
    ax.set_title("Stochastic Oscillators of " +str(TechIndicator[i]['Label'][0]))
    ax.legend()
    ax.set_xlabel("Date")
    ax.set_ylabel("Close Price")
    plt.xticks(rotation=30)
fig.tight_layout()

this code generates plots of the Stochastic Oscillator for multiple stocks using the TechIndicator dataset.

The code begins by setting the plot style to a white grid using plt.style.use(‘seaborn-whitegrid’). Then, a figure object fig is created with a specified size.

Within the figure, a loop iterates over a range of 8, indicating the number of subplots to be created.

For each iteration, a subplot is created using the plt.subplot() function. The Stochastic Oscillator %K values (STOK) are plotted as a line graph in blue color, and the %D values (STOD) are plotted as a line graph in red color. Additionally, the closing price (Close) for the corresponding stock is plotted as a line graph in black color.

The title of each subplot is set to “Stochastic Oscillators of [stock label]”, where the stock label is extracted from the ‘Label’ column for the respective stock.

A legend is displayed to differentiate between %K, %D, and the close price. The x-axis label is set to “Date”, and the y-axis label is set to “Close Price”. The x-axis tick labels are rotated by 30 degrees for better readability.

Finally, fig.tight_layout() is used to optimize the layout of the subplots within the figure.

Overall, this code generates visualizations of the Stochastic Oscillator for multiple stocks. The Stochastic Oscillator is a momentum indicator that helps identify overbought and oversold conditions in the market. Traders and analysts can use these plots to gain insights into potential trend reversals and make informed trading decisions.

# Chaikin Money Flow Plots
import matplotlib.gridspec as gridspec

fig = plt.figure(figsize=(25,40))
outer = gridspec.GridSpec(4, 2, wspace=0.2, hspace=0.2)

for i in range(8):
    inner = gridspec.GridSpecFromSubplotSpec(2, 1,
                    subplot_spec=outer[i], wspace=0.1, hspace=0.1)

    for j in range(2):
        ax = plt.Subplot(fig, inner[j])
        if j==0:
            t = ax.fill(TechIndicator[i].index, TechIndicator[i]['Chaikin_MF'],'b', alpha = 0.5, label = "Chaikin MF")
            ax.set_title("Chaikin Money Flow for " +str(TechIndicator[i]['Label'][0]))
            t = ax.set_ylabel("Money Flow")
        else:
            t = ax.plot(TechIndicator[i].index, TechIndicator[i]['Close'], 'r', label="Close")
            t = ax.set_ylabel("Close")
        ax.legend()
        ax.set_xlabel("Date")
        
        fig.add_subplot(ax)
fig.tight_layout()

this code generates plots of the Chaikin Money Flow (CMF) indicator for multiple stocks using the TechIndicator dataset.

The code begins by importing the gridspec module from matplotlib and creating a figure object fig with a specified size.

The figure is divided into a 4x2 grid using gridspec.GridSpec(4, 2, wspace=0.2, hspace=0.2). This grid will accommodate the subplots for each stock.

A nested loop is used to iterate over the grid and create subplots. The outer loop iterates over the rows of the grid, and the inner loop iterates over the columns. Each iteration creates a subplot within the corresponding cell of the grid.

For each subplot, the code checks the value of j in the inner loop. If j is 0, the Chaikin Money Flow values (Chaikin_MF) are filled as a blue area plot using ax.fill(). The title of the subplot is set to “Chaikin Money Flow for [stock label]”, where the stock label is extracted from the ‘Label’ column for the respective stock. The y-axis label is set to “Money Flow”.

If j is 1, the closing price (Close) for the corresponding stock is plotted as a line graph in red color using ax.plot(). The y-axis label is set to “Close”.

A legend is displayed to differentiate between the Chaikin Money Flow and the close price. The x-axis label is set to “Date”.

The subplots are added to the figure using fig.add_subplot(ax).

Finally, fig.tight_layout() is used to optimize the layout of the subplots within the figure, ensuring proper spacing and alignment.

Overall, this code generates visualizations of the Chaikin Money Flow indicator for multiple stocks. The Chaikin Money Flow is a volume-based indicator that helps assess the accumulation or distribution of money in a stock. Traders and analysts can use these plots to identify potential buying or selling opportunities based on the flow of money in the market.

# Parabolic SAR, Rate of Change, Momentum and VWAP Plots
fig = plt.figure(figsize=(20,25))
for i in range(8):
    ax = plt.subplot(4,2,i+1)
    ax.plot(TechIndicator[i].index, TechIndicator[i]['psar'], 'blue', label="PSAR", alpha = 0.5)
    ax.plot(TechIndicator[i].index, TechIndicator[i]['ROC'], 'red', label="ROC", alpha = 0.5)
    ax.plot(TechIndicator[i].index, TechIndicator[i]['Momentum'], 'green', label="Momentum", alpha = 0.5)
    ax.plot(TechIndicator[i].index, TechIndicator[i]['VWAP'], 'cyan', label="VWAP", alpha = 0.5)
    ax.set_title("PSAR, ROC, Momentum and VWAP of " +str(TechIndicator[i]['Label'][0]))
    ax.legend()
    ax.set_xlabel("Date")
    ax.set_ylabel("Close Price")
    plt.xticks(rotation=30)
fig.tight_layout()

this code generates plots for multiple technical indicators including Parabolic SAR (PSAR), Rate of Change (ROC), Momentum, and Volume Weighted Average Price (VWAP) using the TechIndicator dataset.

The code starts by creating a figure object fig with a specified size.

It then enters a loop that iterates over each stock in the TechIndicator dataset. Within each iteration, a subplot is created using plt.subplot(4, 2, i+1) to allocate a specific cell in a 4x2 grid for the current stock.

Within each subplot, four indicators are plotted:

The Parabolic SAR values (psar) are plotted as a blue line graph using ax.plot(). The Rate of Change values (ROC) are plotted as a red line graph using ax.plot(). The Momentum values are plotted as a green line graph using ax.plot(). The Volume Weighted Average Price values (VWAP) are plotted as a cyan line graph using ax.plot(). Each subplot is given a title of “PSAR, ROC, Momentum, and VWAP of [stock label]”, where the stock label is extracted from the ‘Label’ column for the respective stock.

A legend is displayed to differentiate between the four indicators. The x-axis label is set to “Date” and the y-axis label is set to “Close Price”. The x-axis tick labels are rotated by 30 degrees for better readability.

Finally, fig.tight_layout() is used to optimize the layout of the subplots within the figure, ensuring proper spacing and alignment.

Overall, this code generates visualizations of the Parabolic SAR, Rate of Change, Momentum, and Volume Weighted Average Price indicators for multiple stocks. These indicators provide insights into the trend, momentum, and volume dynamics of the stocks, helping traders and analysts make informed decisions.

Machine Learning
Deep Learning
Stocks
Finance
Artificial Intelligence
Recommended from ReadMedium