From b54fbf0aa82870087d5b04098b7b8ca5b613fff0 Mon Sep 17 00:00:00 2001 From: FxPouya <59786270+FxPouya@users.noreply.github.com> Date: Fri, 26 Dec 2025 10:59:31 +0330 Subject: [PATCH] Add files via upload --- js/ctrader-converter.js | 5 +- js/mq4-converter.js | 5 +- js/mq5-converter.js | 5 +- js/pine-converter.js | 3 +- js/rule-parser.js | 32 ++++++++--- manual.html | 3 +- test-api.html | 116 ++++++++++++++++++++++++++++++++++++++++ 7 files changed, 154 insertions(+), 15 deletions(-) create mode 100644 test-api.html diff --git a/js/ctrader-converter.js b/js/ctrader-converter.js index 95595dc..f4ca9ff 100644 --- a/js/ctrader-converter.js +++ b/js/ctrader-converter.js @@ -16,7 +16,8 @@ class CTraderConverter { const magicNumber = Math.floor(100000 + Math.random() * 900000); const buyConditions = this.parser.parseRules(buy_rules, 'csharp'); - const sellConditions = this.parser.parseRules(sell_rules, 'csharp'); + // SELL rules use inverted operators + const sellConditions = this.parser.parseRulesInverted(buy_rules, 'csharp'); // Convert MQL-style array access to cTrader MarketSeries const convertToCTrader = (condition) => { @@ -108,7 +109,7 @@ namespace cAlgo.Robots public int EndMinute { get; set; } //=== SIGNAL SETTINGS === - [Parameter("Close on Opposite", DefaultValue = true, Group = "Signals")] + [Parameter("Close on Opposite", DefaultValue = false, Group = "Signals")] public bool CloseOnOpposite { get; set; } //=== DISPLAY SETTINGS === diff --git a/js/mq4-converter.js b/js/mq4-converter.js index 15fdc9d..8afa044 100644 --- a/js/mq4-converter.js +++ b/js/mq4-converter.js @@ -16,7 +16,8 @@ class MQ4Converter { const magicNumber = Math.floor(100000 + Math.random() * 900000); const buyConditions = this.parser.parseRules(buy_rules, 'mql'); - const sellConditions = this.parser.parseRules(sell_rules, 'mql'); + // SELL rules use inverted operators + const sellConditions = this.parser.parseRulesInverted(buy_rules, 'mql'); return `//+------------------------------------------------------------------+ //| Strategy_${symbol}.mq4 | @@ -58,7 +59,7 @@ input int EndHour = 22; // End Hour (Server Time) input int EndMinute = 0; // End Minute //=== SIGNAL SETTINGS === -input bool CloseOnOpposite = true; // Close Trade on Opposite Signal +input bool CloseOnOpposite = false; // Close Trade on Opposite Signal //=== DISPLAY SETTINGS === input bool ShowChartInfo = true; // Show Info on Chart diff --git a/js/mq5-converter.js b/js/mq5-converter.js index f08bd65..a93747c 100644 --- a/js/mq5-converter.js +++ b/js/mq5-converter.js @@ -16,7 +16,8 @@ class MQ5Converter { const magicNumber = Math.floor(100000 + Math.random() * 900000); const buyConditions = this.parser.parseRules(buy_rules, 'mq5'); - const sellConditions = this.parser.parseRules(sell_rules, 'mq5'); + // SELL rules use inverted operators + const sellConditions = this.parser.parseRulesInverted(buy_rules, 'mq5'); return `//+------------------------------------------------------------------+ //| Strategy_${symbol}.mq5 | @@ -65,7 +66,7 @@ input int EndMinute = 0; // End Minute //=== SIGNAL SETTINGS === input group "=== Signal Settings ===" -input bool CloseOnOpposite = true; // Close Trade on Opposite Signal +input bool CloseOnOpposite = false; // Close Trade on Opposite Signal //=== DISPLAY SETTINGS === input group "=== Display Settings ===" diff --git a/js/pine-converter.js b/js/pine-converter.js index 92a872d..86c98a7 100644 --- a/js/pine-converter.js +++ b/js/pine-converter.js @@ -13,7 +13,8 @@ class PineConverter { const tpMultiplier = parameters.tp_multiplier || 3.0; const buyConditions = this.parser.parseRules(buy_rules, 'pine'); - const sellConditions = this.parser.parseRules(sell_rules, 'pine'); + // SELL rules use inverted operators + const sellConditions = this.parser.parseRulesInverted(buy_rules, 'pine'); return `//@version=5 strategy("Strategy ${symbol}", overlay=true, diff --git a/js/rule-parser.js b/js/rule-parser.js index 078ca2a..a356d66 100644 --- a/js/rule-parser.js +++ b/js/rule-parser.js @@ -6,33 +6,51 @@ class RuleParser { return rules.map(rule => this.parseRule(rule, platform)); } - parseRule(rule, platform = 'mql') { + // Parse rules with inverted operators (for SELL signals) + parseRulesInverted(rules, platform = 'mql') { + return rules.map(rule => this.parseRule(rule, platform, true)); + } + + parseRule(rule, platform = 'mql', invertOp = false) { if (rule.type === 'simple') { - return this.parseSimpleRule(rule, platform); + return this.parseSimpleRule(rule, platform, invertOp); } else { - return this.parseArithmeticRule(rule, platform); + return this.parseArithmeticRule(rule, platform, invertOp); } } - parseSimpleRule(rule, platform) { + parseSimpleRule(rule, platform, invertOp = false) { const left = this.getPriceReference(rule.left.price, rule.left.shift, platform); const right = this.getPriceReference(rule.right.price, rule.right.shift, platform); - const operator = rule.operator; + const operator = invertOp ? this.invertOperator(rule.operator) : rule.operator; return `${left} ${operator} ${right}`; } - parseArithmeticRule(rule, platform) { + parseArithmeticRule(rule, platform, invertOp = false) { const left1 = this.getPriceReference(rule.left.price1, rule.left.shift1, platform); const left2 = this.getPriceReference(rule.left.price2, rule.left.shift2, platform); const leftOp = rule.left.op; const right = this.getPriceReference(rule.right.price, rule.right.shift, platform); const multiplier = rule.right.multiplier; - const operator = rule.operator; + const operator = invertOp ? this.invertOperator(rule.operator) : rule.operator; return `(${left1} ${leftOp} ${left2}) ${operator} (${right} * ${multiplier})`; } + // Invert comparison operators for SELL signals + invertOperator(operator) { + const inversionMap = { + '<': '>=', + '<=': '>', + '>': '<=', + '>=': '<', + '==': '!=', + '!=': '==' + }; + return inversionMap[operator] || operator; + } + getPriceReference(priceType, shift, platform) { const price = priceType.charAt(0).toUpperCase() + priceType.slice(1).toLowerCase(); diff --git a/manual.html b/manual.html index cae8472..dfcb1e2 100644 --- a/manual.html +++ b/manual.html @@ -221,7 +221,8 @@

Step 2: Activate License

    -
  1. Open the application in your web browser
  2. +
  3. Open the application at: https://web.fxmathquant.com/login.html
  4. Enter your license key in the format: XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX
  5. Click "Activate License"
  6. Wait for validation (requires internet connection)
  7. diff --git a/test-api.html b/test-api.html new file mode 100644 index 0000000..d4f54b2 --- /dev/null +++ b/test-api.html @@ -0,0 +1,116 @@ + + + + + API Test - Trial License + + + + +

    Trial License API Test

    + +
    +

    Test 1: Local API

    +

    Tests: http://localhost/FxMathQuant-Server/api/create.php

    + +
    +
    + +
    +

    Test 2: Production API

    +

    Tests: https://fxmath.com/quantw/api/create.php

    + +
    +
    + + + + + \ No newline at end of file