100 lines
No EOL
3.3 KiB
MQL5
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;
|
|
}; |