588 lines
No EOL
22 KiB
MQL5
588 lines
No EOL
22 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| Universal_Trading_EA.mq5 |
|
|
//| Copyright 2025, MetaQuotes Ltd. |
|
|
//| https://www.mql5.com |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Copyright 2025, MetaQuotes Ltd."
|
|
#property link "https://www.mql5.com"
|
|
#property version "1.00"
|
|
|
|
#include <Trade\Trade.mqh>
|
|
|
|
//=== TRADING LEVELS ===
|
|
input group "=== TRADING LEVELS ==="
|
|
input double EntryBuyLevel = 1.3600; // Buy entry level
|
|
input double TargetLevel = 1.3641; // Target level for buys
|
|
input double SupportLevel = 1.3566; // Support/resistance level
|
|
input double SellTarget = 1.3521; // Target level for sells
|
|
|
|
//=== SCENARIO CONTROLS ===
|
|
input group "=== SCENARIO CONTROLS ==="
|
|
input bool EnableBuyScenario1 = true; // Enable Buy Scenario 1
|
|
input bool EnableBuyScenario2 = true; // Enable Buy Scenario 2
|
|
input bool EnableSellScenario1 = true; // Enable Sell Scenario 1
|
|
input bool EnableSellScenario2 = true; // Enable Sell Scenario 2
|
|
|
|
//=== REVERSAL TRADING ===
|
|
input group "=== REVERSAL TRADING ==="
|
|
input bool EnableAutoReversals = true; // Enable automatic reversals
|
|
input double BuyReversalPips = 35; // Expected pullback pips after buy target
|
|
input double SellReversalPips = 25; // Expected rebound pips after sell target
|
|
|
|
//=== MACD SETTINGS ===
|
|
input group "=== MACD SETTINGS ==="
|
|
input int MACD_Fast = 12; // MACD Fast EMA period
|
|
input int MACD_Slow = 26; // MACD Slow EMA period
|
|
input int MACD_Signal = 9; // MACD Signal period
|
|
input double MACD_OversoldThreshold = -0.0005; // MACD oversold threshold
|
|
input double MACD_OverboughtThreshold = 0.0005; // MACD overbought threshold
|
|
|
|
//=== ENTRY CONDITIONS ===
|
|
input group "=== ENTRY CONDITIONS ==="
|
|
input double EntryTolerancePips = 5; // Price tolerance for entry (pips)
|
|
input double LevelTestTolerancePips = 3; // Price tolerance for level tests (pips)
|
|
input double BreakoutTolerancePips = 2; // Price tolerance for breakouts (pips)
|
|
input int TestTimeoutHours = 4; // Hours between level tests
|
|
input int LevelResetPips = 20; // Pips away to reset test counters
|
|
|
|
//=== RISK MANAGEMENT ===
|
|
input group "=== RISK MANAGEMENT ==="
|
|
input double LotSize = 0.1; // Fixed lot size (0 = auto calculation)
|
|
input double RiskPercent = 2.0; // Risk per trade as % of account
|
|
input double MaxDailyLoss = 5.0; // Maximum daily loss %
|
|
input double MaxSpread = 3.0; // Maximum allowed spread in points
|
|
input double StopLossPips = 30; // Stop loss in pips (0 = based on levels)
|
|
|
|
//=== GENERAL SETTINGS ===
|
|
input group "=== GENERAL SETTINGS ==="
|
|
input int MagicNumber = 123456; // Magic number for orders
|
|
input string TradeComment = "Universal EA"; // Trade comment prefix
|
|
|
|
// Global variables
|
|
CTrade trade;
|
|
int macdHandle;
|
|
double macdMain[], macdSignal[];
|
|
int testCount_Support = 0;
|
|
int testCount_Entry = 0;
|
|
datetime lastTestTime_Support = 0;
|
|
datetime lastTestTime_Entry = 0;
|
|
bool inLongPosition = false;
|
|
bool inShortPosition = false;
|
|
double dailyStartBalance;
|
|
datetime dailyStartTime;
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Expert initialization function |
|
|
//+------------------------------------------------------------------+
|
|
int OnInit()
|
|
{
|
|
// Validate inputs
|
|
if(!ValidateInputs())
|
|
return INIT_PARAMETERS_INCORRECT;
|
|
|
|
// Initialize MACD indicator
|
|
macdHandle = iMACD(_Symbol, PERIOD_CURRENT, MACD_Fast, MACD_Slow, MACD_Signal, PRICE_CLOSE);
|
|
if(macdHandle == INVALID_HANDLE)
|
|
{
|
|
Print("Error creating MACD indicator for ", _Symbol);
|
|
return INIT_FAILED;
|
|
}
|
|
|
|
// Set array properties
|
|
ArraySetAsSeries(macdMain, true);
|
|
ArraySetAsSeries(macdSignal, true);
|
|
|
|
// Set trade parameters
|
|
trade.SetExpertMagicNumber(MagicNumber);
|
|
trade.SetDeviationInPoints(10);
|
|
|
|
// Initialize daily tracking
|
|
dailyStartBalance = AccountInfoDouble(ACCOUNT_BALANCE);
|
|
dailyStartTime = TimeCurrent();
|
|
|
|
// Print configuration
|
|
PrintConfiguration();
|
|
|
|
Print("Universal Trading EA initialized successfully for ", _Symbol);
|
|
return INIT_SUCCEEDED;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Validate input parameters |
|
|
//+------------------------------------------------------------------+
|
|
bool ValidateInputs()
|
|
{
|
|
if(EntryBuyLevel <= 0 || TargetLevel <= 0 || SupportLevel <= 0 || SellTarget <= 0)
|
|
{
|
|
Print("Error: All price levels must be positive");
|
|
return false;
|
|
}
|
|
|
|
if(TargetLevel <= EntryBuyLevel)
|
|
{
|
|
Print("Error: Target level must be above entry buy level");
|
|
return false;
|
|
}
|
|
|
|
if(SupportLevel >= EntryBuyLevel)
|
|
{
|
|
Print("Error: Support level must be below entry buy level");
|
|
return false;
|
|
}
|
|
|
|
if(SellTarget >= SupportLevel)
|
|
{
|
|
Print("Error: Sell target must be below support level");
|
|
return false;
|
|
}
|
|
|
|
if(RiskPercent <= 0 || RiskPercent > 10)
|
|
{
|
|
Print("Error: Risk percent must be between 0 and 10");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Print EA configuration |
|
|
//+------------------------------------------------------------------+
|
|
void PrintConfiguration()
|
|
{
|
|
Print("=== UNIVERSAL TRADING EA CONFIGURATION ===");
|
|
Print("Instrument: ", _Symbol);
|
|
Print("Entry Buy Level: ", EntryBuyLevel);
|
|
Print("Target Level: ", TargetLevel);
|
|
Print("Support Level: ", SupportLevel);
|
|
Print("Sell Target: ", SellTarget);
|
|
Print("Buy Reversal Pips: ", BuyReversalPips);
|
|
Print("Sell Reversal Pips: ", SellReversalPips);
|
|
Print("MACD Oversold: ", MACD_OversoldThreshold);
|
|
Print("MACD Overbought: ", MACD_OverboughtThreshold);
|
|
Print("Risk per Trade: ", RiskPercent, "%");
|
|
Print("=========================================");
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Expert deinitialization function |
|
|
//+------------------------------------------------------------------+
|
|
void OnDeinit(const int reason)
|
|
{
|
|
IndicatorRelease(macdHandle);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Expert tick function |
|
|
//+------------------------------------------------------------------+
|
|
void OnTick()
|
|
{
|
|
// Check daily risk management
|
|
if(!CheckDailyRiskManagement())
|
|
return;
|
|
|
|
// Check spread
|
|
if(!CheckSpread())
|
|
return;
|
|
|
|
// Update MACD values
|
|
if(!UpdateMACDValues())
|
|
return;
|
|
|
|
// Update position status
|
|
UpdatePositionStatus();
|
|
|
|
// Check trading scenarios
|
|
if(EnableBuyScenario1)
|
|
CheckBuyScenario1();
|
|
|
|
if(EnableBuyScenario2)
|
|
CheckBuyScenario2();
|
|
|
|
if(EnableSellScenario1)
|
|
CheckSellScenario1();
|
|
|
|
if(EnableSellScenario2)
|
|
CheckSellScenario2();
|
|
|
|
// Check exit conditions
|
|
CheckExitConditions();
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Check daily risk management |
|
|
//+------------------------------------------------------------------+
|
|
bool CheckDailyRiskManagement()
|
|
{
|
|
// Reset daily tracking at new day
|
|
MqlDateTime timeStruct;
|
|
TimeToStruct(TimeCurrent(), timeStruct);
|
|
MqlDateTime startStruct;
|
|
TimeToStruct(dailyStartTime, startStruct);
|
|
|
|
if(timeStruct.day != startStruct.day)
|
|
{
|
|
dailyStartBalance = AccountInfoDouble(ACCOUNT_BALANCE);
|
|
dailyStartTime = TimeCurrent();
|
|
Print("New trading day started. Daily balance reset for ", _Symbol);
|
|
}
|
|
|
|
// Check if daily loss limit exceeded
|
|
double currentBalance = AccountInfoDouble(ACCOUNT_BALANCE);
|
|
double dailyLoss = (dailyStartBalance - currentBalance) / dailyStartBalance * 100;
|
|
|
|
if(dailyLoss >= MaxDailyLoss)
|
|
{
|
|
Print("Daily loss limit exceeded: ", dailyLoss, "%. Trading stopped for ", _Symbol);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Check spread |
|
|
//+------------------------------------------------------------------+
|
|
bool CheckSpread()
|
|
{
|
|
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
|
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
|
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
|
|
double spread = (ask - bid) / point;
|
|
|
|
return spread <= MaxSpread;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Calculate lot size based on risk management |
|
|
//+------------------------------------------------------------------+
|
|
double CalculateLotSize(double entryPrice, double stopLoss)
|
|
{
|
|
// Use fixed lot size if specified
|
|
if(LotSize > 0)
|
|
return LotSize;
|
|
|
|
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
|
|
double riskAmount = balance * RiskPercent / 100;
|
|
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
|
|
double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
|
|
double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
|
|
double maxLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
|
|
double lotStep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
|
|
|
|
double stopLossPoints = MathAbs(entryPrice - stopLoss) / point;
|
|
if(stopLossPoints == 0) return minLot;
|
|
|
|
double lotSize = riskAmount / (stopLossPoints * tickValue);
|
|
|
|
// Round to nearest lot step
|
|
lotSize = MathFloor(lotSize / lotStep) * lotStep;
|
|
|
|
// Apply limits
|
|
if(lotSize < minLot) lotSize = minLot;
|
|
if(lotSize > maxLot) lotSize = maxLot;
|
|
|
|
return lotSize;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Calculate stop loss level |
|
|
//+------------------------------------------------------------------+
|
|
double CalculateStopLoss(bool isBuy, double entryPrice)
|
|
{
|
|
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
|
|
|
|
if(StopLossPips > 0)
|
|
{
|
|
// Use fixed stop loss pips
|
|
if(isBuy)
|
|
return entryPrice - StopLossPips * point;
|
|
else
|
|
return entryPrice + StopLossPips * point;
|
|
}
|
|
else
|
|
{
|
|
// Use level-based stop loss
|
|
if(isBuy)
|
|
return SupportLevel - 5 * point;
|
|
else
|
|
return EntryBuyLevel + 5 * point;
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Update MACD indicator values |
|
|
//+------------------------------------------------------------------+
|
|
bool UpdateMACDValues()
|
|
{
|
|
if(CopyBuffer(macdHandle, 0, 0, 3, macdMain) < 0 ||
|
|
CopyBuffer(macdHandle, 1, 0, 3, macdSignal) < 0)
|
|
{
|
|
Print("Error copying MACD buffers for ", _Symbol);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Update position status |
|
|
//+------------------------------------------------------------------+
|
|
void UpdatePositionStatus()
|
|
{
|
|
inLongPosition = false;
|
|
inShortPosition = false;
|
|
|
|
for(int i = PositionsTotal() - 1; i >= 0; i--)
|
|
{
|
|
if(PositionGetSymbol(i) == _Symbol && PositionGetInteger(POSITION_MAGIC) == MagicNumber)
|
|
{
|
|
if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
|
|
inLongPosition = true;
|
|
else if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
|
|
inShortPosition = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Check Buy Scenario 1: Buy at entry level with MACD above zero |
|
|
//+------------------------------------------------------------------+
|
|
void CheckBuyScenario1()
|
|
{
|
|
if(inLongPosition)
|
|
return;
|
|
|
|
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
|
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
|
|
|
|
// Check if price is near entry level
|
|
if(MathAbs(ask - EntryBuyLevel) <= EntryTolerancePips * point)
|
|
{
|
|
// Check MACD conditions: above zero and rising (starting to rise)
|
|
if(macdMain[0] > 0 && macdMain[0] > macdMain[1])
|
|
{
|
|
double stopLoss = CalculateStopLoss(true, ask);
|
|
double lotSize = CalculateLotSize(ask, stopLoss);
|
|
|
|
// Execute buy order
|
|
if(trade.Buy(lotSize, _Symbol, ask, stopLoss, TargetLevel,
|
|
TradeComment + " - Buy Scenario 1"))
|
|
{
|
|
Print("Buy Scenario 1 executed for ", _Symbol, " at ", ask, " Lot: ", lotSize,
|
|
" MACD: ", macdMain[0], " (rising from ", macdMain[1], ")");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Check Buy Scenario 2: Two tests of support with MACD oversold |
|
|
//+------------------------------------------------------------------+
|
|
void CheckBuyScenario2()
|
|
{
|
|
if(inLongPosition)
|
|
return;
|
|
|
|
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
|
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
|
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
|
|
|
|
// Check if price is testing support level
|
|
if(MathAbs(bid - SupportLevel) <= LevelTestTolerancePips * point)
|
|
{
|
|
// Check if this is a new test
|
|
if(TimeCurrent() - lastTestTime_Support > TestTimeoutHours * 3600)
|
|
{
|
|
testCount_Support++;
|
|
lastTestTime_Support = TimeCurrent();
|
|
Print("Test #", testCount_Support, " of support level detected for ", _Symbol);
|
|
|
|
// If second test and MACD is oversold
|
|
if(testCount_Support >= 2 && macdMain[0] < MACD_OversoldThreshold)
|
|
{
|
|
double stopLoss = CalculateStopLoss(true, ask);
|
|
double lotSize = CalculateLotSize(ask, stopLoss);
|
|
|
|
// Execute buy order
|
|
if(trade.Buy(lotSize, _Symbol, ask, stopLoss, TargetLevel,
|
|
TradeComment + " - Buy Scenario 2"))
|
|
{
|
|
Print("Buy Scenario 2 executed for ", _Symbol, " at ", ask, " Lot: ", lotSize,
|
|
" MACD oversold: ", macdMain[0], " (threshold: ", MACD_OversoldThreshold, ")");
|
|
testCount_Support = 0; // Reset counter
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Reset counter if price moves away from level
|
|
if(MathAbs(bid - SupportLevel) > LevelResetPips * point)
|
|
{
|
|
testCount_Support = 0;
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Check Sell Scenario 1: Sell below support with MACD below zero |
|
|
//+------------------------------------------------------------------+
|
|
void CheckSellScenario1()
|
|
{
|
|
if(inShortPosition)
|
|
return;
|
|
|
|
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
|
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
|
|
|
|
// Check if price breaks below support level
|
|
if(bid < SupportLevel - BreakoutTolerancePips * point)
|
|
{
|
|
// Check MACD conditions: below zero and declining (starting to decline)
|
|
if(macdMain[0] < 0 && macdMain[0] < macdMain[1])
|
|
{
|
|
double stopLoss = CalculateStopLoss(false, bid);
|
|
double lotSize = CalculateLotSize(bid, stopLoss);
|
|
|
|
// Execute sell order
|
|
if(trade.Sell(lotSize, _Symbol, bid, stopLoss, SellTarget,
|
|
TradeComment + " - Sell Scenario 1"))
|
|
{
|
|
Print("Sell Scenario 1 executed for ", _Symbol, " at ", bid, " Lot: ", lotSize,
|
|
" MACD: ", macdMain[0], " (declining from ", macdMain[1], ")");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Check Sell Scenario 2: Two tests of entry with MACD overbought |
|
|
//+------------------------------------------------------------------+
|
|
void CheckSellScenario2()
|
|
{
|
|
if(inShortPosition)
|
|
return;
|
|
|
|
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
|
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
|
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
|
|
|
|
// Check if price is testing entry level
|
|
if(MathAbs(ask - EntryBuyLevel) <= LevelTestTolerancePips * point)
|
|
{
|
|
// Check if this is a new test
|
|
if(TimeCurrent() - lastTestTime_Entry > TestTimeoutHours * 3600)
|
|
{
|
|
testCount_Entry++;
|
|
lastTestTime_Entry = TimeCurrent();
|
|
Print("Test #", testCount_Entry, " of entry level detected for ", _Symbol);
|
|
|
|
// If second test and MACD is overbought
|
|
if(testCount_Entry >= 2 && macdMain[0] > MACD_OverboughtThreshold)
|
|
{
|
|
double stopLoss = CalculateStopLoss(false, bid);
|
|
double lotSize = CalculateLotSize(bid, stopLoss);
|
|
|
|
// Execute sell order
|
|
if(trade.Sell(lotSize, _Symbol, bid, stopLoss, SellTarget,
|
|
TradeComment + " - Sell Scenario 2"))
|
|
{
|
|
Print("Sell Scenario 2 executed for ", _Symbol, " at ", bid, " Lot: ", lotSize,
|
|
" MACD overbought: ", macdMain[0], " (threshold: ", MACD_OverboughtThreshold, ")");
|
|
testCount_Entry = 0; // Reset counter
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Reset counter if price moves away from level
|
|
if(MathAbs(ask - EntryBuyLevel) > LevelResetPips * point)
|
|
{
|
|
testCount_Entry = 0;
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Check exit conditions and automatic reversals |
|
|
//+------------------------------------------------------------------+
|
|
void CheckExitConditions()
|
|
{
|
|
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
|
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
|
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
|
|
|
|
for(int i = PositionsTotal() - 1; i >= 0; i--)
|
|
{
|
|
if(PositionGetSymbol(i) == _Symbol && PositionGetInteger(POSITION_MAGIC) == MagicNumber)
|
|
{
|
|
ulong ticket = PositionGetInteger(POSITION_TICKET);
|
|
double currentPrice = (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) ? bid : ask;
|
|
|
|
// Check long position exit at target
|
|
if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
|
|
{
|
|
if(currentPrice >= TargetLevel)
|
|
{
|
|
if(trade.PositionClose(ticket))
|
|
{
|
|
Print("Long position closed at target for ", _Symbol, ": ", currentPrice);
|
|
|
|
// Open automatic reversal if enabled
|
|
if(EnableAutoReversals && BuyReversalPips > 0)
|
|
{
|
|
double reversalTarget = TargetLevel - BuyReversalPips * point;
|
|
double stopLoss = TargetLevel + 15 * point;
|
|
double lotSize = CalculateLotSize(bid, stopLoss);
|
|
|
|
if(trade.Sell(lotSize, _Symbol, bid, stopLoss, reversalTarget,
|
|
TradeComment + " - Auto Reversal Short"))
|
|
{
|
|
Print("Auto reversal short opened for ", _Symbol,
|
|
" expecting ", BuyReversalPips, " pip pullback");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Check short position exit at target
|
|
else if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
|
|
{
|
|
if(currentPrice <= SellTarget)
|
|
{
|
|
if(trade.PositionClose(ticket))
|
|
{
|
|
Print("Short position closed at target for ", _Symbol, ": ", currentPrice);
|
|
|
|
// Open automatic reversal if enabled
|
|
if(EnableAutoReversals && SellReversalPips > 0)
|
|
{
|
|
double reversalTarget = SellTarget + SellReversalPips * point;
|
|
double stopLoss = SellTarget - 15 * point;
|
|
double lotSize = CalculateLotSize(ask, stopLoss);
|
|
|
|
if(trade.Buy(lotSize, _Symbol, ask, stopLoss, reversalTarget,
|
|
TradeComment + " - Auto Reversal Long"))
|
|
{
|
|
Print("Auto reversal long opened for ", _Symbol,
|
|
" expecting ", SellReversalPips, " pip rebound");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Trade transaction function |
|
|
//+------------------------------------------------------------------+
|
|
void OnTradeTransaction(const MqlTradeTransaction& trans,
|
|
const MqlTradeRequest& request,
|
|
const MqlTradeResult& result)
|
|
{
|
|
if(trans.type == TRADE_TRANSACTION_DEAL_ADD)
|
|
{
|
|
Print("Trade executed: ", trans.symbol, " Volume: ", trans.volume,
|
|
" Price: ", trans.price, " Type: ",
|
|
(trans.deal_type == DEAL_TYPE_BUY ? "BUY" : "SELL"));
|
|
}
|
|
} |