Merge pull request #217 from HojouFotytu/develop

removed formula parsing
This commit is contained in:
HojouFotytu 2020-08-08 13:13:52 +09:00 committed by GitHub
commit 3dd5a8bfd1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 17 additions and 240 deletions

View File

@ -9,205 +9,6 @@ using System.Text.RegularExpressions;
namespace Core.ProfitTrailer
{
public class OperandToken : Token
{
}
public class OrToken : OperandToken
{
}
public class AndToken : OperandToken
{
}
public class BooleanValueToken : Token
{
}
public class FalseToken : BooleanValueToken
{
}
public class TrueToken : BooleanValueToken
{
}
public class ParenthesisToken : Token
{
}
public class ClosedParenthesisToken : ParenthesisToken
{
}
public class OpenParenthesisToken : ParenthesisToken
{
}
public class NegationToken : Token
{
}
public abstract class Token
{
}
public class Tokenizer
{
private readonly StringReader _reader;
private string _text;
public Tokenizer(string text)
{
_text = text;
_reader = new StringReader(text);
}
public IEnumerable<Token> Tokenize()
{
var tokens = new List<Token>();
while (_reader.Peek() != -1)
{
while (Char.IsWhiteSpace((char)_reader.Peek()))
{
_reader.Read();
}
if (_reader.Peek() == -1)
break;
var c = (char)_reader.Peek();
switch (c)
{
case '!':
tokens.Add(new NegationToken());
_reader.Read();
break;
case '(':
tokens.Add(new OpenParenthesisToken());
_reader.Read();
break;
case ')':
tokens.Add(new ClosedParenthesisToken());
_reader.Read();
break;
default:
if (Char.IsLetter(c))
{
var token = ParseKeyword();
tokens.Add(token);
}
else
{
var remainingText = _reader.ReadToEnd() ?? string.Empty;
throw new Exception(string.Format("Unknown grammar found at position {0} : '{1}'", _text.Length - remainingText.Length, remainingText));
}
break;
}
}
return tokens;
}
private Token ParseKeyword()
{
var text = new StringBuilder();
while (Char.IsLetter((char)_reader.Peek()))
{
text.Append((char)_reader.Read());
}
var potentialKeyword = text.ToString().ToLower();
switch (potentialKeyword)
{
case "true":
return new TrueToken();
case "false":
return new FalseToken();
case "and":
return new AndToken();
case "or":
return new OrToken();
default:
throw new Exception("Expected keyword (True, False, and, or) but found " + potentialKeyword);
}
}
}
public class Parser
{
private readonly IEnumerator<Token> _tokens;
public Parser(IEnumerable<Token> tokens)
{
_tokens = tokens.GetEnumerator();
_tokens.MoveNext();
}
public bool Parse()
{
while (_tokens.Current != null)
{
var isNegated = _tokens.Current is NegationToken;
if (isNegated)
_tokens.MoveNext();
var boolean = ParseBoolean();
if (isNegated)
boolean = !boolean;
while (_tokens.Current is OperandToken)
{
var operand = _tokens.Current;
if (!_tokens.MoveNext())
{
throw new Exception("Missing expression after operand");
}
var nextBoolean = ParseBoolean();
if (operand is AndToken)
boolean = boolean && nextBoolean;
else
boolean = boolean || nextBoolean;
}
return boolean;
}
throw new Exception("Empty expression");
}
private bool ParseBoolean()
{
if (_tokens.Current is BooleanValueToken)
{
var current = _tokens.Current;
_tokens.MoveNext();
if (current is TrueToken)
return true;
return false;
}
if (_tokens.Current is OpenParenthesisToken)
{
_tokens.MoveNext();
var expInPars = Parse();
if (!(_tokens.Current is ClosedParenthesisToken))
throw new Exception("Expecting Closing Parenthesis");
_tokens.MoveNext();
return expInPars;
}
if (_tokens.Current is ClosedParenthesisToken)
throw new Exception("Unexpected Closed Parenthesis");
// since its not a BooleanConstant or Expression in parenthesis, it must be a expression again
var val = Parse();
return val;
}
}
public static class StrategyHelper
{
public static string GetStrategyShortcut(string strategyName, bool onlyValidStrategies)
@ -218,16 +19,20 @@ namespace Core.ProfitTrailer
string strategyLetter = "";
string strategyNameOnly = strategyName;
// PT allows for "advanced_stats" to be turned on in the application settings, to show details of the trailing logic.
// This code ensures PTM doesn't generate an unnecessary shortcut for this information
// PT allows for "advanced_stats" to show details of the trailing logic.
if (result.Contains("STATS"))
{
result = "";
}
// strategy labels that are variable value
if (result.Contains("REBUY"))
// strategy labels with variable values
if (result.Contains("BUY TIMEOUT AS"))
{
time = strategyName.Remove(0, 14);
time = strategyName.Remove(0, 15);
result = "REBUY " + time;
}
if (result.Contains("BUY TIMEOUT"))
{
time = strategyName.Remove(0, 12);
result = "REBUY " + time;
}
if (result.Contains("CHANGE PERC"))
@ -246,7 +51,6 @@ namespace Core.ProfitTrailer
leverage = leverage.Remove(leverage.Length - 1, 1);
result = "ISOL " + leverage + "X";
}
// buy/sell strategies beginning with PT 2.3.3 contain the strategy designation letter followed by a colon and space.
// remove the letter and colon, change to shortcut, then reapply the letter and colon
if (strategyName.Contains(":"))
{
@ -592,54 +396,27 @@ namespace Core.ProfitTrailer
isValidStrategy = StrategyHelper.IsValidStrategy(strategy.Name);
if (!isValidStrategy)
{
if (strategy.Name.Contains("TRIGGERED"))
// remove levels already triggered, to show only currently waiting trigger
{
strategyText += "";
}
else if (strategy.Name.Contains("STATS"))
// avoid parsing advanced buy stats
// Avoid displaying advanced buy stats and completed level formulas
{
strategy.Name = "";
}
else if (strategy.Name.Contains("FORMULA"))
// Parse Various PT Formulas
// Avoid displaying formula details
{
if (strategy.Name.Contains("LEVEL"))
// level X
{
string level = strategy.Name.Substring(5, 2);
string expression = strategy.Name.Remove(0, 17);
expression = expression.Replace("<span class=\"tdgreen\">", "true").Replace("<span class=\"red\">", "false").Replace("</span>", "").Replace("&&", "and").Replace("||", "or");
expression = regx.Replace(expression, String.Empty);
var tokens = new Tokenizer(expression).Tokenize();
var parser = new Parser(tokens);
if (parser.Parse())
{
strategyText += "<span class=\"label label-success\" data-toggle=\"tooltip\" data-placement=\"top\" title=\"LEVEL FORMULA\">L " + level + "</span> ";
}
else
{
strategyText += "<span class=\"label label-danger\" data-toggle=\"tooltip\" data-placement=\"top\" title=\"LEVEL FORMULA\">L " + level + "</span> ";
}
string level = strategy.Name.Substring(5, 1);
strategyText += "<span class=\"label label-warning\" data-toggle=\"tooltip\" data-placement=\"top\" title=\"LEVEL FORMULA\">L " + level + "</span> ";
}
else
// standard formula
{
string expression = strategy.Name.Remove(0, 10);
expression = expression.Replace("<span class=\"tdgreen\">", "true").Replace("<span class=\"red\">", "false").Replace("</span>", "").Replace("&&", "and").Replace("||", "or");
expression = regx.Replace(expression, String.Empty);
var tokens = new Tokenizer(expression).Tokenize();
var parser = new Parser(tokens);
if (parser.Parse())
{
strategyText += "<span class=\"label label-success\" data-toggle=\"tooltip\" data-placement=\"top\" title=\"CONDITIONAL FORMULA\">FORM</span> ";
}
else
{
strategyText += "<span class=\"label label-danger\" data-toggle=\"tooltip\" data-placement=\"top\" title=\"CONDITIONAL FORMULA\">FORM</span> ";
}
strategyText += "<span class=\"label label-warning\" data-toggle=\"tooltip\" data-placement=\"top\" title=\"CONDITIONAL FORMULA\">FORM</span> ";
}
}
else
@ -663,7 +440,7 @@ namespace Core.ProfitTrailer
{
if (isTrue)
{
strategyText = "<span class=\"label label-success\" data-toggle=\"tooltip\" data-placement=\"top\" title=\"" + strategyText + "\">" + StrategyHelper.GetStrategyShortcut(strategyText, true) + "</span>";
strategyText = "<span class=\"label label-success\" data-toggle=\"tooltip\" data-placement=\"top\" title=\"" + strategyText + "\">" + StrategyHelper.GetStrategyShortcut(strategyText, true) + "</span> ";
if (isTrailingBuyActive)
{
@ -675,7 +452,7 @@ namespace Core.ProfitTrailer
isValidStrategy = StrategyHelper.IsValidStrategy(strategyText);
if (isValidStrategy)
{
strategyText = "<span class=\"label label-danger\" data-toggle=\"tooltip\" data-placement=\"top\" title=\"" + strategyText + "\">" + StrategyHelper.GetStrategyShortcut(strategyText, true) + "</span>";
strategyText = "<span class=\"label label-danger\" data-toggle=\"tooltip\" data-placement=\"top\" title=\"" + strategyText + "\">" + StrategyHelper.GetStrategyShortcut(strategyText, true) + "</span> ";
}
else if (strategyText.Equals("") && isValidStrategy == false)
{

View File

@ -6,7 +6,7 @@ using Core.Helper;
using Microsoft.Extensions.DependencyInjection;
[assembly: AssemblyVersion("2.4.4")]
[assembly: AssemblyVersion("2.4.5")]
[assembly: AssemblyProduct("PT Magic")]
namespace PTMagic