Merge pull request #96 from djbadders/develop

Fixes for when settings have blank file properties
This commit is contained in:
HojouFotytu 2019-03-17 15:08:35 +09:00 committed by GitHub
commit 08d8d8bd99
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 218 additions and 199 deletions

View File

@ -40,7 +40,6 @@ namespace Core.Main.DataObjects.PTMagicData
public string ProfitTrailerServerAPIToken { get; set; } public string ProfitTrailerServerAPIToken { get; set; }
public string ProfitTrailerMonitorURL { get; set; } = "http://localhost:8081/"; public string ProfitTrailerMonitorURL { get; set; } = "http://localhost:8081/";
public string ProfitTrailerDefaultSettingName { get; set; } = "default"; public string ProfitTrailerDefaultSettingName { get; set; } = "default";
public bool AlwaysLoadDefaultBeforeSwitch { get; set; } = true;
public int FloodProtectionMinutes { get; set; } = 15; public int FloodProtectionMinutes { get; set; } = 15;
public string Exchange { get; set; } public string Exchange { get; set; }
public double StartBalance { get; set; } = 0; public double StartBalance { get; set; } = 0;

View File

@ -32,7 +32,8 @@ namespace Core.Main
private int _runCount = 0; private int _runCount = 0;
private int _totalElapsedSeconds = 0; private int _totalElapsedSeconds = 0;
private bool _globalSettingWritten = false; private bool _globalSettingWritten = false;
private bool _singleMarketSettingWritten = false; private bool _singleMarketSettingChanged = false;
private List<KeyValuePair<string, string>> _lastActiveSingleMarketSettings = null;
private bool _enforceSettingsReapply = false; private bool _enforceSettingsReapply = false;
private DateTime _lastRuntime = Constants.confMinDate; private DateTime _lastRuntime = Constants.confMinDate;
private DateTime _lastSettingsChange = Constants.confMinDate; private DateTime _lastSettingsChange = Constants.confMinDate;
@ -160,15 +161,15 @@ namespace Core.Main
} }
} }
public bool SingleMarketSettingWritten public bool SingleMarketSettingChanged
{ {
get get
{ {
return _singleMarketSettingWritten; return _singleMarketSettingChanged;
} }
set set
{ {
_singleMarketSettingWritten = value; _singleMarketSettingChanged = value;
} }
} }
@ -853,93 +854,134 @@ namespace Core.Main
// Only let one thread change the settings at once // Only let one thread change the settings at once
lock (_lockObj) lock (_lockObj)
{ {
this.RunCount++; try
this.EnforceSettingsReapply = this.HaveSettingsChanged() || this.EnforceSettingsReapply;
if (PTMagicConfiguration.GeneralSettings.Application.IsEnabled)
{ {
// 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" // Change state to "Running"
this.State = Constants.PTMagicBotState_Running; this.State = Constants.PTMagicBotState_Running;
this.RunCount++;
this.LastRuntime = DateTime.UtcNow; this.LastRuntime = DateTime.UtcNow;
this.LastRuntimeSummary = new Summary(); this.EnforceSettingsReapply = this.HaveSettingsChanged() || this.EnforceSettingsReapply;
this.LastRuntimeSummary.LastRuntime = this.LastRuntime;
this.LastRuntimeSummary.Version = this.CurrentVersion.Major.ToString() + "." + this.CurrentVersion.Minor.ToString() + "." + this.CurrentVersion.Build.ToString();
// Check for latest GitHub version if (PTMagicConfiguration.GeneralSettings.Application.IsEnabled)
this.CheckLatestGitHubVersion(this.LastRuntimeSummary.Version); {
// Validate settings
this.ValidateSettings();
// Get latest main fiat currency exchange rate // Start the process
this.GetMainFiatCurrencyDetails(); 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 // Initialise the last runtime summary
this.LoadCurrentProfitTrailerProperties(); 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 // Check for latest GitHub version
this.LoadSMSSummaries(); this.CheckLatestGitHubVersion(this.LastRuntimeSummary.Version);
// Get saved market info // Get latest main fiat currency exchange rate
this.MarketInfos = BaseAnalyzer.GetMarketInfosFromFile(this.PTMagicConfiguration, this.Log); this.GetMainFiatCurrencyDetails();
// Build exchange market data // Load current PT files
this.BuildMarketData(); this.LoadCurrentProfitTrailerProperties();
// Get markets from PT properties // Loading SMS Summaries
this.BuildMarketList(); this.LoadSMSSummaries();
this.ValidateMarketList();
// Build global market trends configured in settings // Get saved market info
this.BuildGlobalMarketTrends(); this.MarketInfos = BaseAnalyzer.GetMarketInfosFromFile(this.PTMagicConfiguration, this.Log);
// Check for global settings triggers // Build exchange market data
GlobalSetting triggeredSetting = this.PTMagicConfiguration.AnalyzerSettings.GlobalSettings.Find(s => s.SettingName.Equals(this.DefaultSettingName, StringComparison.InvariantCultureIgnoreCase)); this.BuildMarketData();
List<string> matchedTriggers = new List<string>();
this.CheckGlobalSettingsTriggers(ref triggeredSetting, ref matchedTriggers);
// Activate global setting // Get markets from PT properties
this.ActivateSetting(ref triggeredSetting, ref matchedTriggers); this.BuildMarketList();
this.ValidateMarketList();
// Check for single market trend triggers // Build global market trends configured in settings
this.ApplySingleMarketSettings(); this.BuildGlobalMarketTrends();
// Save new properties to Profit Trailer // Check for global settings triggers
this.SaveProfitTrailerProperties(); GlobalSetting triggeredSetting = this.PTMagicConfiguration.AnalyzerSettings.GlobalSettings.Find(s => s.SettingName.Equals(this.DefaultSettingName, StringComparison.InvariantCultureIgnoreCase));
List<string> matchedTriggers = new List<string>();
this.CheckGlobalSettingsTriggers(ref triggeredSetting, ref matchedTriggers);
// Save Single Market Settings Summary // Activate global setting
this.SaveSingleMarketSettingsSummary(); this.ActivateSetting(ref triggeredSetting, ref matchedTriggers);
// Save Runtime Summary // Check for single market trend triggers
this.SaveRuntimeSummary(); 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 // Cleanup to free memory in between intervals
this.Cleanup(); this.Cleanup();
// Change state to Finished / Stopped // Change state to Finished / Stopped
this.State = Constants.PTMagicBotState_Idle; this.State = Constants.PTMagicBotState_Idle;
} }
else
{
this.State = Constants.PTMagicBotState_Idle;
Log.DoLogWarn("PTMagic disabled, shutting down until next raid...");
}
} }
} }
else else
{ {
if (this.RunCount > 1) 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")) 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) if (this.TriggeredSingleMarketSettings.Count > 0)
{ {
// Write single market settings
this.Log.DoLogInfo("Building single market settings for '" + this.TriggeredSingleMarketSettings.Count.ToString() + "' markets..."); this.Log.DoLogInfo("Building single market settings for '" + this.TriggeredSingleMarketSettings.Count.ToString() + "' markets...");
SettingsHandler.CompileSingleMarketProperties(this, matchedMarketTriggers); // Write single market settings
this.SingleMarketSettingWritten = true; 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."); this.Log.DoLogInfo("Building single market settings completed.");
} }
@ -2018,9 +2068,8 @@ namespace Core.Main
this.Log.DoLogInfo("No settings triggered for single markets."); this.Log.DoLogInfo("No settings triggered for single markets.");
// Remove single market settings if no triggers are met - if necessary // Remove single market settings if no triggers are met - if necessary
this.SingleMarketSettingWritten = SettingsHandler.RemoveSingleMarketSettings(this); this.SingleMarketSettingChanged = SettingsHandler.RemoveSingleMarketSettings(this);
} }
} }
else else
{ {
@ -2028,13 +2077,31 @@ namespace Core.Main
} }
} }
private bool haveSingleMarketSettingsHaveChanged(List<KeyValuePair<string, string>> oldMarketTriggers, List<KeyValuePair<string, string>> 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() private void SaveProfitTrailerProperties()
{ {
// Get current PT properties // Get current PT properties
string pairsPropertiesPath, dcaPropertiesPath, indicatorsPropertiesPath; string pairsPropertiesPath, dcaPropertiesPath, indicatorsPropertiesPath;
GetProfitTrailerPropertiesPaths(out pairsPropertiesPath, out dcaPropertiesPath, out 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) // Save current PT properties to API (Valid for PT 2.x and above)
this.Log.DoLogInfo("Saving properties using API..."); this.Log.DoLogInfo("Saving properties using API...");
@ -2064,15 +2131,12 @@ namespace Core.Main
this.Log.DoLogInfo("Single Market Settings Summary saved."); this.Log.DoLogInfo("Single Market Settings Summary saved.");
} }
private void SaveRuntimeSummary() private void SaveRuntimeSummary(int elapsedSeconds)
{ {
DateTime endTime = DateTime.UtcNow; this.Log.DoLogInfo("Building LastRuntimeSummary.json for your monitor...");
int elapsedSeconds = (int)Math.Round(endTime.Subtract(this.LastRuntime).TotalSeconds, 0);
this.LastRuntimeSummary.LastRuntimeSeconds = elapsedSeconds; this.LastRuntimeSummary.LastRuntimeSeconds = elapsedSeconds;
this.Log.DoLogInfo("Building LastRuntimeSummary.json for your monitor...");
// Load existing runtime summary and read ongoing data // Load existing runtime summary and read ongoing data
if (File.Exists(Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + Constants.PTMagicPathData + Path.DirectorySeparatorChar + "LastRuntimeSummary.json")) 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); 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() private void Cleanup()
{ {
// Clear down memory
this.GlobalSettingWritten = false; this.GlobalSettingWritten = false;
this.SingleMarketSettingWritten = false; this.SingleMarketSettingChanged = false;
this.EnforceSettingsReapply = false; this.EnforceSettingsReapply = false;
this.PairsLines = null; this.PairsLines = null;
@ -2562,6 +2594,14 @@ namespace Core.Main
this.ExchangeMarketList = null; this.ExchangeMarketList = null;
this.MarketList = new List<string>(); this.MarketList = new List<string>();
this.LastRuntimeSummary = null; 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 #endregion
} }

View File

@ -200,99 +200,86 @@ namespace Core.ProfitTrailer
{ {
bool headerLinesExist = false; bool headerLinesExist = false;
List<string> result = new List<string>(); List<string> result = new List<string>();
List<string> fileLines = (List<string>)ptmagicInstance.GetType().GetProperty(fileType + "Lines").GetValue(ptmagicInstance, null); List<string> fileLines = null;
// Analsye the properties for the setting and apply
Dictionary<string, object> properties = (Dictionary<string, object>)setting.GetType().GetProperty(fileType + "Properties").GetValue(setting, null); Dictionary<string, object> properties = (Dictionary<string, object>)setting.GetType().GetProperty(fileType + "Properties").GetValue(setting, null);
if (properties != null)
// Building Properties
if (properties == null || !properties.ContainsKey("File"))
{ {
// Building Properties // Load default settings as basis for the switch
if (!setting.SettingName.Equals(ptmagicInstance.DefaultSettingName, StringComparison.InvariantCultureIgnoreCase) && ptmagicInstance.PTMagicConfiguration.GeneralSettings.Application.AlwaysLoadDefaultBeforeSwitch && !properties.ContainsKey("File")) GlobalSetting defaultSetting = ptmagicInstance.PTMagicConfiguration.AnalyzerSettings.GlobalSettings.Find(a => a.SettingName.Equals(ptmagicInstance.DefaultSettingName, StringComparison.InvariantCultureIgnoreCase));
Dictionary<string, object> defaultProperties = (Dictionary<string, object>)defaultSetting.GetType().GetProperty(fileType + "Properties").GetValue(defaultSetting, null);
if (defaultProperties.ContainsKey("File"))
{ {
// Load default settings as basis for the switch // Load the default settings file lines
GlobalSetting defaultSetting = ptmagicInstance.PTMagicConfiguration.AnalyzerSettings.GlobalSettings.Find(a => a.SettingName.Equals(ptmagicInstance.DefaultSettingName, StringComparison.InvariantCultureIgnoreCase)); fileLines = SettingsFiles.GetPresetFileLinesAsList(defaultSetting.SettingName, defaultProperties["File"].ToString(), ptmagicInstance.PTMagicConfiguration);
if (defaultSetting != null) }
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<string, object> defaultProperties = new Dictionary<string, object>(); bool madeSubstitution = false;
switch (fileType.ToLower())
foreach (string settingProperty in properties.Keys)
{ {
case "pairs": if (madeSubstitution)
defaultProperties = defaultSetting.PairsProperties; {
break; // We've made a substitution so no need to process the rest of the properties
case "dca":
defaultProperties = defaultSetting.DCAProperties;
break;
case "inidcators":
defaultProperties = defaultSetting.IndicatorsProperties;
break; 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 else
{ {
// Check if settings are configured in a seperate file // Non property line, just copy it
if (properties.ContainsKey("File")) result.Add(line);
{
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);
}
} }
} }
@ -340,10 +327,11 @@ namespace Core.ProfitTrailer
return madeSubstitutions; return madeSubstitutions;
} }
public static void CompileSingleMarketProperties(PTMagic ptmagicInstance, Dictionary<string, List<string>> matchedTriggers) public static List<KeyValuePair<string, string>> CompileSingleMarketProperties(PTMagic ptmagicInstance, Dictionary<string, List<string>> matchedTriggers)
{ {
try try
{ {
List<KeyValuePair<string, string>> smsApplied = new List<KeyValuePair<string, string>>();
List<string> globalPairsLines = new List<string>(); List<string> globalPairsLines = new List<string>();
List<string> globalDCALines = new List<string>(); List<string> globalDCALines = new List<string>();
List<string> globalIndicatorsLines = new List<string>(); List<string> globalIndicatorsLines = new List<string>();
@ -470,6 +458,7 @@ namespace Core.ProfitTrailer
} }
ptmagicInstance.Log.DoLogInfo("Built single market settings '" + setting.SettingName + "' for '" + marketPair + "'."); ptmagicInstance.Log.DoLogInfo("Built single market settings '" + setting.SettingName + "' for '" + marketPair + "'.");
smsApplied.Add(new KeyValuePair<string, string>(marketPair, setting.SettingName));
} }
newPairsLines = SettingsHandler.BuildPropertyLinesForSingleMarketSetting(ptmagicInstance.LastRuntimeSummary.MainMarket, marketPair, ptmagicInstance.TriggeredSingleMarketSettings[marketPair], pairsPropertiesToApply, matchedTriggers, globalPairsProperties, newPairsLines, ptmagicInstance.PTMagicConfiguration, ptmagicInstance.Log); 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.PairsLines = globalPairsLines;
ptmagicInstance.DCALines = globalDCALines; ptmagicInstance.DCALines = globalDCALines;
ptmagicInstance.IndicatorsLines = globalIndicatorsLines; ptmagicInstance.IndicatorsLines = globalIndicatorsLines;
return smsApplied;
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@ -89,13 +89,6 @@
</div> </div>
</div> </div>
<div class="form-group row">
<label class="col-md-4 col-form-label">Always Load Default Before Switch <i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="If this is enabled, PTMagic will always load default settings before switching to another setting."></i></label>
<div class="col-md-8">
<input type="checkbox" name="Application_AlwaysLoadDefaultBeforeSwitch" checked="@(Model.PTMagicConfiguration.GeneralSettings.Application.AlwaysLoadDefaultBeforeSwitch)" data-plugin="switchery" data-color="#81c868" data-size="small" />
</div>
</div>
<div class="form-group row"> <div class="form-group row">
<label class="col-md-4 col-form-label">Flood Protection Minutes <i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="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."></i></label> <label class="col-md-4 col-form-label">Flood Protection Minutes <i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="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."></i></label>
<div class="col-md-8"> <div class="col-md-8">

View File

@ -70,7 +70,6 @@ namespace Monitor.Pages
PTMagicConfiguration.GeneralSettings.Application.Exchange = HttpContext.Request.Form["Application_Exchange"]; 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.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.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.FloodProtectionMinutes = SystemHelper.TextToInteger(HttpContext.Request.Form["Application_FloodProtectionMinutes"], PTMagicConfiguration.GeneralSettings.Application.FloodProtectionMinutes);
PTMagicConfiguration.GeneralSettings.Application.InstanceName = HttpContext.Request.Form["Application_InstanceName"]; PTMagicConfiguration.GeneralSettings.Application.InstanceName = HttpContext.Request.Form["Application_InstanceName"];
PTMagicConfiguration.GeneralSettings.Application.CoinMarketCapAPIKey = HttpContext.Request.Form["Application_CoinMarketCapAPIKey"]; PTMagicConfiguration.GeneralSettings.Application.CoinMarketCapAPIKey = HttpContext.Request.Form["Application_CoinMarketCapAPIKey"];

View File

@ -12,8 +12,7 @@
"StartBalance": 0, // The balance you had in your wallet when you started working with Profit Trailer "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 "TimezoneOffset": "+0:00", // Your timezone offset from UTC time
"MainFiatCurrency": "USD", // Your main fiat currency that will be used in the monitor "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": 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
"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
"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 "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 "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 "FreeCurrencyConverterAPIKey": "" // If "MainFiatCurrency" above is anything other than USD, you must obtain an API key from https://free.currencyconverterapi.com/free-api-key

View File

@ -12,8 +12,7 @@
"StartBalance": 0, // The balance you had in your wallet when you started working with Profit Trailer "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 "TimezoneOffset": "+0:00", // Your timezone offset from UTC time
"MainFiatCurrency": "USD", // Your main fiat currency that will be used in the monitor "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": 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
"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
"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 "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 "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 "FreeCurrencyConverterAPIKey": "" // If "MainFiatCurrency" above is anything other than USD, you must obtain an API key from https://free.currencyconverterapi.com/free-api-key

View File

@ -12,8 +12,7 @@
"StartBalance": 0, // The balance you had in your wallet when you started working with Profit Trailer "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 "TimezoneOffset": "+0:00", // Your timezone offset from UTC time
"MainFiatCurrency": "USD", // Your main fiat currency that will be used in the monitor "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": 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
"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
"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 "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 "CoinMarketCapAPIKey": "" //CoinMarketCap Api
}, },