DaveSkender / Stock.Indicators

Stock Indicators for .NET is a C# NuGet package that transforms raw equity, commodity, forex, or cryptocurrency financial market price quotes into technical indicators and trading insights. You'll need this essential data in the investment tools that you're building for algorithmic trading, technical analysis, machine learning, or visual charting.
https://dotnet.StockIndicators.dev
Apache License 2.0
975 stars 246 forks source link

Average Daily Range (ADR) #1250

Open bobtabor opened 1 month ago

bobtabor commented 1 month ago

the problem

The library contains ATR (Average True Range). The ADR (Average Daily Range) has been popularized recently by popular trader Qullamaggie (Kristjan Kullamägi ... https://qullamaggie.com/). The formula and intent is slightly different -- ATR captures movement with pre-market gaps, but ADR captures intraday only and is used by swing traders (and maybe day traders) to decide if there's enough movement in the stock to warrant taking a position.

See: https://www.alpharithms.com/average-daily-range-adr-090415/

I was able to ask ChatGPT for an implementation, but I have no confidence in the algorithm.

an idea

No response

code example

public static decimal CalculateDailyRangePercentage(Daily day)
        {
            return ((day.High - day.Low) / day.Close) * 100;
        }

        public static decimal CalculateAverageDailyRangePercentage(List<Daily> data, int period = 20)
        {
            List<decimal> dailyRangePercentages = new List<decimal>();

            if (data.Count < period) return 0M;

            for (int i = data.Count - period; i < data.Count; i++)
            {
                decimal dailyRangePercentage = CalculateDailyRangePercentage(data[i]);
                dailyRangePercentages.Add(dailyRangePercentage);
            }

            return dailyRangePercentages.Average();
        }
DaveSkender commented 1 month ago

:heart: Thanks for the recommendation! This does look similar in nature to True Range and Average True Range.

From your link, average daily range is an SMA of High - Low for each candle.

I'll take a closer look later for adding to the library. For now, this can be done with a fairly simple implementation:

IEnumerable<SmaResult> adr = quotes
  .Select(x => new BasicData()
   {
     Date = x.Date,
     Value = (double)(x.High - x.Low)  // dr
   })
  .GetSma(lookbackPeriods);

The normalization to a percentage that you're showing with /Close makes sense too as an extra returned property; though, I'd probably do the percentage as ADR/close (not shown) instead of avg(DR/close) (below).

IEnumerable<SmaResult> adrp = quotes
  .Select(x => new BasicData()
   {
     Date = x.Date,
     Value = (double)(x.High - x.Low)/x.Close
   })
  .GetSma(lookbackPeriods);