using BinanceExchange.API.Models.Response; public static class Indicators { public static decimal getSMA(List responses, int curIndex, int interval, int startIndex = 0) { // curIndex = Math.Clamp(curIndex,0, responses.Count); // decimal total = 0; // for(int i=curIndex-interval; i < curIndex; i++){ // total += responses[i].Close; // } // // decimal length = (curIndex-startIndex); if(length <= 0){length=1;} // // decimal N = (length / (decimal)interval); // Console.WriteLine($"SMA Cacl ({interval}) : {total}/{interval} = {total/interval}"); // return total / interval; decimal total = 0; for (int x = (curIndex > 1500) ? 1500 : 0; x < interval; x++) { total += (curIndex - x >= 0) ? responses[curIndex - x].Close : (decimal)0; } return total / (decimal)interval; } public static decimal getSMA(List responses, int curIndex, int interval, int startIndex = 0) { decimal total = 0; for (int x = (curIndex > 1500) ? 1500 : 0; x < interval; x++) { total += (curIndex - x >= 0) ? responses[curIndex - x] : (decimal)0; } return total / (decimal)interval; } public static decimal getEMA(List responses, int curIndex, int startIndex, int periods, decimal? prevEma = null) { if (curIndex < 1) { return 0; } if (startIndex - curIndex > 1500) { return 0; }; if (curIndex >= responses.Count) { return 0; }; // decimal N = (decimal)curIndex / (decimal)periods; decimal multiplier = (decimal)2 / ((decimal)(periods + 1)); decimal firstHalf = responses[curIndex].Close * multiplier; //First half of the equation decimal secondHalf = getEMA(responses, curIndex - 1, startIndex, periods) * (1 - multiplier); //Second half of the equation // decimal secondHalf = (prevEma ?? getSMA(responses, curIndex-1, periods)) * (1- multiplier); //Second half of the equation return firstHalf + secondHalf; } public static decimal getEMA(List responses, int curIndex, int startIndex, int periods) { if (curIndex < 1) { return 0; } if (startIndex - curIndex > 1500) { return 0; }; if (curIndex >= responses.Count) { return 0; }; // decimal N = (decimal)curIndex / (decimal)periods; decimal multiplier = (decimal)2 / ((decimal)(periods + 1)); decimal firstHalf = responses[curIndex] * multiplier; //First half of the equation decimal secondHalf = getEMA(responses, curIndex - 1, startIndex, periods) * (1 - multiplier); //Second half of the equation // decimal secondHalf = (prevEma ?? getSMA(responses, curIndex-1, periods)) * (1- multiplier); //Second half of the equation return firstHalf + secondHalf; } public static decimal getMACD(List responses, int shortPeriod, int longPeriod, int curIndex) { return getEMA(responses, curIndex, curIndex, shortPeriod) - getEMA(responses, curIndex, curIndex, longPeriod); } public static decimal getATR(List responses, int period, int curIndex, List prevATRs) { if (curIndex <= 0 || curIndex > responses.Count) { return 0; } if (curIndex >= responses.Count) { return 0; }; decimal TR = responses[curIndex].High - responses[curIndex].Low; if (curIndex > 1) { decimal tr2 = responses[curIndex].High - responses[curIndex - 1].Close; decimal tr3 = responses[curIndex].Low - responses[curIndex - 1].Close; if (tr2 > TR) { TR = tr2; } if (tr3 > TR) { TR = tr3; } } if (curIndex < period) { //get just the TR return TR; } decimal prevATR = 0; if (prevATRs.Count > 0) { // int start = curIndex - period; // for (int i = start; i < curIndex; i++) // { // prevATR += prevATRs[i]; // } // prevATR = (prevATR) / (decimal)(curIndex-start); prevATR = prevATRs[curIndex - 1]; } decimal ATR = (decimal)((prevATR * (decimal)(period - 1)) + TR) / (decimal)period; return ATR; } public static decimal getRSI(List responses, int index, int period = 14){ decimal avgGain = 0; decimal avgLoss =0; if(index < 2){return 0;} int length = 0; for(int i=index; i > index - period && i > 0; i--){ length++; avgGain += responses[i].Close - responses[i-1].Close; avgLoss += responses[i-1].Close - responses[i].Close; } if(length <=0){return 0;} avgGain /= length; avgLoss /= length; decimal f =(1.0m+(avgGain/(avgLoss==0 ? 1: avgLoss))); //Avoiding dividing by 0 if(f<=0){return 0;} return 100.0m - (100.0m/f); } public static bool didMACDLineCrossSignalLine(decimal[] MACDs, decimal[] Signals, int index, int period = 7, decimal threshold = (decimal)0.1) { int counter = 0; if (index >= MACDs.Length || index >= Signals.Length) { return false; } if (index - period < 0) { return false; }; for (int i = index; i > index - period; i--) { if (MACDs[i] < Signals[i]) { counter++; } } bool wasMACDUnder = counter > ((float)period / 2f); return wasMACDUnder && MACDs[index] > Signals[index]; } public static decimal getAvgDiff(List responses, int i) { decimal avgDiff = 0; if (i > 10) { for (int k = 1; k < 6; k++) { avgDiff += responses[i - k].Close; } avgDiff = avgDiff / (decimal)5; avgDiff = responses[i].Close - avgDiff; } return avgDiff; } }