mirror of
https://github.com/FxPouya/FxMathQuantWebApp.git
synced 2026-07-27 18:27:44 +00:00
329 lines
11 KiB
JavaScript
329 lines
11 KiB
JavaScript
// MQ4 Converter
|
|
class MQ4Converter {
|
|
constructor(strategy) {
|
|
this.strategy = strategy;
|
|
this.parser = new RuleParser();
|
|
}
|
|
|
|
generate() {
|
|
const { parameters, buy_rules, sell_rules } = this.strategy;
|
|
const symbol = parameters.symbol || 'EURUSD';
|
|
const atrPeriod = parameters.atr_period || 14;
|
|
const slMultiplier = parameters.sl_multiplier || 2.0;
|
|
const tpMultiplier = parameters.tp_multiplier || 3.0;
|
|
|
|
// Generate random 6-digit magic number
|
|
const magicNumber = Math.floor(100000 + Math.random() * 900000);
|
|
|
|
const buyConditions = this.parser.parseRules(buy_rules, 'mql');
|
|
const sellConditions = this.parser.parseRules(sell_rules, 'mql');
|
|
|
|
return `//+------------------------------------------------------------------+
|
|
//| Strategy_${symbol}.mq4 |
|
|
//| Generated by Strategy Converter |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "FxMath Quant"
|
|
#property link "https://fxmath.com"
|
|
#property version "1.00"
|
|
#property strict
|
|
|
|
//=== TRADE SETTINGS ===
|
|
input double LotSize = 0.1; // Lot Size
|
|
input int ATR_Period = ${atrPeriod}; // ATR Period
|
|
input double SL_Multiplier = ${slMultiplier.toFixed(2)}; // SL ATR Multiplier
|
|
input double TP_Multiplier = ${tpMultiplier.toFixed(2)}; // TP ATR Multiplier
|
|
input int MagicNumber = ${magicNumber}; // Magic Number
|
|
input string TradeComment = "FxMath EA"; // Trade Comment
|
|
input int Slippage = 3; // Slippage
|
|
|
|
//=== SL/TP SETTINGS ===
|
|
input bool EnableHardSL = true; // Enable Hard Stop Loss
|
|
input bool EnableHardTP = true; // Enable Hard Take Profit
|
|
|
|
//=== TRAILING STOP ===
|
|
input bool EnableTrailing = false; // Enable Trailing Stop
|
|
input double TrailingStart = 30; // Trailing Start (pips)
|
|
input double TrailingStep = 10; // Trailing Step (pips)
|
|
|
|
//=== BREAKEVEN ===
|
|
input bool EnableBreakeven = false; // Enable Breakeven
|
|
input double BreakevenStart = 20; // Breakeven Start (pips)
|
|
input double BreakevenOffset = 2; // Breakeven Offset (pips)
|
|
|
|
//=== TIME FILTER ===
|
|
input bool EnableTimeFilter = false; // Enable Time Filter
|
|
input int StartHour = 8; // Start Hour (Server Time)
|
|
input int StartMinute = 0; // Start Minute
|
|
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
|
|
|
|
//=== DISPLAY SETTINGS ===
|
|
input bool ShowChartInfo = true; // Show Info on Chart
|
|
|
|
// Global Variables
|
|
double atrValue;
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Expert initialization function |
|
|
//+------------------------------------------------------------------+
|
|
int OnInit()
|
|
{
|
|
Print("Strategy EA initialized for ${symbol}");
|
|
Print("Magic Number: ", MagicNumber);
|
|
return(INIT_SUCCEEDED);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Expert deinitialization function |
|
|
//+------------------------------------------------------------------+
|
|
void OnDeinit(const int reason)
|
|
{
|
|
Print("Strategy EA deinitialized");
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Expert tick function |
|
|
//+------------------------------------------------------------------+
|
|
void OnTick()
|
|
{
|
|
// Calculate ATR
|
|
atrValue = iATR(Symbol(), 0, ATR_Period, 1);
|
|
|
|
// Check for open positions
|
|
bool hasPosition = false;
|
|
for(int i = OrdersTotal() - 1; i >= 0; i--)
|
|
{
|
|
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
|
|
{
|
|
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
|
|
{
|
|
hasPosition = true;
|
|
ManagePosition();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// If no position, check for entry signals
|
|
if(!hasPosition)
|
|
{
|
|
// Check time filter
|
|
if(EnableTimeFilter && !IsTimeAllowed())
|
|
return;
|
|
|
|
// Check Buy Signal
|
|
if(CheckBuySignal())
|
|
{
|
|
OpenBuyOrder();
|
|
}
|
|
// Check Sell Signal
|
|
else if(CheckSellSignal())
|
|
{
|
|
OpenSellOrder();
|
|
}
|
|
}
|
|
|
|
// Display chart info
|
|
if(ShowChartInfo)
|
|
DisplayChartInfo();
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Check if current time is allowed for trading |
|
|
//+------------------------------------------------------------------+
|
|
bool IsTimeAllowed()
|
|
{
|
|
int currentHour = Hour();
|
|
int currentMinute = Minute();
|
|
int currentMinutes = currentHour * 60 + currentMinute;
|
|
int startMinutes = StartHour * 60 + StartMinute;
|
|
int endMinutes = EndHour * 60 + EndMinute;
|
|
|
|
if(startMinutes < endMinutes)
|
|
return (currentMinutes >= startMinutes && currentMinutes < endMinutes);
|
|
else
|
|
return (currentMinutes >= startMinutes || currentMinutes < endMinutes);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Manage existing position |
|
|
//+------------------------------------------------------------------+
|
|
void ManagePosition()
|
|
{
|
|
if(!OrderSelect(0, SELECT_BY_POS, MODE_TRADES))
|
|
return;
|
|
|
|
int orderType = OrderType();
|
|
double orderOpenPrice = OrderOpenPrice();
|
|
double orderSL = OrderStopLoss();
|
|
double orderTP = OrderTakeProfit();
|
|
|
|
// Check for opposite signal
|
|
if(CloseOnOpposite)
|
|
{
|
|
if(orderType == OP_BUY && CheckSellSignal())
|
|
{
|
|
if(!OrderClose(OrderTicket(), OrderLots(), Bid, Slippage, clrRed))
|
|
Print("Error closing buy order: ", GetLastError());
|
|
return;
|
|
}
|
|
else if(orderType == OP_SELL && CheckBuySignal())
|
|
{
|
|
if(!OrderClose(OrderTicket(), OrderLots(), Ask, Slippage, clrGreen))
|
|
Print("Error closing sell order: ", GetLastError());
|
|
return;
|
|
}
|
|
}
|
|
|
|
double currentPrice = (orderType == OP_BUY) ? Bid : Ask;
|
|
double point = Point;
|
|
double pipValue = point * 10;
|
|
|
|
// Breakeven
|
|
if(EnableBreakeven)
|
|
{
|
|
double profit = (orderType == OP_BUY) ?
|
|
(currentPrice - orderOpenPrice) :
|
|
(orderOpenPrice - currentPrice);
|
|
|
|
if(profit >= BreakevenStart * pipValue)
|
|
{
|
|
double newSL = orderOpenPrice + (BreakevenOffset * pipValue *
|
|
((orderType == OP_BUY) ? 1 : -1));
|
|
|
|
if((orderType == OP_BUY && newSL > orderSL) ||
|
|
(orderType == OP_SELL && (orderSL == 0 || newSL < orderSL)))
|
|
{
|
|
if(!OrderModify(OrderTicket(), orderOpenPrice, newSL, orderTP, 0, clrBlue))
|
|
Print("Error modifying order for breakeven: ", GetLastError());
|
|
}
|
|
}
|
|
}
|
|
|
|
// Trailing Stop
|
|
if(EnableTrailing)
|
|
{
|
|
double profit = (orderType == OP_BUY) ?
|
|
(currentPrice - orderOpenPrice) :
|
|
(orderOpenPrice - currentPrice);
|
|
|
|
if(profit >= TrailingStart * pipValue)
|
|
{
|
|
double newSL = currentPrice - (TrailingStep * pipValue *
|
|
((orderType == OP_BUY) ? 1 : -1));
|
|
|
|
if((orderType == OP_BUY && newSL > orderSL) ||
|
|
(orderType == OP_SELL && (orderSL == 0 || newSL < orderSL)))
|
|
{
|
|
if(!OrderModify(OrderTicket(), orderOpenPrice, newSL, orderTP, 0, clrBlue))
|
|
Print("Error modifying order for trailing stop: ", GetLastError());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Display chart information |
|
|
//+------------------------------------------------------------------+
|
|
void DisplayChartInfo()
|
|
{
|
|
string info = "\\n=== " + TradeComment + " ===\\n";
|
|
info += "Symbol: " + Symbol() + "\\n";
|
|
info += "Magic: " + IntegerToString(MagicNumber) + "\\n";
|
|
|
|
bool hasPosition = false;
|
|
for(int i = OrdersTotal() - 1; i >= 0; i--)
|
|
{
|
|
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
|
|
{
|
|
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
|
|
{
|
|
hasPosition = true;
|
|
info += "Position: " + (OrderType() == OP_BUY ? "BUY" : "SELL") + "\\n";
|
|
info += "Profit: " + DoubleToStr(OrderProfit(), 2) + "\\n";
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(!hasPosition)
|
|
info += "No Position\\n";
|
|
|
|
Comment(info);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Check Buy Signal |
|
|
//+------------------------------------------------------------------+
|
|
bool CheckBuySignal()
|
|
{
|
|
return (${buyConditions.join(' &&\n ')});
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Check Sell Signal |
|
|
//+------------------------------------------------------------------+
|
|
bool CheckSellSignal()
|
|
{
|
|
return (${sellConditions.join(' &&\n ')});
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Open Buy Order |
|
|
//+------------------------------------------------------------------+
|
|
void OpenBuyOrder()
|
|
{
|
|
double price = Ask;
|
|
double sl = EnableHardSL ? price - (atrValue * SL_Multiplier) : 0;
|
|
double tp = EnableHardTP ? price + (atrValue * TP_Multiplier) : 0;
|
|
|
|
sl = (sl > 0) ? NormalizeDouble(sl, Digits) : 0;
|
|
tp = (tp > 0) ? NormalizeDouble(tp, Digits) : 0;
|
|
|
|
int ticket = OrderSend(Symbol(), OP_BUY, LotSize, price, Slippage, sl, tp,
|
|
TradeComment, MagicNumber, 0, clrGreen);
|
|
|
|
if(ticket > 0)
|
|
{
|
|
Print("Buy order opened at ", price, " SL: ", sl, " TP: ", tp);
|
|
}
|
|
else
|
|
{
|
|
Print("Error opening buy order: ", GetLastError());
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Open Sell Order |
|
|
//+------------------------------------------------------------------+
|
|
void OpenSellOrder()
|
|
{
|
|
double price = Bid;
|
|
double sl = EnableHardSL ? price + (atrValue * SL_Multiplier) : 0;
|
|
double tp = EnableHardTP ? price - (atrValue * TP_Multiplier) : 0;
|
|
|
|
sl = (sl > 0) ? NormalizeDouble(sl, Digits) : 0;
|
|
tp = (tp > 0) ? NormalizeDouble(tp, Digits) : 0;
|
|
|
|
int ticket = OrderSend(Symbol(), OP_SELL, LotSize, price, Slippage, sl, tp,
|
|
TradeComment, MagicNumber, 0, clrRed);
|
|
|
|
if(ticket > 0)
|
|
{
|
|
Print("Sell order opened at ", price, " SL: ", sl, " TP: ", tp);
|
|
}
|
|
else
|
|
{
|
|
Print("Error opening sell order: ", GetLastError());
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
`;
|
|
}
|
|
}
|
|
|
|
window.MQ4Converter = MQ4Converter;
|