FabTrader_Logo_Main
  • Home
  • Courses
    • Build Algo Trading Platform using Python Course
  • Store
  • Tools
  • Stories
  • About Me
₹0.00 0 Cart
Edit Content
FabTrader_Logo_Main
Welcome to FabTrader Community!

Course Dashboard
Store Account
Cart
Algo Trading Course
About Me
Store
Stories

Get in touch with me

hello@fabtrader.in

blog banner background shape images
  • FabTrader
  • March 15, 2025

Find Moving Average Slope, Angle and its Trend using python

  • 7 min read
  • 347 Views

Technical analysis continues to be one of the most powerful tools in an investor’s arsenal. While there are countless indicators available, sometimes the simplest approaches yield the most valuable insights. Today, I want to share a technique I’ve been using for years that has consistently helped me identify trend strength and potential reversals: calculating the slope of moving averages.

Why Moving Average Slopes Matter

Moving averages smooth out price data to help us see the underlying trend. But here’s the thing – it’s not just about whether a stock is trading above or below its moving average. The angle or slope of that moving average tells us something crucial about momentum.

A steep upward slope indicates strong bullish momentum. A flattening slope might signal a potential trend weakening. And a downward slope often confirms bearish momentum is taking hold.

After years of eyeballing these slopes on charts, I finally decided to quantify this approach. Below, I’ll share the exact method I use to calculate these slopes and how you can implement it yourself.

The Python Implementation

I’ve created a straightforward Python script that:

  1. Pulls real stock data from Yahoo Finance
  2. Calculates a moving average (I typically use 20 days)
  3. Measures the slope of that moving average over a recent period (usually 30 days)
  4. Visualizes everything so you can see what’s happening

#
"""
------------------------------------------------------------------------------------
                          FabTrader Algo Trading
------------------------------------------------------------------------------------
This utility calculates the slope of a moving average for a given scrip

For more information, visit our alog trading community:
www.fabtrader.in
"""
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime, timedelta
from sklearn.linear_model import LinearRegression
import yfinance as yf


def calculate_ma_slope(prices, ma_window=20, slope_period=30):
    """
    Calculate the slope of the moving average line for a given time period.

    Parameters:
    ----------
    prices : pandas Series
        Series of historical closing prices.
    ma_window : int
        Window size for the moving average calculation (default: 20 days).
    slope_period : int
        Time period over which to calculate the slope (default: 30 days).

    Returns:
    -------
    slope : float
        The slope of the moving average line over the specified period.
    """
    # Ensure we have enough data
    if len(prices) < ma_window + slope_period:
        raise ValueError(f"Need at least {ma_window + slope_period} data points")

    # Calculate moving average
    ma_series = prices.rolling(window=ma_window).mean()

    # Get the last slope_period points where MA is available
    ma_values = ma_series.dropna().iloc[-slope_period:].values

    # Create X values (time indices)
    X = np.array(range(slope_period)).reshape(-1, 1)

    # Fit linear regression to find the slope
    model = LinearRegression()
    model.fit(X, ma_values)

    # Get the slope coefficient
    slope = model.coef_[0]

    return slope, ma_series


def analyze_stock_ma_slope(ticker_symbol="AAPL", ma_window=20, slope_period=30, days_of_data=200):
    """
    Analyze the moving average slope for a given stock ticker.

    Parameters:
    ----------
    ticker_symbol : str
        Yahoo Finance ticker symbol (default: "AAPL" for Apple Inc).
    ma_window : int
        Window size for the moving average calculation (default: 20 days).
    slope_period : int
        Time period over which to calculate the slope (default: 30 days).
    days_of_data : int
        Number of days of historical data to retrieve (default: 200).
    """
    # Download data
    end_date = datetime.now()
    start_date = end_date - timedelta(days=days_of_data + 50)  # Add buffer for weekends/holidays

    # print(
    #     f"Downloading data for {ticker_symbol} from {start_date.strftime('%Y-%m-%d')} to {end_date.strftime('%Y-%m-%d')}...")

    data = yf.download(ticker_symbol, start=start_date, end=end_date, progress=False, auto_adjust=True)

    if data.empty:
        print(f"No data found for ticker {ticker_symbol}")
        return

    # print(f"Retrieved {len(data)} days of data for {ticker_symbol}")

    # Ensure we have enough data
    if len(data) < ma_window + slope_period:
        print(f"Not enough data. Need at least {ma_window + slope_period} trading days.")
        return

    # Calculate MA and its slope
    closing_prices = data['Close']
    slope, ma_series = calculate_ma_slope(closing_prices, ma_window, slope_period)

    print(f"\nStock : {ticker_symbol}")
    print(f"{ma_window}-Day MA slope over the last {slope_period} days: {slope[0]:.4f}")

    # Determine trend strength and direction
    abs_slope = abs(slope)
    if abs_slope < 0.1:
        strength = "very weak"
    elif abs_slope < 0.5:
        strength = "weak"
    elif abs_slope < 1.0:
        strength = "moderate"
    elif abs_slope < 2.0:
        strength = "strong"
    else:
        strength = "very strong"

    direction = "upward" if slope > 0 else "downward"
    if abs_slope < 0.05:
        trend_description = "mostly flat"
    else:
        trend_description = f"{strength} {direction}"

    print(f"Moving Average Slope Trend: {trend_description}")


