Fibonacci Retracement Level Calculator in Python

Mark Zhou
4 min readDec 18, 2023

--

Photo by Star of the Sea on Unsplash

Technical analysis in financial markets has always been an area of keen interest and continuous innovation. One such evolution is the development of a sophisticated Fibonacci Retracement Level calculator in Python. This journey from a basic function to an advanced, integrated tool encapsulates the need for adaptive and nuanced market analysis.

Initial Concept: The Basic Fibonacci Retracement Function

Our journey began with a simple Python function to calculate Fibonacci retracement levels. The basic premise was straightforward — input the high and low prices of a stock, and the function computes the key Fibonacci levels: 23.6%, 38.2%, 50%, 61.8%, and 100%.

def fibonacci_retracement_levels(high, low):
difference = high - low
return {
'23.6%': high - difference * 0.236,
'38.2%': high - difference * 0.382,
'50%': high - difference * 0.5,
'61.8%': high - difference * 0.618,
'100%': low
}

Adaptive Lookback Period Based on Volatility

To enhance the tool’s relevance to current market conditions, we introduced an adaptive lookback period. The determine_lookback_period function was developed to dynamically adjust this period based on the stock's volatility, calculated from historical data.

import datetime
import yfinance as yf

def determine_lookback_period(base_lookback=252):
end_date = datetime.date.today()
start_date = end_date - datetime.timedelta(days=base_lookback)
data = yf.download(self.stock_symbol, start=start_date, end=end_date)
data['Daily_Return'] = data['Close'].pct_change()
volatility = data['Daily_Return'].std()
adjusted_lookback = int(base_lookback / 2) if volatility > data['Daily_Return'].std() else base_lookback
start_date = end_date - datetime.timedelta(days=adjusted_lookback)
return adjusted_lookback, start_date, end_date

Excluding Outliers

Recognizing that stock prices can be subject to extreme values, we included functions to exclude outliers. We provided both statistical and percentage-based methods for outlier exclusion.

def exclude_outliers_statistical(data, n_std=2):
mean_price = data['Close'].mean()
std_dev = data['Close'].std()
return data[(data['Close'] >= mean_price - n_std * std_dev) & (data['Close'] <= mean_price + n_std * std_dev)]

def exclude_outliers_percentage(data, threshold=10):
median_price = data['Close'].median()
return data[(data['Close'] >= median_price * (1 - threshold / 100)) & (data['Close'] <= median_price * (1 + threshold / 100))]

Incorporating Moving Averages

Moving averages were integrated to identify significant support and resistance levels. The calculate_moving_averages function added both short-term and long-term moving averages to the analysis.

def calculate_moving_averages(data, short_window, long_window):
"""
Fetch historical data for a stock and calculate short-term and long-term moving averages.

:param stock_symbol: Stock symbol to fetch data for.
:param start_date: Start date in 'YYYY-MM-DD' format.
:param end_date: End date in 'YYYY-MM-DD' format.
:param short_window: Window for short-term moving average.
:param long_window: Window for long-term moving average.
:return: DataFrame with moving averages added.
"""
start_date, end_date = self.determine_lookback_period()[1:]
# Fetch historical stock data
data = yf.download(self.stock_symbol, start=start_date, end=end_date)

# Calculate moving averages
data['Short_MA'] = data['Close'].rolling(window=short_window).mean()
data['Long_MA'] = data['Close'].rolling(window=long_window).mean()
return data

Recent Highs and Lows

We included a function to capture the most recent peak and trough in the stock price, thereby providing a current view of market extremes.

def recentHighLow(data, lookback_period=60):
"""
Find the most recent high and low prices within a lookback period.

:param data: Pandas DataFrame with stock prices.
:param lookback_period: Number of days to look back.
:return: Tuple of recent high and low prices.
"""
recent_data = data[-lookback_period:]
recent_high = recent_data['Close'].max()
recent_low = recent_data['Close'].min()
return recent_high, recent_low

Trend Analysis for Enhanced Insight

The trend_analysis function was designed to identify major trends in the stock price and calculate Fibonacci levels within these trends.

def trendAnalysis(data):
"""
Identify major trend and calculate Fibonacci retracement levels within the trend.

:param data: Pandas DataFrame with stock prices.
:return: Tuple of trend type ('upward' or 'downward'), high and low prices in the trend.
"""
# Implement logic to identify the trend
# For simplicity, let's assume an upward trend is identified
trend_type = 'upward'
trend_high = data['Close'].max()
trend_low = data['Close'].min()

# Calculate Fibonacci levels within the trend
fib_levels = self.fibonacci_retracement_levels(trend_high, trend_low)
return trend_type, fib_levels

The Culmination: Integrating into a Cohesive Class

The final integration involved combining these functionalities into the FibonacciRetracementLevel class. This class streamlined the entire analysis process, from determining the lookback period to calculating Fibonacci levels based on recent price movements and overall trend analysis.

def main(outlier_method='statistical', n_std=2, threshold=10):
lookback_period = self.determine_lookback_period()
data = yf.download(self.stock_symbol, period=f"{lookback_period}d")

short_window = int(lookback_period / 4)
long_window = int(lookback_period / 2)
data_with_ma = self.calculate_moving_averages(data, short_window, long_window)

if outlier_method == 'statistical':
data_no_outliers = self.exclude_outliers_statistical(data_with_ma, n_std)
elif outlier_method == 'percentage':
data_no_outliers = self.exclude_outliers_percentage(data_with_ma, threshold)

recent_high, recent_low = self.recent_highs_lows(data_no_outliers, long_window)
fib_levels_recent = self.fibonacci_retracement_levels(recent_high, recent_low)

trend_type, fib_levels_trend = self.trend_analysis(data_no_outliers)
return fib_levels_recent, fib_levels_trend

Conclusion

This comprehensive Python tool for calculating Fibonacci retracement levels stands as a testament to the importance of adaptive and detailed analysis in financial markets. By integrating various methodologies — from volatility-based lookback periods to outlier exclusion and trend analysis — this tool provides a nuanced and tailored approach to technical market analysis, empowering traders and analysts with refined, actionable insights.

--

--