Tuesday, February 18, 2025

Lower Enveloping with the Different Interpolation Methods

This introduces finding the lower peaks of a financial time series to interpolate these values across the data points of the lower peaks to generate the lower envelope of this time series. 

There are different interpolation methods introduced here. Piecewise Cubic Hermite Interpolating Polynomial (PCHIP), Natural Cubic Spline Interpolation, and AKIMA Spline Interpolations are the effective tool for the enveloping. The choice will differ depending on the purpose of finding the envelope. 

My Python codes are displayed below:

 

Comparison 



Continuity provided by the derivatives 








# importing necessary tools for math and plot

# For mathematics
import math
import numpy as np

# https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.find_peaks.html
# https://stackoverflow.com/questions/1713335/peak-finding-algorithm-for-python-scipy
from scipy.signal import find_peaks

# Piecewise Cubic Hermite Interpolating Polynomial (PCHIP)
# https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.pchip_interpolate.html
# https://pythonnumericalmethods.studentorg.berkeley.edu/notebooks/chapter17.03-Cubic-Spline-Interpolation.html
from scipy.interpolate import pchip_interpolate

# Cubic Spline Interpolation
# https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.CubicSpline.html
from scipy.interpolate import CubicSpline

# AKIMA Spling Interpolation
# https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.Akima1DInterpolator.html
from scipy.interpolate import Akima1DInterpolator

# Inline animations in Jupyter
# https://stackoverflow.com/questions/43445103/inline-animations-in-jupyter
from matplotlib.animation import FuncAnimation
import matplotlib.animation as animation
import itertools # for joining lists inside a list
from itertools import count

# For graphing
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import pandas as pd
from pandas.tseries.offsets import *
# Setting Plot Size
plt.rcParams["figure.figsize"] = (12,7)


# Calling stock values from Yahoo finance API
# Ref. https://www.kaggle.com/code/alessandrozanette/s-p500-analysis-using-yfinance-data
## Calling API from Yahoo Finance: Uncomment the line "!pip install yfinance" if not done
# !pip install yfinance # Uncomment it to run if not installed yet in a different cell separated from this one.

import yfinance as yf
%config InlineBackend.figure_format='retina'
import warnings
warnings.filterwarnings("ignore")



' ######### Calling Yahoo Finance dataset with API ######### '
def Dataset(Ticker_stock, No_Years_Data):
    # Parameter Adjustment
    # Set Ticker Symbol
    # e.g. Ticker="^GSPC" for S&P 500, Ticker="NDAQ" for NASDAQ, Ticker="TOPX" for TOPIX
    # Ticker="AMZN" for Amazon.com Inc., "AAPL" for Apple Inc., Ticker="NTDOY" for NINTENDO
    Ticker_stock=Ticker_stock # Ticker symbok for a stock
   
    # Set the number of years to download data
    No_Years_Data=No_Years_Data;
   
    # Now, let's retrieve the data of the past x years using yfinance
    Years="".join([str(No_Years_Data),'y']) # Set the number of years ! Adjust
    y_t = yf.Ticker(Ticker_stock).history(period=Years)  # Ticker Symbokl ! Adjust !
   
    # Another way to dl data
    # y_t = yf.download(Ticker_stock, start="2015-01-01", end="2023-12-31")
   
    # Let's take a look at the called data
    #display(y_t.tail())
   
    # Change to list
    # https://stackoverflow.com/questions/39597553/from-datetimeindex-to-list-of-times
    t_j=y_t.index.tolist()
    t_j=[t_j[j].strftime("%Y-%m-%d") for j in range(len(t_j))]
   
    # change from numpy array to list
    y_t=y_t["Close"].tolist()
   
    # # Plotting the data y_t with its date t
    # for k in range(No_Years_Data*4):
    #     Window=int(math.floor(len(t)/No_Years_Data)/4)
    #     St=k*Window; Ed=St+Window; print(St,Ed)
    #     plt.figure(); plt.plot(t[St:Ed],y_t[St:Ed]); plt.xticks(rotation=90); plt.show()
   
    ## Linear Interpolation of data
    # https://stackoverflow.com/questions/2315032/how-do-i-find-missing-dates-in-a-list-of-sorted-dates
    # https://stackoverflow.com/questions/13019719/get-business-days-between-start-and-end-date-using-pandas
    t_raw=t_j.copy()
    t_intpl = pd.date_range(start=t_raw[0], end=t_raw[-1], freq=BDay()) # Interpolating only for business days
    y_raw=y_t.copy()
    y_intpl = np.interp(pd.to_datetime(t_intpl).astype(int), pd.to_datetime(t_raw).astype(int), y_raw)
    t_j=t_intpl.copy(); y_t=y_intpl.copy()
    t_j=t_j.tolist()
    t_j=[t_j[j].strftime("%Y-%m-%d") for j in range(len(t_j))]
    t_j=np.array(t_j)
   
    return t_j, y_t