if __name__ == "__main__":
    # You can change these parameters
    ticker = "AAPL"  # Apple Inc.
    ma_window = 20  # 20-day moving average
    slope_period = 30  # Calculate slope over 30 days

    analyze_stock_ma_slope(ticker_symbol=ticker, ma_window=ma_window, slope_period=slope_period)

How It Works

The magic happens in the calculate_ma_slope() function. Here’s what it does:

  1. First, we calculate the moving average of our price data (typically the 20-day MA)
  2. Then we take the most recent period (typically 30 days) of that moving average
  3. Next, we use linear regression to fit a straight line to those MA points
  4. Finally, we extract the slope coefficient from that regression line

This approach gives us a precise, quantitative measure of the MA slope rather than just eyeballing it.

Real-World Example: Apple (AAPL)

Let me show you a recent analysis I did on Apple stock. Running the code with default parameters gave me the following output:

Interpreting Slope Values

Over time, I’ve developed some guidelines for interpreting these slope values:

  • Very Strong Uptrend: Slope > 2.0
  • Strong Uptrend: Slope between 1.0 and 2.0
  • Moderate Uptrend: Slope between 0.5 and 1.0
  • Mild Uptrend: Slope between 0.1 and 0.5
  • Flat/Sideways: Slope between -0.1 and 0.1
  • Mild Downtrend: Slope between -0.5 and -0.1
  • Moderate Downtrend: Slope between -1.0 and -0.5
  • Strong Downtrend: Slope between -2.0 and -1.0
  • Very Strong Downtrend: Slope < -2.0

These values will vary somewhat depending on the price of the stock – a $1000 stock will naturally have larger slope values than a $10 stock. But the classifications still provide a good rule of thumb.

How I Use This in My Trading

I use this tool as part of my broader analysis process. Here’s my typical approach:

  1. Run this analysis on my watchlist stocks weekly
  2. Flag stocks with significant slope changes (e.g., from negative to positive)
  3. Look for stocks where the slope is strengthening but price hasn’t yet made a big move
  4. Be cautious with stocks showing extremely steep slopes – they often revert

The most valuable signals often come from slope changes rather than absolute values. A slope that’s turning from negative to positive can indicate a new uptrend forming, even before it becomes obvious on the chart.

Conclusion

Moving average slopes provide a quantifiable measure of trend strength that’s often overlooked by casual chart readers. By incorporating this analysis into your toolkit, you gain deeper insight into momentum and potential trend changes.

In future posts, I’ll explore how to combine this slope analysis with other indicators like RSI and MACD to create a more comprehensive trading system. I’ll also share some specific case studies where this approach identified significant market turns well ahead of more common indicators.

What technical indicators do you find most usefu


Support this community : FabTrader.in is a one-person initiative dedicated to helping individuals on their F.I.R.E. journey. Running and maintaining this community takes time, effort, and resources. If you’ve found value in the content, consider making a donation to support this mission.

Donate

Disclaimer: The information provided in this article is for educational and informational purposes only and should not be construed as financial, investment, or legal advice. The content is based on publicly available information and personal opinions and may not be suitable for all investors. Investing involves risks, including the loss of principal. Always conduct your own research and consult a qualified financial advisor before making any investment decisions. The author and website assume no liability for any financial losses or decisions made based on the information presented.

FabTrader

Vivek is an algorithmic trader, Python programmer, and a passionate advocate of the F.I.R.E. (Financial Independence, Retire Early) movement. He achieved his financial independence at the age of 45 and is dedicated to helping others embark on their own journeys toward financial freedom.

Home
Store
Stories
Algo Trading Platform Using Python Course
About Me

©2024 Fabtrader.in - An unit of Rough Sketch Company. All Rights Reserved

Terms & Conditions
Privacy Policy
Shipping & Delivery
About and Contact
Refunds