diff --git a/Core/DataObjects/PTMagicData.cs b/Core/DataObjects/PTMagicData.cs index 8a16385..1a44711 100644 --- a/Core/DataObjects/PTMagicData.cs +++ b/Core/DataObjects/PTMagicData.cs @@ -40,7 +40,6 @@ namespace Core.Main.DataObjects.PTMagicData public string ProfitTrailerServerAPIToken { get; set; } public string ProfitTrailerMonitorURL { get; set; } = "http://localhost:8081/"; public string ProfitTrailerDefaultSettingName { get; set; } = "default"; - public bool AlwaysLoadDefaultBeforeSwitch { get; set; } = true; public int FloodProtectionMinutes { get; set; } = 15; public string Exchange { get; set; } public double StartBalance { get; set; } = 0; diff --git a/Core/Main/PTMagic.cs b/Core/Main/PTMagic.cs index 9c538ce..e8d2f8f 100644 --- a/Core/Main/PTMagic.cs +++ b/Core/Main/PTMagic.cs @@ -32,7 +32,8 @@ namespace Core.Main private int _runCount = 0; private int _totalElapsedSeconds = 0; private bool _globalSettingWritten = false; - private bool _singleMarketSettingWritten = false; + private bool _singleMarketSettingChanged = false; + private List> _lastActiveSingleMarketSettings = null; private bool _enforceSettingsReapply = false; private DateTime _lastRuntime = Constants.confMinDate; private DateTime _lastSettingsChange = Constants.confMinDate; @@ -160,15 +161,15 @@ namespace Core.Main } } - public bool SingleMarketSettingWritten + public bool SingleMarketSettingChanged { get { - return _singleMarketSettingWritten; + return _singleMarketSettingChanged; } set { - _singleMarketSettingWritten = value; + _singleMarketSettingChanged = value; } } @@ -853,93 +854,134 @@ namespace Core.Main // Only let one thread change the settings at once lock (_lockObj) { - this.RunCount++; - - this.EnforceSettingsReapply = this.HaveSettingsChanged() || this.EnforceSettingsReapply; - - if (PTMagicConfiguration.GeneralSettings.Application.IsEnabled) + try { - // Validate settings - this.ValidateSettings(); - - // Start the process - this.Log.DoLogInfo(""); - this.Log.DoLogInfo("##########################################################"); - this.Log.DoLogInfo("#********************************************************#"); - this.Log.DoLogInfo("Starting market trend check with Version " + this.CurrentVersion.Major + "." + this.CurrentVersion.Minor + "." + this.CurrentVersion.Build); - // Change state to "Running" this.State = Constants.PTMagicBotState_Running; - + this.RunCount++; this.LastRuntime = DateTime.UtcNow; - this.LastRuntimeSummary = new Summary(); - this.LastRuntimeSummary.LastRuntime = this.LastRuntime; - this.LastRuntimeSummary.Version = this.CurrentVersion.Major.ToString() + "." + this.CurrentVersion.Minor.ToString() + "." + this.CurrentVersion.Build.ToString(); + this.EnforceSettingsReapply = this.HaveSettingsChanged() || this.EnforceSettingsReapply; - // Check for latest GitHub version - this.CheckLatestGitHubVersion(this.LastRuntimeSummary.Version); + if (PTMagicConfiguration.GeneralSettings.Application.IsEnabled) + { + // Validate settings + this.ValidateSettings(); - // Get latest main fiat currency exchange rate - this.GetMainFiatCurrencyDetails(); + // Start the process + this.Log.DoLogInfo(""); + this.Log.DoLogInfo("##########################################################"); + this.Log.DoLogInfo("#********************************************************#"); + this.Log.DoLogInfo("Starting market trend check with Version " + this.CurrentVersion.Major + "." + this.CurrentVersion.Minor + "." + this.CurrentVersion.Build); - // Load current PT files - this.LoadCurrentProfitTrailerProperties(); + // Initialise the last runtime summary + this.LastRuntimeSummary = new Summary(); + this.LastRuntimeSummary.LastRuntime = this.LastRuntime; + this.LastRuntimeSummary.Version = this.CurrentVersion.Major.ToString() + "." + this.CurrentVersion.Minor.ToString() + "." + this.CurrentVersion.Build.ToString(); - // Loading SMS Summaries - this.LoadSMSSummaries(); + // Check for latest GitHub version + this.CheckLatestGitHubVersion(this.LastRuntimeSummary.Version); - // Get saved market info - this.MarketInfos = BaseAnalyzer.GetMarketInfosFromFile(this.PTMagicConfiguration, this.Log); + // Get latest main fiat currency exchange rate + this.GetMainFiatCurrencyDetails(); - // Build exchange market data - this.BuildMarketData(); + // Load current PT files + this.LoadCurrentProfitTrailerProperties(); - // Get markets from PT properties - this.BuildMarketList(); - this.ValidateMarketList(); + // Loading SMS Summaries + this.LoadSMSSummaries(); - // Build global market trends configured in settings - this.BuildGlobalMarketTrends(); + // Get saved market info + this.MarketInfos = BaseAnalyzer.GetMarketInfosFromFile(this.PTMagicConfiguration, this.Log); - // Check for global settings triggers - GlobalSetting triggeredSetting = this.PTMagicConfiguration.AnalyzerSettings.GlobalSettings.Find(s => s.SettingName.Equals(this.DefaultSettingName, StringComparison.InvariantCultureIgnoreCase)); - List matchedTriggers = new List(); - this.CheckGlobalSettingsTriggers(ref triggeredSetting, ref matchedTriggers); + // Build exchange market data + this.BuildMarketData(); - // Activate global setting - this.ActivateSetting(ref triggeredSetting, ref matchedTriggers); + // Get markets from PT properties + this.BuildMarketList(); + this.ValidateMarketList(); - // Check for single market trend triggers - this.ApplySingleMarketSettings(); + // Build global market trends configured in settings + this.BuildGlobalMarketTrends(); - // Save new properties to Profit Trailer - this.SaveProfitTrailerProperties(); + // Check for global settings triggers + GlobalSetting triggeredSetting = this.PTMagicConfiguration.AnalyzerSettings.GlobalSettings.Find(s => s.SettingName.Equals(this.DefaultSettingName, StringComparison.InvariantCultureIgnoreCase)); + List matchedTriggers = new List(); + this.CheckGlobalSettingsTriggers(ref triggeredSetting, ref matchedTriggers); - // Save Single Market Settings Summary - this.SaveSingleMarketSettingsSummary(); + // Activate global setting + this.ActivateSetting(ref triggeredSetting, ref matchedTriggers); - // Save Runtime Summary - this.SaveRuntimeSummary(); + // Check for single market trend triggers + this.ApplySingleMarketSettings(); + // Save new properties to Profit Trailer + this.SaveProfitTrailerProperties(); + + // Save Single Market Settings Summary + this.SaveSingleMarketSettingsSummary(); + + // Claculate raid time + DateTime endTime = DateTime.UtcNow; + int elapsedSeconds = (int)Math.Round(endTime.Subtract(this.LastRuntime).TotalSeconds, 0); + this.TotalElapsedSeconds += elapsedSeconds; + + // Save Runtime Summary + this.SaveRuntimeSummary(elapsedSeconds); + + // Summarise raid + this.Log.DoLogInfo("##########################################################"); + this.Log.DoLogInfo("#******************* RAID SUMMARY ********************#"); + this.Log.DoLogInfo("+ PT Magic Version: " + this.LastRuntimeSummary.Version); + if (!SystemHelper.IsRecentVersion(this.LastRuntimeSummary.Version, this.LatestVersion)) + { + this.Log.DoLogWarn("+ Your version is out of date! The most recent version is " + this.LatestVersion); + } + this.Log.DoLogInfo("+ Instance name: " + PTMagicConfiguration.GeneralSettings.Application.InstanceName); + this.Log.DoLogInfo("+ Time spent: " + SystemHelper.GetProperDurationTime(elapsedSeconds)); + this.Log.DoLogInfo("+ Active setting: " + this.LastRuntimeSummary.CurrentGlobalSetting.SettingName); + this.Log.DoLogInfo("+ Global setting changed: " + ((this.LastRuntimeSummary.LastGlobalSettingSwitch == this.LastRuntimeSummary.LastRuntime) ? "Yes" : "No") + " " + ((this.LastRuntimeSummary.FloodProtectedSetting != null) ? "(Flood protection!)" : "")); + this.Log.DoLogInfo("+ Single Market Settings changed: " + (this.SingleMarketSettingChanged ? "Yes" : "No")); + this.Log.DoLogInfo("+ PT Config updated: " + (((this.GlobalSettingWritten || this.SingleMarketSettingChanged) && !this.PTMagicConfiguration.GeneralSettings.Application.TestMode) ? "Yes" : "No")); + this.Log.DoLogInfo("+ Markets with active single market settings: " + this.TriggeredSingleMarketSettings.Count.ToString()); + foreach (string activeSMS in this.SingleMarketSettingsCount.Keys) + { + this.Log.DoLogInfo("+ " + activeSMS + ": " + this.SingleMarketSettingsCount[activeSMS].ToString()); + } + this.Log.DoLogInfo("+ " + this.TotalElapsedSeconds.ToString() + " Magicbots killed in " + this.RunCount.ToString() + " raids on Cryptodragon's Lair " + this.PTMagicConfiguration.AnalyzerSettings.MarketAnalyzer.IntervalMinutes.ToString() + "."); + this.Log.DoLogInfo(""); + this.Log.DoLogInfo("DO NOT CLOSE THIS WINDOW! THIS IS THE BOT THAT ANALYZES TRENDS AND CHANGES SETTINGS!"); + this.Log.DoLogInfo(""); + this.Log.DoLogInfo("#********************************************************#"); + this.Log.DoLogInfo("##########################################################"); + this.Log.DoLogInfo(""); + } + else + { + this.State = Constants.PTMagicBotState_Idle; + Log.DoLogWarn("PTMagic disabled, shutting down until next raid..."); + } + } + catch (Exception ex) + { + // Error + this.Log.DoLogCritical("A error occurred during the raid, the raid did not complete, but will try again next interval!", ex); + } + finally + { // Cleanup to free memory in between intervals this.Cleanup(); // Change state to Finished / Stopped this.State = Constants.PTMagicBotState_Idle; } - else - { - this.State = Constants.PTMagicBotState_Idle; - Log.DoLogWarn("PTMagic disabled, shutting down until next raid..."); - } } } else { if (this.RunCount > 1) { - Log.DoLogWarn("PTMagic already raiding since " + this.LastRuntime.ToString() + " - Process frozen? Checking things..."); + Log.DoLogWarn("PTMagic already raiding since " + this.LastRuntime.ToLocalTime().ToString() + " - Process frozen? Checking things..."); if (File.Exists(Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + Constants.PTMagicPathData + Path.DirectorySeparatorChar + "LastRuntimeSummary.json")) { @@ -2004,12 +2046,20 @@ namespace Core.Main if (this.TriggeredSingleMarketSettings.Count > 0) { - - // Write single market settings this.Log.DoLogInfo("Building single market settings for '" + this.TriggeredSingleMarketSettings.Count.ToString() + "' markets..."); - SettingsHandler.CompileSingleMarketProperties(this, matchedMarketTriggers); - this.SingleMarketSettingWritten = true; + // Write single market settings + var newSingleMarketSettings = SettingsHandler.CompileSingleMarketProperties(this, matchedMarketTriggers); + + // Compare against last run to see if they have changed or not + if (_lastActiveSingleMarketSettings == null || haveSingleMarketSettingsHaveChanged(_lastActiveSingleMarketSettings, newSingleMarketSettings)) + { + // Single market settings differ from the last raid, so update + this.SingleMarketSettingChanged = true; + } + + // Buffer for next raid + _lastActiveSingleMarketSettings = newSingleMarketSettings; this.Log.DoLogInfo("Building single market settings completed."); } @@ -2018,9 +2068,8 @@ namespace Core.Main this.Log.DoLogInfo("No settings triggered for single markets."); // Remove single market settings if no triggers are met - if necessary - this.SingleMarketSettingWritten = SettingsHandler.RemoveSingleMarketSettings(this); + this.SingleMarketSettingChanged = SettingsHandler.RemoveSingleMarketSettings(this); } - } else { @@ -2028,13 +2077,31 @@ namespace Core.Main } } + private bool haveSingleMarketSettingsHaveChanged(List> oldMarketTriggers, List> newMarketTriggers) + { + // Check if the SMS settings have changed between raids + string oldSms = "", newSms = ""; + + foreach (var entry in oldMarketTriggers) + { + oldSms += string.Format("{0}: {1}|", entry.Key, entry.Value); + } + + foreach (var entry in newMarketTriggers) + { + newSms += string.Format("{0}: {1}|", entry.Key, entry.Value); + } + + return !string.Equals(oldSms, newSms, StringComparison.OrdinalIgnoreCase); + } + private void SaveProfitTrailerProperties() { // Get current PT properties string pairsPropertiesPath, dcaPropertiesPath, indicatorsPropertiesPath; GetProfitTrailerPropertiesPaths(out pairsPropertiesPath, out dcaPropertiesPath, out indicatorsPropertiesPath); - if (this.GlobalSettingWritten || this.SingleMarketSettingWritten) + if (this.GlobalSettingWritten || this.SingleMarketSettingChanged) { // Save current PT properties to API (Valid for PT 2.x and above) this.Log.DoLogInfo("Saving properties using API..."); @@ -2064,15 +2131,12 @@ namespace Core.Main this.Log.DoLogInfo("Single Market Settings Summary saved."); } - private void SaveRuntimeSummary() + private void SaveRuntimeSummary(int elapsedSeconds) { - DateTime endTime = DateTime.UtcNow; - int elapsedSeconds = (int)Math.Round(endTime.Subtract(this.LastRuntime).TotalSeconds, 0); + this.Log.DoLogInfo("Building LastRuntimeSummary.json for your monitor..."); this.LastRuntimeSummary.LastRuntimeSeconds = elapsedSeconds; - this.Log.DoLogInfo("Building LastRuntimeSummary.json for your monitor..."); - // Load existing runtime summary and read ongoing data if (File.Exists(Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + Constants.PTMagicPathData + Path.DirectorySeparatorChar + "LastRuntimeSummary.json")) { @@ -2509,45 +2573,13 @@ namespace Core.Main this.Log.DoLogCritical("Nope, another Exception while writing LastRuntimeSummary.json", ex2); } } - - string logsPath = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + Constants.PTMagicPathLogs + Path.DirectorySeparatorChar; - if (Directory.Exists(logsPath)) - { - FileHelper.CleanupFiles(logsPath, 24 * 3); - this.Log.DoLogInfo("Cleaned up logfiles."); - } - - this.TotalElapsedSeconds += elapsedSeconds; - this.Log.DoLogInfo("##########################################################"); - this.Log.DoLogInfo("#******************* RAID SUMMARY ********************#"); - this.Log.DoLogInfo("+ PT Magic Version: " + this.LastRuntimeSummary.Version); - if (!SystemHelper.IsRecentVersion(this.LastRuntimeSummary.Version, this.LatestVersion)) - { - this.Log.DoLogWarn("+ Your version is out of date! The most recent version is " + this.LatestVersion); - } - this.Log.DoLogInfo("+ Instance name: " + PTMagicConfiguration.GeneralSettings.Application.InstanceName); - this.Log.DoLogInfo("+ Time spent: " + SystemHelper.GetProperDurationTime(elapsedSeconds)); - this.Log.DoLogInfo("+ Active setting: " + this.LastRuntimeSummary.CurrentGlobalSetting.SettingName); - this.Log.DoLogInfo("+ Global setting changed: " + ((this.LastRuntimeSummary.LastGlobalSettingSwitch == this.LastRuntimeSummary.LastRuntime) ? "Yes" : "No") + " " + ((this.LastRuntimeSummary.FloodProtectedSetting != null) ? "(Flood protection!)" : "")); - this.Log.DoLogInfo("+ PT Config updated: " + (((this.GlobalSettingWritten || this.SingleMarketSettingWritten) && !this.PTMagicConfiguration.GeneralSettings.Application.TestMode) ? "Yes" : "No")); - this.Log.DoLogInfo("+ Markets with active single market settings: " + this.TriggeredSingleMarketSettings.Count.ToString()); - foreach (string activeSMS in this.SingleMarketSettingsCount.Keys) - { - this.Log.DoLogInfo("+ " + activeSMS + ": " + this.SingleMarketSettingsCount[activeSMS].ToString()); - } - this.Log.DoLogInfo("+ " + this.TotalElapsedSeconds.ToString() + " Magicbots killed in " + this.RunCount.ToString() + " raids on Cryptodragon's Lair " + this.PTMagicConfiguration.AnalyzerSettings.MarketAnalyzer.IntervalMinutes.ToString() + "."); - this.Log.DoLogInfo(""); - this.Log.DoLogInfo("DO NOT CLOSE THIS WINDOW! THIS IS THE BOT THAT ANALYZES TRENDS AND CHANGES SETTINGS!"); - this.Log.DoLogInfo(""); - this.Log.DoLogInfo("#********************************************************#"); - this.Log.DoLogInfo("##########################################################"); - this.Log.DoLogInfo(""); } private void Cleanup() { + // Clear down memory this.GlobalSettingWritten = false; - this.SingleMarketSettingWritten = false; + this.SingleMarketSettingChanged = false; this.EnforceSettingsReapply = false; this.PairsLines = null; @@ -2562,6 +2594,14 @@ namespace Core.Main this.ExchangeMarketList = null; this.MarketList = new List(); this.LastRuntimeSummary = null; + + // Cleanup log files + string logsPath = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + Constants.PTMagicPathLogs + Path.DirectorySeparatorChar; + if (Directory.Exists(logsPath)) + { + FileHelper.CleanupFiles(logsPath, 24 * 3); + this.Log.DoLogInfo("Cleaned up logfiles."); + } } #endregion } diff --git a/Core/ProfitTrailer/SettingsHandler.cs b/Core/ProfitTrailer/SettingsHandler.cs index 43d1cd7..5c9ace3 100644 --- a/Core/ProfitTrailer/SettingsHandler.cs +++ b/Core/ProfitTrailer/SettingsHandler.cs @@ -200,99 +200,86 @@ namespace Core.ProfitTrailer { bool headerLinesExist = false; List result = new List(); - List fileLines = (List)ptmagicInstance.GetType().GetProperty(fileType + "Lines").GetValue(ptmagicInstance, null); + List fileLines = null; + // Analsye the properties for the setting and apply Dictionary properties = (Dictionary)setting.GetType().GetProperty(fileType + "Properties").GetValue(setting, null); - if (properties != null) + + // Building Properties + if (properties == null || !properties.ContainsKey("File")) { - // Building Properties - if (!setting.SettingName.Equals(ptmagicInstance.DefaultSettingName, StringComparison.InvariantCultureIgnoreCase) && ptmagicInstance.PTMagicConfiguration.GeneralSettings.Application.AlwaysLoadDefaultBeforeSwitch && !properties.ContainsKey("File")) + // Load default settings as basis for the switch + GlobalSetting defaultSetting = ptmagicInstance.PTMagicConfiguration.AnalyzerSettings.GlobalSettings.Find(a => a.SettingName.Equals(ptmagicInstance.DefaultSettingName, StringComparison.InvariantCultureIgnoreCase)); + Dictionary defaultProperties = (Dictionary)defaultSetting.GetType().GetProperty(fileType + "Properties").GetValue(defaultSetting, null); + + if (defaultProperties.ContainsKey("File")) { - // Load default settings as basis for the switch - GlobalSetting defaultSetting = ptmagicInstance.PTMagicConfiguration.AnalyzerSettings.GlobalSettings.Find(a => a.SettingName.Equals(ptmagicInstance.DefaultSettingName, StringComparison.InvariantCultureIgnoreCase)); - if (defaultSetting != null) + // Load the default settings file lines + fileLines = SettingsFiles.GetPresetFileLinesAsList(defaultSetting.SettingName, defaultProperties["File"].ToString(), ptmagicInstance.PTMagicConfiguration); + } + else + { + // No preset file defined, this is a bad settings file! + throw new ApplicationException(string.Format("No 'File' setting found in the '{0}Properties' of the 'Default' setting section in the 'settings.analyzer.json' file; this must be defined!", fileType)); + } + } + else + { + // Settings are configured in a seperate file + fileLines = SettingsFiles.GetPresetFileLinesAsList(setting.SettingName, properties["File"].ToString(), ptmagicInstance.PTMagicConfiguration); + } + + // Check for PTM header in preset file + // Loop through config line by line reprocessing where required. + foreach (string line in fileLines) + { + if (line.IndexOf("PTMagic_ActiveSetting", StringComparison.InvariantCultureIgnoreCase) > -1) + { + // Setting current active setting + result.Add("# PTMagic_ActiveSetting = " + setting.SettingName); + headerLinesExist = true; + } + else if (line.IndexOf("PTMagic_LastChanged", StringComparison.InvariantCultureIgnoreCase) > -1) + { + // Setting last change datetime + result.Add("# PTMagic_LastChanged = " + settingLastChanged.ToShortDateString() + " " + settingLastChanged.ToShortTimeString()); + } + else if (line.IndexOf("PTMagic_SingleMarketSettings", StringComparison.InvariantCultureIgnoreCase) > -1) + { + // Single Market Settings will get overwritten every single run => crop the lines + break; + } + else if (IsPropertyLine(line)) + { + // We have got a property line + if (properties != null) { - Dictionary defaultProperties = new Dictionary(); - switch (fileType.ToLower()) + bool madeSubstitution = false; + + foreach (string settingProperty in properties.Keys) { - case "pairs": - defaultProperties = defaultSetting.PairsProperties; - break; - case "dca": - defaultProperties = defaultSetting.DCAProperties; - break; - case "inidcators": - defaultProperties = defaultSetting.IndicatorsProperties; + if (madeSubstitution) + { + // We've made a substitution so no need to process the rest of the properties break; + } + else + { + madeSubstitution = SettingsHandler.BuildPropertyLine(result, setting.SettingName, line, properties, settingProperty); + } } - if (defaultProperties.ContainsKey("File")) + if (!madeSubstitution) { - fileLines = SettingsFiles.GetPresetFileLinesAsList(defaultSetting.SettingName, defaultProperties["File"].ToString(), ptmagicInstance.PTMagicConfiguration); + // No substitution made, so simply copy the line + result.Add(line); } } } else { - // Check if settings are configured in a seperate file - if (properties.ContainsKey("File")) - { - fileLines = SettingsFiles.GetPresetFileLinesAsList(setting.SettingName, properties["File"].ToString(), ptmagicInstance.PTMagicConfiguration); - } - } - - // Check for PTM header in preset file - // Loop through config line by line reprocessing where required. - foreach (string line in fileLines) - { - if (line.IndexOf("PTMagic_ActiveSetting", StringComparison.InvariantCultureIgnoreCase) > -1) - { - // Setting current active setting - result.Add("# PTMagic_ActiveSetting = " + setting.SettingName); - headerLinesExist = true; - } - else if (line.IndexOf("PTMagic_LastChanged", StringComparison.InvariantCultureIgnoreCase) > -1) - { - // Setting last change datetime - result.Add("# PTMagic_LastChanged = " + settingLastChanged.ToShortDateString() + " " + settingLastChanged.ToShortTimeString()); - } - else if (line.IndexOf("PTMagic_SingleMarketSettings", StringComparison.InvariantCultureIgnoreCase) > -1) - { - // Single Market Settings will get overwritten every single run => crop the lines - break; - } - else if (IsPropertyLine(line)) - { - // We have got a property line - if (properties != null) - { - bool madeSubstitution = false; - - foreach (string settingProperty in properties.Keys) - { - if (madeSubstitution) - { - // We've made a substitution so no need to process the rest of the properties - break; - } - else - { - madeSubstitution = SettingsHandler.BuildPropertyLine(result, setting.SettingName, line, properties, settingProperty); - } - } - - if (!madeSubstitution) - { - // No substitution made, so simply copy the line - result.Add(line); - } - } - } - else - { - // Non property line, just copy it - result.Add(line); - } + // Non property line, just copy it + result.Add(line); } } @@ -340,10 +327,11 @@ namespace Core.ProfitTrailer return madeSubstitutions; } - public static void CompileSingleMarketProperties(PTMagic ptmagicInstance, Dictionary> matchedTriggers) + public static List> CompileSingleMarketProperties(PTMagic ptmagicInstance, Dictionary> matchedTriggers) { try { + List> smsApplied = new List>(); List globalPairsLines = new List(); List globalDCALines = new List(); List globalIndicatorsLines = new List(); @@ -470,6 +458,7 @@ namespace Core.ProfitTrailer } ptmagicInstance.Log.DoLogInfo("Built single market settings '" + setting.SettingName + "' for '" + marketPair + "'."); + smsApplied.Add(new KeyValuePair(marketPair, setting.SettingName)); } newPairsLines = SettingsHandler.BuildPropertyLinesForSingleMarketSetting(ptmagicInstance.LastRuntimeSummary.MainMarket, marketPair, ptmagicInstance.TriggeredSingleMarketSettings[marketPair], pairsPropertiesToApply, matchedTriggers, globalPairsProperties, newPairsLines, ptmagicInstance.PTMagicConfiguration, ptmagicInstance.Log); @@ -485,6 +474,8 @@ namespace Core.ProfitTrailer ptmagicInstance.PairsLines = globalPairsLines; ptmagicInstance.DCALines = globalDCALines; ptmagicInstance.IndicatorsLines = globalIndicatorsLines; + + return smsApplied; } catch (Exception ex) { diff --git a/Monitor/Pages/SettingsGeneral.cshtml b/Monitor/Pages/SettingsGeneral.cshtml index 2d2ac23..58df383 100644 --- a/Monitor/Pages/SettingsGeneral.cshtml +++ b/Monitor/Pages/SettingsGeneral.cshtml @@ -89,13 +89,6 @@ -
- -
- -
-
-
diff --git a/Monitor/Pages/SettingsGeneral.cshtml.cs b/Monitor/Pages/SettingsGeneral.cshtml.cs index 899e5eb..2b25ccf 100644 --- a/Monitor/Pages/SettingsGeneral.cshtml.cs +++ b/Monitor/Pages/SettingsGeneral.cshtml.cs @@ -70,7 +70,6 @@ namespace Monitor.Pages PTMagicConfiguration.GeneralSettings.Application.Exchange = HttpContext.Request.Form["Application_Exchange"]; PTMagicConfiguration.GeneralSettings.Application.StartBalance = SystemHelper.TextToDouble(HttpContext.Request.Form["Application_StartBalance"], PTMagicConfiguration.GeneralSettings.Application.StartBalance, "en-US"); PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset = HttpContext.Request.Form["Application_TimezoneOffset"].ToString().Replace(" ", ""); - PTMagicConfiguration.GeneralSettings.Application.AlwaysLoadDefaultBeforeSwitch = HttpContext.Request.Form["Application_AlwaysLoadDefaultBeforeSwitch"].Equals("on"); PTMagicConfiguration.GeneralSettings.Application.FloodProtectionMinutes = SystemHelper.TextToInteger(HttpContext.Request.Form["Application_FloodProtectionMinutes"], PTMagicConfiguration.GeneralSettings.Application.FloodProtectionMinutes); PTMagicConfiguration.GeneralSettings.Application.InstanceName = HttpContext.Request.Form["Application_InstanceName"]; PTMagicConfiguration.GeneralSettings.Application.CoinMarketCapAPIKey = HttpContext.Request.Form["Application_CoinMarketCapAPIKey"]; diff --git a/PTMagic/_defaults/_default settings PT 2.x/_default settings BTC or ETH/settings.general.json b/PTMagic/_defaults/_default settings PT 2.x/_default settings BTC or ETH/settings.general.json index f117631..05e044d 100644 --- a/PTMagic/_defaults/_default settings PT 2.x/_default settings BTC or ETH/settings.general.json +++ b/PTMagic/_defaults/_default settings PT 2.x/_default settings BTC or ETH/settings.general.json @@ -12,8 +12,7 @@ "StartBalance": 0, // The balance you had in your wallet when you started working with Profit Trailer "TimezoneOffset": "+0:00", // Your timezone offset from UTC time "MainFiatCurrency": "USD", // Your main fiat currency that will be used in the monitor - "AlwaysLoadDefaultBeforeSwitch": true, // If this is enabled, PTMagic will always load default settings before switching to another setting - "FloodProtectionMinutes": 15, // If a price trend is just zig-zagging around its trigger, you may want to protect your settings from getting switched back and forth every minute + "FloodProtectionMinutes": 0, // If a price trend is just zig-zagging around its trigger, you may want to protect your settings from getting switched back and forth every minute "InstanceName": "PT Magic", // The name of the instance of this bot. This will be used in your monitor and your Telegram messages. In case you are running more than one bot, you may set different names to separate them "CoinMarketCapAPIKey": "", //CoinMarketCap Api "FreeCurrencyConverterAPIKey": "" // If "MainFiatCurrency" above is anything other than USD, you must obtain an API key from https://free.currencyconverterapi.com/free-api-key diff --git a/PTMagic/_defaults/_default settings PT 2.x/_default settings USDT/settings.general.json b/PTMagic/_defaults/_default settings PT 2.x/_default settings USDT/settings.general.json index f117631..05e044d 100644 --- a/PTMagic/_defaults/_default settings PT 2.x/_default settings USDT/settings.general.json +++ b/PTMagic/_defaults/_default settings PT 2.x/_default settings USDT/settings.general.json @@ -12,8 +12,7 @@ "StartBalance": 0, // The balance you had in your wallet when you started working with Profit Trailer "TimezoneOffset": "+0:00", // Your timezone offset from UTC time "MainFiatCurrency": "USD", // Your main fiat currency that will be used in the monitor - "AlwaysLoadDefaultBeforeSwitch": true, // If this is enabled, PTMagic will always load default settings before switching to another setting - "FloodProtectionMinutes": 15, // If a price trend is just zig-zagging around its trigger, you may want to protect your settings from getting switched back and forth every minute + "FloodProtectionMinutes": 0, // If a price trend is just zig-zagging around its trigger, you may want to protect your settings from getting switched back and forth every minute "InstanceName": "PT Magic", // The name of the instance of this bot. This will be used in your monitor and your Telegram messages. In case you are running more than one bot, you may set different names to separate them "CoinMarketCapAPIKey": "", //CoinMarketCap Api "FreeCurrencyConverterAPIKey": "" // If "MainFiatCurrency" above is anything other than USD, you must obtain an API key from https://free.currencyconverterapi.com/free-api-key diff --git a/_Development/DevSettings/settings.general.json b/_Development/DevSettings/settings.general.json index d31b3f6..e9337bb 100644 --- a/_Development/DevSettings/settings.general.json +++ b/_Development/DevSettings/settings.general.json @@ -12,8 +12,7 @@ "StartBalance": 0, // The balance you had in your wallet when you started working with Profit Trailer "TimezoneOffset": "+0:00", // Your timezone offset from UTC time "MainFiatCurrency": "USD", // Your main fiat currency that will be used in the monitor - "AlwaysLoadDefaultBeforeSwitch": true, // If this is enabled, PTMagic will always load default settings before switching to another setting - "FloodProtectionMinutes": 15, // If a price trend is just zig-zagging around its trigger, you may want to protect your settings from getting switched back and forth every minute + "FloodProtectionMinutes": 0, // If a price trend is just zig-zagging around its trigger, you may want to protect your settings from getting switched back and forth every minute "InstanceName": "PT Magic", // The name of the instance of this bot. This will be used in your monitor and your Telegram messages. In case you are running more than one bot, you may set different names to separate them "CoinMarketCapAPIKey": "" //CoinMarketCap Api },