Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how to show more area at the far right side of the Ichimoku Cloud Chart #691

Open
soshk opened this issue Mar 5, 2025 · 1 comment
Open
Labels
question Further information is requested

Comments

@soshk
Copy link

soshk commented Mar 5, 2025

Greeting!
I am a newbie in Python, and I greatly appreciate this brilliantly made built-in package for visualization of yfinance data.
I am learning and trying to plot the Ichimoku Cloud Chart, and found that the plot displayed would show with the x-axis limited at the latest data date, while the Ichimoku indicator actually would plot the cloud area 26days into future.

I tried to extend the x-axis using the xlim() function to extend 1 month into future, but the cloud still is not shown in the plot.

I have checked and make sure that in my calculations, the shift() function is applied to the calculation of the 3 lines, Leading Span A, Leading Span B, and Lagging Span. Thus I believe that there would be data to be plotted for the future date.

The first chart below is the plot generated from my broken code.
And the lower chart is a chart I got from a free online platform. I target to make my plot look more or less like this.
May I get help on how I can correctly plot the cloud for the Ichimoku chart?

Thanks in advance.

This is the chart plotted from my broken python code
Image

This is the chart I got from a free online platform. I target to make my plot look more or less like this.
Image

@soshk soshk added the question Further information is requested label Mar 5, 2025
@soshk
Copy link
Author

soshk commented Mar 5, 2025

in case it is necessart, this is my broken code

# This allows multiple outputs from a single jupyter notebook cell:
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"

import yfinance as yf
import pandas as pd
import mplfinance as mpf
import numpy as np
import datetime as dt
from datetime import timedelta, date

# for fixing 
# Error: Cannot compare tz-naive and tz-aware datetime-like objects
import pytz
from dateutil.relativedelta import relativedelta

# Print mplfinance version for debugging
#print(f"mplfinance version: {mpf.__version__}")

def get_stock_data(stock_symbol, start, end):
    # Fetch stock data
    security = yf.Ticker(stock_symbol)
    stock = security.history(interval='1d', start=start_date, end=end_date)
    #stock = yf.download(stock_symbol, start=start_date, end=end_date)
        
    if stock.empty:
        raise ValueError(f"No data retrieved for symbol '{stock_symbol}' between {start_date} and {end_date}")
    
    # Calculate Ichimoku components, default parameters = 9, 26, 52
    # Tenkan-sen (Conversion Line): (9-period high + 9-period low)/2
    high_9 = stock['High'].rolling(window=9).max()
    low_9 = stock['Low'].rolling(window=9).min()
    stock['Tenkan_sen'] = (high_9 + low_9) / 2
    
    # Kijun-sen (Base Line): (26-period high + 26-period low)/2
    high_26 = stock['High'].rolling(window=26).max()
    low_26 = stock['Low'].rolling(window=26).min()
    stock['Kijun_sen'] = (high_26 + low_26) / 2
    
    # Senkou Span A (Leading Span A): (Conversion Line + Base Line)/2 shifted 26 periods forward
    stock['Senkou_Span_A'] = ((stock['Tenkan_sen'] + stock['Kijun_sen']) / 2).shift(26)
    
    # Senkou Span B (Leading Span B): (52-period high + 52-period low)/2 shifted 26 periods forward
    high_52 = stock['High'].rolling(window=52).max()
    low_52 = stock['Low'].rolling(window=52).min()
    stock['Senkou_Span_B'] = ((high_52 + low_52) / 2).shift(26)
    
    # Chikou Span (Lagging Span): Close price shifted 26 periods back
    stock['Chikou_Span'] = stock['Close'].shift(-26)
    
    # Calculate MACD, default parameter = 12, 26, 9
    stock['EMA_12'] = stock['Close'].ewm(span=12, adjust=False).mean()
    stock['EMA_26'] = stock['Close'].ewm(span=26, adjust=False).mean()
    stock['MACD'] = stock['EMA_12'] - stock['EMA_26']
    stock['Signal_Line'] = stock['MACD'].ewm(span=9, adjust=False).mean()
    stock['MACD_Hist'] = stock['MACD'] - stock['Signal_Line']
    
    # Calculate RSI, default 14days RSI vs 5days SMA
    delta = stock['Close'].diff()
    gain = (delta.where(delta > 0, 0)).rolling(window=14).mean()
    loss = (-delta.where(delta < 0, 0)).rolling(window=14).mean()
    rs = gain / loss
    stock['RSI'] = 100 - (100 / (1 + rs))
    
    
    return stock

