I am developing a stock analysis program in Python
One of the fundamental things I need to is to recognise swings from price feed (open, high, low, close data)
Price data is fractal by nature - smaller structures are found within larger structures.
In my case I am looking for small swings within large swings. I.e. minor swings within major swings. The above example chart depicts my goal.
A few definitions to get out of the way. Each swing is made of two legs / parts - impulse leg and reaction leg
Impulse leg will be in the direction of flow of the the market
Reaction leg is against the direction of the impulse
Both impulse and reaction legs can be either up or down depending on the flow of the market Below models illustrate this definition. If there is no direction in the price, its known to be a ranging market
The next important definition is the understanding of highs and low. A new high confirms a new low while a new low confirms a new high This is illustrated by the below model
The below is how I have approached the matter in Python
import numpy as np
from scipy.signal import argrelextrema
def get_pivots(price: np.ndarray):
maxima = argrelextrema(price, np.greater)
minima = argrelextrema(price, np.less)
return np.concatenate((price[maxima], price[minima]))
For simplicity I will be passing a flattened 1d numpy
array into the above function. argrelextrema
helps be identify where pivots are. I.e. identfies where the price turns.
I am wondering how I could find the nesting of pivots to form minor and major swings.
I am looking to produce a list that loosely resembles this structure.
[major swing
[minor swing1],
[minor swing2],
[minor swing3
[micro swing1],
[micro swing2]
]
]
Sample data I have created is
data = [5,6,7,8,9,10,11,12,13,14,16,17,18,19,20, # AB(Major) impulse
19,18,17,16,15,14,13,12,11,10,9,8, # BC(Major) reaction
9,10,11,12,13, 14,15, # C0C1 (Minor) impulse
14,13,12,11,10, # C1C2 (Minor) reaction
11, 12, 13, 14, 15, 16, 17, 18, # C2C3 (Minor) impulse
17, 16, 15, 15, 14, 13, 12, # C3C4 (Minor) reaction
13, 14, 15, 16, 17, 18, 19, 20, 21, # C4C5 (Minor) impulse
20, 19, 18, 17, 16, 15, 14, # C5C6 (Minor) reaction
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 # CD (Major) impulse
]
I believe some kind of recursive implementation is likely to help. I am not entirely familiar with implementation using this paradigm