I have a working script that shows a volume profile for a stock with the dates on the bottom and price on the y-axis.
It works great for daily data but when i try to change the time to 5 minutes or 1 hour for instance, rather than showing a separate volume profile bar for each hour, all of the bars are crammed together for each day.
So an hourly chart over 20 days, for instance, will have 20 dates with 8 bars crammed into each date rather than 20 days with 8 separate bars.
How can i fix this?
import yfinance as yf
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
def calculate_volume_profile(data, price_levels):
volume_profile = np.zeros_like(price_levels)
for idx in range(len(price_levels)):
volume_profile[idx] = data.loc[(data['Low'] <= price_levels[idx]) & (data['High'] > price_levels[idx]), 'Volume'].sum()
return volume_profile
def plot_stock_data_with_volume_profile(symbol, data, price_levels, volume_profile):
# Plotting the stock data and volume profile
fig, ax1 = plt.subplots(figsize=(12, 8))
# Plotting the stock prices as a line plot
ax1.plot(data.index, data['Close'], color='blue', label='Price')
ax1.set_xlabel('Date')
ax1.set_ylabel('Price', color='blue')
ax1.tick_params(axis='y', labelcolor='blue')
# Adding volume profile as a bar chart
ax2 = ax1.twinx()
ax2.bar(data.index, volume_profile, width=0.5, color='gray', alpha=0.6, label='Volume Profile')
ax2.set_ylabel('Volume', color='gray')
ax2.tick_params(axis='y', labelcolor='gray')
# Adding labels, title, and legend
ax1.set_title(f'Stock Data with Volume Profile for {symbol}')
ax1.legend(loc='upper left')
ax2.legend(loc='upper right')
plt.tight_layout()
plt.show()
def main():
# Define the ticker symbol
tickerSymbol = 'nflx'
# Get data on this ticker
tickerData = yf.Ticker(tickerSymbol)
# Get the historical prices for this ticker
tickerDf = tickerData.history(start="2023-10-01", end="2023-10-08", interval='60m')
# Calculate price levels for volume profile (using close prices)
price_levels = np.linspace(tickerDf['Low'].min(), tickerDf['High'].max(), len(tickerDf)) # Adjust interval as needed
# Calculate volume profile
volume_profile = calculate_volume_profile(tickerDf, price_levels)
# Plot stock data with volume profile
plot_stock_data_with_volume_profile(tickerSymbol, tickerDf, price_levels, volume_profile)
if __name__ == "__main__":
main()