multiple timeframe sup

This commit is contained in:
Sewmina 2025-01-14 22:55:18 +05:30
parent 27594f73e1
commit bf83a4b912
9 changed files with 146 additions and 74 deletions

0
.editorconfig Normal file
View File

2
.gitignore vendored
View File

@ -400,5 +400,7 @@ FodyWeavers.xsd
*.sln.iml
*.png
Charts/*
Secrets.cs
.aider*

View File

@ -1,4 +1,5 @@
using BinanceExchange.API.Client;
using BinanceExchange.API.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
@ -11,14 +12,49 @@ namespace SignalsTest
{
private static BinanceClient m_client;
public static BinanceClient Client { get { if(m_client == null)
public static BinanceClient Client
{
get
{
if (m_client == null)
{
m_client = new BinanceClient(new ClientConfiguration()
{
ApiKey = Secrets.BINANCE_API_PK,
SecretKey = Secrets.BINANCE_API_SK,
});
} return m_client;
} }
}
return m_client;
}
}
public static List<CoinWatch> watches = new List<CoinWatch>();
public static CoinWatch GetCoinWatch(string symbol, KlineInterval interval){
foreach(CoinWatch watch in watches){
if(watch.pair == symbol && watch.interval == interval){
return watch;
}
}
return watches[0];
}
public static CoinWatch GetCoinWatchLongest(string symbol){
CoinWatch match = watches[0];
foreach(CoinWatch watch in watches){
if(watch.pair == symbol){
if(match.pair != watch.pair){
match = watch;
}
if(Utils.GetMinutesForInterval(match.interval) < Utils.GetMinutesForInterval(watch.interval)){
match = watch;
}
}
}
return match;
}
}
}

View File

@ -24,6 +24,9 @@ namespace SignalsTest
public KlineInterval interval = KlineInterval.FifteenMinutes;
public List<KlineCandleStickResponse> candles=new List<KlineCandleStickResponse>();
public List<TAReport> reports = new List<TAReport>();
public List<decimal> resistancePoints = new List<decimal>();
public List<decimal> supportPoints = new List<decimal>();
public event EventHandler<BinanceTradeData> PriceUpdated;
bool usingCache;
public CoinWatch(string pair,int index, KlineInterval _interval = KlineInterval.FifteenMinutes , bool useCache=false)
@ -98,6 +101,10 @@ namespace SignalsTest
reports.Add(report);
}
resistancePoints =Confirmations.GetResistanceLevels(reports);
supportPoints = Confirmations.GetSupportiveLevels(reports);
Console.WriteLine($"Drawing chart for {reports.Count} candles, Coin: {symbol}, ceil:{max}, floor:{min}");
// Console.WriteLine("Picasso did his job");
@ -133,10 +140,10 @@ namespace SignalsTest
}
if(triggers!= ""){
Picasso.DrawChart(reports, max ,min, maxVol, symbol);
Picasso.DrawChart(reports, max ,min, maxVol, symbol, interval);
string message = $"`{symbol}` {triggers} \nCurrent price: {reports[reports.Count-1].Close}";
Messenger.instance.ScheduleMessage(message, symbol);
string message = $"`{symbol}` [{Utils.GetMinutesForInterval(interval)}m] {triggers} \nCurrent price: {reports[reports.Count-1].Close}";
Messenger.instance.ScheduleMessage(message, symbol, Utils.GetMinutesForInterval(interval).ToString());
}
}

View File

@ -1,39 +1,41 @@
using BinanceExchange.API.Enums;
public static class CoinsList{
public static List<string> symbols= [
"BTCUSDT",
"ADAUSDT",
"AIXBTUSDT",
"XRPUSDT",
"XLMUSDT",
"SOLUSDT",
"AVAXUSDT",
"ENAUSDT",
"HIVEUSDT",
"STEEMUSDT",
"MOVEUSDT",
"DOGEUSDT",
"PEPEUSDT",
"ACTUSDT",
"STGUSDT",
"ONEUSDT",
"LINKUSDT",
"ARUSDT",
"RUNEUSDT",
"USUALUSDT",
"ZKUSDT",
"JUPUSDT",
"LUNAUSDT",
"DUSKUSDT",
"SUIUSDT",
"INJUSDT",
"FILUSDT",
"GRTUSDT",
"HBARUSDT",
"CFXUSDT",
"TLMUSDT",
"NEARUSDT",
"FORTHUSDT",
"ETHUSDT",
"PNUTUSDT"
];
public static Dictionary<string, List<KlineInterval>> symbols = new Dictionary<string, List<KlineInterval>> {
{ "BTCUSDT", [KlineInterval.FifteenMinutes, KlineInterval.OneHour] },
{ "ADAUSDT", [KlineInterval.FifteenMinutes, KlineInterval.OneHour] },
{ "AIXBTUSDT", [KlineInterval.FifteenMinutes, KlineInterval.OneHour] },
{ "XRPUSDT", [KlineInterval.FifteenMinutes, KlineInterval.OneHour] },
{ "XLMUSDT", [KlineInterval.FifteenMinutes, KlineInterval.OneHour] },
{ "SOLUSDT", [KlineInterval.FifteenMinutes, KlineInterval.OneHour] },
{ "AVAXUSDT", [KlineInterval.FifteenMinutes, KlineInterval.OneHour] },
{ "ENAUSDT", [KlineInterval.FifteenMinutes, KlineInterval.OneHour] },
{ "HIVEUSDT", [KlineInterval.FifteenMinutes, KlineInterval.OneHour] },
{ "STEEMUSDT", [KlineInterval.FifteenMinutes, KlineInterval.OneHour] },
{ "MOVEUSDT", [KlineInterval.FifteenMinutes, KlineInterval.OneHour] },
{ "DOGEUSDT", [KlineInterval.FifteenMinutes, KlineInterval.OneHour] },
{ "PEPEUSDT", [KlineInterval.FifteenMinutes, KlineInterval.OneHour] },
{ "ACTUSDT", [KlineInterval.FifteenMinutes, KlineInterval.OneHour] },
{ "STGUSDT", [KlineInterval.FifteenMinutes, KlineInterval.OneHour] },
{ "ONEUSDT", [KlineInterval.FifteenMinutes, KlineInterval.OneHour] },
{ "LINKUSDT", [KlineInterval.FifteenMinutes, KlineInterval.OneHour] },
{ "ARUSDT", [KlineInterval.FifteenMinutes, KlineInterval.OneHour] },
{ "RUNEUSDT", [KlineInterval.FifteenMinutes, KlineInterval.OneHour] },
{ "USUALUSDT", [KlineInterval.FifteenMinutes, KlineInterval.OneHour] },
{ "ZKUSDT", [KlineInterval.FifteenMinutes, KlineInterval.OneHour] },
{ "JUPUSDT", [KlineInterval.FifteenMinutes, KlineInterval.OneHour] },
{ "LUNAUSDT", [KlineInterval.FifteenMinutes, KlineInterval.OneHour] },
{ "DUSKUSDT", [KlineInterval.FifteenMinutes, KlineInterval.OneHour] },
{ "SUIUSDT", [KlineInterval.FifteenMinutes, KlineInterval.OneHour] },
{ "INJUSDT", [KlineInterval.FifteenMinutes, KlineInterval.OneHour] },
{ "FILUSDT", [KlineInterval.FifteenMinutes, KlineInterval.OneHour] },
{ "GRTUSDT", [KlineInterval.FifteenMinutes, KlineInterval.OneHour] },
{ "HBARUSDT", [KlineInterval.FifteenMinutes, KlineInterval.OneHour] },
{ "CFXUSDT", [KlineInterval.FifteenMinutes, KlineInterval.OneHour] },
{ "TLMUSDT", [KlineInterval.FifteenMinutes, KlineInterval.OneHour] },
{ "NEARUSDT", [KlineInterval.FifteenMinutes, KlineInterval.OneHour] },
{ "FORTHUSDT", [KlineInterval.FifteenMinutes, KlineInterval.OneHour] },
{ "ETHUSDT", [KlineInterval.FifteenMinutes, KlineInterval.OneHour] },
{ "PNUTUSDT", [KlineInterval.FifteenMinutes, KlineInterval.OneHour] }
};
}

7
CustomTypes.cs Normal file
View File

@ -0,0 +1,7 @@
public class MessageQueueItem{
public string symbol;
public string interval;
public string filename=>"Charts/"+symbol+interval+".png";
public string text;
}

View File

@ -23,10 +23,14 @@ namespace SignalsTest
public const string chatId = "@doralockscryptosignals";
public const string chatId_test = "@SignalTestPrivate";
public Dictionary<string,string> messagesSchedule = new Dictionary<string, string>();
public List<MessageQueueItem> messagesSchedule = new List<MessageQueueItem>();
public void ScheduleMessage(string text, string filename=""){
messagesSchedule.Add(text,filename);
public void ScheduleMessage(string text, string symbol="", string interval=""){
messagesSchedule.Add(new MessageQueueItem(){
symbol = symbol,
interval=interval,
text=text
});
}
public async void InitializeScheduler(){
@ -39,25 +43,26 @@ namespace SignalsTest
continue;
}
string message = messagesSchedule.Keys.ElementAt(0);
string filename = messagesSchedule[message];
MessageQueueItem queueItem = messagesSchedule[0];
string message = queueItem.text;
string filename = queueItem.filename;
string symbol = queueItem.symbol;
try{
if(filename.Length < 2){
if(symbol.Length < 2){
await botClient.SendTextMessageAsync(_chatId, message);
}else{
FileStream fsSource = new FileStream($"{filename}.png", FileMode.Open, FileAccess.Read);
FileStream fsSource = new FileStream(filename, FileMode.Open, FileAccess.Read);
InputFile photo = InputFile.FromStream(fsSource);
string url = $"https://www.tradingview.com/chart/?symbol=BINANCE%3A{filename}";
string url = $"https://www.tradingview.com/chart/?symbol=BINANCE%3A{symbol}";
// string formattedMessage = message.Replace($"`{filename}`", $"`{filename}`[Trading View]({url})");
string formattedMessage = message.Replace(
$"`{filename}`",
$"<a href=\"{url}\">{filename}</a>"
$"`{symbol}`",
$"<a href=\"{url}\">{symbol}</a>"
);
await botClient.SendPhotoAsync(_chatId, photo,caption: formattedMessage,parseMode: ParseMode.Html);
}
messagesSchedule.Remove(message);
messagesSchedule.Remove(queueItem);
}catch(Exception e){
Console.WriteLine($"Error occured while sending {message} to {filename}");
Console.WriteLine(e.ToString());

View File

@ -8,12 +8,13 @@ using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using Newtonsoft.Json;
using System.Diagnostics;
using BinanceExchange.API.Enums;
public class Picasso{
public static void DrawChart(List<TAReport> reports, decimal max, decimal min, decimal volMax, string filename="test"){
public static void DrawChart(List<TAReport> reports, decimal max, decimal min, decimal volMax, string filename="test", KlineInterval interval = KlineInterval.FifteenMinutes){
// float height = (float)Math.Ceiling(max - min) * 2f;
// float width = ((float)height / 9f) * 16f;
decimal heightRange = max-min;
@ -125,15 +126,16 @@ public class Picasso{
#endregion
#region LINES
List<decimal> resistancePoints = Confirmations.GetResistanceLevels(reports);
foreach(decimal point in resistancePoints){
CoinWatch longestWatch = Brian.GetCoinWatchLongest(filename);
foreach(decimal point in longestWatch.resistancePoints){
float yVal = ((float)(point-min) * heightMultiplier) + candlesOffset;
// Console.WriteLine($"{filename} res at {yVal/height}");
img.Mutate(ctx=> ctx.DrawLine(Color.Red,1f, [new PointF(0, yVal), new PointF(width, yVal)]));
}
List<decimal> supPoints = Confirmations.GetSupportiveLevels(reports);
foreach(decimal point in supPoints){
foreach(decimal point in longestWatch.supportPoints){
float yVal = ((float)(point-min) * heightMultiplier) + candlesOffset;
// Console.WriteLine($"{filename} sup at {yVal/height}");
img.Mutate(ctx=> ctx.DrawLine(Color.Green,1f, [new PointF(0, yVal), new PointF(width, yVal)]));
@ -150,7 +152,6 @@ public class Picasso{
IPath stochFast = GetPath(reports, "Stochastic", widthMultiplier, (float)volumeHeightMultiplier/100f, 0, 0);
IPath stochK3 = GetPath(reports, "StochasticK3", widthMultiplier, (float)volumeHeightMultiplier/100f, 0, 0);
IPath stPath = GetPath(reports, "ST", widthMultiplier,(float)heightMultiplier, (float)min, candlesOffset);
#endregion
//NewChart
@ -161,6 +162,7 @@ public class Picasso{
throw new Exception($"Couldn't find font {TextFont}");
var font = fontFamily.CreateFont(TextFontSize, FontStyle.Regular);
int intervalInMins = Utils.GetMinutesForInterval(interval);
img.Mutate(ctx => ctx.Draw(Color.Yellow, 2, sma20Path).
Draw(Color.Purple, 2, sma50Path).
@ -169,9 +171,9 @@ public class Picasso{
Draw(Color.Cyan, 3,stochFast).
Draw(Color.Orange, 3, stochK3).
Flip(FlipMode.Vertical).
DrawText(filename, font,new Color(Rgba32.ParseHex("#FFFFFF")), new PointF(10,10)));
DrawText($"{filename}- {intervalInMins}m", font,new Color(Rgba32.ParseHex("#FFFFFF")), new PointF(10,10)));
img.Save($"{filename}.png");
img.Save($"Charts/{filename}{intervalInMins}.png");
}
}

View File

@ -1,20 +1,31 @@
using BinanceExchange.API.Models.WebSocket;
using BinanceExchange.API.Enums;
using BinanceExchange.API.Models.WebSocket;
using SignalsTest;
class Program
{
static ManualResetEvent _quitEvent = new ManualResetEvent(false);
static List<CoinWatch> watches = new List<CoinWatch>();
private static void Main(string[] args)
{
Console.WriteLine("Initializing Messiah");
Messenger.instance.ScheduleMessage("Rebooted bot");
for (int i=0; i < CoinsList.symbols.Count; i++){
CoinWatch btcWatch = new CoinWatch(CoinsList.symbols[i], i);
// for (int i=0; i < CoinsList.symbols.Count; i++){
// CoinWatch btcWatch = new CoinWatch(CoinsList.symbols[i], i);
// btcWatch.PriceUpdated += CoinWatch_OnPriceUpdate;
// watches.Add(btcWatch);
// }
Brian.watches = new List<CoinWatch>();
int i=0;
foreach(KeyValuePair<string, List<KlineInterval>> symbol in CoinsList.symbols){
foreach(KlineInterval interval in symbol.Value){
CoinWatch btcWatch = new CoinWatch(symbol.Key, i, interval);
btcWatch.PriceUpdated += CoinWatch_OnPriceUpdate;
watches.Add(btcWatch);
Brian.watches.Add(btcWatch);
i++;
}
}
CheckSuccess();
_quitEvent.WaitOne();
@ -22,17 +33,17 @@ class Program
async static void CheckSuccess(){
await Task.Delay(120000);
await Task.Delay(160000);
List<string> failedList = new List<string>();
string commasList = "";
foreach(CoinWatch coin in watches){
foreach(CoinWatch coin in Brian.watches){
if(!coin.kickstarted){
failedList.Add(coin.pair);
commasList += coin.pair + ", ";
commasList += $"{coin.pair}[{coin.interval}]" + ", ";
}
}
string msg = $"Reboot complete: {failedList.Count} Failed out of {watches.Count}. Failed list: \n{commasList}";
string msg = $"Reboot complete: {failedList.Count} Failed out of {Brian.watches.Count}. Failed list: \n{commasList}";
Console.WriteLine(msg);
Messenger.instance.ScheduleMessage(msg);
}