ForexTheFirst/TradeEngine.mqh
super.admin 6d249e3e27 convert
2025-05-30 14:55:54 +02:00

100 lines
No EOL
3.3 KiB
MQL5

//+------------------------------------------------------------------+
//| TradeEngine.mqh |
//| Marino Bantli |
//| maban.ch |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
struct deals
{
ulong magic;
ulong orderID;
string comment;
};
class TradeEngine
{
private:
uint GUID;
CTrade trade;
public:
uint NewDirectEntry(ENUM_ORDER_TYPE type, double lots, double sl, double tp, string comment);
double GetRiskReward(double entry, double tp, double sl);
double GetLots(double entry, double sl, double risk);
TradeEngine(uint uniqueNumber);
~TradeEngine();
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
TradeEngine::TradeEngine(uint uniqueNumber)
{
GUID = uniqueNumber;
trade.SetExpertMagicNumber(GUID);
trade.LogLevel(LOG_LEVEL_ERRORS);
trade.SetTypeFilling(ORDER_FILLING_FOK);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
TradeEngine::~TradeEngine()
{
GUID = NULL;
}
//+------------------------------------------------------------------+
uint TradeEngine::NewDirectEntry(ENUM_ORDER_TYPE type, double lots, double sl, double tp, string comment)
{
double entryPrice;
MqlTick price;
SymbolInfoTick(Symbol() ,price);
switch(type)
{
case ORDER_TYPE_BUY:
entryPrice = price.ask;
break;
case ORDER_TYPE_SELL:
entryPrice = price.bid;
break;
}
//Open Trade Position
if(trade.PositionOpen(Symbol(), type, lots, entryPrice, sl, tp, comment)) { Alert(__FUNCTION__ + ": Error with PositionOpen! Comment: "); }
return NULL;
}
double TradeEngine::GetRiskReward(double entry, double tp, double sl)
{
double calculatedRR = 0;
double distanceToTp = MathAbs(entry - tp);
double distanceToSl = MathAbs(entry - sl);
calculatedRR = NormalizeDouble(distanceToTp / distanceToSl, 1);
return calculatedRR;
}
double TradeEngine::GetLots(double entry, double sl, double risk)
{
double MinLots = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_MIN);
double MaxLots = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_MAX);
double LotSteps = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_STEP);
double TickSize = SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_SIZE);
double TickValue = SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_VALUE);
double AccountValue = fmin(fmin(AccountInfoDouble(ACCOUNT_EQUITY), AccountInfoDouble(ACCOUNT_BALANCE)), AccountInfoDouble(ACCOUNT_MARGIN_FREE));
double SlTicks = MathAbs(entry - sl);
double RiskValue = AccountValue * risk;
double PotentialLoss = SlTicks * TickValue / TickSize;
double CalculatedLots = fmin(MaxLots, fmax(MinLots, round(RiskValue / PotentialLoss / LotSteps) * LotSteps));
return CalculatedLots;
};