From 653257933813f2d470148fe92ffdad712fea25cd Mon Sep 17 00:00:00 2001 From: Sewmina Date: Sun, 12 Jan 2025 18:21:35 +0530 Subject: [PATCH] Remove ST, TGOR. Add TWS --- CoinWatch.cs | 16 ++++++++----- CoinsList.cs | 1 - Extensions.cs | 18 ++++++++++++++ Messenger.cs | 4 +++- Patterns.cs | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++ Picasso.cs | 53 ++++++++++++++++++++++++++++++++--------- TAReport.cs | 15 +++++++----- Utils.cs | 2 ++ 8 files changed, 149 insertions(+), 25 deletions(-) create mode 100644 Extensions.cs diff --git a/CoinWatch.cs b/CoinWatch.cs index 273a168..dba9654 100644 --- a/CoinWatch.cs +++ b/CoinWatch.cs @@ -65,7 +65,7 @@ namespace SignalsTest req.Interval = interval; req.Symbol = pair; req.EndTime = DateTime.Now; - req.Limit = 100; + req.Limit = 150; candles = await Brian.Client.GetKlinesCandlesticks(req); Console.WriteLine($"Done gettings Kandles for {req.Symbol}, {candles.Count} kandles retreived"); @@ -113,11 +113,15 @@ namespace SignalsTest } string triggers = ""; - if(isStSwitch){ - triggers += "Switched SuperTrend\n"; - } - if(reports[reports.Count-1].TGOR && !reports[reports.Count-2].TGOR){//Ignore if two in row - triggers += "Price dropped\n"; + // if(isStSwitch){ + // triggers += "Switched SuperTrend\n"; + // } + // if(reports[reports.Count-1].TGOR && !reports[reports.Count-2].TGOR){//Ignore if two in row + // triggers += "Price dropped\n"; + // } + + if(reports[reports.Count-1].TWS > 0){ + triggers += $"Three White Soldiers appeared"; } if(triggers!= ""){ diff --git a/CoinsList.cs b/CoinsList.cs index 013dc87..93e812d 100644 --- a/CoinsList.cs +++ b/CoinsList.cs @@ -12,7 +12,6 @@ public static class CoinsList{ "MOVEUSDT", "DOGEUSDT", "PEPEUSDT", - "RLCUSDT", "ACTUSDT", "STGUSDT", "ONEUSDT", diff --git a/Extensions.cs b/Extensions.cs new file mode 100644 index 0000000..025b5b4 --- /dev/null +++ b/Extensions.cs @@ -0,0 +1,18 @@ +using BinanceExchange.API.Models.Response; + +public static class Extensions{ + public static bool isGreen(this KlineCandleStickResponse candle){ + return candle.Close > candle.Open; + } + + public static float getShadowRatio(this KlineCandleStickResponse candle){ + decimal shadowLen = candle.High-candle.Low; + decimal candleLen = Math.Abs(candle.Open-candle.Close); + + return (float)(candleLen/(shadowLen==0 ? 1 :shadowLen)); + } + + public static float getCandleLength(this KlineCandleStickResponse candle){ + return (float)Math.Abs(candle.Open-candle.Close); + } +} \ No newline at end of file diff --git a/Messenger.cs b/Messenger.cs index e577aed..8574c7f 100644 --- a/Messenger.cs +++ b/Messenger.cs @@ -32,7 +32,8 @@ namespace SignalsTest string _chatId = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? chatId_test : chatId; while(true){ - await Task.Delay(3500); + await Task.Delay(1500); + if(messagesSchedule.Count <=0){ continue; } @@ -54,6 +55,7 @@ namespace SignalsTest Console.WriteLine($"Error occured while sending {message} to {filename}"); Console.WriteLine(e.ToString()); } + await Task.Delay(1500); } } diff --git a/Patterns.cs b/Patterns.cs index 793e987..4c8d94b 100644 --- a/Patterns.cs +++ b/Patterns.cs @@ -48,4 +48,69 @@ public static class Patterns{ return false; } + + public static int GetThreeWhiteSoldiers(List responses, int curIndex){ + if(curIndex < 10){ + return 0; + } + + KlineCandleStickResponse candle1 = responses[curIndex]; + KlineCandleStickResponse candle2 = responses[curIndex-1]; + KlineCandleStickResponse candle3 = responses[curIndex-2]; + + bool isAllGreen = candle1.isGreen() && candle2.isGreen() && candle3.isGreen(); + + //LP:using average shadow is a bad idea, check each shadow + // float averageShadowRatio = (candle1.getShadowRatio() + candle2.getShadowRatio() + candle3.getShadowRatio())/3f; + + + bool areSoldiers = AreAllSolid([candle1,candle2, candle3],0.6f); + bool areSoldiersThin = AreAllSolid([candle1,candle2, candle3], 0.4f); + + + bool areSameSize = AreSameCandleSizes([candle1,candle2,candle3]); + + if(isAllGreen && areSoldiers && areSameSize){ + //Best + return 3; + }else if(isAllGreen&& areSoldiersThin && areSameSize){ + //Not strong + return 2; + }else if(isAllGreen){ + //Meh + return 1; + } + + return 0; + } + + + public static bool AreSameCandleSizes(List responses, float tolerance= 0.5f){ + float totalHeight = 0; + foreach(KlineCandleStickResponse response in responses){ + totalHeight+= response.getCandleLength(); + } + + float avgHeight = totalHeight / (float)responses.Count; + + foreach(KlineCandleStickResponse response in responses){ + float diff = Math.Abs(avgHeight - response.getCandleLength()); + + if(diff > tolerance){ + return false; //One failed to match size + } + } + + return true; + } + + public static bool AreAllSolid(List responses, float tolerance= 0.75f){ + foreach(KlineCandleStickResponse response in responses){ + if(response.getShadowRatio() < tolerance){ + return false; + } + } + + return true; + } } \ No newline at end of file diff --git a/Picasso.cs b/Picasso.cs index 1a3723b..2afd236 100644 --- a/Picasso.cs +++ b/Picasso.cs @@ -20,7 +20,7 @@ public class Picasso{ float candlesOffset = 0.3f * height; float volumeSize = 0.2f * height; - using (Image img = new Image((int)width + 100, (int)height)){ + using (Image img = new Image((int)width + 100, (int)height, Color.FromRgb(13,18,25))){ //Draw Candles for(int i=0; i < reports.Count; i++){ @@ -52,11 +52,39 @@ public class Picasso{ DrawLine(candleColor, 10, volumePoints) ); - if(reports[i].TGOR){ - PointF[] tgorPoints = new PointF[2]; - tgorPoints[0] = new PointF(i * widthMultiplier, lowVal+ candlesOffset); - tgorPoints[1] = new PointF(i * widthMultiplier, lowVal- 15+ candlesOffset); - img.Mutate(ctx=>ctx.DrawLine(Color.Blue, 15, tgorPoints)); + PointF[] bottomPoints = new PointF[2]; + bottomPoints[0] = new PointF(i * widthMultiplier, lowVal+ candlesOffset); + bottomPoints[1] = new PointF(i * widthMultiplier, lowVal- 15+ candlesOffset); + + if(reports[i].TWS > 1){ + Color TWSColor = Color.Blue; + if(reports[i].TWS == 2){ + TWSColor = Color.Cyan; + }else if(reports[i].TWS== 3){ + TWSColor = Color.White; + } + + float TWSHeight = 15; + + if(i > 22){ + bool hasCrossedST = false; + bool hasCrossedMA = false; + for(int z = 0; z < 20; z++){ + if(!reports[i-z].STUp && reports[i].STUp){ + hasCrossedST=true; + } + + if(reports[i-z].SMA20 < reports[i-z].Open && reports[i].SMA20 > reports[i].Open){ + hasCrossedMA=true; + } + } + + if(hasCrossedMA) TWSHeight+=15; + if(hasCrossedST) TWSHeight+=15; + } + + + img.Mutate(ctx=>ctx.DrawLine(TWSColor, TWSHeight, bottomPoints)); } } @@ -66,8 +94,10 @@ public class Picasso{ // Console.WriteLine(float.Parse(t.ToString())); //Overlay - IPath sma7Path = GetPath(reports, "SMA7", widthMultiplier,(float)heightMultiplier, (float)min, candlesOffset); - IPath sma25Path = GetPath(reports, "SMA25", widthMultiplier,(float)heightMultiplier, (float)min, candlesOffset); + IPath sma20Path = GetPath(reports, "SMA20", widthMultiplier,(float)heightMultiplier, (float)min, candlesOffset); + IPath sma50Path = GetPath(reports, "SMA50", widthMultiplier,(float)heightMultiplier, (float)min, candlesOffset); + IPath sma200Path = GetPath(reports, "SMA200", widthMultiplier,(float)heightMultiplier, (float)min, candlesOffset); + IPath stPath = GetPath(reports, "ST", widthMultiplier,(float)heightMultiplier, (float)min, candlesOffset); //NewChart @@ -79,11 +109,12 @@ public class Picasso{ var font = fontFamily.CreateFont(TextFontSize, FontStyle.Regular); - img.Mutate(ctx => ctx.Draw(Color.Yellow, 2, sma7Path). - Draw(Color.Purple, 2, sma25Path). + img.Mutate(ctx => ctx.Draw(Color.Yellow, 2, sma20Path). + Draw(Color.Purple, 2, sma50Path). + Draw(Color.Cyan, 2, sma200Path). Draw(Color.Green, 3, stPath). Flip(FlipMode.Vertical). - DrawText(filename, font,new Color(Rgba32.ParseHex("#000000FF")), new PointF(10,10))); + DrawText(filename, font,new Color(Rgba32.ParseHex("#FFFFFF")), new PointF(10,10))); img.Save($"{filename}.png"); } diff --git a/TAReport.cs b/TAReport.cs index 2f6d120..7caae3d 100644 --- a/TAReport.cs +++ b/TAReport.cs @@ -20,9 +20,9 @@ namespace SignalsTest public decimal High; public decimal Low; public DateTime CloseTime; - public decimal SMA7; - public decimal SMA25; - public decimal SMA99; + public decimal SMA20; + public decimal SMA50; + public decimal SMA200; public decimal EMA7, EMA25, EMA99; @@ -39,6 +39,8 @@ namespace SignalsTest public decimal RSI = 0; + public int TWS =0; + public bool STUp = false; public bool TGOR=false; public static TAReport Generate(string _pair, int _interval, List response, int index, List history) @@ -61,9 +63,9 @@ namespace SignalsTest // { // report.SMAs.Add(ema, Indicators.getEMA(response, index, 0, ema)); // } - report.SMA7 = Indicators.getSMA(response, index, 7); - report.SMA25 = Indicators.getSMA(response, index, 25); - report.SMA99 = Indicators.getSMA(response, index, 99); + report.SMA20 = Indicators.getSMA(response, index, 20); + report.SMA50 = Indicators.getSMA(response, index, 50); + report.SMA200 = Indicators.getSMA(response, index, 200); report.EMA7 = Indicators.getEMA(response, index, 0, 7); report.EMA25 = Indicators.getEMA(response, index, 0, 25); @@ -137,6 +139,7 @@ namespace SignalsTest report.ST = currentTrendUp ? finalLowerBand : finalUpperBand; report.TGOR= Patterns.GetTGOR(response, index); + report.TWS = Patterns.GetThreeWhiteSoldiers(response,index); return report; } diff --git a/Utils.cs b/Utils.cs index 353ec2e..024cf30 100644 --- a/Utils.cs +++ b/Utils.cs @@ -61,5 +61,7 @@ namespace SignalsTest return response; } + + } }