From 8bb359abbdd5cdaa2d50f708424d67a1dd9b7c1e Mon Sep 17 00:00:00 2001
From: djbadders <34887832+djbadders@users.noreply.github.com>
Date: Wed, 17 Feb 2021 17:41:30 +0000
Subject: [PATCH 1/7] Fixes to security
---
Monitor/Pages/_get/DownloadFile.cshtml.cs | 13 ++--
Monitor/_Internal/BasePageModelSecure.cs | 68 ++++++++++++++++----
Monitor/_Internal/BasePageModelSecureAJAX.cs | 49 ++------------
3 files changed, 66 insertions(+), 64 deletions(-)
diff --git a/Monitor/Pages/_get/DownloadFile.cshtml.cs b/Monitor/Pages/_get/DownloadFile.cshtml.cs
index 63498ca..2d7cfed 100644
--- a/Monitor/Pages/_get/DownloadFile.cshtml.cs
+++ b/Monitor/Pages/_get/DownloadFile.cshtml.cs
@@ -1,11 +1,6 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Linq;
+using System.Collections;
using Core.Main;
using Core.Helper;
-using Core.Main.DataObjects.PTMagicData;
-using Core.MarketAnalyzer;
namespace Monitor.Pages {
public class DownloadFileModel : _Internal.BasePageModelSecure {
@@ -14,7 +9,11 @@ namespace Monitor.Pages {
// Initialize Config
base.Init();
- InitializeDownload();
+ // Check we have a log in
+ if (base.IsLoggedIn(this.HttpContext))
+ {
+ InitializeDownload();
+ }
}
private void InitializeDownload() {
diff --git a/Monitor/_Internal/BasePageModelSecure.cs b/Monitor/_Internal/BasePageModelSecure.cs
index 12ff0ee..080b8ef 100644
--- a/Monitor/_Internal/BasePageModelSecure.cs
+++ b/Monitor/_Internal/BasePageModelSecure.cs
@@ -7,32 +7,72 @@ namespace Monitor._Internal
{
public class BasePageModelSecure : BasePageModel
{
+ // The string to redirect to if it fails security
+ protected string _redirectUrl;
+
+ public BasePageModelSecure(string redirect = null)
+ {
+ // Configure redirect URL
+ _redirectUrl = !String.IsNullOrEmpty(redirect) ? redirect : "Login";
+ }
+
+ ///
+ /// Must be called from inheritting pages to check security
+ ///
public void Init()
{
+ // Initialise base class
base.PreInit();
- if (String.IsNullOrEmpty(HttpContext.Session.GetString("LoggedIn" + PTMagicConfiguration.GeneralSettings.Monitor.Port.ToString())) && PTMagicConfiguration.GeneralSettings.Monitor.IsPasswordProtected)
+ // Security check
+ if (!IsLoggedIn(this.HttpContext))
{
- bool redirectToLogin = true;
- if (Request.Cookies.ContainsKey("PTMRememberMeKey"))
+ HttpContext.Response.Redirect(PTMagicConfiguration.GeneralSettings.Monitor.RootUrl + _redirectUrl);
+ }
+ }
+
+ ///
+ /// Check to see a user if logged in interactively
+ ///
+ /// Boolean - User logged in or not
+ protected Boolean IsLoggedIn(HttpContext context)
+ {
+ bool isLoggedIn = false;
+
+ if (PTMagicConfiguration.GeneralSettings.Monitor.IsPasswordProtected)
+ {
+ // Do we have a session active?
+ if (!String.IsNullOrEmpty(context.Session.GetString("LoggedIn" + PTMagicConfiguration.GeneralSettings.Monitor.Port.ToString())))
{
- string rememberMeKey = Request.Cookies["PTMRememberMeKey"];
- if (!rememberMeKey.Equals(""))
+ isLoggedIn = true;
+ }
+ else
+ {
+ // Do we have a auto login cookie?
+ if (Request.Cookies.ContainsKey("PTMRememberMeKey"))
{
- string encryptedPassword = EncryptionHelper.Decrypt(Request.Cookies["PTMRememberMeKey"]);
- if (encryptedPassword.Equals(PTMagicConfiguration.SecureSettings.MonitorPassword))
+ string rememberMeKey = Request.Cookies["PTMRememberMeKey"];
+ if (!rememberMeKey.Equals(""))
{
- HttpContext.Session.SetString("LoggedIn" + PTMagicConfiguration.GeneralSettings.Monitor.Port.ToString(), DateTime.UtcNow.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'"));
- redirectToLogin = false;
+ string encryptedPassword = EncryptionHelper.Decrypt(Request.Cookies["PTMRememberMeKey"]);
+ if (encryptedPassword.Equals(PTMagicConfiguration.SecureSettings.MonitorPassword))
+ {
+ context.Session.SetString("LoggedIn" + PTMagicConfiguration.GeneralSettings.Monitor.Port.ToString(), DateTime.UtcNow.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'"));
+ isLoggedIn = true;
+ }
}
}
}
-
- if (redirectToLogin)
- {
- HttpContext.Response.Redirect(PTMagicConfiguration.GeneralSettings.Monitor.RootUrl + "Login");
- }
}
+ else
+ {
+ // No password required
+ isLoggedIn = true;
+ }
+
+ return isLoggedIn;
}
+
}
+
}
diff --git a/Monitor/_Internal/BasePageModelSecureAJAX.cs b/Monitor/_Internal/BasePageModelSecureAJAX.cs
index c1c7c6a..c69cc4d 100644
--- a/Monitor/_Internal/BasePageModelSecureAJAX.cs
+++ b/Monitor/_Internal/BasePageModelSecureAJAX.cs
@@ -1,49 +1,12 @@
-using System;
-using System.IO;
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Mvc;
-using Microsoft.AspNetCore.Mvc.RazorPages;
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.DependencyInjection;
-using Newtonsoft.Json;
-using Core.Main;
-using Core.Helper;
-using Core.Main.DataObjects.PTMagicData;
-using Core.MarketAnalyzer;
-using Core.ProfitTrailer;
-using Microsoft.Extensions.Primitives;
-
-namespace Monitor._Internal
+namespace Monitor._Internal
{
- public class BasePageModelSecureAJAX : BasePageModel
+ public class BasePageModelSecureAJAX : BasePageModelSecure
{
- public void Init()
- {
- base.PreInit();
-
- if (String.IsNullOrEmpty(HttpContext.Session.GetString("LoggedIn" + PTMagicConfiguration.GeneralSettings.Monitor.Port.ToString())) && PTMagicConfiguration.GeneralSettings.Monitor.IsPasswordProtected)
- {
- bool redirectToLogin = true;
- if (Request.Cookies.ContainsKey("PTMRememberMeKey"))
- {
- string rememberMeKey = Request.Cookies["PTMRememberMeKey"];
- if (!rememberMeKey.Equals(""))
- {
- string encryptedPassword = EncryptionHelper.Decrypt(Request.Cookies["PTMRememberMeKey"]);
- if (encryptedPassword.Equals(PTMagicConfiguration.SecureSettings.MonitorPassword))
- {
- HttpContext.Session.SetString("LoggedIn" + PTMagicConfiguration.GeneralSettings.Monitor.Port.ToString(), DateTime.UtcNow.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'"));
- redirectToLogin = false;
- }
- }
- }
-
- if (redirectToLogin)
- {
- HttpContext.Response.Redirect(PTMagicConfiguration.GeneralSettings.Monitor.RootUrl + "_get/ReturnToLogin");
- }
- }
+ public BasePageModelSecureAJAX() : base(@"_get/ReturnToLogin") {
+ // Logic in base class
}
+
}
+
}
From 03b2acdf43194413c719e5180c680bbd5e305011 Mon Sep 17 00:00:00 2001
From: djbadders <34887832+djbadders@users.noreply.github.com>
Date: Wed, 17 Feb 2021 18:32:07 +0000
Subject: [PATCH 2/7] Security fix to avoid using the assets folder when
creating zips
---
Monitor/Pages/_get/DownloadFile.cshtml.cs | 26 +++++++++++++++++------
Monitor/Startup.cs | 10 ++++++++-
2 files changed, 28 insertions(+), 8 deletions(-)
diff --git a/Monitor/Pages/_get/DownloadFile.cshtml.cs b/Monitor/Pages/_get/DownloadFile.cshtml.cs
index 2d7cfed..900fa5a 100644
--- a/Monitor/Pages/_get/DownloadFile.cshtml.cs
+++ b/Monitor/Pages/_get/DownloadFile.cshtml.cs
@@ -1,5 +1,7 @@
-using System.Collections;
-using Core.Main;
+using System;
+using System.Collections;
+using System.IO;
+using Microsoft.Net.Http.Headers;
using Core.Helper;
namespace Monitor.Pages {
@@ -16,19 +18,29 @@ namespace Monitor.Pages {
}
}
- private void InitializeDownload() {
+ private async void InitializeDownload() {
+ // Zip the file in an non web accessible folder
string fileName = GetStringParameter("f", "");
+ string tempFolder = PTMagicMonitorBasePath + System.IO.Path.DirectorySeparatorChar + "tmp" + System.IO.Path.DirectorySeparatorChar;
+
if (System.IO.File.Exists(PTMagicBasePath + fileName)) {
- if (!System.IO.Directory.Exists(PTMagicMonitorBasePath + "wwwroot" + System.IO.Path.DirectorySeparatorChar + "assets" + System.IO.Path.DirectorySeparatorChar + "tmp" + System.IO.Path.DirectorySeparatorChar)) {
- System.IO.Directory.CreateDirectory(PTMagicMonitorBasePath + "wwwroot" + System.IO.Path.DirectorySeparatorChar + "assets" + System.IO.Path.DirectorySeparatorChar + "tmp" + System.IO.Path.DirectorySeparatorChar);
+ if (!System.IO.Directory.Exists(tempFolder)) {
+ System.IO.Directory.CreateDirectory(tempFolder);
}
string sourcefilePath = PTMagicBasePath + fileName;
- string destinationFilePath = PTMagicMonitorBasePath + "wwwroot" + System.IO.Path.DirectorySeparatorChar + "assets" + System.IO.Path.DirectorySeparatorChar + "tmp" + System.IO.Path.DirectorySeparatorChar + fileName + ".zip";
+ string destinationFilePath = tempFolder + fileName + ".zip";
ZIPHelper.CreateZipFile(new ArrayList() { sourcefilePath }, destinationFilePath);
- Response.Redirect(PTMagicConfiguration.GeneralSettings.Monitor.RootUrl + "assets/tmp/" + fileName + ".zip");
+ // Write out the file
+ var data = System.IO.File.ReadAllBytes(destinationFilePath);
+
+ Response.ContentType = "application/zip";
+ Response.Headers[HeaderNames.CacheControl] = "no-cache";
+ Response.Headers[HeaderNames.ContentDisposition] = String.Format("attachment; filename={0}", fileName);
+ await Response.BodyWriter.WriteAsync(new Memory(data));
+ Response.BodyWriter.Complete();
}
}
}
diff --git a/Monitor/Startup.cs b/Monitor/Startup.cs
index b50797d..fa46e14 100644
--- a/Monitor/Startup.cs
+++ b/Monitor/Startup.cs
@@ -7,6 +7,7 @@ using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Core.Main;
+using Core.Helper;
using System.Runtime.InteropServices;
using System.Diagnostics;
@@ -58,6 +59,13 @@ namespace Monitor
{
options.AllowSynchronousIO = true;
});
+
+ // Remove the old tmp folder if it exists
+ string oldTmpFolder = monitorBasePath + System.IO.Path.DirectorySeparatorChar + "wwwroot" + System.IO.Path.DirectorySeparatorChar + "assets" + System.IO.Path.DirectorySeparatorChar + "tmp" + System.IO.Path.DirectorySeparatorChar;
+ if (System.IO.Directory.Exists(oldTmpFolder))
+ {
+ System.IO.Directory.Delete(oldTmpFolder, true);
+ }
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
@@ -77,7 +85,7 @@ namespace Monitor
// Configure request pipeline
app.UseStaticFiles();
app.UseSession();
- app.UseMvcWithDefaultRoute();
+ app.UseMvcWithDefaultRoute();
// Open the browser
if (systemConfiguration.GeneralSettings.Monitor.OpenBrowserOnStart) OpenBrowser("http://localhost:" + systemConfiguration.GeneralSettings.Monitor.Port.ToString());
From 32eae764316e308d095e6fcf654c86be5417bbf3 Mon Sep 17 00:00:00 2001
From: HojouFotytu <36724681+HojouFotytu@users.noreply.github.com>
Date: Thu, 18 Feb 2021 16:59:31 +0900
Subject: [PATCH 3/7] Trading View fixes
---
Core/Helper/SystemHelper.cs | 28 +++++++++++++++-------------
Monitor/Pages/SettingsGeneral.cshtml | 1 -
PTMagic/Program.cs | 2 +-
3 files changed, 16 insertions(+), 15 deletions(-)
diff --git a/Core/Helper/SystemHelper.cs b/Core/Helper/SystemHelper.cs
index c315e50..3c2d269 100644
--- a/Core/Helper/SystemHelper.cs
+++ b/Core/Helper/SystemHelper.cs
@@ -536,20 +536,14 @@ namespace Core.Helper
string result = "#";
if (platform.Equals("TradingView"))
{
- result = "https://www.tradingview.com/symbols/" + market.ToUpper() + "/?exchange=" + exchange.ToUpper();
- }
- else if (platform.Equals("TradingViewFutures"))
- {
- result = "https://www.tradingview.com/chart/?symbol=";
-
- string pairName = SystemHelper.StripBadCode(market, Constants.WhiteListMinimal);
-
- if (pairName.StartsWith(mainMarket))
+ if (exchange.Equals("binancefutures", StringComparison.InvariantCultureIgnoreCase))
{
- pairName = pairName.Replace(mainMarket, "") + mainMarket;
+ result = "https://www.tradingview.com/chart/?symbol=BINANCE:" + market.ToUpper() + "PERP";
+ }
+ else
+ {
+ result = "https://www.tradingview.com/?symbol=" + exchange.ToUpper() + ":" + market.ToUpper();
}
-
- result += pairName + "PERP";
}
else
{
@@ -614,8 +608,16 @@ namespace Core.Helper
pairName = pairName.Replace(mainMarket, "") + mainMarket;
}
- result += pairName;
+ if (exchange.Equals("binancefutures", StringComparison.InvariantCultureIgnoreCase))
+ {
+ result = "BINANCE:" + pairName + "PERP";
+ }
+ else
+ {
+ result += pairName;
+ }
+
return result;
}
diff --git a/Monitor/Pages/SettingsGeneral.cshtml b/Monitor/Pages/SettingsGeneral.cshtml
index 5447e0b..64c3783 100644
--- a/Monitor/Pages/SettingsGeneral.cshtml
+++ b/Monitor/Pages/SettingsGeneral.cshtml
@@ -243,7 +243,6 @@
diff --git a/PTMagic/Program.cs b/PTMagic/Program.cs
index ff6fbbd..11bc420 100644
--- a/PTMagic/Program.cs
+++ b/PTMagic/Program.cs
@@ -6,7 +6,7 @@ using Core.Helper;
using Microsoft.Extensions.DependencyInjection;
-[assembly: AssemblyVersion("2.5.4")]
+[assembly: AssemblyVersion("2.5.5")]
[assembly: AssemblyProduct("PT Magic")]
namespace PTMagic
From 5065c374ff89d1eeacd79536a49d5a942549762f Mon Sep 17 00:00:00 2001
From: HojouFotytu <36724681+HojouFotytu@users.noreply.github.com>
Date: Thu, 18 Feb 2021 17:23:20 +0900
Subject: [PATCH 4/7] distribution chart revert
---
Monitor/Pages/_get/DashboardBottom.cshtml.cs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Monitor/Pages/_get/DashboardBottom.cshtml.cs b/Monitor/Pages/_get/DashboardBottom.cshtml.cs
index 96bc581..eeb3004 100644
--- a/Monitor/Pages/_get/DashboardBottom.cshtml.cs
+++ b/Monitor/Pages/_get/DashboardBottom.cshtml.cs
@@ -196,15 +196,15 @@ namespace Monitor.Pages
{
if (sellStrategyText.Contains("PENDING"))
{
- PendingBalance = PendingBalance + ((dcaLogEntry.Amount * dcaLogEntry.CurrentPrice) / dcaLogEntry.Leverage != 0 ? dcaLogEntry.Leverage : 1);
+ PendingBalance = PendingBalance + ((dcaLogEntry.Amount * dcaLogEntry.CurrentPrice) / dcaLogEntry.Leverage);
}
else if (dcaLogEntry.BuyStrategies.Count > 0)
{
- DCABalance = DCABalance + ((dcaLogEntry.Amount * dcaLogEntry.CurrentPrice) / dcaLogEntry.Leverage != 0 ? dcaLogEntry.Leverage : 1);
+ DCABalance = DCABalance + ((dcaLogEntry.Amount * dcaLogEntry.CurrentPrice) / dcaLogEntry.Leverage);
}
else
{
- PairsBalance = PairsBalance + ((dcaLogEntry.Amount * dcaLogEntry.CurrentPrice) / dcaLogEntry.Leverage != 0 ? dcaLogEntry.Leverage : 1);
+ PairsBalance = PairsBalance + ((dcaLogEntry.Amount * dcaLogEntry.CurrentPrice) / dcaLogEntry.Leverage);
}
}
}
From 34662bf6f06633dd650c3c542729c018e3a18389 Mon Sep 17 00:00:00 2001
From: HojouFotytu <36724681+HojouFotytu@users.noreply.github.com>
Date: Thu, 18 Feb 2021 18:02:26 +0900
Subject: [PATCH 5/7] TCV calculations fix
---
Monitor/Pages/SalesAnalyzer.cshtml.cs | 7 ++++++-
Monitor/Pages/_get/DashboardBottom.cshtml.cs | 22 ++++++--------------
2 files changed, 12 insertions(+), 17 deletions(-)
diff --git a/Monitor/Pages/SalesAnalyzer.cshtml.cs b/Monitor/Pages/SalesAnalyzer.cshtml.cs
index 37725f3..1b2a00f 100644
--- a/Monitor/Pages/SalesAnalyzer.cshtml.cs
+++ b/Monitor/Pages/SalesAnalyzer.cshtml.cs
@@ -161,7 +161,12 @@ namespace Monitor.Pages
double AvailableBalance = PTData.GetCurrentBalance();
foreach (Core.Main.DataObjects.PTMagicData.DCALogData dcaLogEntry in PTData.DCALog)
{
- totalCurrentValue = totalCurrentValue + ((dcaLogEntry.Amount * dcaLogEntry.CurrentPrice) / dcaLogEntry.Leverage != 0 ? dcaLogEntry.Leverage : 1);
+ double leverage = dcaLogEntry.Leverage;
+ if (leverage == 0)
+ {
+ leverage = 1;
+ }
+ totalCurrentValue = totalCurrentValue + ((dcaLogEntry.Amount * dcaLogEntry.CurrentPrice) / leverage);
}
totalCurrentValue = totalCurrentValue + AvailableBalance;
}
diff --git a/Monitor/Pages/_get/DashboardBottom.cshtml.cs b/Monitor/Pages/_get/DashboardBottom.cshtml.cs
index eeb3004..a410c22 100644
--- a/Monitor/Pages/_get/DashboardBottom.cshtml.cs
+++ b/Monitor/Pages/_get/DashboardBottom.cshtml.cs
@@ -177,34 +177,24 @@ namespace Monitor.Pages
string sellStrategyText = Core.ProfitTrailer.StrategyHelper.GetStrategyText(Summary, dcaLogEntry.SellStrategies, dcaLogEntry.SellStrategy, isSellStrategyTrue, isTrailingSellActive);
// Aggregate totals
- if (dcaLogEntry.Leverage == 0)
+ double leverage = dcaLogEntry.Leverage;
+ if (leverage == 0)
{
- if (sellStrategyText.Contains("PENDING"))
- {
- PendingBalance = PendingBalance + (dcaLogEntry.Amount * dcaLogEntry.CurrentPrice);
- }
- else if (dcaLogEntry.BuyStrategies.Count > 0)
- {
- DCABalance = DCABalance + (dcaLogEntry.Amount * dcaLogEntry.CurrentPrice);
- }
- else
- {
- PairsBalance = PairsBalance + (dcaLogEntry.Amount * dcaLogEntry.CurrentPrice);
- }
+ leverage = 1;
}
else
{
if (sellStrategyText.Contains("PENDING"))
{
- PendingBalance = PendingBalance + ((dcaLogEntry.Amount * dcaLogEntry.CurrentPrice) / dcaLogEntry.Leverage);
+ PendingBalance = PendingBalance + ((dcaLogEntry.Amount * dcaLogEntry.CurrentPrice) / leverage);
}
else if (dcaLogEntry.BuyStrategies.Count > 0)
{
- DCABalance = DCABalance + ((dcaLogEntry.Amount * dcaLogEntry.CurrentPrice) / dcaLogEntry.Leverage);
+ DCABalance = DCABalance + ((dcaLogEntry.Amount * dcaLogEntry.CurrentPrice) / leverage);
}
else
{
- PairsBalance = PairsBalance + ((dcaLogEntry.Amount * dcaLogEntry.CurrentPrice) / dcaLogEntry.Leverage);
+ PairsBalance = PairsBalance + ((dcaLogEntry.Amount * dcaLogEntry.CurrentPrice) / leverage);
}
}
}
From c2718c7dbd8437bb1b8e9a7c01e15577b4da3223 Mon Sep 17 00:00:00 2001
From: HojouFotytu <36724681+HojouFotytu@users.noreply.github.com>
Date: Thu, 18 Feb 2021 18:06:52 +0900
Subject: [PATCH 6/7] distribution fix re-fixed
---
Monitor/Pages/_get/DashboardBottom.cshtml.cs | 21 +++++++++-----------
1 file changed, 9 insertions(+), 12 deletions(-)
diff --git a/Monitor/Pages/_get/DashboardBottom.cshtml.cs b/Monitor/Pages/_get/DashboardBottom.cshtml.cs
index a410c22..5eb3390 100644
--- a/Monitor/Pages/_get/DashboardBottom.cshtml.cs
+++ b/Monitor/Pages/_get/DashboardBottom.cshtml.cs
@@ -182,20 +182,17 @@ namespace Monitor.Pages
{
leverage = 1;
}
+ if (sellStrategyText.Contains("PENDING"))
+ {
+ PendingBalance = PendingBalance + ((dcaLogEntry.Amount * dcaLogEntry.CurrentPrice) / leverage);
+ }
+ else if (dcaLogEntry.BuyStrategies.Count > 0)
+ {
+ DCABalance = DCABalance + ((dcaLogEntry.Amount * dcaLogEntry.CurrentPrice) / leverage);
+ }
else
{
- if (sellStrategyText.Contains("PENDING"))
- {
- PendingBalance = PendingBalance + ((dcaLogEntry.Amount * dcaLogEntry.CurrentPrice) / leverage);
- }
- else if (dcaLogEntry.BuyStrategies.Count > 0)
- {
- DCABalance = DCABalance + ((dcaLogEntry.Amount * dcaLogEntry.CurrentPrice) / leverage);
- }
- else
- {
- PairsBalance = PairsBalance + ((dcaLogEntry.Amount * dcaLogEntry.CurrentPrice) / leverage);
- }
+ PairsBalance = PairsBalance + ((dcaLogEntry.Amount * dcaLogEntry.CurrentPrice) / leverage);
}
}
totalCurrentValue = PendingBalance + DCABalance + PairsBalance + AvailableBalance;
From 925e2a492669e27c4820ef7e28bf8f12877d4d44 Mon Sep 17 00:00:00 2001
From: HojouFotytu <36724681+HojouFotytu@users.noreply.github.com>
Date: Thu, 18 Feb 2021 18:19:42 +0900
Subject: [PATCH 7/7] change TV link to UK
---
Core/Helper/SystemHelper.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Core/Helper/SystemHelper.cs b/Core/Helper/SystemHelper.cs
index 3c2d269..dcb2f79 100644
--- a/Core/Helper/SystemHelper.cs
+++ b/Core/Helper/SystemHelper.cs
@@ -538,11 +538,11 @@ namespace Core.Helper
{
if (exchange.Equals("binancefutures", StringComparison.InvariantCultureIgnoreCase))
{
- result = "https://www.tradingview.com/chart/?symbol=BINANCE:" + market.ToUpper() + "PERP";
+ result = "https://uk.tradingview.com/chart/?symbol=BINANCE:" + market.ToUpper() + "PERP";
}
else
{
- result = "https://www.tradingview.com/?symbol=" + exchange.ToUpper() + ":" + market.ToUpper();
+ result = "https://uk.tradingview.com/?symbol=" + exchange.ToUpper() + ":" + market.ToUpper();
}
}
else