def plot_ichimoku_with_indicators(stock_symbol, data):
    # Prepare the data for mplfinance (OHLC format)
    ohlc_data = data[['Open', 'High', 'Low', 'Close', 'Volume']].copy()
    
    # Debugging
    print("ohlc_data head:\n", ohlc_data.head())
    print("ohlc_data columns:", ohlc_data.columns.tolist())
    print("Volume NaN count in ohlc_data:", ohlc_data['Volume'].isna().sum())
    
    # Define additional plots for Ichimoku lines
    ichimoku_lines = [
        mpf.make_addplot(data['Tenkan_sen'], color='red', label='Tenkan-sen'),
        mpf.make_addplot(data['Kijun_sen'], color='blue', label='Kijun-sen'),
        mpf.make_addplot(data['Senkou_Span_A'], color='yellow', label='Senkou_Span_A'),
        mpf.make_addplot(data['Senkou_Span_B'], color='purple', label='Senkou_Span_B'),        
        mpf.make_addplot(data['Chikou_Span'], color='black', label='Chikou Span'),        
    ]
    
    # Define the fill_between Senkou_Span_A and Senkou_Span_B for the cloud directly in the plot call
    cloud_fill = [dict(y1=data['Senkou_Span_A'].values, y2=data['Senkou_Span_B'].values, where=data['Senkou_Span_A'] >= data['Senkou_Span_B'], alpha=0.3, color='green'),
                    dict(y1=data['Senkou_Span_A'].values, y2=data['Senkou_Span_B'].values, where=data['Senkou_Span_A'] < data['Senkou_Span_B'], alpha=0.3, color='red')]
    
    # Volume = True in mpf.plot(), being panel = 1
    
    # Define MACD panel
    macd_plots = [
        mpf.make_addplot(data['MACD'], color='blue', label='MACD', ylabel='MACD', y_on_right=False, panel=2, title="MACD"),
        mpf.make_addplot(data['Signal_Line'], color='orange', label='Signal Line', panel=2),
        mpf.make_addplot(data['MACD_Hist'], type='bar', color='gray', alpha=0.5, label='Histogram', panel=2),
        mpf.make_addplot(pd.Series(0, index=data.index), color='black', linestyle='--', panel=2, width=0.5)
    ]
    
    # Define RSI panel
    rsi_plots = [
        mpf.make_addplot(data['RSI'], color='blue', label='RSI', ylabel='RSI', y_on_right=False, panel=3, title="RSI"),
        mpf.make_addplot(pd.Series(70, index=data.index), color='red', linestyle='--', panel=3, width=0.5),
        mpf.make_addplot(pd.Series(30, index=data.index), color='green', linestyle='--', panel=3, width=0.5)
    ]

    all_plots = ichimoku_lines + macd_plots + rsi_plots
        
    # Plot using mplfinance
    mpf.plot(ohlc_data,
             type='hollow_candle',  # Use candlestick chart, hollow
             style='yahoo',  # Yahoo-style coloring
             title=f'Ichimoku Cloud Chart - {stock_symbol}',
             addplot=all_plots,
             volume=True,   # panel = 1
             panel_ratios=(3, 1, 1, 1),  # Adjust panel sizes
             fill_between=cloud_fill, # Add cloud fill for Ichimoku
             ylabel='Price',
             ylabel_lower='Volume',
             #y_on_right=False,
             xlim=(start_date, xlim_end),
             figscale=1.5,
             tight_layout=True,
    )

# Example usage
if __name__ == "__main__":
    #Set parameters
    #ask suer for stock symbol
    stock_symbol = input("Please enter the stock symbol: ")
    start_date = dt.datetime(date.today().year - 1, date.today().month, date.today().day, tzinfo=pytz.UTC)
    end_date = dt.datetime(date.today().year, date.today().month, date.today().day, tzinfo=pytz.UTC)
    xlim_end = dt.datetime.today().replace(tzinfo=pytz.UTC) + relativedelta(months=1)

    # Get data and plot
    try:
        ichimoku_data = get_stock_data(stock_symbol, start_date, end_date)
        if ichimoku_data.empty:
            raise ValueError("No data returned for the specified stock symbol.")
        plot_ichimoku_with_indicators(stock_symbol, ichimoku_data)
    except Exception as e:
        print(f"Error: {str(e)}")

# Requirements:
# pip install yfinance pandas mplfinance numpy #

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

1 participant