Finding Tops and Bottons on stock prices free

by dorivaltsu in category Trend at 04/07/2022
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.

price tops and bottoms with angle

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.

Notification Publishing copyrighted material is strictly prohibited. If you believe there is copyrighted material in this section you may use the Copyright Infringement Notification form to submit a claim.
Formula / Source Code
Language: C#
Trading Platform: cAlgocTrader
// -------------------------------------------------------------------------------------------------
//
//    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;
        }
    }
}
Comments

porterduncan6704225 - July 19, 2022 @ 05:38

Enjoy drift hunters as an activity to retrain your head on one subject that demands focus and shouldn't be disregarded. It offers a wealth of knowledge and is unquestionably the result of your work.

nobit2021 - July 21, 2022 @ 06:28

I find a lot of interesting information whenever I visit your website, which I do frequently. Not only are there some wonderful articles, but also some wonderful comments. I am grateful to you, and I hope that you will spread the word about my page. foodle

gmkenneyy - July 31, 2022 @ 22:50

int barSpan = 10;

Bars.HighPrices.Maximum(barSpan);

Bars.LowPrices.Minimum(barSpan);

will also do the job, no need to reinvent the wheel

lenkalee266 - August 24, 2022 @ 13:01

Thank you for producing such a fascinating essay on this subject. This has sparked a lot of thought in me, and I'm looking forward to reading more. Nerdle game 

junealexis001 - September 12, 2022 @ 12:06

Great site i love it keep posting more!   https://fencingsantafe.com

Johnklein - November 20, 2022 @ 20:12

Wybrałem Vulkan Bet bonus bez depozytu (vulkanbet-pl.com/darmowe-spiny-bez-dozytu/) dla najlepszych slotów. Wydaje się, że jest w stanie często wygrywać. I można grać w tym klubie gry może nie tylko dla zabawy, ale także do zarabiania pieniędzy. Wszyscy znajomi są już uzależnieni od hazardu. Polecam im przyjazd do nas!

0