Description
Below is a Python code that I created to identify tops and bottoms on price charts of stocks or any financial assets.
I also invented an extra indicator that calculates the angle between the last two tops and the angle between the last two bottoms, imagining that a straight line connects both.
I am using these indicators to operar opções binárias as we say in Brazil.
# Last tops:
# In the case of a window of 3, this value is i-1. In the case of a window of 5, it is i-2. In the case of a window of 7, it is i-3.
df['maximo'] = df['max'].rolling(window=9, center=True).max()
df['top'] = np.where(df['max']==df['maximo'], df['max'], np.nan)
df['top_1'] = np.nan
df['top_2'] = np.nan
df['top_3'] = np.nan
df['top_4'] = np.nan
df['top_5'] = np.nan
df['top_6'] = np.nan
df['top_7'] = np.nan
for i in range(4, df.shape[0]): # considering window = 9
if df['top'][i-4]>0 and df['top_1'][i-1]!=df['top'][i-4]: # ignoring consecutive tops
df['top_1'][i] = df['top'][i-4]
df['top_2'][i] = df['top_1'][i-1]
df['top_3'][i] = df['top_2'][i-1]
df['top_4'][i] = df['top_3'][i-1]
df['top_5'][i] = df['top_4'][i-1]
df['top_6'][i] = df['top_5'][i-1]
df['top_7'][i] = df['top_6'][i-1]
else:
df['top_1'][i] = df['top_1'][i-1]
df['top_2'][i] = df['top_2'][i-1]
df['top_3'][i] = df['top_3'][i-1]
df['top_4'][i] = df['top_4'][i-1]
df['top_5'][i] = df['top_5'][i-1]
df['top_6'][i] = df['top_6'][i-1]
df['top_7'][i] = df['top_7'][i-1]
# Last bottoms:
df['minimo'] = df['min'].rolling(window=9, center=True).min()
df['bottom'] = np.where(df['min']==df['minimo'], df['min'], np.nan)
df['bottom_1'] = np.nan
df['bottom_2'] = np.nan
df['bottom_3'] = np.nan
df['bottom_4'] = np.nan
df['bottom_5'] = np.nan
df['bottom_6'] = np.nan
df['bottom_7'] = np.nan
for i in range(4, df.shape[0]):
if df['bottom'][i-4]>0 and df['bottom_1'][i-1]!=df['bottom'][i-4]:
df['bottom_1'][i] = df['bottom'][i-4]
df['bottom_2'][i] = df['bottom_1'][i-1]
df['bottom_3'][i] = df['bottom_2'][i-1]
df['bottom_4'][i] = df['bottom_3'][i-1]
df['bottom_5'][i] = df['bottom_4'][i-1]
df['bottom_6'][i] = df['bottom_5'][i-1]
df['bottom_7'][i] = df['bottom_6'][i-1]
else:
df['bottom_1'][i] = df['bottom_1'][i-1]
df['bottom_2'][i] = df['bottom_2'][i-1]
df['bottom_3'][i] = df['bottom_3'][i-1]
df['bottom_4'][i] = df['bottom_4'][i-1]
df['bottom_5'][i] = df['bottom_5'][i-1]
df['bottom_6'][i] = df['bottom_6'][i-1]
df['bottom_7'][i] = df['bottom_7'][i-1]
# Counting the nº of candles before a new top:
df['count_tops'] = df.groupby((df['top_1'] != df['top_1'].shift(1)).cumsum()).cumcount()+1
df['AP1'] = np.nan # Angle between top_1 and top_2
df['AP2'] = np.nan
df['AP3'] = np.nan
df['AP4'] = np.nan
df['AP5'] = np.nan
df['AP6'] = np.nan
for i in range(4, df.shape[0]):
if df['top_2'][i] != df['top_2'][i-1]: # when top_2 is updated
df['AP1'][i] = (df['top_1'][i] - df['top_2'][i])/df['count_tops'][i-1] # find the angle between top_1 and top_2
df['AP2'][i] = df['AP1'][i-1] # do the same for the others
df['AP3'][i] = df['AP2'][i-1]
df['AP4'][i] = df['AP3'][i-1]
df['AP5'][i] = df['AP4'][i-1]
df['AP6'][i] = df['AP5'][i-1]
else:
df['AP1'][i] = df['AP1'][i-1]
df['AP2'][i] = df['AP2'][i-1]
df['AP3'][i] = df['AP3'][i-1]
df['AP4'][i] = df['AP4'][i-1]
df['AP5'][i] = df['AP5'][i-1]
df['AP6'][i] = df['AP6'][i-1]
# Same for bottoms:
df['count_bottoms'] = df.groupby((df['bottom_1'] != df['bottom_1'].shift(1)).cumsum()).cumcount()+1
df['AF1'] = np.nan
df['AF2'] = np.nan
df['AF3'] = np.nan
df['AF4'] = np.nan
df['AF5'] = np.nan
df['AF6'] = np.nan
for i in range(4, df.shape[0]):
if df['bottom_2'][i] != df['bottom_2'][i-1]:
df['AF1'][i] = (df['bottom_1'][i] - df['bottom_2'][i])/df['count_bottoms'][i-1]
df['AF2'][i] = df['AF1'][i-1]
df['AF3'][i] = df['AF2'][i-1]
df['AF4'][i] = df['AF3'][i-1]
df['AF5'][i] = df['AF4'][i-1]
df['AF6'][i] = df['AF5'][i-1]
else:
df['AF1'][i] = df['AF1'][i-1]
df['AF2'][i] = df['AF2'][i-1]
df['AF3'][i] = df['AF3'][i-1]
df['AF4'][i] = df['AF4'][i-1]
df['AF5'][i] = df['AF5'][i-1]
df['AF6'][i] = df['AF6'][i-1]
More concepts can be found here.
// -------------------------------------------------------------------------------------------------
//
// This code is a cTrader Automate API example.
//
// All changes to this file might be lost on the next application update.
// If you are going to modify this file please make a copy using the "Duplicate" command.
//
// -------------------------------------------------------------------------------------------------
using System;
using cAlgo.API;
namespace cAlgo
{
[Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AutoRescale = false, AccessRights = AccessRights.None)]
public class SamplePriceChannels : Indicator
{
[Parameter(DefaultValue = 20)]
public int Periods { get; set; }
[Output("Upper", LineColor = "Pink")]
public IndicatorDataSeries Upper { get; set; }
[Output("Lower", LineColor = "Pink")]
public IndicatorDataSeries Lower { get; set; }
[Output("Center", LineColor = "Pink")]
public IndicatorDataSeries Center { get; set; }
public override void Calculate(int index)
{
double upper = double.MinValue;
double lower = double.MaxValue;
for (int i = index - Periods; i <= index - 1; i++)
{
upper = Math.Max(Bars.HighPrices[i], upper);
lower = Math.Min(Bars.LowPrices[i], lower);
}
Upper[index] = upper;
Lower[index] = lower;
Center[index] = (upper + lower) / 2;
}
}
}
dorivaltsu
Joined on 04.07.2022
- Distribution: Free
- Language: C#
- Trading platform: cTrader Automate
- File name: Sample Price Channels.algo
- Rating: 2.5
- Installs: 2178
- Modified: 04/07/2022 20:24
int barSpan = 10;
Bars.HighPrices.Maximum(barSpan);
Bars.LowPrices.Minimum(barSpan);
will also do the job, no need to reinvent the wheel