Closed rocketpoweryul closed 5 months ago
The main issue seems to be that the peak at about 75$ is not being detected as a peak, only a swing high.
The alternative is to detect these excursions and disqualify the consolidation, however this does not solve the issue that this undetected peak could have been a new candidate for the left side of the consolidation.
The main logic at fault appears in filter_peaks function in the TATools module.
Detection of positive peaks is coded as such:
for i in range( 1, len(swing_highs) - 1 ):
prev_swing_high_price = df.loc[swing_highs[i-1], 'High']
curr_swing_high_price = df.loc[swing_highs[i ], 'High']
next_swing_high_price = df.loc[swing_highs[i+1], 'High']
# detect positive peak
if ( curr_swing_high_price > prev_swing_high_price ) and ( curr_swing_high_price > next_swing_high_price ):
df.loc[swing_highs[i], 'Peak'] = 1
The undetected peak remains so because the next peak is higher. However it's quite clear it is a peak, and the information that can help us here is that the next swing low is lower than the previous swing high, which indicates a significant change in price direction, which is exactly what peak detection is for.
Note any mitigation likely needs to be inversely applied to detecting negative peaks.
# loop through swing highs, starting at the second occurrence and ending at 2nd last occurrence given the rules
for i in range( 1, len(swing_highs) - 1 ):
prev_swing_high_price = df.loc[swing_highs[i-1], 'High']
curr_swing_high_price = df.loc[swing_highs[i ], 'High']
next_swing_high_price = df.loc[swing_highs[i+1], 'High']
next_swing_low_price = df.loc[swing_lows[i+1], 'Low']
# detect positive peak
if ( curr_swing_high_price > prev_swing_high_price ) and \
( curr_swing_high_price > next_swing_high_price or prev_swing_high_price > next_swing_low_price):
df.loc[swing_highs[i], 'Peak'] = 1
This code now checks that the next swing low undercuts the previous swing high.
Conversely, for troughs, or negative peaks, let's imagine the opposite scenario:
Red arrows are peaks, hollow are swings.
The associated code is:
# loop through swing lows, starting at the second occurrence and ending at 2nd last occurrence given the rules
for i in range( 1, len(swing_lows) - 1 ):
prev_swing_low_price = df.loc[swing_lows[i-1], 'Low' ]
curr_swing_low_price = df.loc[swing_lows[i ], 'Low' ]
next_swing_low_price = df.loc[swing_lows[i+1], 'Low' ]
# detect negative peak
if ( curr_swing_low_price < prev_swing_low_price ) and ( curr_swing_low_price < next_swing_low_price ):
df.loc[swing_lows[i], 'Peak'] = -1
Corrected similarly to:
# loop through swing lows, starting at the second occurrence and ending at 2nd last occurrence given the rules
for i in range( 1, len(swing_lows) - 1 ):
prev_swing_low_price = df.loc[swing_lows[i-1], 'Low' ]
curr_swing_low_price = df.loc[swing_lows[i ], 'Low' ]
next_swing_low_price = df.loc[swing_lows[i+1], 'Low' ]
next_swing_high_price = df.loc[swing_highs[i+1], 'High']
# detect negative peak
if ( curr_swing_low_price < prev_swing_low_price ) and \
( curr_swing_low_price < next_swing_low_price or prev_swing_low_price < next_swing_high_price):
df.loc[swing_lows[i], 'Peak'] = -1
Solution works. Not exhaustively tested, though.
Issue
Consolidation detection doesn't detect previous breakout.
Description
See image below. Detection logic doesn't see the excursion out of the base. This could be because no peaks occur during that excursion.
Root Cause
Detection logic isn't robust to excursions above a consolidation that do not create a peak, perhaps. This is still TBC.
Corrective Action
See future comments