Fix for issue #90 stops SMS settings getting stuck

This commit is contained in:
djbadders 2019-03-13 21:00:54 +00:00
parent 67bbfb7580
commit bb6b5421d2
3 changed files with 109 additions and 166 deletions

View File

@ -40,7 +40,8 @@ namespace Core.Main
private DateTime _lastVersionCheck = Constants.confMinDate;
private DateTime _lastFiatCurrencyCheck = Constants.confMinDate;
private string _lastSetting = "";
private string _activeSetting = "";
private string _activeSettingName = "";
private GlobalSetting _activeSetting = null;
private string _defaultSettingName = "";
private string _pairsFileName = "PAIRS.PROPERTIES";
private string _dcaFileName = "DCA.PROPERTIES";
@ -255,19 +256,7 @@ namespace Core.Main
}
}
public string LastSetting
{
get
{
return _lastSetting;
}
set
{
_lastSetting = value;
}
}
public string ActiveSetting
public GlobalSetting ActiveSetting
{
get
{
@ -279,6 +268,18 @@ namespace Core.Main
}
}
public string ActiveSettingName
{
get
{
return _activeSettingName;
}
set
{
_activeSettingName = value;
}
}
public string PairsFileName
{
get
@ -589,6 +590,11 @@ namespace Core.Main
// Force settings refresh first time
EnforceSettingsReapply = true;
// Set the Active config
this.ActiveSetting = this.PTMagicConfiguration.AnalyzerSettings.GlobalSettings.Find(s => s.SettingName.Equals(this.DefaultSettingName, StringComparison.InvariantCultureIgnoreCase));
this.ActiveSettingName = ActiveSetting.SettingName;
this.LastSettingsChange = DateTime.UtcNow;
// Start polling
this.StartPTMagicIntervalTimer();
@ -846,12 +852,10 @@ namespace Core.Main
{
this.RunCount++;
bool headerLinesAdded = false;
this.EnforceSettingsReapply = this.HaveSettingsChanged() || this.EnforceSettingsReapply;
if (PTMagicConfiguration.GeneralSettings.Application.IsEnabled)
{
// Validate settings
this.ValidateSettings();
@ -901,19 +905,19 @@ namespace Core.Main
this.CheckGlobalSettingsTriggers(ref triggeredSetting, ref matchedTriggers);
// Activate global setting
this.ActivateSetting(ref headerLinesAdded, ref triggeredSetting, ref matchedTriggers);
this.ActivateSetting(ref triggeredSetting, ref matchedTriggers);
// Check for single market trend triggers
this.ApplySingleMarketSettings();
// Save new properties to Profit Trailer
this.SaveProfitTrailerProperties(headerLinesAdded);
this.SaveProfitTrailerProperties();
// Save Single Market Settings Summary
this.SaveSingleMarketSettingsSummary();
// Save Runtime Summary
this.SaveRuntimeSummary(headerLinesAdded);
this.SaveRuntimeSummary();
// Cleanup to free memory in between intervals
this.Cleanup();
@ -1107,15 +1111,10 @@ namespace Core.Main
private void LoadCurrentProfitTrailerProperties()
{
// Load current PT properties from API (Valid for PT 2.x and above)
this.Log.DoLogInfo("Loading current Profit Trailer properties from API...");
this.Log.DoLogInfo("Loading current Profit Trailer properties from preset files...");
// Get current PT properties
string pairsPropertiesPath, dcaPropertiesPath, indicatorsPropertiesPath;
GetProfitTrailerPropertiesPaths(out pairsPropertiesPath, out dcaPropertiesPath, out indicatorsPropertiesPath);
this.PairsLines = SettingsAPI.GetPropertyLinesFromAPI("PAIRS", this.PTMagicConfiguration, this.Log);
this.DCALines = SettingsAPI.GetPropertyLinesFromAPI("DCA", this.PTMagicConfiguration, this.Log);
this.IndicatorsLines = SettingsAPI.GetPropertyLinesFromAPI("INDICATORS", this.PTMagicConfiguration, this.Log);
// Get current preset file PT properties
SettingsHandler.CompileProperties(this, this.ActiveSetting, this.LastSettingsChange.ToLocalTime());
if (this.PairsLines != null && this.DCALines != null && this.IndicatorsLines != null)
{
@ -1363,21 +1362,13 @@ namespace Core.Main
}
}
private void ActivateSetting(ref bool headerLinesAdded, ref GlobalSetting triggeredSetting, ref List<string> matchedTriggers)
private void ActivateSetting(ref GlobalSetting triggeredSetting, ref List<string> matchedTriggers)
{
// Get the current active setting
string activeSettingName = SettingsHandler.GetActiveSetting(this, ref headerLinesAdded);
if (String.IsNullOrEmpty(activeSettingName) && this.PTMagicConfiguration.GeneralSettings.Application.TestMode)
{
activeSettingName = this.ActiveSetting;
}
GlobalSetting activeSetting = this.PTMagicConfiguration.AnalyzerSettings.GlobalSettings.Find(s => s.SettingName.Equals(activeSettingName, StringComparison.InvariantCultureIgnoreCase));
// Do we need to write the settings?
if (this.EnforceSettingsReapply || !activeSettingName.Equals(triggeredSetting.SettingName, StringComparison.InvariantCultureIgnoreCase))
if (this.EnforceSettingsReapply || !this.ActiveSettingName.Equals(triggeredSetting.SettingName, StringComparison.InvariantCultureIgnoreCase))
{
// Check if we need to force a refresh of the settings
this.Log.DoLogInfo("Setting '" + activeSettingName + "' currently active. Checking for flood protection...");
this.Log.DoLogInfo("Setting '" + this.ActiveSettingName + "' currently active. Checking for flood protection...");
// If the setting we are about to activate is the default one, do not list matched triggers
if (triggeredSetting.SettingName.Equals(this.DefaultSettingName, StringComparison.InvariantCultureIgnoreCase))
@ -1389,7 +1380,7 @@ namespace Core.Main
if (this.EnforceSettingsReapply || this.LastSettingsChange <= DateTime.UtcNow.AddMinutes(-PTMagicConfiguration.GeneralSettings.Application.FloodProtectionMinutes))
{
// Setting not set => Change setting
if (!EnforceSettingsReapply)
if (!this.ActiveSettingName.Equals(triggeredSetting.SettingName, StringComparison.InvariantCultureIgnoreCase))
{
this.Log.DoLogInfo("Switching global settings to '" + triggeredSetting.SettingName + "'...");
}
@ -1398,44 +1389,51 @@ namespace Core.Main
this.Log.DoLogInfo("Applying '" + triggeredSetting.SettingName + "' as the settings.analyzer.json or a preset file got changed.");
}
SettingsHandler.CompileProperties(this, triggeredSetting);
// Get file lines from the preset files
SettingsHandler.CompileProperties(this, triggeredSetting, DateTime.Now);
this.GlobalSettingWritten = true;
this.Log.DoLogInfo("Setting '" + triggeredSetting.SettingName + "' now active!");
// Record the switch in the runtime summary
this.LastRuntimeSummary.LastGlobalSettingSwitch = this.LastRuntimeSummary.LastRuntime;
this.LastRuntimeSummary.CurrentGlobalSetting = triggeredSetting;
// Build Telegram message
string telegramMessage;
telegramMessage = this.PTMagicConfiguration.GeneralSettings.Application.InstanceName + ": Setting switched to '*" + SystemHelper.SplitCamelCase(triggeredSetting.SettingName) + "*'.";
if (matchedTriggers.Count > 0)
{
telegramMessage += "\n\n*Matching Triggers:*";
foreach (string triggerResult in matchedTriggers)
{
telegramMessage += "\n" + triggerResult;
}
}
if (this.AverageMarketTrendChanges.Keys.Count > 0)
{
telegramMessage += "\n\n*Market Trends:*";
foreach (string key in this.AverageMarketTrendChanges.Keys)
{
telegramMessage += "\n" + key + ": " + this.AverageMarketTrendChanges[key].ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")) + "%";
}
}
// Send Telegram message
if (this.PTMagicConfiguration.GeneralSettings.Telegram.IsEnabled)
{
TelegramHelper.SendMessage(this.PTMagicConfiguration.GeneralSettings.Telegram.BotToken, this.PTMagicConfiguration.GeneralSettings.Telegram.ChatId, telegramMessage, this.PTMagicConfiguration.GeneralSettings.Telegram.SilentMode, this.Log);
}
// Record last settings run
this.LastSetting = activeSettingName;
this.LastSettingsChange = DateTime.UtcNow;
// Build Telegram message
try
{
string telegramMessage;
telegramMessage = this.PTMagicConfiguration.GeneralSettings.Application.InstanceName + ": Setting switched to '*" + SystemHelper.SplitCamelCase(triggeredSetting.SettingName) + "*'.";
if (matchedTriggers.Count > 0)
{
telegramMessage += "\n\n*Matching Triggers:*";
foreach (string triggerResult in matchedTriggers)
{
telegramMessage += "\n" + triggerResult;
}
}
if (this.AverageMarketTrendChanges.Keys.Count > 0)
{
telegramMessage += "\n\n*Market Trends:*";
foreach (string key in this.AverageMarketTrendChanges.Keys)
{
telegramMessage += "\n" + key + ": " + this.AverageMarketTrendChanges[key].ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")) + "%";
}
}
// Send Telegram message
if (this.PTMagicConfiguration.GeneralSettings.Telegram.IsEnabled)
{
TelegramHelper.SendMessage(this.PTMagicConfiguration.GeneralSettings.Telegram.BotToken, this.PTMagicConfiguration.GeneralSettings.Telegram.ChatId, telegramMessage, this.PTMagicConfiguration.GeneralSettings.Telegram.SilentMode, this.Log);
}
}
catch (Exception ex)
{
this.Log.DoLogCritical("Failed to send Telegram message", ex);
}
}
else
{
@ -1443,7 +1441,7 @@ namespace Core.Main
this.Log.DoLogInfo("Flood protection active until " + this.LastSettingsChange.AddMinutes(PTMagicConfiguration.GeneralSettings.Application.FloodProtectionMinutes).ToString() + " (UTC). Not switching settings to '" + triggeredSetting.SettingName + "'!");
this.LastRuntimeSummary.FloodProtectedSetting = triggeredSetting;
this.LastRuntimeSummary.CurrentGlobalSetting = activeSetting;
this.LastRuntimeSummary.CurrentGlobalSetting = this.ActiveSetting;
}
}
else
@ -1456,7 +1454,9 @@ namespace Core.Main
this.LastRuntimeSummary.CurrentGlobalSetting = triggeredSetting;
}
this.ActiveSetting = this.LastRuntimeSummary.CurrentGlobalSetting.SettingName;
// Set Active settings
this.ActiveSetting = this.LastRuntimeSummary.CurrentGlobalSetting;
this.ActiveSettingName = this.ActiveSetting.SettingName;
}
private void ApplySingleMarketSettings()
@ -1494,17 +1494,17 @@ namespace Core.Main
// Check ignore global settings
List<string> ignoredGlobalSettings = SystemHelper.ConvertTokenStringToList(marketSetting.IgnoredGlobalSettings, ",");
if (ignoredGlobalSettings.Contains(this.ActiveSetting))
if (ignoredGlobalSettings.Contains(this.ActiveSettingName))
{
this.Log.DoLogDebug("'" + marketPair + "' - '" + this.ActiveSetting + "' - Is ignored in '" + marketSetting.SettingName + "'.");
this.Log.DoLogDebug("'" + marketPair + "' - '" + this.ActiveSettingName + "' - Is ignored in '" + marketSetting.SettingName + "'.");
continue;
}
// Check allowed global settings
List<string> allowedGlobalSettings = SystemHelper.ConvertTokenStringToList(marketSetting.AllowedGlobalSettings, ",");
if (allowedGlobalSettings.Count > 0 && !allowedGlobalSettings.Contains(this.ActiveSetting))
if (allowedGlobalSettings.Count > 0 && !allowedGlobalSettings.Contains(this.ActiveSettingName))
{
this.Log.DoLogDebug("'" + marketPair + "' - '" + this.ActiveSetting + "' - Is not allowed in '" + marketSetting.SettingName + "'.");
this.Log.DoLogDebug("'" + marketPair + "' - '" + this.ActiveSettingName + "' - Is not allowed in '" + marketSetting.SettingName + "'.");
continue;
}
@ -2025,25 +2025,28 @@ namespace Core.Main
}
}
private void SaveProfitTrailerProperties(bool headerLinesAdded)
private void SaveProfitTrailerProperties()
{
// Get current PT properties
string pairsPropertiesPath, dcaPropertiesPath, indicatorsPropertiesPath;
GetProfitTrailerPropertiesPaths(out pairsPropertiesPath, out dcaPropertiesPath, out indicatorsPropertiesPath);
if (headerLinesAdded || this.GlobalSettingWritten || this.SingleMarketSettingWritten)
if (this.GlobalSettingWritten || this.SingleMarketSettingWritten)
{
// Save current PT properties to API (Valid for PT 2.x and above)
this.Log.DoLogInfo("Saving properties using API...");
// Send all Properties
if (!this.PTMagicConfiguration.GeneralSettings.Application.TestMode) SettingsAPI.SendPropertyLinesToAPI(this.PairsLines, this.DCALines, this.IndicatorsLines, this.PTMagicConfiguration, this.Log);
if (!this.PTMagicConfiguration.GeneralSettings.Application.TestMode)
{
SettingsAPI.SendPropertyLinesToAPI(this.PairsLines, this.DCALines, this.IndicatorsLines, this.PTMagicConfiguration, this.Log);
}
this.Log.DoLogInfo("Properties saved!");
}
else
{
this.Log.DoLogInfo("Nothing changed, no files touched!");
this.Log.DoLogInfo("Nothing changed, no config written!");
}
}
@ -2058,7 +2061,7 @@ namespace Core.Main
this.Log.DoLogInfo("Single Market Settings Summary saved.");
}
private void SaveRuntimeSummary(bool headerLinesAdded)
private void SaveRuntimeSummary()
{
DateTime endTime = DateTime.UtcNow;
int elapsedSeconds = (int)Math.Round(endTime.Subtract(this.LastRuntime).TotalSeconds, 0);
@ -2523,7 +2526,7 @@ namespace Core.Main
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("+ Files changed: " + (((headerLinesAdded || this.GlobalSettingWritten || this.SingleMarketSettingWritten) && !this.PTMagicConfiguration.GeneralSettings.Application.TestMode) ? "Yes" : "No"));
this.Log.DoLogInfo("+ Files changed: " + (((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)
{

View File

@ -39,31 +39,11 @@ namespace Core.ProfitTrailer
}
}
public static string GetActiveSetting(PTMagicConfiguration systemConfiguration, string pairsFileName, string dcaFileName, string indicatorsFileName, LogHelper log)
{
string pairsPropertiesPath = systemConfiguration.GeneralSettings.Application.ProfitTrailerPath + Constants.PTPathTrading + Path.DirectorySeparatorChar + pairsFileName;
string result = SettingsFiles.GetActiveSettingFromFile(pairsPropertiesPath, systemConfiguration, log);
if (result.Equals(""))
{
SettingsFiles.WriteHeaderLines(pairsPropertiesPath, "Default", systemConfiguration);
string dcaPropertiesPath = systemConfiguration.GeneralSettings.Application.ProfitTrailerPath + Constants.PTPathTrading + Path.DirectorySeparatorChar + dcaFileName;
SettingsFiles.WriteHeaderLines(dcaPropertiesPath, "Default", systemConfiguration);
string inditactorsPropertiesPath = systemConfiguration.GeneralSettings.Application.ProfitTrailerPath + Constants.PTPathTrading + Path.DirectorySeparatorChar + indicatorsFileName;
SettingsFiles.WriteHeaderLines(inditactorsPropertiesPath, "Default", systemConfiguration);
}
return result;
}
public static void WriteHeaderLines(string filePath, string settingName, PTMagicConfiguration systemConfiguration)
{
// Writing Header lines
List<string> lines = File.ReadAllLines(filePath).ToList();
lines.Insert(0, "");
lines.Insert(0, "#");
lines.Insert(0, "# ####################################");
lines.Insert(0, "# PTMagic_LastChanged = " + DateTime.UtcNow.ToShortDateString() + " " + DateTime.UtcNow.ToShortTimeString());
lines.Insert(0, "# PTMagic_ActiveSetting = " + SystemHelper.StripBadCode(settingName, Constants.WhiteListProperties));
@ -150,7 +130,6 @@ namespace Core.ProfitTrailer
}
}
if (forceCheck)
{
log.DoLogInfo("Checking automated settings for presets...");

View File

@ -136,55 +136,15 @@ namespace Core.ProfitTrailer
return result;
}
public static string GetActiveSetting(PTMagic ptmagicInstance, ref bool headerLinesAdded)
public static void WriteHeaderLines(string settingsName, DateTime settingsChangeTimestamp, List<string> lines)
{
string result = "";
if ((ptmagicInstance.PairsLines == null) || ptmagicInstance.PTMagicConfiguration.GeneralSettings.Application.TestMode)
{
// Return current active setting
result = ptmagicInstance.ActiveSetting;
}
else
{
// Determine from file lines
foreach (string line in ptmagicInstance.PairsLines)
{
if (line.IndexOf("PTMagic_ActiveSetting", StringComparison.InvariantCultureIgnoreCase) > -1)
{
result = line.Replace("PTMagic_ActiveSetting", "", StringComparison.InvariantCultureIgnoreCase);
result = result.Replace("#", "");
result = result.Replace("=", "").Trim();
result = SystemHelper.StripBadCode(result, Constants.WhiteListProperties);
break;
}
}
if (result.Equals(""))
{
SettingsHandler.WriteHeaderLines("Pairs", ptmagicInstance);
SettingsHandler.WriteHeaderLines("DCA", ptmagicInstance);
SettingsHandler.WriteHeaderLines("Indicators", ptmagicInstance);
headerLinesAdded = true;
}
}
return result;
}
public static void WriteHeaderLines(string fileType, PTMagic ptmagicInstance)
{
List<string> fileLines = (List<string>)ptmagicInstance.GetType().GetProperty(fileType + "Lines").GetValue(ptmagicInstance, null);
// Writing Header lines
fileLines.Insert(0, "#");
fileLines.Insert(0, "# ####################################");
fileLines.Insert(0, "# PTMagic_LastChanged = " + DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString());
fileLines.Insert(0, "# PTMagic_ActiveSetting = " + SystemHelper.StripBadCode(ptmagicInstance.DefaultSettingName, Constants.WhiteListProperties));
fileLines.Insert(0, "# ####################################");
ptmagicInstance.GetType().GetProperty(fileType + "Lines").SetValue(ptmagicInstance, fileLines);
lines.Insert(0, "#");
lines.Insert(0, "# ####################################");
lines.Insert(0, "# PTMagic_LastChanged = " + settingsChangeTimestamp.ToShortDateString() + " " + settingsChangeTimestamp.ToShortTimeString());
lines.Insert(0, "# PTMagic_ActiveSetting = " + SystemHelper.StripBadCode(settingsName, Constants.WhiteListProperties));
lines.Insert(0, "# ####### PTMagic Current Setting ########");
lines.Insert(0, "# ####################################");
}
public static Dictionary<string, string> GetPropertiesAsDictionary(List<string> propertyLines)
@ -229,27 +189,25 @@ namespace Core.ProfitTrailer
return result;
}
public static void CompileProperties(PTMagic ptmagicInstance, GlobalSetting setting)
public static void CompileProperties(PTMagic ptmagicInstance, GlobalSetting setting, DateTime settingTimestamp)
{
SettingsHandler.BuildPropertyLines("Pairs", ptmagicInstance, setting);
SettingsHandler.BuildPropertyLines("DCA", ptmagicInstance, setting);
SettingsHandler.BuildPropertyLines("Indicators", ptmagicInstance, setting);
SettingsHandler.BuildPropertyLines("Pairs", ptmagicInstance, setting, settingTimestamp);
SettingsHandler.BuildPropertyLines("DCA", ptmagicInstance, setting, settingTimestamp);
SettingsHandler.BuildPropertyLines("Indicators", ptmagicInstance, setting, settingTimestamp);
}
public static void BuildPropertyLines(string fileType, PTMagic ptmagicInstance, GlobalSetting setting)
public static void BuildPropertyLines(string fileType, PTMagic ptmagicInstance, GlobalSetting setting, DateTime settingLastChanged)
{
bool headerLinesExist = false;
List<string> result = new List<string>();
List<string> fileLines = (List<string>)ptmagicInstance.GetType().GetProperty(fileType + "Lines").GetValue(ptmagicInstance, null);
Dictionary<string, object> properties = (Dictionary<string, object>)setting.GetType().GetProperty(fileType + "Properties").GetValue(setting, null);
if (properties != null)
{
// 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));
if (defaultSetting != null)
@ -283,27 +241,23 @@ namespace Core.ProfitTrailer
}
}
// 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 = " + DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString());
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;
}
@ -342,6 +296,13 @@ namespace Core.ProfitTrailer
}
}
// Write header lines if required
if (!headerLinesExist)
{
WriteHeaderLines(setting.SettingName, settingLastChanged, result);
}
// Save lines to current context for the file type
ptmagicInstance.GetType().GetProperty(fileType + "Lines").SetValue(ptmagicInstance, result);
}