' ######### Calling dataset to analyse ######### '

# Example of Barrick Gold Corp

# Parameter Adjustment
# Set Ticker Symbol
# e.g. Ticker="^GSPC" for S&P 500, Ticker="NDAQ" for NASDAQ, Ticker="^N225" for Nikkei
# Ticker="AMZN" for Amazon.com Inc., "AAPL" for Apple Inc., Ticker="NTDOY" for NINTENDO
Ticker_stock="GOLD" # Ticker symbok for a stock

# Set the number of years to download data
No_Years_Data=5;

# Output
t_j, y_t = Dataset(Ticker_stock, 2)
N=len(y_t); j=list(range(0,N)) # Generating the index label
y_j=y_t.copy() # Copying the main variable with the different subscript name
plt.figure();plt.plot(t_j, y_t, color='lightsteelblue'); plt.show(block=False)


' ######### Defining the function for displaying animation ######### '
def MoveStepByStep(f_j,Title):
    N_=len(f_j)
    plt.figure()
    plt.rcParams["animation.html"] = "jshtml"
    plt.rcParams['figure.dpi'] = 150  
    plt.ioff()
    fig, ax = plt.subplots()
    count_ = count(); NoFrames=30; StepSize=math.floor(N_/NoFrames);
    plt.figure();
    def animate(a):
        counts=next(count_); Show=counts*StepSize
        ax.cla()
        ax.set_title(Title);
        ax.plot(j[0:Show],f_j[0:Show], label=Title, color='darkseagreen')
        ax.plot(p,f_p, "*", color='Magenta', label="Lower Peaks", markersize=9);
        ax.set_xlim(0,N_)
        ax.set_ylim(min(f_j)*0.9,max(f_j)*1.1)
       
    Animation=animation.FuncAnimation(fig, animate, frames=NoFrames)
    display(Animation)
    # Separating figures
    plt.show(block=False)

' ######### Enveloping the lower peaks with the different interpolation methods ######### '

# Finding the lower peaks
p, _ = find_peaks(-y_j, prominence=1)
t_p=t_j[p]; y_p=y_j[p] # Saving values at the peak points

# Adding the first point
p=np.append(0,p); y_p=np.append(y_j[0],y_p); t_p=np.append(t_j[0],t_p);

plt.figure();
plt.plot(y_j, color='lightsteelblue', label="Original");
plt.plot(p, y_p, "*", color='Magenta', label="Lower Peaks", markersize=9);
plt.legend(loc="best")
plt.show(); plt.show(block=False)



# Adding  the variable name for the lower envelope
f_p=y_p.copy()

f_j_list=[] # Storing the interpolation showcase.
Title_list=[] # Storing the interpolation methods' name

