TF-altProjekte/Experts/6954/trendmeEA.mq5

2019 lines
141 KiB
MQL5
Raw Permalink Normal View History

2025-05-30 16:31:33 +02:00
<EFBFBD><EFBFBD>//+------------------------------------------------------------------+
//| trendmeEA.mq4 |
//| Copyright 2019, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#define pdxversion "1.00"
#property copyright "Klymenko Roman (needtome@icloud.com)"
#property link "https://www.mql5.com/en/users/needtome"
#property version pdxversion
#property strict
enum TypeOfLimit //Limit Mode
{
STOP,//STOP
LIMIT,// LIMIT
};
enum TypeOfStop //Stop Mode
{
STOP_NONE,// none
STOP_HIGH,// by wicks
STOP_OPEN,// by open
STOP_CLOSE,// by close
};
enum TypeOfBar //Bar Mode
{
BAR_1,// bar 1
BAR_0,// bar 0
BAR_01,// bars 0 and 1
};
enum BarType //Bar Type
{
BAR_NONE,// do not enter
BAR_MIN,// take profit 1
};
enum TypeOfPos
{
MY_BUY,
MY_SELL,
MY_BUYSTOP,
MY_BUYLIMIT,
MY_SELLSTOP,
MY_SELLLIMIT,
MY_BUYSLTP,
MY_SELLSLTP,
};
enum TypeOfLang{
MY_ENG, // English
MY_RUS, // CAA:89
};
enum TypeOfLots //Lots Mode
{
MY_FIXED,//Fixed
MY_ARIFMET,// Arifmet
MY_GEOMET,// Geomet
};
input int EA_Magic=333;
input TypeOfLimit typeLimit=STOP; // (-) Limit order type
input string my_cmt="trendmeEA"; // Comment
input bool open_LONG = true; // Open Long
input bool open_SHORT = true; // Open Short
input double Lot=0.01; //Lot size
input TypeOfLots typeLot=MY_FIXED; // (-) Increasing a lot in a chain
input uint maxLimits=5; // Max number of limit orders in one direction
input bool noOpenFirstLine=false; // Do not place the nearest orders
input int desicion=3; // Decade for limit orders
input int d_offset=0; // Shift in points
input double order_TP=2.5; // Order take profit
input double order_SL=0; // Order stop loss
input int maxOnPrice=33; // Max orders at the same price
input int maxAll=300; // Max orders in one direction
input double noOpenLongMax=0; // Do not open Long if the price exceeds
input double noOpenLongMin=0; // Do not open Long if the price is less than
input double noOpenShortMax=0; // Do not open Short if the price exceeds
input double noOpenShortMin=0; // Do not open Short if the price is less than
input uint doubleLot1=0; // #1 Increase lot if the balance increases, $
input uint doubleLot2=0; // #2 Increase lot if the balance increases, $
input uint doubleLot3=0; // #3 Increase lot if the balance increases, $
sinput string delimeter_02=""; // --- Closing all positions
input double takeProfit=0; // Profit, $
input double equityGross=0; // If equity increased, $
input double equityLess=0; // If equity decreased, $
input double closeAllMax=0; // Close all at price exceeding
input double closeAllMin=0; // Close all at price less than
sinput string delimeter_05=""; // --- (-) Trailing Stop
input uint trailing1NumStepsStart=0;
input uint trailing1NumStepsSave=1;
input uint trailing1NumStepsTP=0;
input uint trailing2NumStepsStart=0;
input uint trailing2NumStepsSave=3;
input uint trailing2NumStepsTP=0;
sinput string delimeter_07=""; // --- In bar direction
input bool BARS_enabled=false; // Use entry by bar only
input BarType BARS_type=BAR_NONE; // Bar accounting type
input TypeOfBar typeBar=BAR_1; // Bar index
input ENUM_TIMEFRAMES BARS_Timeframe=PERIOD_M15; // Timeframe
sinput string delimeter_09=""; // --- Other
input TypeOfLang LANG=MY_RUS; // Language
#ifdef __MQL5__
#include <Trade\Trade.mqh>
CTrade Trade;
enum TypeOfFilling //Filling Mode
{
FOK,//ORDER_FILLING_FOK
RETURN,// ORDER_FILLING_RETURN
IOC,//ORDER_FILLING_IOC
};
input TypeOfFilling useORDER_FILLING_RETURN=FOK; // Order filling mode
#endif
MqlTick lastme;
double rawPrice=0;
double maxPrice=0;
double minPrice=0;
double step=0;
uint LongLimit=0;
uint ShortLimit=0;
uint LongPos=0;
uint ShortPos=0;
double LongVol=0;
double ShortVol=0;
double minStop=0;
string prefix_graph="trendme_";
string msg_lines[];
uchar lines_size=0;
double curLot;
int h;
double buf0[];
double buf1[];
double buf2[];
int cur_offset;
bool noLong=false;
bool noShort=false;
datetime Old_Time=0;
struct translate{
string err1;
string err2;
string err3;
string err4;
string err5;
string err6;
string err7;
string err8;
string err9;
string err64;
string err65;
string err128;
string err129;
string err130;
string err131;
string err132;
string err133;
string err134;
string err135;
string err136;
string err137;
string err138;
string err139;
string err140;
string err141;
string err145;
string err146;
string err147;
string err148;
string err0;
string retcode;
string retcode10004;
string retcode10006;
string retcode10007;
string retcode10010;
string retcode10011;
string retcode10012;
string retcode10013;
string retcode10014;
string retcode10015;
string retcode10016;
string retcode10017;
string retcode10018;
string retcode10019;
string retcode10020;
string retcode10021;
string retcode10022;
string retcode10023;
string retcode10024;
string retcode10025;
string retcode10026;
string retcode10027;
string retcode10028;
string retcode10029;
string retcode10030;
string retcode10031;
string retcode10032;
string retcode10033;
string retcode10034;
string retcode10035;
string retcode10036;
string retcode10038;
string retcode10039;
string retcode10040;
string retcode10041;
string retcode10042;
string retcode10043;
string retcode10044;
};
translate langs;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
if(!MQLInfoInteger(MQL_TRADE_ALLOWED)){
Comment("The Expert Advisor is not allowed to trade! ("+(string) EA_Magic+")");
return(INIT_SUCCEEDED);
}
init_lang();
if(desicion>0){
step=1/MathPow(10, desicion);
}else if(desicion<0){
step=MathPow(10, MathAbs(desicion));
}else{
step=1;
}
cur_offset=d_offset;
if(_Digits==5 || _Digits==3){
if(cur_offset>0){
cur_offset*=10;
}
}
if( noOpenLongMax>0 && ObjectFind(0, prefix_graph+"_noOpenLongMax")<0 ){
ObjectCreate(0, prefix_graph+"_noOpenLongMax", OBJ_HLINE, 0, 0, maxPrice);
ObjectSetInteger(0,prefix_graph+"_noOpenLongMax",OBJPROP_COLOR,clrMagenta);
ObjectSetInteger(0,prefix_graph+"_noOpenLongMax",OBJPROP_SELECTABLE,false);
ObjectSetInteger(0,prefix_graph+"_noOpenLongMax",OBJPROP_BACK,true);
}
if( noOpenLongMin>0 && ObjectFind(0, prefix_graph+"_noOpenLongMin")<0 ){
ObjectCreate(0, prefix_graph+"_noOpenLongMin", OBJ_HLINE, 0, 0, maxPrice);
ObjectSetInteger(0,prefix_graph+"_noOpenLongMin",OBJPROP_COLOR,clrMagenta);
ObjectSetInteger(0,prefix_graph+"_noOpenLongMin",OBJPROP_SELECTABLE,false);
ObjectSetInteger(0,prefix_graph+"_noOpenLongMin",OBJPROP_BACK,true);
}
minStop=SymbolInfoDouble(_Symbol, SYMBOL_POINT)*SymbolInfoInteger(_Symbol, SYMBOL_TRADE_STOPS_LEVEL);
//---
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
ObjectsDeleteAll(0, prefix_graph);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
if( equityLess>0 && AccountInfoDouble(ACCOUNT_BALANCE)-AccountInfoDouble(ACCOUNT_EQUITY)>= equityLess ){
closeAllPos();
}
if( equityGross>0 && GlobalVariableCheck(prefix_graph+"_equity") && AccountInfoDouble(ACCOUNT_EQUITY)-GlobalVariableGet(prefix_graph+"_equity")>= equityGross ){
closeAllPos();
}else if( checkTakeProfit()){
closeAllPos();
}
if( !pdxIsNewBar() ){
return;
}
if( GlobalVariableCheck(prefix_graph+"_equity") ){
Comment("Equity on begin: "+(string) GlobalVariableGet(prefix_graph+"_equity"));
}
#ifdef __MQL5__
LongPos=getCountOrdersForPrice(0, ORDER_TYPE_BUY);
ShortPos=getCountOrdersForPrice(0, ORDER_TYPE_SELL);
#else
LongPos=getCountOrdersForPrice(0, OP_BUY);
ShortPos=getCountOrdersForPrice(0, OP_SELL);
#endif
/*
if( LongPos > ShortPos*1.5 ){
closeProfit(MY_BUY, (int) (LongPos-ShortPos*1.3) );
}else if( ShortPos > LongPos*1.5 ){
closeProfit(MY_SELL, (int) (ShortPos-LongPos*1.3) );
}
*/
// checkTrailingStop();
getmeinfo_btn(_Symbol);
SymbolInfoTick(_Symbol, lastme);
if( lastme.bid==0 ){
return;
}
curLot=Lot;
if( doubleLot1>0 && AccountInfoDouble(ACCOUNT_BALANCE)>doubleLot1 && AccountInfoDouble(ACCOUNT_EQUITY) > doubleLot1/2 ){
curLot+=Lot;
}
if( doubleLot2>0 && AccountInfoDouble(ACCOUNT_BALANCE)>doubleLot2 && AccountInfoDouble(ACCOUNT_EQUITY) > doubleLot2/2 ){
curLot+=Lot;
}
if( doubleLot3>0 && AccountInfoDouble(ACCOUNT_BALANCE)>doubleLot3 && AccountInfoDouble(ACCOUNT_EQUITY) > doubleLot3/2 ){
curLot+=Lot;
}
if( closeAllMax>0 && lastme.bid>closeAllMax && LongVol<ShortVol ){
closeAllPos();
ExpertRemove();
}else if( closeAllMin>0 && lastme.ask<closeAllMin && LongVol>ShortVol ){
closeAllPos();
ExpertRemove();
}
noLong=false;
noShort=false;
rawPrice=getRawPrice();
maxPrice=rawPrice+step*(maxLimits+1);
minPrice=rawPrice-step*(maxLimits+1);
if( existLimits() ){
delDeadLimits();
addNewLimits();
}else{
initLimits();
}
}
//+------------------------------------------------------------------+
double getRawPrice(){
if(desicion>=0){
return StringToDouble(DoubleToString(lastme.bid, desicion));
}else{
return StringToDouble(DoubleToString(lastme.bid/MathPow(10, MathAbs(desicion)), 0))*MathPow(10, MathAbs(desicion));
}
}
bool existLimits(){
#ifdef __MQL5__
int cntMyPos=PositionsTotal();
for(int ti=cntMyPos-1; ti>=0; ti--){
if(PositionGetSymbol(ti)!=_Symbol) continue;
if(EA_Magic>0 && PositionGetInteger(POSITION_MAGIC)!=EA_Magic) continue;
return true;
}
int cntMyPosO=OrdersTotal();
for(int ti=cntMyPosO-1; ti>=0; ti--){
ulong orderTicket=OrderGetTicket(ti);
if(OrderGetString(ORDER_SYMBOL)!=_Symbol) continue;
if(EA_Magic>0 && OrderGetInteger(ORDER_MAGIC)!=EA_Magic) continue;
return true;
}
#else
int cntMyPos=OrdersTotal();
if(cntMyPos>0){
for(int ti=cntMyPos-1; ti>=0; ti--){
if(OrderSelect(ti,SELECT_BY_POS,MODE_TRADES)==false) continue;
if(OrderSymbol()!=_Symbol) continue;
if(EA_Magic>0 && OrderMagicNumber()!=EA_Magic) continue;
return true;
}
}
#endif
return false;
}
void initLimits(){
GlobalVariableSet(prefix_graph+"_equity", AccountInfoDouble(ACCOUNT_EQUITY));
double tp;
double sl;
MqlRates rates[];
bool BARS_noLong=false;
bool BARS_noShort=false;
if(BARS_enabled ){
ArraySetAsSeries(rates, true);
if( CopyRates( _Symbol, BARS_Timeframe, 0, 2, rates)==2 ){
switch(typeBar){
case BAR_1:
if( rates[1].close > rates[1].open ){
BARS_noShort=true;
}else if( rates[1].close < rates[1].open ){
BARS_noLong=true;
}else{
BARS_noShort=true;
BARS_noLong=true;
}
break;
case BAR_0:
if( rates[0].close > rates[0].open ){
BARS_noShort=true;
}else if( rates[0].close < rates[0].open ){
BARS_noLong=true;
}else{
BARS_noShort=true;
BARS_noLong=true;
}
break;
case BAR_01:
if( rates[0].close > rates[0].open && rates[1].close > rates[1].open ){
BARS_noShort=true;
}else if( rates[0].close < rates[0].open && rates[1].close < rates[1].open ){
BARS_noLong=true;
}else{
BARS_noShort=true;
BARS_noLong=true;
}
break;
}
}
if( BARS_type == BAR_NONE ){
if( BARS_noLong ){
noLong=true;
}
if( BARS_noShort ){
noShort=true;
}
}
}
double curPrice=rawPrice;
if( lastme.bid<curPrice && curPrice-lastme.bid > minStop ){
curPrice-=step;
}
if(cur_offset>0){
curPrice+=cur_offset*SymbolInfoDouble(_Symbol, SYMBOL_POINT);
}
double curCurLot=curLot;
while(1==1){
if( !open_LONG || noLong ) break;
curPrice+=step;
if( curPrice>maxPrice ){
break;
}
if( noOpenLongMax>0 && curPrice>noOpenLongMax ){
break;
}
if( noOpenLongMin>0 && curPrice<noOpenLongMin ){
continue;
}
if( curPrice-lastme.ask < minStop ) continue;
tp=0;
sl=0;
if(typeLimit==STOP){
if(order_TP>0){
tp=curPrice+step*order_TP;
}
if(order_SL>0){
sl=curPrice-step*order_SL;
}
if( BARS_type == BAR_MIN && BARS_noLong ){
tp = curPrice+step*order_TP;
}
if(!pdxSendOrder(MY_BUYSTOP, curPrice, sl, tp, curCurLot, 0, "", _Symbol)){
}
}else{
if(order_TP>0){
tp=curPrice-step*order_TP;
}
if(order_SL>0){
sl=curPrice+step*order_SL;
}
if( BARS_type == BAR_MIN && BARS_noLong ){
tp = curPrice-step*order_TP;
}
if(!pdxSendOrder(MY_SELLLIMIT, curPrice, sl, tp, curCurLot, 0, "", _Symbol)){
}
}
switch(typeLot){
case MY_ARIFMET:
curCurLot+=curLot;
break;
case MY_GEOMET:
curCurLot*=2;
break;
}
}
curPrice=rawPrice;
if( lastme.bid>curPrice && lastme.bid-curPrice > minStop ){
curPrice+=step;
}
if(cur_offset>0){
curPrice-=cur_offset*SymbolInfoDouble(_Symbol, SYMBOL_POINT);
}
curCurLot=curLot;
while(1==1){
if( !open_SHORT || noShort ) break;
curPrice-=step;
if( curPrice<minPrice ){
break;
}
if( noOpenShortMax>0 && curPrice>noOpenShortMax ){
continue;
}
if( noOpenShortMin>0 && curPrice<noOpenShortMin ){
break;
}
if( lastme.bid-curPrice < minStop ) continue;
tp=0;
sl=0;
if(typeLimit==STOP){
if(order_TP>0){
tp=curPrice-step*order_TP;
}
if(order_SL>0){
sl=curPrice+step*order_SL;
}
if( BARS_type == BAR_MIN && BARS_noShort ){
tp = curPrice-step*order_TP;
}
if(!pdxSendOrder(MY_SELLSTOP, curPrice, sl, tp, curCurLot, 0, "", _Symbol)){
}
}else{
if(order_TP>0){
tp=curPrice+step*order_TP;
}
if(order_SL>0){
sl=curPrice-step*order_SL;
}
if( BARS_type == BAR_MIN && BARS_noShort ){
tp = curPrice+step*order_TP;
}
if(!pdxSendOrder(MY_BUYLIMIT, curPrice, sl, tp, curCurLot, 0, "", _Symbol)){
}
}
switch(typeLot){
case MY_ARIFMET:
curCurLot+=curLot;
break;
case MY_GEOMET:
curCurLot*=2;
break;
}
}
}
void delDeadLimits(){
LongLimit=0;
ShortLimit=0;
#ifdef __MQL5__
int cntMyPosO=OrdersTotal();
for(int ti=cntMyPosO-1; ti>=0; ti--){
ulong orderTicket=OrderGetTicket(ti);
if(OrderGetString(ORDER_SYMBOL)!=_Symbol) continue;
if(EA_Magic>0 && OrderGetInteger(ORDER_MAGIC)!=EA_Magic) continue;
if( OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_BUY_STOP && OrderGetDouble(ORDER_PRICE_OPEN)>maxPrice ){
Trade.OrderDelete(orderTicket);
continue;
}else if( OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_SELL_STOP && OrderGetDouble(ORDER_PRICE_OPEN)<minPrice ){
Trade.OrderDelete(orderTicket);
continue;
}else if( OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_BUY_STOP && OrderGetDouble(ORDER_PRICE_OPEN)<lastme.bid ){
Trade.OrderDelete(orderTicket);
continue;
}else if( OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_SELL_STOP && OrderGetDouble(ORDER_PRICE_OPEN)>lastme.bid ){
Trade.OrderDelete(orderTicket);
continue;
}else if( OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_BUY_LIMIT && OrderGetDouble(ORDER_PRICE_OPEN)<minPrice ){
Trade.OrderDelete(orderTicket);
continue;
}else if( OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_SELL_LIMIT && OrderGetDouble(ORDER_PRICE_OPEN)>maxPrice ){
Trade.OrderDelete(orderTicket);
continue;
}else if( OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_BUY_LIMIT && OrderGetDouble(ORDER_PRICE_OPEN)>lastme.bid ){
Trade.OrderDelete(orderTicket);
continue;
}else if( OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_SELL_LIMIT && OrderGetDouble(ORDER_PRICE_OPEN)<lastme.bid ){
Trade.OrderDelete(orderTicket);
continue;
}
if( OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_BUY_STOP ){
LongLimit++;
}else if(OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_SELL_STOP){
ShortLimit++;
}else if( OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_BUY_LIMIT ){
LongLimit++;
}else if(OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_SELL_LIMIT){
ShortLimit++;
}
}
#else
int cntMyPos=OrdersTotal();
if(cntMyPos>0){
for(int ti=cntMyPos-1; ti>=0; ti--){
if(OrderSelect(ti,SELECT_BY_POS,MODE_TRADES)==false) continue;
if(OrderSymbol()!=_Symbol) continue;
if(EA_Magic>0 && OrderMagicNumber()!=EA_Magic) continue;
if( OrderType()==OP_BUY || OrderType()==OP_SELL ){ continue; }
if( OrderType()==OP_BUYSTOP && OrderOpenPrice()>maxPrice ){
if(OrderDelete(OrderTicket())){
continue;
}
}else if( OrderType()==OP_SELLSTOP && OrderOpenPrice()<minPrice ){
if(OrderDelete(OrderTicket())){
continue;
}
}else if( OrderType()==OP_BUYSTOP && OrderOpenPrice()<lastme.bid ){
if(OrderDelete(OrderTicket())){
continue;
}
}else if( OrderType()==OP_SELLSTOP && OrderOpenPrice()>lastme.bid ){
if(OrderDelete(OrderTicket())){
continue;
}
}else if( OrderType()==OP_BUYLIMIT && OrderOpenPrice()<minPrice ){
if(OrderDelete(OrderTicket())){
continue;
}
}else if( OrderType()==OP_SELLLIMIT && OrderOpenPrice()>maxPrice ){
if(OrderDelete(OrderTicket())){
continue;
}
}else if( OrderType()==OP_BUYLIMIT && OrderOpenPrice()>lastme.bid ){
if(OrderDelete(OrderTicket())){
continue;
}
}else if( OrderType()==OP_SELLLIMIT && OrderOpenPrice()<lastme.bid ){
if(OrderDelete(OrderTicket())){
continue;
}
}
if(OrderType()==OP_BUYSTOP){
LongLimit++;
}else if(OrderType()==OP_SELLSTOP){
ShortLimit++;
}else if(OrderType()==OP_BUYLIMIT){
LongLimit++;
}else if(OrderType()==OP_SELLLIMIT){
ShortLimit++;
}
}
}
#endif
}
#ifdef __MQL5__
int getCountOrdersForPrice(double price, ENUM_ORDER_TYPE type){
int count=0;
int cntMyPos=PositionsTotal();
MqlTick latest_price;
SymbolInfoTick(_Symbol,latest_price);
for(int ti=cntMyPos-1; ti>=0; ti--){
if(PositionGetSymbol(ti)!=_Symbol) continue;
if(EA_Magic>0 && PositionGetInteger(POSITION_MAGIC)!=EA_Magic) continue;
if( PositionGetInteger(POSITION_TYPE)!=type ) continue;
if(price>0){
if( PositionGetDouble(POSITION_PRICE_OPEN) < price-(step/3) ) continue;
if( PositionGetDouble(POSITION_PRICE_OPEN) > price+(step/3) ) continue;
}
if( trailing1NumStepsStart>1 && trailing1NumStepsSave>0 && PositionGetDouble(POSITION_SL)==0 ){
double tp;
if( PositionGetInteger(POSITION_TYPE)==ORDER_TYPE_BUY ){
if( latest_price.bid-PositionGetDouble(POSITION_PRICE_OPEN) > step*trailing1NumStepsStart ){
tp = PositionGetDouble(POSITION_TP);
if(tp>0){
tp+=step*trailing1NumStepsTP;
}
if( pdxSendOrder(MY_BUYSLTP, PositionGetDouble(POSITION_PRICE_OPEN), NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN)+step*trailing1NumStepsSave, _Digits), tp, PositionGetDouble(POSITION_VOLUME), PositionGetInteger(POSITION_TICKET), PositionGetString(POSITION_COMMENT), PositionGetString(POSITION_SYMBOL))){ }
}
}else{
if( PositionGetDouble(POSITION_PRICE_OPEN)-latest_price.ask > step*trailing1NumStepsStart ){
tp = PositionGetDouble(POSITION_TP);
if(tp>0){
tp-=step*trailing1NumStepsTP;
}
if( pdxSendOrder(MY_SELLSLTP, PositionGetDouble(POSITION_PRICE_OPEN), NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN)-step*trailing1NumStepsSave, _Digits), tp, PositionGetDouble(POSITION_VOLUME), PositionGetInteger(POSITION_TICKET), PositionGetString(POSITION_COMMENT), PositionGetString(POSITION_SYMBOL))){ }
}
}
}
if( trailing2NumStepsStart>1 && trailing2NumStepsSave>0 && PositionGetDouble(POSITION_SL)>0 ){
double tp;
if( PositionGetInteger(POSITION_TYPE)==ORDER_TYPE_BUY ){
if( PositionGetDouble(POSITION_SL)>PositionGetDouble(POSITION_PRICE_OPEN) && latest_price.bid-PositionGetDouble(POSITION_PRICE_OPEN) > step*trailing2NumStepsStart ){
tp = PositionGetDouble(POSITION_TP);
if(tp>0){
tp+=step*trailing2NumStepsTP;
}
if( pdxSendOrder(MY_BUYSLTP, PositionGetDouble(POSITION_PRICE_OPEN), NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN)+step*trailing2NumStepsSave, _Digits), tp, PositionGetDouble(POSITION_VOLUME), PositionGetInteger(POSITION_TICKET), PositionGetString(POSITION_COMMENT), PositionGetString(POSITION_SYMBOL))){ }
}
}else{
if( PositionGetDouble(POSITION_SL)<PositionGetDouble(POSITION_PRICE_OPEN) && PositionGetDouble(POSITION_PRICE_OPEN)-latest_price.ask > step*trailing2NumStepsStart ){
tp = PositionGetDouble(POSITION_TP);
if(tp>0){
tp-=step*trailing2NumStepsTP;
}
if( pdxSendOrder(MY_SELLSLTP, PositionGetDouble(POSITION_PRICE_OPEN), NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN)-step*trailing2NumStepsSave, _Digits), tp, PositionGetDouble(POSITION_VOLUME), PositionGetInteger(POSITION_TICKET), PositionGetString(POSITION_COMMENT), PositionGetString(POSITION_SYMBOL))){ }
}
}
}
count++;
}
return count;
}
#else
int getCountOrdersForPrice(double price, int type){
int count=0;
int cntMyPos=OrdersTotal();
if(cntMyPos>0){
MqlTick latest_price;
SymbolInfoTick(_Symbol,latest_price);
for(int ti=cntMyPos-1; ti>=0; ti--){
if(OrderSelect(ti,SELECT_BY_POS,MODE_TRADES)==false) continue;
if( OrderType()==OP_BUY || OrderType()==OP_SELL ){ }else{ continue; }
if(OrderSymbol()!=_Symbol) continue;
if(EA_Magic>0 && OrderMagicNumber()!=EA_Magic) continue;
if(OrderType()!=type) continue;
if( trailing1NumStepsStart>1 && trailing1NumStepsSave>0 && OrderStopLoss()==0 ){
double tp;
if( OrderType()==OP_BUY ){
if( latest_price.bid-OrderOpenPrice() > step*trailing1NumStepsStart ){
tp = OrderTakeProfit();
if(tp>0){
tp+=step*trailing1NumStepsTP;
}
if( OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(OrderOpenPrice()+step*trailing1NumStepsSave, _Digits),tp,0) ){}
}
}else{
if( OrderOpenPrice()-latest_price.ask > step*trailing1NumStepsStart ){
tp = OrderTakeProfit();
if(tp>0){
tp-=step*trailing1NumStepsTP;
}
if( OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(OrderOpenPrice()-step*trailing1NumStepsSave, _Digits),tp,0) ){}
}
}
}
if( trailing2NumStepsStart>1 && trailing2NumStepsSave>0 && OrderStopLoss()>0 ){
double tp;
if( OrderType()==OP_BUY ){
if( OrderStopLoss()>OrderOpenPrice() && latest_price.bid-OrderOpenPrice() > step*trailing2NumStepsStart ){
tp = OrderTakeProfit();
if(tp>0){
tp+=step*trailing2NumStepsTP;
}
if( OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(OrderOpenPrice()+step*trailing2NumStepsSave, _Digits),tp,0) ){}
}
}else{
if( OrderStopLoss()<OrderOpenPrice() && OrderOpenPrice()-latest_price.ask > step*trailing2NumStepsStart ){
tp = OrderTakeProfit();
if(tp>0){
tp-=step*trailing2NumStepsTP;
}
if( OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(OrderOpenPrice()-step*trailing2NumStepsSave, _Digits),tp,0) ){}
}
}
}
if(price>0){
if( OrderOpenPrice() < price-(step/3) ) continue;
if( OrderOpenPrice() > price+(step/3) ) continue;
}
count++;
}
}
return count;
}
#endif
void addNewLimits(){
if(AccountInfoDouble(ACCOUNT_BALANCE) < 1) return;
MqlDateTime curT;
TimeToStruct(Old_Time, curT);
MqlRates rates[];
double tp;
double sl;
int lotMult=1;
double rangeMax=0;
double rangeMin=0;
bool isSmallRange=false;
bool BARS_noLong=false;
bool BARS_noShort=false;
if(BARS_enabled ){
ArraySetAsSeries(rates, true);
if( CopyRates( _Symbol, BARS_Timeframe, 0, 3, rates)==3 ){
switch(typeBar){
case BAR_1:
if( rates[1].close > rates[1].open ){
BARS_noShort=true;
}else if( rates[1].close < rates[1].open ){
BARS_noLong=true;
}else{
BARS_noShort=true;
BARS_noLong=true;
}
break;
case BAR_0:
if( rates[0].close > rates[0].open ){
BARS_noShort=true;
}else if( rates[0].close < rates[0].open ){
BARS_noLong=true;
}else{
BARS_noShort=true;
BARS_noLong=true;
}
break;
case BAR_01:
if( rates[0].close > rates[0].open && rates[1].close > rates[1].open ){
BARS_noShort=true;
}else if( rates[0].close < rates[0].open && rates[1].close < rates[1].open ){
BARS_noLong=true;
}else{
BARS_noShort=true;
BARS_noLong=true;
}
break;
}
if( rangeMax==0 || rangeMax<rates[0].high ){
rangeMax=rates[0].high;
}
if( rangeMax==0 || rangeMax<rates[1].high ){
rangeMax=rates[1].high;
}
if( rangeMin==0 || rangeMin>rates[0].low ){
rangeMin=rates[0].low;
}
if( rangeMin==0 || rangeMin>rates[1].low ){
rangeMin=rates[1].low;
}
}
if( BARS_type == BAR_NONE ){
if( BARS_noLong ){
noLong=true;
}
if( BARS_noShort ){
noShort=true;
}
}
}
double curPrice=rawPrice;
if(cur_offset>0){
curPrice+=cur_offset*SymbolInfoDouble(_Symbol, SYMBOL_POINT);
}
int count;
if(LongLimit<maxLimits && open_LONG && !noLong ){
double curCurLot=curLot;
curCurLot*=lotMult;
if( noOpenFirstLine ){
curPrice+=step;
}
while(1==1){
curPrice+=step;
if( curPrice>maxPrice ){
break;
}
if( isSmallRange && curPrice<rangeMax ){
continue;
}
if( noOpenLongMax>0 && curPrice>noOpenLongMax ){
break;
}
if( noOpenLongMin>0 && curPrice<noOpenLongMin ){
continue;
}
bool isCheckLimit=false;
if(typeLimit==STOP){
#ifdef __MQL5__
isCheckLimit=checkLimitOnPrice(curPrice, ORDER_TYPE_BUY_STOP);
#else
isCheckLimit=checkLimitOnPrice(curPrice, OP_BUYSTOP);
#endif
}else{
#ifdef __MQL5__
isCheckLimit=checkLimitOnPrice(curPrice, ORDER_TYPE_SELL_LIMIT);
#else
isCheckLimit=checkLimitOnPrice(curPrice, OP_SELLLIMIT);
#endif
}
if(isCheckLimit) break;
if(typeLimit==STOP){
#ifdef __MQL5__
if( maxAll>0 && getCountOrdersForPrice(0, ORDER_TYPE_BUY)<=maxAll ){
count=getCountOrdersForPrice(curPrice, ORDER_TYPE_BUY);
#else
if( maxAll>0 && getCountOrdersForPrice(0, OP_BUY)<=maxAll ){
count=getCountOrdersForPrice(curPrice, OP_BUY);
#endif
if( count<=maxOnPrice ){
tp=0;
sl=0;
if(typeLimit==STOP){
if(order_TP>0){
tp=curPrice+step*order_TP;
}
if(order_SL>0){
sl=curPrice-step*order_SL;
}
if( BARS_type == BAR_MIN && BARS_noLong ){
tp = curPrice+step*order_TP;
}
if(pdxSendOrder(MY_BUYSTOP, curPrice, sl, tp, curCurLot, 0, "", _Symbol)){
LongLimit++;
}
}else{
if(order_TP>0){
tp=curPrice-step*order_TP;
}
if(order_SL>0){
sl=curPrice+step*order_SL;
}
if( BARS_type == BAR_MIN && BARS_noLong ){
tp = curPrice-step*order_TP;
}
if(pdxSendOrder(MY_SELLLIMIT, curPrice, sl, tp, curCurLot, 0, "", _Symbol)){
ShortLimit++;
}
}
}
}
}else{
#ifdef __MQL5__
if( maxAll>0 && getCountOrdersForPrice(0, ORDER_TYPE_SELL)<=maxAll ){
count=getCountOrdersForPrice(curPrice, ORDER_TYPE_SELL);
#else
if( maxAll>0 && getCountOrdersForPrice(0, OP_SELL)<=maxAll ){
count=getCountOrdersForPrice(curPrice, OP_SELL);
#endif
if( count<=maxOnPrice ){
tp=0;
sl=0;
if(typeLimit==STOP){
if(order_TP>0){
tp=curPrice+step*order_TP;
}
if(order_SL>0){
sl=curPrice-step*order_SL;
}
if( BARS_type == BAR_MIN && BARS_noLong ){
tp = curPrice+step*order_TP;
}
if(pdxSendOrder(MY_BUYSTOP, curPrice, sl, tp, curCurLot, 0, "", _Symbol)){
LongLimit++;
}
}else{
if(order_TP>0){
tp=curPrice-step*order_TP;
}
if(order_SL>0){
sl=curPrice+step*order_SL;
}
if( BARS_type == BAR_MIN && BARS_noLong ){
tp = curPrice-step*order_TP;
}
if(pdxSendOrder(MY_SELLLIMIT, curPrice, sl, tp, curCurLot, 0, "", _Symbol)){
ShortLimit++;
}
}
}
}
}
if(LongLimit>=maxLimits){
break;
}
switch(typeLot){
case MY_ARIFMET:
curCurLot+=curLot;
break;
case MY_GEOMET:
curCurLot*=2;
break;
}
}
}
if(ShortLimit<maxLimits && open_SHORT && !noShort ){
curPrice=rawPrice;
if(cur_offset<0){
curPrice-=cur_offset*SymbolInfoDouble(_Symbol, SYMBOL_POINT);
}
double curCurLot=curLot;
curCurLot*=lotMult;
if( noOpenFirstLine ){
curPrice-=step;
}
while(1==1){
curPrice-=step;
if( curPrice<minPrice ){
break;
}
if( isSmallRange && curPrice>rangeMin ){
continue;
}
if( noOpenShortMax>0 && curPrice>noOpenShortMax ){
break;
}
if( noOpenShortMin>0 && curPrice<noOpenShortMin ){
continue;
}
bool isCheckLimit=false;
if(typeLimit==STOP){
#ifdef __MQL5__
isCheckLimit=checkLimitOnPrice(curPrice, ORDER_TYPE_SELL_STOP);
#else
isCheckLimit=checkLimitOnPrice(curPrice, OP_SELLSTOP);
#endif
}else{
#ifdef __MQL5__
isCheckLimit=checkLimitOnPrice(curPrice, ORDER_TYPE_BUY_LIMIT);
#else
isCheckLimit=checkLimitOnPrice(curPrice, OP_BUYLIMIT);
#endif
}
if(isCheckLimit) break;
if(typeLimit==STOP){
#ifdef __MQL5__
if( maxAll>0 && getCountOrdersForPrice(0, ORDER_TYPE_SELL)<=maxAll ){
count=getCountOrdersForPrice(curPrice, ORDER_TYPE_SELL);
#else
if( maxAll>0 && getCountOrdersForPrice(0, OP_SELL)<=maxAll ){
count=getCountOrdersForPrice(curPrice, OP_SELL);
#endif
if( count<=maxOnPrice ){
tp=0;
sl=0;
if(order_TP>0){
tp=curPrice-step*order_TP;
}
if(order_SL>0){
sl=curPrice+step*order_SL;
}
if( BARS_type == BAR_MIN && BARS_noShort ){
tp = curPrice-step*order_TP;
}
if(typeLimit==STOP){
if(pdxSendOrder(MY_SELLSTOP, curPrice, sl, tp, curCurLot, 0, "", _Symbol)){
ShortLimit++;
}
}else{
if(pdxSendOrder(MY_BUYLIMIT, curPrice, 0, 0, curCurLot, 0, "", _Symbol)){
ShortLimit++;
}
}
}
}
}else{
#ifdef __MQL5__
if( maxAll>0 && getCountOrdersForPrice(0, ORDER_TYPE_BUY)<=maxAll ){
count=getCountOrdersForPrice(curPrice, ORDER_TYPE_BUY);
#else
if( maxAll>0 && getCountOrdersForPrice(0, OP_BUY)<=maxAll ){
count=getCountOrdersForPrice(curPrice, OP_BUY);
#endif
if( count<=maxOnPrice ){
tp=0;
sl=0;
if(order_TP>0){
tp=curPrice-step*order_TP;
}
if(order_SL>0){
sl=curPrice+step*order_SL;
}
if( BARS_type == BAR_MIN && BARS_noShort ){
tp = curPrice-step*order_TP;
}
if(typeLimit==STOP){
if(pdxSendOrder(MY_SELLSTOP, curPrice, sl, tp, curCurLot, 0, "", _Symbol)){
ShortLimit++;
}
}else{
if(pdxSendOrder(MY_BUYLIMIT, curPrice, 0, 0, curCurLot, 0, "", _Symbol)){
ShortLimit++;
}
}
}
}
}
if(ShortLimit>=maxLimits){
break;
}
switch(typeLot){
case MY_ARIFMET:
curCurLot+=curLot;
break;
case MY_GEOMET:
curCurLot*=2;
break;
}
}
}
}
#ifdef __MQL5__
bool checkLimitOnPrice(double price, ENUM_ORDER_TYPE type){
int cntMyPosO=OrdersTotal();
for(int ti=cntMyPosO-1; ti>=0; ti--){
ulong orderTicket=OrderGetTicket(ti);
if(OrderGetString(ORDER_SYMBOL)!=_Symbol) continue;
if(EA_Magic>0 && OrderGetInteger(ORDER_MAGIC)!=EA_Magic) continue;
if( OrderGetInteger(ORDER_TYPE)!=type ) continue;
if( OrderGetDouble(ORDER_PRICE_OPEN) < price-(step/3) ) continue;
if( OrderGetDouble(ORDER_PRICE_OPEN) > price+(step/3) ) continue;
return true;
}
return false;
}
#else
bool checkLimitOnPrice(double price, int type){
int cntMyPos=OrdersTotal();
if(cntMyPos>0){
for(int ti=cntMyPos-1; ti>=0; ti--){
if(OrderSelect(ti,SELECT_BY_POS,MODE_TRADES)==false) continue;
if(OrderSymbol()!=_Symbol) continue;
if(EA_Magic>0 && OrderMagicNumber()!=EA_Magic) continue;
if(OrderType()!=type) continue;
if( OrderOpenPrice() < price-(step/3) ) continue;
if( OrderOpenPrice() > price+(step/3) ) continue;
return true;
}
}
return false;
}
#endif
bool pdxIsNewBar(){
datetime New_Time[1];
if(CopyTime(_Symbol,_Period,0,1,New_Time)>0){
if(Old_Time!=New_Time[0]){
Old_Time=New_Time[0];
return true;
}
}
return false;
}
void checkTrailingStop(){
#ifdef __MQL5__
#else
int cntMyPos=OrdersTotal();
if(cntMyPos>0){
for(int ti=cntMyPos-1; ti>=0; ti--){
if(OrderSelect(ti,SELECT_BY_POS,MODE_TRADES)==false) continue;
if( OrderType()==OP_BUY || OrderType()==OP_SELL ){}else{ continue; }
if(OrderSymbol()!=_Symbol) continue;
if(EA_Magic>0 && OrderMagicNumber()!=EA_Magic) continue;
double profit=0;
profit+=OrderCommission();
profit+=OrderProfit();
profit+=OrderSwap();
if(profit>40 ){
MqlTick latest_price;
SymbolInfoTick(OrderSymbol(),latest_price);
if( latest_price.bid>OrderOpenPrice() ){
double newStop=NormalizeDouble(OrderOpenPrice()+((profit-30)*SymbolInfoDouble(_Symbol, SYMBOL_POINT)), _Digits);
if(newStop>OrderStopLoss()){
if( !OrderModify(OrderTicket(), OrderOpenPrice(), newStop, OrderTakeProfit(), 0 ) ){ ExpertRemove(); }
}
}else{
double newStop=NormalizeDouble(OrderOpenPrice()-((profit-30)*SymbolInfoDouble(_Symbol, SYMBOL_POINT)), _Digits);
if(newStop<OrderStopLoss()){
if( !OrderModify(OrderTicket(), OrderOpenPrice(), newStop, OrderTakeProfit(), 0 ) ){ ExpertRemove(); }
}
}
}
}
}
#endif
}
bool checkTakeProfit(){
if( takeProfit<=0 ) return false;
double curProfit=0;
double profit=0;
#ifdef __MQL5__
int cntMyPos=PositionsTotal();
for(int ti=cntMyPos-1; ti>=0; ti--){
if(PositionGetSymbol(ti)!=_Symbol) continue;
if(EA_Magic>0 && PositionGetInteger(POSITION_MAGIC)!=EA_Magic) continue;
profit+=PositionGetDouble(POSITION_PROFIT);
profit+=PositionGetDouble(POSITION_SWAP);
}
#else
int cntMyPos=OrdersTotal();
if(cntMyPos>0){
for(int ti=cntMyPos-1; ti>=0; ti--){
if(OrderSelect(ti,SELECT_BY_POS,MODE_TRADES)==false) continue;
if( OrderType()==OP_BUY || OrderType()==OP_SELL ){}else{ continue; }
if(OrderSymbol()!=_Symbol) continue;
if(EA_Magic>0 && OrderMagicNumber()!=EA_Magic) continue;
profit+=OrderCommission();
profit+=OrderProfit();
profit+=OrderSwap();
}
}
#endif
if(profit>takeProfit){
return true;
}
return false;
}
void closeByPos(){
bool repeatOpen=false;
#ifdef __MQL5__
int cntMyPos=PositionsTotal();
for(int ti=cntMyPos-1; ti>=0; ti--){
if(PositionGetSymbol(ti)!=_Symbol) continue;
if(EA_Magic>0 && PositionGetInteger(POSITION_MAGIC)!=EA_Magic) continue;
if( PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY ){
long closefirst=PositionGetInteger(POSITION_TICKET);
double closeLots=PositionGetDouble(POSITION_VOLUME);
for(int ti2=cntMyPos-1; ti2>=0; ti2--){
if(PositionGetSymbol(ti2)!=_Symbol) continue;
if(EA_Magic>0 && PositionGetInteger(POSITION_MAGIC)!=EA_Magic) continue;
if( PositionGetInteger(POSITION_TYPE)!=POSITION_TYPE_SELL ) continue;
if( PositionGetDouble(POSITION_VOLUME)!=closeLots ) continue;
MqlTradeRequest request;
MqlTradeResult result;
ZeroMemory(request);
ZeroMemory(result);
request.action=TRADE_ACTION_CLOSE_BY;
request.position=closefirst;
request.position_by=PositionGetInteger(POSITION_TICKET);
if(EA_Magic>0) request.magic=EA_Magic;
if(OrderSend(request,result)){
repeatOpen=true;
break;
}
}
if(repeatOpen){
break;
}
}
}
#else
int cntMyPos=OrdersTotal();
if(cntMyPos>0){
for(int ti=cntMyPos-1; ti>=0; ti--){
if(OrderSelect(ti,SELECT_BY_POS,MODE_TRADES)==false) continue;
if( OrderSymbol()!=_Symbol ) continue;
if(EA_Magic>0 && OrderMagicNumber()!=EA_Magic) continue;
if( OrderType()==OP_BUY ){
int closefirst=OrderTicket();
double closeLots=OrderLots();
for(int ti2=cntMyPos-1; ti2>=0; ti2--){
if(OrderSelect(ti2,SELECT_BY_POS,MODE_TRADES)==false) continue;
if( OrderSymbol()!=_Symbol ) continue;
if(EA_Magic>0 && OrderMagicNumber()!=EA_Magic) continue;
if( OrderType()!=OP_SELL ) continue;
if( OrderLots()<closeLots ) continue;
if( OrderCloseBy(closefirst, OrderTicket()) ){
repeatOpen=true;
break;
}
}
if(repeatOpen){
break;
}
}
}
}
#endif
// if we closed a position by an opposite one,
// launch the closeByPos function again
if(repeatOpen){
closeByPos();
}
}
void closeAllPos(){
closeByPos();
#ifdef __MQL5__
int cntMyPos=PositionsTotal();
for(int ti=cntMyPos-1; ti>=0; ti--){
if(PositionGetSymbol(ti)!=_Symbol) continue;
if(EA_Magic>0 && PositionGetInteger(POSITION_MAGIC)!=EA_Magic) continue;
Trade.PositionClose(PositionGetInteger(POSITION_TICKET));
}
int cntMyPosO=OrdersTotal();
for(int ti=cntMyPosO-1; ti>=0; ti--){
ulong orderTicket=OrderGetTicket(ti);
if(OrderGetString(ORDER_SYMBOL)!=_Symbol) continue;
if(EA_Magic>0 && OrderGetInteger(ORDER_MAGIC)!=EA_Magic) continue;
Trade.OrderDelete(orderTicket);
}
#else
int cntMyPos=OrdersTotal();
if(cntMyPos>0){
for(int ti=cntMyPos-1; ti>=0; ti--){
if(OrderSelect(ti,SELECT_BY_POS,MODE_TRADES)==false) continue;
if( OrderSymbol()!=_Symbol ) continue;
if(EA_Magic>0 && OrderMagicNumber()!=EA_Magic) continue;
if( OrderType()==OP_BUY ){
MqlTick latest_price;
if(!SymbolInfoTick(OrderSymbol(),latest_price)){
Alert(GetLastError());
return;
}
if(!OrderClose(OrderTicket(), OrderLots(),latest_price.bid,100)){
}
}else if(OrderType()==OP_SELL){
MqlTick latest_price;
if(!SymbolInfoTick(OrderSymbol(),latest_price)){
Alert(GetLastError());
return;
}
if(!OrderClose(OrderTicket(), OrderLots(),latest_price.ask,100)){
}
}else{
if(!OrderDelete(OrderTicket())){
}
}
}
}
#endif
// remove the position closing button
if(ObjectFind(0, prefix_graph+"delall")>0){
ObjectDelete(0, prefix_graph+"delall");
}
}
bool pdxSendOrder(TypeOfPos mytype, double price, double sl, double tp, double volume, ulong position=0, string comment="", string sym=""){
if( !StringLen(sym) ){
sym=_Symbol;
}
int curDigits=(int) SymbolInfoInteger(sym, SYMBOL_DIGITS);
if(sl>0){
sl=NormalizeDouble(sl,curDigits);
}
if(tp>0){
tp=NormalizeDouble(tp,curDigits);
}
if(price>0){
price=NormalizeDouble(price,curDigits);
}else{
#ifdef __MQL5__
#else
MqlTick latest_price;
SymbolInfoTick(sym,latest_price);
if( mytype == MY_SELL ){
price=latest_price.ask;
}else if( mytype == MY_BUY ){
price=latest_price.bid;
}
#endif
}
if( StringLen(my_cmt) && comment=="" ){
comment=my_cmt;
}
#ifdef __MQL5__
ENUM_TRADE_REQUEST_ACTIONS action=TRADE_ACTION_DEAL;
ENUM_ORDER_TYPE type=ORDER_TYPE_BUY;
switch(mytype){
case MY_BUY:
action=TRADE_ACTION_DEAL;
type=ORDER_TYPE_BUY;
break;
case MY_BUYSLTP:
action=TRADE_ACTION_SLTP;
type=ORDER_TYPE_BUY;
break;
case MY_BUYSTOP:
action=TRADE_ACTION_PENDING;
type=ORDER_TYPE_BUY_STOP;
break;
case MY_BUYLIMIT:
action=TRADE_ACTION_PENDING;
type=ORDER_TYPE_BUY_LIMIT;
break;
case MY_SELL:
action=TRADE_ACTION_DEAL;
type=ORDER_TYPE_SELL;
break;
case MY_SELLSLTP:
action=TRADE_ACTION_SLTP;
type=ORDER_TYPE_SELL;
break;
case MY_SELLSTOP:
action=TRADE_ACTION_PENDING;
type=ORDER_TYPE_SELL_STOP;
break;
case MY_SELLLIMIT:
action=TRADE_ACTION_PENDING;
type=ORDER_TYPE_SELL_LIMIT;
break;
}
MqlTradeRequest mrequest;
MqlTradeResult mresult;
ZeroMemory(mrequest);
mrequest.action = action;
mrequest.sl = sl;
mrequest.tp = tp;
mrequest.symbol = sym;
if(position>0){
mrequest.position = position;
}
if(StringLen(comment)){
mrequest.comment=comment;
}
if(action!=TRADE_ACTION_SLTP){
if(price>0){
mrequest.price = price;
}
if(volume>0){
mrequest.volume = volume;
}
mrequest.type = type;
mrequest.magic = EA_Magic;
switch(useORDER_FILLING_RETURN){
case FOK:
mrequest.type_filling = ORDER_FILLING_FOK;
break;
case RETURN:
mrequest.type_filling = ORDER_FILLING_RETURN;
break;
case IOC:
mrequest.type_filling = ORDER_FILLING_IOC;
break;
}
mrequest.deviation=100;
}
if(OrderSend(mrequest,mresult)){
if(mresult.retcode==10009 || mresult.retcode==10008){
if(action!=TRADE_ACTION_SLTP){
switch(type){
case ORDER_TYPE_BUY:
// Alert("Order Buy #:",mresult.order," sl",sl," tp",tp," p",price," !!");
break;
case ORDER_TYPE_SELL:
// Alert("Order Sell #:",mresult.order," sl",sl," tp",tp," p",price," !!");
break;
}
}else{
// Alert("Order Modify SL #:",mresult.order," sl",sl," tp",tp," !!");
}
return true;
}else{
msgErr(GetLastError(), mresult.retcode);
}
}
#else
int type=OP_BUY;
switch(mytype){
case MY_BUY:
type=OP_BUY;
break;
case MY_BUYSTOP:
type=OP_BUYSTOP;
break;
case MY_BUYLIMIT:
type=OP_BUYLIMIT;
break;
case MY_SELL:
type=OP_SELL;
break;
case MY_SELLSTOP:
type=OP_SELLSTOP;
break;
case MY_SELLLIMIT:
type=OP_SELLLIMIT;
break;
}
if(OrderSend(sym, type, volume, price, 100, sl, tp, comment, EA_Magic, 0)<0){
msgErr(GetLastError());
}else{
switch(type){
case OP_BUY:
Alert("Order Buy sl",sl," tp",tp," p",price," !!");
break;
case OP_SELL:
Alert("Order Sell sl",sl," tp",tp," p",price," !!");
break;
}
return true;
}
#endif
return false;
}
void msgErr(int err, int retcode=0){
string curErr="";
switch(err){
case 1:
curErr=langs.err1;
break;
case 2:
curErr=langs.err2;
break;
case 3:
curErr=langs.err3;
break;
case 4:
curErr=langs.err4;
break;
case 5:
curErr=langs.err5;
break;
case 6:
curErr=langs.err6;
break;
case 7:
curErr=langs.err7;
break;
case 8:
curErr=langs.err8;
break;
case 9:
curErr=langs.err9;
break;
case 64:
curErr=langs.err64;
break;
case 65:
curErr=langs.err65;
break;
case 128:
curErr=langs.err128;
break;
case 129:
curErr=langs.err129;
break;
case 130:
curErr=langs.err130;
break;
case 131:
curErr=langs.err131;
break;
case 132:
curErr=langs.err132;
break;
case 133:
curErr=langs.err133;
break;
case 134:
curErr=langs.err134;
break;
case 135:
curErr=langs.err135;
break;
case 136:
curErr=langs.err136;
break;
case 137:
curErr=langs.err137;
break;
case 138:
curErr=langs.err138;
break;
case 139:
curErr=langs.err139;
break;
case 140:
curErr=langs.err140;
break;
case 141:
curErr=langs.err141;
break;
case 145:
curErr=langs.err145;
break;
case 146:
curErr=langs.err146;
break;
case 147:
curErr=langs.err147;
break;
case 148:
curErr=langs.err148;
break;
default:
curErr=langs.err0+": "+(string) err;
}
if(retcode>0){
curErr+=" ";
switch(retcode){
case 10004:
curErr+=langs.retcode10004;
break;
case 10006:
curErr+=langs.retcode10006;
break;
case 10007:
curErr+=langs.retcode10007;
break;
case 10010:
curErr+=langs.retcode10010;
break;
case 10011:
curErr+=langs.retcode10011;
break;
case 10012:
curErr+=langs.retcode10012;
break;
case 10013:
curErr+=langs.retcode10013;
break;
case 10014:
curErr+=langs.retcode10014;
break;
case 10015:
curErr+=langs.retcode10015;
break;
case 10016:
curErr+=langs.retcode10016;
break;
case 10017:
curErr+=langs.retcode10017;
break;
case 10018:
curErr+=langs.retcode10018;
break;
case 10019:
curErr+=langs.retcode10019;
break;
case 10020:
curErr+=langs.retcode10020;
break;
case 10021:
curErr+=langs.retcode10021;
break;
case 10022:
curErr+=langs.retcode10022;
break;
case 10023:
curErr+=langs.retcode10023;
break;
case 10024:
curErr+=langs.retcode10024;
break;
case 10025:
curErr+=langs.retcode10025;
break;
case 10026:
curErr+=langs.retcode10026;
break;
case 10027:
curErr+=langs.retcode10027;
break;
case 10028:
curErr+=langs.retcode10028;
break;
case 10029:
curErr+=langs.retcode10029;
break;
case 10030:
curErr+=langs.retcode10030;
break;
case 10031:
curErr+=langs.retcode10031;
break;
case 10032:
curErr+=langs.retcode10032;
break;
case 10033:
curErr+=langs.retcode10033;
break;
case 10034:
curErr+=langs.retcode10034;
break;
case 10035:
curErr+=langs.retcode10035;
break;
case 10036:
curErr+=langs.retcode10036;
break;
case 10038:
curErr+=langs.retcode10038;
break;
case 10039:
curErr+=langs.retcode10039;
break;
case 10040:
curErr+=langs.retcode10040;
break;
case 10041:
curErr+=langs.retcode10041;
break;
case 10042:
curErr+=langs.retcode10042;
break;
case 10043:
curErr+=langs.retcode10043;
break;
case 10044:
curErr+=langs.retcode10044;
break;
}
}
Alert(curErr);
}
void init_lang(){
switch(LANG){
case MY_ENG:
langs.err1="No error, but unknown result. (1)";
langs.err2="General error (2)";
langs.err3="Incorrect parameters (3)";
langs.err4="Trade server busy (4)";
langs.err5="Old client terminal version (5)";
langs.err6="No connection to trade server (6)";
langs.err7="Not enough rights (7)";
langs.err8="Too frequent requests (8)";
langs.err9="Invalid operation disruptive server operation (9)";
langs.err64="Account blocked (64)";
langs.err65="Invalid account number (65)";
langs.err128="Expired waiting period for transaction (128)";
langs.err129="Invalid price (129)";
langs.err130="Wrong stop loss (130)";
langs.err131="Wrong volume (131)";
langs.err132="Market closed (132)";
langs.err133="Trade prohibited (133)";
langs.err134="Not enough money to complete transaction. (134)";
langs.err135="Price changed (135)";
langs.err136="No prices (136)";
langs.err137="Broker busy (137)";
langs.err138="New prices (138)";
langs.err139="Order blocked and already being processed (139)";
langs.err140="Only purchase allowed (140)";
langs.err141="Too many requests (141)";
langs.err145="Modification prohibited because order too close to market. (145)";
langs.err146="Trading subsystem busy (146)";
langs.err147="Using order expiration date prohibited by broker (147)";
langs.err148="Number of open and pending orders reached limit set by broker (148)";
langs.err0="Error occurred while running request";
langs.retcode="Reason";
langs.retcode10004="Requote";
langs.retcode10006="Request rejected";
langs.retcode10007="Request canceled by trader";
langs.retcode10010="Only part of request completed";
langs.retcode10011="Request processing error";
langs.retcode10012="Request canceled by timeout";
langs.retcode10013="Invalid request";
langs.retcode10014="Invalid volume in request";
langs.retcode10015="Invalid price in request";
langs.retcode10016="Invalid stops in request";
langs.retcode10017="Trade disabled";
langs.retcode10018="Market closed";
langs.retcode10019="Not enough money to complete request";
langs.retcode10020="Prices changed";
langs.retcode10021="No quotes to process request";
langs.retcode10022="Invalid order expiration date in request";
langs.retcode10023="Order state changed";
langs.retcode10024="Too frequent requests";
langs.retcode10025="No changes in request";
langs.retcode10026="Autotrading disabled by server";
langs.retcode10027="Autotrading disabled by client terminal";
langs.retcode10028="Request locked for processing";
langs.retcode10029="Order or position frozen";
langs.retcode10030="Invalid order filling type";
langs.retcode10031="No connection with trade server";
langs.retcode10032="Operation allowed only for live accounts";
langs.retcode10033="Number of pending orders reached limit";
langs.retcode10034="Volume of orders and positions for symbol reached limit";
langs.retcode10035="Incorrect or prohibited order type";
langs.retcode10036="Position with specified POSITION_IDENTIFIER already closed";
langs.retcode10038="Close volume exceeds current position volume";
langs.retcode10039="Close order already exists for specified position";
langs.retcode10040="Number of open items exceeded";
langs.retcode10041="Pending order activation request rejected, order canceled";
langs.retcode10042="Only long positions allowed";
langs.retcode10043="Only short positions allowed";
langs.retcode10044="Only position closing allowed";
break;
case MY_RUS:
langs.err0="> 2@5<O 2K?>;=5=8O 70?@>A0 ?@>87>H;0 >H81:0";
langs.err1="5B >H81:8, => @57C;LB0B =58725AB5= (1)";
langs.err2="1I0O >H81:0 (2)";
langs.err3="5?@028;L=K5 ?0@0<5B@K (3)";
langs.err4="">@3>2K9 A5@25@ 70=OB (4)";
langs.err5="!B0@0O 25@A8O :;85=BA:>3> B5@<8=0;0 (5)";
langs.err6="5B A2O78 A B>@3>2K< A5@25@>< (6)";
langs.err7="54>AB0B>G=> ?@02 (7)";
langs.err8="!;8H:>< G0ABK5 70?@>AK (8)";
langs.err9="54>?CAB8<0O >?5@0F8O =0@CH0NI0O DC=:F8>=8@>20=85 A5@25@0 (9)";
langs.err64="!G5B 701;>:8@>20= (64)";
langs.err65="5?@028;L=K9 =><5@ AG5B0 (65)";
langs.err128="AB5: A@>: >6840=8O A>25@H5=8O A45;:8 (128)";
langs.err129="5?@028;L=0O F5=0 (129)";
langs.err130="5?@028;L=K5 AB>?K (130)";
langs.err131="5?@028;L=K9 >1J5< (131)";
langs.err132=" K=>: 70:@KB (132)";
langs.err133="">@3>2;O 70?@5I5=0 (133)";
langs.err134="54>AB0B>G=> 45=53 4;O A>25@H5=8O >?5@0F88 (134)";
langs.err135="&5=0 87<5=8;0AL (135)";
langs.err136="5B F5= (136)";
langs.err137="@>:5@ 70=OB (137)";
langs.err138=">2K5 F5=K (138)";
langs.err139="@45@ 701;>:8@>20= 8 C65 >1@010BK205BAO (139)";
langs.err140=" 07@5H5=0 B>;L:> ?>:C?:0 (140)";
langs.err141="!;8H:>< <=>3> 70?@>A>2 (141)";
langs.err145=">48D8:0F8O 70?@5I5=0, B0: :0: >@45@ A;8H:>< 1;87>: : @K=:C (145)";
langs.err146=">4A8AB5<0 B>@3>2;8 70=OB0 (146)";
langs.err147="A?>;L7>20=85 40BK 8AB5G5=8O >@45@0 70?@5I5=> 1@>:5@>< (147)";
langs.err148=">;8G5AB2> >B:@KBKE 8 >B;>65==KE >@45@>2 4>AB83;> ?@545;0, CAB0=>2;5==>3> 1@>:5@>< (148)";
langs.retcode="@8G8=0";
langs.retcode10004=" 5:2>B0";
langs.retcode10006="0?@>A >B:;>=5=";
langs.retcode10007="0?@>A >B<5=5= B@5945@><";
langs.retcode10010="0O2:0 2K?>;=5=0 G0AB8G=>";
langs.retcode10011="H81:0 >1@01>B:8 70?@>A0";
langs.retcode10012="0?@>A >B<5=5= ?> 8AB5G5=8N 2@5<5=8";
langs.retcode10013="5?@028;L=K9 70?@>A";
langs.retcode10014="5?@028;L=K9 >1J5< 2 70?@>A5";
langs.retcode10015="5?@028;L=0O F5=0 2 70?@>A5";
langs.retcode10016="5?@028;L=K5 AB>?K 2 70?@>A5";
langs.retcode10017="">@3>2;O 70?@5I5=0";
langs.retcode10018=" K=>: 70:@KB";
langs.retcode10019="5B 4>AB0B>G=KE 45=56=KE A@54AB2 4;O 2K?>;=5=8O 70?@>A0";
langs.retcode10020="&5=K 87<5=8;8AL";
langs.retcode10021="BACBAB2CNB :>B8@>2:8 4;O >1@01>B:8 70?@>A0";
langs.retcode10022="525@=0O 40B0 8AB5G5=8O >@45@0 2 70?@>A5";
langs.retcode10023="!>AB>O=85 >@45@0 87<5=8;>AL";
langs.retcode10024="!;8H:>< G0ABK5 70?@>AK";
langs.retcode10025=" 70?@>A5 =5B 87<5=5=89";
langs.retcode10026="2B>B@5948=3 70?@5I5= A5@25@><";
langs.retcode10027="2B>B@5948=3 70?@5I5= :;85=BA:8< B5@<8=0;><";
langs.retcode10028="0?@>A 701;>:8@>20= 4;O >1@01>B:8";
langs.retcode10029="@45@ 8;8 ?>78F8O 70<>@>65=K";
langs.retcode10030="#:070= =5?>445@68205<K9 B8? 8A?>;=5=8O >@45@0 ?> >AB0B:C ";
langs.retcode10031="5B A>548=5=8O A B>@3>2K< A5@25@><";
langs.retcode10032="?5@0F8O @07@5H5=0 B>;L:> 4;O @50;L=KE AG5B>2";
langs.retcode10033=">AB83=CB ;8<8B =0 :>;8G5AB2> >B;>65==KE >@45@>2";
langs.retcode10034=">AB83=CB ;8<8B =0 >1J5< >@45@>2 8 ?>78F89 4;O 40==>3> A8<2>;0";
langs.retcode10035="525@=K9 8;8 70?@5IQ==K9 B8? >@45@0";
langs.retcode10036=">78F8O A C:070==K< POSITION_IDENTIFIER C65 70:@KB0";
langs.retcode10038="0:@K205<K9 >1J5< ?@52KH05B B5:CI89 >1J5< ?>78F88";
langs.retcode10039=";O C:070==>9 ?>78F88 C65 5ABL >@45@ =0 70:@KB85";
langs.retcode10040=">;8G5AB2> >B:@KBKE ?>78F89 ?@52KH5=>";
langs.retcode10041="0?@>A =0 0:B820F8N >B;>65==>3> >@45@0 >B:;>=5=, 0 A0< >@45@ >B<5=5=";
langs.retcode10042=" 07@5H5=K B>;L:> 4;8==K5 ?>78F88";
langs.retcode10043=" 07@5H5=K B>;L:> :>@>B:85 ?>78F88";
langs.retcode10044=" 07@5H5=> B>;L:> 70:@K20BL ACI5AB2CNI85 ?>78F88";
break;
}
}
void getmeinfo_btn(string symname){
double profit=0;
double positionExist=false;
LongVol=0;
ShortVol=0;
// count the number of open Long and Short positions,
// as well as their total profit
#ifdef __MQL5__
int cntMyPos=PositionsTotal();
for(int ti=cntMyPos-1; ti>=0; ti--){
if(PositionGetSymbol(ti)!=symname) continue;
if(EA_Magic>0 && PositionGetInteger(POSITION_MAGIC)!=EA_Magic) continue;
positionExist=true;
profit+=PositionGetDouble(POSITION_PROFIT);
profit+=PositionGetDouble(POSITION_SWAP);
if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY){
LongVol+=PositionGetDouble(POSITION_VOLUME);
}else{
ShortVol+=PositionGetDouble(POSITION_VOLUME);
}
}
#else
int cntMyPos=OrdersTotal();
if(cntMyPos>0){
for(int ti=cntMyPos-1; ti>=0; ti--){
if(OrderSelect(ti,SELECT_BY_POS,MODE_TRADES)==false) continue;
if( OrderType()==OP_BUY || OrderType()==OP_SELL ){}else{ continue; }
if(OrderSymbol()!=symname) continue;
if(EA_Magic>0 && OrderMagicNumber()!=EA_Magic) continue;
positionExist=true;
profit+=OrderCommission();
profit+=OrderProfit();
profit+=OrderSwap();
if(OrderType()==OP_BUY){
LongVol+=OrderLots();
}else{
ShortVol+=OrderLots();
}
}
}
#endif
// if there are open positions,
// then add the button for closing them
if(positionExist){
createObject(prefix_graph+"delall", 163, "0:@KBL 2A5 ("+(string) profit+") L: "+(string) LongVol+" S: "+(string) ShortVol);
}else{
// otherwise, remove the position closing button
if(ObjectFind(0, prefix_graph+"delall")>0){
ObjectDelete(0, prefix_graph+"delall");
}
}
// update the current chart to implement
// changes
ChartRedraw(0);
}
void createObject(string name, int weight, string title){
// if there is no 'name' button on the chart, create it
if(ObjectFind(0, name)<0){
// define the shift relative to the chart right angle where the button is to be displayed
long offset= ChartGetInteger(0, CHART_WIDTH_IN_PIXELS)-87;
long offsetY=0;
for(int ti=0; ti<ObjectsTotal((long) 0); ti++){
string objName= ObjectName(0, ti);
if( StringFind(objName, prefix_graph)<0 ){
continue;
}
long tmpOffset=ObjectGetInteger(0, objName, OBJPROP_YDISTANCE);
if( tmpOffset>offsetY){
offsetY=tmpOffset;
}
}
for(int ti=0; ti<ObjectsTotal((long) 0); ti++){
string objName= ObjectName(0, ti);
if( StringFind(objName, prefix_graph)<0 ){
continue;
}
long tmpOffset=ObjectGetInteger(0, objName, OBJPROP_YDISTANCE);
if( tmpOffset!=offsetY ){
continue;
}
tmpOffset=ObjectGetInteger(0, objName, OBJPROP_XDISTANCE);
if( tmpOffset>0 && tmpOffset<offset){
offset=tmpOffset;
}
}
offset-=(weight+1);
if(offset<0){
offset=ChartGetInteger(0, CHART_WIDTH_IN_PIXELS)-87;
offsetY+=25;
offset-=(weight+1);
}
ObjectCreate(0, name, OBJ_BUTTON, 0, 0, 0);
ObjectSetInteger(0,name,OBJPROP_XDISTANCE,offset);
ObjectSetInteger(0,name,OBJPROP_YDISTANCE,offsetY);
ObjectSetString(0,name,OBJPROP_TEXT, title);
ObjectSetInteger(0,name,OBJPROP_XSIZE,weight);
ObjectSetInteger(0,name,OBJPROP_FONTSIZE, 8);
ObjectSetInteger(0,name,OBJPROP_COLOR, clrBlack);
ObjectSetInteger(0,name,OBJPROP_YSIZE,25);
ObjectSetInteger(0,name,OBJPROP_BGCOLOR, clrLightGray);
ChartRedraw(0);
}else{
ObjectSetString(0,name,OBJPROP_TEXT, title);
}
}
void OnChartEvent(const int id, // event ID
const long& lparam, // event parameter of the long type
const double& dparam, // event parameter of the double type
const string& sparam) // event parameter of the string type
{
string text="";
switch(id){
case CHARTEVENT_OBJECT_CLICK:
// if the clicked button name is prefix_graph+"delall", then
if (sparam==prefix_graph+"delall"){
closeAllPos();
}
break;
}
}