620 lines
49 KiB
MQL5
620 lines
49 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| StandartFunctions.mqh |
|
|
//| AHMAD KAZBAR |
|
|
//| https://www.mql5.com |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "AHMAD KAZBAR"
|
|
#property version "1.00"
|
|
|
|
#include <Trade/Trade.mqh>
|
|
#include <Trade/PositionInfo.mqh>
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
class CBar : public CObject
|
|
{
|
|
public:
|
|
double c;
|
|
double o;
|
|
double h;
|
|
double l;
|
|
datetime t;
|
|
int i;
|
|
bool p ;
|
|
string type;
|
|
|
|
CBar(double _c,double _o,double _h,double _l,datetime _t,int _i,string _type,bool peak)
|
|
{
|
|
c = _c;
|
|
o = _o;
|
|
h = _h;
|
|
l = _l;
|
|
t= _t;
|
|
i = _i;
|
|
p = peak;
|
|
type = _type;
|
|
}
|
|
bool Equals(double val,double val2) { return val == val2; }
|
|
};
|
|
struct STradeSum
|
|
{
|
|
int count;
|
|
double profit;
|
|
double trailPrice;
|
|
};
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
class StandartFunctions
|
|
{
|
|
private:
|
|
|
|
string m_symbol;
|
|
ENUM_TIMEFRAMES m_timeFrame;
|
|
int m_digits;
|
|
CTrade m_trade;
|
|
long m_magic;
|
|
datetime previous_time;
|
|
bool m_print_log;
|
|
|
|
public:
|
|
StandartFunctions(string symbol,ENUM_TIMEFRAMES timeFrame,long exMagic,bool p_log = false)
|
|
{
|
|
|
|
m_symbol = symbol;
|
|
m_timeFrame = timeFrame;
|
|
m_magic = exMagic;
|
|
m_digits = (int)SymbolInfoInteger(m_symbol,SYMBOL_DIGITS);
|
|
m_trade.SetExpertMagicNumber(exMagic);
|
|
IsNewBar();
|
|
m_print_log = p_log;
|
|
}
|
|
StandartFunctions();
|
|
~StandartFunctions();
|
|
bool IsNewBar();
|
|
bool IsNewBarDay();
|
|
double High(int shift);
|
|
double Close(int shift);
|
|
double Low(int shift);
|
|
double Open(int shift);
|
|
datetime Time(int shift);
|
|
double Bid();
|
|
double Ask();
|
|
double PipeToDouble(double pips);
|
|
double CalculateLotByBalance();
|
|
double tr(int shifit);
|
|
double CalculatePipsFromDollars(double dollarAmount,double lotSize);
|
|
double CalcLots(double slPoints);
|
|
double Size(int shift);
|
|
ulong BuyLimit(double lot,double entry,double stop,double tp,string comment,datetime expirt);
|
|
ulong SellLimit(double lot,double entry,double stop,double tp,string comment,datetime expirt);
|
|
ulong BuyStop(double lot,double entry,double stop,double tp,string comment,datetime expirt);
|
|
ulong SellStop(double lot,double entry,double stop,double tp,string comment,datetime expirt);
|
|
ulong OpenOrder(ENUM_ORDER_TYPE OrderType,double lot,double entry,double stop,double tp,string comment);
|
|
void UpdatePosition(double trailingPips,double target);
|
|
bool UpdatePosition(const ulong ticket,const double sl,const double tp);
|
|
void GetTradeSum(STradeSum &sum,ENUM_POSITION_TYPE type);
|
|
void DrawArrow(string name, datetime arrowTime, double arrowPrice, string direction = "up", color clr = clrLime, int size = 2);
|
|
bool IsPivotHigh(int index,int Left,int Right,const MqlRates &m_rates[]);
|
|
bool IsPivotLow(int index,int Left,int Right,const MqlRates &m_rates[]);
|
|
bool CheckTradeAllowed();
|
|
ENUM_TIMEFRAMES GetTimeFrame(){return m_timeFrame;}
|
|
};
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
StandartFunctions::StandartFunctions()
|
|
{
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
StandartFunctions::~StandartFunctions()
|
|
{
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
double StandartFunctions::High(int shift) {return iHigh(m_symbol,m_timeFrame,shift);}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
double StandartFunctions::Low(int shift) {return iLow(m_symbol,m_timeFrame,shift);}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
double StandartFunctions::Close(int shift) {return iClose(m_symbol,m_timeFrame,shift);}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
double StandartFunctions::Open(int shift) {return iOpen(m_symbol,m_timeFrame,shift);}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
datetime StandartFunctions::Time(int shift) {return iTime(m_symbol,m_timeFrame,shift);}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
double StandartFunctions::Ask(void) { return NormalizeDouble(SymbolInfoDouble(m_symbol,SYMBOL_ASK),m_digits);}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
double StandartFunctions::Bid(void) { return NormalizeDouble(SymbolInfoDouble(m_symbol,SYMBOL_ASK),m_digits);}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void StandartFunctions::GetTradeSum(STradeSum &sum,ENUM_POSITION_TYPE type)
|
|
{
|
|
sum.count = 0;
|
|
sum.profit = 0.0;
|
|
sum.trailPrice = 0.0;
|
|
int count = PositionsTotal();
|
|
if(count <=0)
|
|
return;
|
|
for(int i = OrdersTotal()-1; i >= 0; i--)
|
|
{
|
|
COrderInfo order;
|
|
if(order.SelectByIndex(i))
|
|
{
|
|
if(order.Magic() != m_magic)
|
|
continue;
|
|
|
|
if(order.Symbol() != m_symbol)
|
|
continue;
|
|
///Print(__FUNCTION__," > Found pending order with ticket #",order.Ticket(),"...");
|
|
|
|
if(order.OrderType() == ORDER_TYPE_BUY_LIMIT)
|
|
sum.count++;
|
|
if(order.OrderType() == ORDER_TYPE_SELL_LIMIT)
|
|
sum.count++;
|
|
|
|
}
|
|
}
|
|
for(int i = count-1; i>=0; i--)
|
|
{
|
|
ulong ticket = PositionGetTicket(i);
|
|
if(ticket>0)
|
|
{
|
|
if(PositionGetInteger(POSITION_TYPE) == type)
|
|
{
|
|
sum.count++;
|
|
sum.profit += PositionGetDouble(POSITION_PROFIT)+PositionGetDouble(POSITION_SWAP);
|
|
double entry = PositionGetDouble(POSITION_PRICE_OPEN);
|
|
double profit = PositionGetDouble(POSITION_PROFIT);
|
|
if(type==POSITION_TYPE_BUY)
|
|
{
|
|
if(sum.trailPrice==0 || PositionGetDouble(POSITION_PRICE_OPEN)<sum.trailPrice)
|
|
{
|
|
sum.trailPrice = PositionGetDouble(POSITION_PRICE_OPEN);
|
|
}
|
|
}
|
|
else
|
|
if(type==POSITION_TYPE_SELL)
|
|
{
|
|
if(sum.trailPrice==0 || PositionGetDouble(POSITION_PRICE_OPEN)>sum.trailPrice)
|
|
{
|
|
sum.trailPrice = PositionGetDouble(POSITION_PRICE_OPEN);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
bool StandartFunctions::IsNewBar(void)
|
|
{
|
|
datetime current_time = iTime(m_symbol,m_timeFrame,0);
|
|
if(previous_time != current_time)
|
|
{
|
|
previous_time = current_time;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
bool StandartFunctions::IsNewBarDay(void)
|
|
{
|
|
static datetime prevTime = 0;
|
|
datetime currentTime = iTime(m_symbol,PERIOD_D1,0);
|
|
if(prevTime == currentTime)
|
|
return false;
|
|
prevTime = currentTime;
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
double StandartFunctions::tr(int shift)
|
|
{
|
|
double t1 = High(shift) - Low(shift) ;
|
|
double t2 = MathAbs(High(shift) - Close(shift+1));
|
|
double t3 = MathAbs(Low(shift) - Close(shift+1));
|
|
return MathMax(MathMax(t1, t2), t3);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
double StandartFunctions::Size(int shift)
|
|
{
|
|
double totalSize = High(shift) - Low(shift);
|
|
double totalSize2 = High(shift+1) - Low(shift+1);
|
|
return totalSize/totalSize2;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
double StandartFunctions::PipeToDouble(double pips)
|
|
{
|
|
return NormalizeDouble(PointsToDouble(m_symbol,pips),m_digits);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
ulong StandartFunctions::OpenOrder(ENUM_ORDER_TYPE OrderType,double lot,double entry,double stoploos,double tp,string comment)
|
|
{
|
|
|
|
ulong result =-1;
|
|
if(CanOpenOrder(m_symbol,OrderType,lot,entry))
|
|
{
|
|
if(!m_trade.PositionOpen(m_symbol,OrderType,lot,entry,stoploos,tp,comment))
|
|
return -1;
|
|
else
|
|
return m_trade.ResultOrder();
|
|
}
|
|
else
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
ulong StandartFunctions::BuyLimit(double lot,double entry,double stoploos,double tp,string comment,datetime expirt)
|
|
{
|
|
|
|
if(!m_trade.BuyLimit(lot,entry,m_symbol,stoploos,tp,ORDER_TIME_GTC,expirt,comment))
|
|
return -1;
|
|
ulong result = m_trade.ResultOrder();
|
|
return result;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
ulong StandartFunctions::BuyStop(double lot,double entry,double stoploos,double tp,string comment,datetime expirt)
|
|
{
|
|
|
|
if(!m_trade.BuyStop(lot,entry,m_symbol,stoploos,tp,ORDER_TIME_GTC,expirt,comment))
|
|
return -1;
|
|
return m_trade.ResultDeal();
|
|
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
ulong StandartFunctions::SellLimit(double lot,double entry,double stoploos,double tp,string comment,datetime expirt)
|
|
{
|
|
if(!m_trade.SellLimit(lot,entry,m_symbol,stoploos,tp,ORDER_TIME_GTC,expirt,comment))
|
|
return -1;
|
|
ulong result = m_trade.ResultOrder();
|
|
return result;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
ulong StandartFunctions::SellStop(double lot,double entry,double stoploos,double tp,string comment,datetime expirt)
|
|
{
|
|
if(!m_trade.SellStop(lot,entry,m_symbol,stoploos,tp,ORDER_TIME_GTC,expirt,comment))
|
|
return -1;
|
|
return m_trade.ResultDeal();
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
bool StandartFunctions::UpdatePosition(const ulong ticket,const double sl,const double tp)
|
|
{
|
|
return m_trade.PositionModify(ticket,sl,tp);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void StandartFunctions::DrawArrow(string name, datetime arrowTime, double arrowPrice, string dir = "up", color clr = clrLime, int size = 2)
|
|
{
|
|
string objName = name + "_" + dir + "_" + TimeToString(arrowTime, TIME_SECONDS);
|
|
if(!ObjectCreate(0, objName, OBJ_ARROW, 0, arrowTime, arrowPrice))
|
|
return;
|
|
|
|
int arrowCode = (dir == "down") ? 234 : 233; // 233 = up, 234 = down
|
|
color arrowColor = (dir == "down") ? clrRed : clr;
|
|
|
|
ObjectSetInteger(0, objName, OBJPROP_ARROWCODE, arrowCode);
|
|
ObjectSetInteger(0, objName, OBJPROP_COLOR, arrowColor);
|
|
ObjectSetInteger(0, objName, OBJPROP_WIDTH, size);
|
|
ObjectSetInteger(0, objName, OBJPROP_BACK, false);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
double StandartFunctions::CalculateLotByBalance()
|
|
{
|
|
// 1) Get current account balance
|
|
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
|
|
|
|
// 2) Compute how many “$100” increments
|
|
int increments = int(balance / 100.0);
|
|
// e.g.: if balance=250.75 → increments = floor(250.75/100) = 2
|
|
|
|
// 3) Base lot = increments * 0.01
|
|
double lot = increments * 0.01;
|
|
// e.g.: 2 * 0.01 = 0.02
|
|
|
|
// 4) Fetch symbol’s min/max/step volume
|
|
double minLot = SymbolInfoDouble(m_symbol, SYMBOL_VOLUME_MIN);
|
|
double maxLot = SymbolInfoDouble(m_symbol, SYMBOL_VOLUME_MAX);
|
|
double step = SymbolInfoDouble(m_symbol, SYMBOL_VOLUME_STEP);
|
|
// 5) If computed lot < minimum, set to minLot
|
|
if(lot < minLot)
|
|
lot = minLot;
|
|
|
|
// 6) Round “lot” down to nearest multiple of “step”
|
|
// e.g. if step=0.01 and lot=0.027, MathFloor(0.027/0.01)=2 → 2*0.01=0.02
|
|
if(step > 0.0)
|
|
lot = MathFloor(lot / step) * step;
|
|
|
|
// 7) If that rounding pushed lot > maxLot, clamp to maxLot
|
|
if(lot > maxLot)
|
|
lot = maxLot;
|
|
|
|
return(lot);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
bool StandartFunctions::CheckTradeAllowed()
|
|
{
|
|
MqlDateTime date_cur;
|
|
TimeTradeServer(date_cur);
|
|
datetime seconds_cur = date_cur.hour * 3600 + date_cur.min * 60 + date_cur.sec;
|
|
int i = 0;
|
|
while(true)
|
|
{
|
|
datetime seconds_from = {}, seconds_to = {};
|
|
if(!SymbolInfoSessionTrade(m_symbol, (ENUM_DAY_OF_WEEK)date_cur.day_of_week, i, seconds_from, seconds_to))
|
|
break;
|
|
if(seconds_cur > seconds_from && seconds_cur < seconds_to)
|
|
return true;
|
|
++i;
|
|
}
|
|
return false;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void StandartFunctions::UpdatePosition(double trailingPips,double target)
|
|
{
|
|
int total = PositionsTotal();
|
|
for(int i = total-1; i >= 0; i--)
|
|
{
|
|
ulong position_ticket = PositionGetTicket(i);
|
|
string m_pair = "";
|
|
double m_lot = 0.0;
|
|
double m_profit = 0.0;
|
|
double m_stopLoos = 0.0;
|
|
double m_open_price = 0.0;
|
|
double m_tp = 0.0;
|
|
long m_position_type;
|
|
long magic;
|
|
double m_point;
|
|
double m_bid;
|
|
double m_ask;
|
|
if(
|
|
!PositionGetString(POSITION_SYMBOL,m_pair) ||
|
|
!PositionGetDouble(POSITION_VOLUME,m_lot) ||
|
|
!PositionGetDouble(POSITION_PROFIT,m_profit)||
|
|
!PositionGetDouble(POSITION_PRICE_OPEN,m_open_price)||
|
|
!PositionGetInteger(POSITION_MAGIC,magic)||
|
|
!PositionGetDouble(POSITION_TP,m_tp)||
|
|
!PositionGetDouble(POSITION_SL,m_stopLoos))
|
|
{
|
|
return;
|
|
Print("POSITION_SYMBOL ERROR");
|
|
}
|
|
if(m_symbol != m_pair && m_magic != magic)
|
|
return;
|
|
if(
|
|
!SymbolInfoDouble(m_pair, SYMBOL_BID,m_bid)||
|
|
!SymbolInfoDouble(m_pair, SYMBOL_ASK,m_ask)||
|
|
!SymbolInfoDouble(m_pair, SYMBOL_POINT,m_point))
|
|
{
|
|
return;
|
|
Print("SYMBOL_DIGITS ERROR");
|
|
}
|
|
if(!PositionGetInteger(POSITION_TYPE,m_position_type))
|
|
{
|
|
return;
|
|
Print("POSITION_TYPE ERROR");
|
|
}
|
|
|
|
string m_position_name = m_position_type == POSITION_TYPE_BUY ? "BUY" :m_position_type == POSITION_TYPE_SELL ? "SELL" : "UNKOWN";
|
|
if(m_position_name == "UNKOWN")
|
|
{
|
|
Print("POSITION_TYPE ERROR");
|
|
return;
|
|
}
|
|
NormalizeDouble(m_bid,(int)m_digits);
|
|
NormalizeDouble(m_ask,(int)m_digits);
|
|
NormalizeDouble(m_profit,(int)m_digits);
|
|
NormalizeDouble(m_stopLoos,(int)m_digits);
|
|
NormalizeDouble(m_tp,(int)m_digits);
|
|
NormalizeDouble(m_open_price,(int)m_digits);
|
|
|
|
|
|
//double close = Close(1,m_pair,PERIOD_M5);
|
|
double buy_stop = m_bid - trailingPips ;
|
|
double sell_stop = m_ask + trailingPips ;
|
|
//double atr = tr(0,m_pair,PERIOD_H1);
|
|
//Print(
|
|
// StringFormat(
|
|
// "Pair:%s,Position:%s,Open:%.2f,Profit:%-.*f,StopLoos:%.2f,Lot:%.2f",
|
|
// m_pair,m_position_name,m_open_price,m_digits,m_profit,m_stopLoos,m_lot)
|
|
//);
|
|
//Print(StringFormat("buy:%-.*f,sell:%-.*f,m_avg:%.2f,latAvg:%.2f",m_digits,buy_stop,m_digits,sell_stop,m_avg,m_lastAvg));
|
|
|
|
if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
|
|
{
|
|
if(m_profit >= target)
|
|
{
|
|
double dollarToPip =
|
|
NormalizeDouble(CalculatePipsFromDollars(m_profit,m_lot),(int)m_digits);
|
|
//m_trade.PositionClose(position_ticket);
|
|
|
|
}
|
|
|
|
if(buy_stop > m_stopLoos && buy_stop > m_open_price)
|
|
{
|
|
if(m_trade.PositionModify(position_ticket,buy_stop,m_tp))
|
|
Print("PositionModify");
|
|
else
|
|
Print(_LastError);
|
|
}
|
|
//if(m_profit >= trailingPips*3)
|
|
// m_trade.PositionClose(position_ticket);
|
|
}
|
|
if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
|
|
{
|
|
if(m_profit >= target)
|
|
{
|
|
double dollarToPip =
|
|
NormalizeDouble(CalculatePipsFromDollars(m_profit,m_lot),(int)m_digits);
|
|
//m_trade.PositionClose(position_ticket);
|
|
|
|
}
|
|
if(m_stopLoos == 0)
|
|
{
|
|
if(sell_stop < m_open_price)
|
|
{
|
|
if(m_trade.PositionModify(position_ticket,sell_stop,m_tp))
|
|
Print("PositionModify");
|
|
else
|
|
Print(_LastError);
|
|
}
|
|
}
|
|
else
|
|
if(sell_stop < m_stopLoos && sell_stop < m_open_price)
|
|
{
|
|
if(m_trade.PositionModify(position_ticket,sell_stop,m_tp))
|
|
Print("PositionModify");
|
|
else
|
|
Print(_LastError);
|
|
|
|
}
|
|
//if(m_profit >= trailingPips*3)
|
|
// m_trade.PositionClose(position_ticket);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
double StandartFunctions::CalcLots(double slPoints)
|
|
{
|
|
|
|
double risk = AccountInfoDouble(ACCOUNT_BALANCE) * 10 / 100;
|
|
|
|
double ticksize = SymbolInfoDouble(m_symbol,SYMBOL_TRADE_TICK_SIZE);
|
|
|
|
double tickvalue = SymbolInfoDouble(m_symbol,SYMBOL_TRADE_TICK_VALUE);
|
|
|
|
double lotstep = SymbolInfoDouble(m_symbol,SYMBOL_VOLUME_STEP);
|
|
|
|
double moneyPerLotstep = slPoints / ticksize * tickvalue * lotstep;
|
|
|
|
double lots = MathFloor(risk / moneyPerLotstep) * lotstep;
|
|
|
|
lots = MathMin(lots,SymbolInfoDouble(m_symbol,SYMBOL_VOLUME_MAX));
|
|
|
|
lots = MathMax(lots,SymbolInfoDouble(m_symbol,SYMBOL_VOLUME_MIN));
|
|
|
|
return lots;
|
|
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
double StandartFunctions::CalculatePipsFromDollars(double dollarAmount,double lotSize)
|
|
{
|
|
double tickSize = SymbolInfoDouble(m_symbol, SYMBOL_TRADE_TICK_SIZE);
|
|
double tickValue = SymbolInfoDouble(m_symbol, SYMBOL_TRADE_TICK_VALUE);
|
|
double point = SymbolInfoDouble(m_symbol, SYMBOL_POINT);
|
|
int digits = (int)SymbolInfoInteger(m_symbol, SYMBOL_DIGITS);
|
|
|
|
|
|
double pipValue = tickValue / tickSize * point;
|
|
|
|
|
|
double pips = dollarAmount / (pipValue * lotSize);
|
|
|
|
return pips;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
bool StandartFunctions::IsPivotHigh(int index,int Left,int Right,const MqlRates &rates[])
|
|
{
|
|
for(int j = 1; j <= Right; j++)
|
|
if(rates[index].high <= rates[index - j].high)
|
|
return false;
|
|
for(int j = 1; j <= Right; j++)
|
|
if(rates[index].high <= rates[index + j].high)
|
|
return false;
|
|
return true;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
bool StandartFunctions::IsPivotLow(int index,int Left,int Right,const MqlRates &rates[])
|
|
{
|
|
for(int j = 1; j <= Left; j++)
|
|
if(rates[index].low >= rates[index - j].low)
|
|
return false;
|
|
for(int j = 1; j <= Right; j++)
|
|
if(rates[index].low>= rates[index + j].low)
|
|
return false;
|
|
return true;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
int PipsToPoint(string symbol,double pips)
|
|
{
|
|
int D = (int) SymbolInfoInteger(symbol,SYMBOL_DIGITS);
|
|
return (int)(pips* ((D==3 || D==5) ? 10 : 1));
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
double PointsToDouble(string symbol,double point)
|
|
{
|
|
Print(SymbolInfoDouble(symbol,SYMBOL_POINT));
|
|
return (point * SymbolInfoDouble(symbol,SYMBOL_POINT));
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
bool CanOpenOrder(string symbol,ENUM_ORDER_TYPE OrderType,double lot,double entry)
|
|
{
|
|
double margin = 0.0;
|
|
if(!OrderCalcMargin(OrderType, symbol, lot, entry, margin))
|
|
{
|
|
return false;
|
|
}
|
|
double freeMargin = AccountInfoDouble(ACCOUNT_MARGIN_FREE);
|
|
if(margin > freeMargin)
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
//+------------------------------------------------------------------+
|