# Defininig function to output the lower envelope
def PlotLowerEnvelope(Title,p,y_j,f_j):
    plt.figure();
    plt.title(Title)
    plt.plot(y_j, color='lightsteelblue', label="Original");
    plt.plot(p, y_p, "*", color='Magenta', label="Lower Peaks", markersize=9);
    plt.plot(f_j, color='darkgreen', label=Title);
    plt.legend(loc="best")
    plt.show(); plt.show(block=False)

# Linear interpolation
f_j_Linear = np.interp(pd.to_datetime(t_j).astype(int), pd.to_datetime(t_p).astype(int), f_p)
Title='Linear Interpolation'
f_j_list.append(f_j_Linear); Title_list.append(Title)
PlotLowerEnvelope(Title,p,y_j,f_j_Linear)
MoveStepByStep(f_j_Linear,Title)

# Piecewise Cubic Hermite Interpolating Polynomial (PCHIP)
f_j_PCHIP = pchip_interpolate(p, f_p,j)
Title='PCHIP'
f_j_list.append(f_j_PCHIP); Title_list.append(Title)
PlotLowerEnvelope(Title,p,y_j,f_j_PCHIP)
MoveStepByStep(f_j_PCHIP,Title)

# Cubic Spline Interpolation
f_j_CSP = CubicSpline(p, f_p, bc_type='natural'); f_j_CSP=f_j_CSP(j)
Title='Cubic Spline'
f_j_list.append(f_j_CSP); Title_list.append(Title)
PlotLowerEnvelope(Title,p,y_j,f_j_CSP)
MoveStepByStep(f_j_CSP,Title)

# Akima Spline Interpolation
f_j_Akima = Akima1DInterpolator(p, f_p)(j)
Title='Akima Spline'
f_j_list.append(f_j_Akima); Title_list.append(Title)
PlotLowerEnvelope(Title,p,y_j,f_j_Akima)
MoveStepByStep(f_j_Akima,Title)

# Comparing these interpolation methods
N_cut=math.floor(N*0.95)
plt.rcParams["figure.figsize"] = (18,9)
plt.figure();
plt.title("Comparing these interpolation methods")
plt.plot(y_j[0:N_cut], color='lightsteelblue', label="Original");
plt.plot(p, y_p[0:N_cut], "*", color='Magenta', label="Lower Peaks", markersize=9);
for k in range(len(f_j_list)):
    plt.plot(f_j_list[k][0:N_cut], "--", label=Title_list[k]);
    plt.legend(loc="best")
plt.show(); plt.show(block=False)

# Showing derivatives of these functions
NoDerivs=2
plt.figure()
fig, axs = plt.subplots(len(f_j_list), NoDerivs+1)
plt.tight_layout()
for k in range(len(f_j_list)):
    f_j=f_j_list[k];d_f_j=f_j;
    for l in range(NoDerivs+1):    
        SubPlotTitle = "".join([Title_list[k]," Diff(",str(l),")"])
        axs[k, l].plot(d_f_j,".",color='darkgreen');
        axs[k, l].set_title(label=SubPlotTitle)
        d_f_j=np.diff(d_f_j)
plt.show(block=False)






Monday, February 17, 2025

A memory of Myonchan (Youmu) with her grandpa Youki Konnpaku and their master Yuyuko Saigyouji in Hakugyokurou - Touhou Project

 


Posted on my pixiv: https://www.pixiv.net/en/artworks/127342629
A memory of Myonchan (Youmu) with her grandpa Youki Konnpaku and their master Yuyuko Saigyouji in Hakugyokurou

 I tried to illustrate Youmu's precious memory with her grandpa before his disappearance. So, I used the faint colouring to depict such a scene in her memory...


 

Sunday, February 09, 2025

Thursday, February 06, 2025

My own standing picture of Eiki Shiki Yamaxanadu for my own Yukkuri kaisetsu!

 


 



Posted on my pixiv: https://www.pixiv.net/en/artworks/126945746 

 I have created the standing picture of Eiki Shiki Yamaxanadu for my own Yukkuri kaisetsu!

 Used in this story movie of my YouTube channel: