168 lines
6.0 KiB
C#
168 lines
6.0 KiB
C#
using BinanceExchange.API.Models.Response;
|
|
|
|
public static class Indicators
|
|
{
|
|
|
|
public static decimal getSMA(List<KlineCandleStickResponse> 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<decimal> 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<KlineCandleStickResponse> 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<decimal> 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<KlineCandleStickResponse> responses, int shortPeriod, int longPeriod, int curIndex)
|
|
{
|
|
return getEMA(responses, curIndex, curIndex, shortPeriod) - getEMA(responses, curIndex, curIndex, longPeriod);
|
|
}
|
|
|
|
public static decimal getATR(List<KlineCandleStickResponse> responses, int period, int curIndex, List<decimal> 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<KlineCandleStickResponse> 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));
|
|
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<KlineCandleStickResponse> 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;
|
|
}
|
|
} |