iK_StDv_1_1

Author: Ivan Katsko
Price Data Components
Series array that contains open prices of each barSeries array that contains close prices for each bar
Orders Execution
It automatically opens orders when conditions are reachedChecks for the total of open ordersChecks for the total of closed ordersIt Closes Orders by itself
Indicators Used
Standard Deviation indicator
Miscellaneous
It plays sound alerts
0 Views
0 Downloads
0 Favorites
iK_StDv_1_1
//+------------------------------------------------------------------+
//|                                                                  |
//|       Ñîâåòíèê íà ðàçâîðîò ïî                                    |
//|       êîìáèíàöèè ñâå÷åé                                          |
//|                             http://www.mql4.com/ru/users/ikatsko |
//+------------------------------------------------------------------+
#property copyright "Ivan Katsko"
#property link      "ICQ:372739628"
#include <stdlib.mqh>
//----
extern double Lots         = 0.1;       // Æåñòêî çàäàííîå êîëè÷. ëîòîâ ("0" - ñîâåòíèê âûáèðàåò ñàì)
extern double MaxRisk      = 3;         // Ìàêñèìàëüíûé Loss â ðàçàõ  ê ñâîáîäíûì ñðåäñòâàì
extern int History         = 125;       // Êîëè÷.áàðîâ â ðàñ÷¸òíîé èñòîðèè
extern int MaPerBegin      = 4;
extern int MaPerEnd        = 22;
extern int StDvErr         = 5;
//extern int AveragingPeriod = 3;
extern int Variant         = 1;         // 1 ðàáîåì â òðåíäå, 2 ðàáîòàåì âî ôëåòå, 0 ðàáîòàåì â îáåèõ ñëó÷àÿõ
extern int Wait            = 1;         // Çàäåðæêà (â ïåðèîäàõ) ïðè èçìåíåíèè íàïðàâëåíèÿ
extern double MarginCutoff = 300;       // Expert will stop trading if equity level decreases to that level.
extern int    Slippage     = 4;         // Possible fix for not getting closed Could be higher with some brokers    
//----
int    MagicNumber;                     // Magic EA identifier. Allows for several co-existing EA with different input values
int    attempt             = 5;         //Ïîïûòîê íà îòêðûòèå/çàêðûòèå îðäåðîâ
string ExpertName;                      // To "easy read" which EA place an specific order and remember me forever :)
string news_wav            = "news.wav";
double lotMM, balans, old_balans, loss,price_buy, price_sell, time_buy, time_sell;
double direction           = 0,         // Íàïðàâëåíèå òåêóùåå : ">0" - êóïèòü; "<0" - ïðîäàòü
       old_direction       = 0;         // Íàïðàâëåíèå ïðåäûäóùåå: ">0" - êóïèòü; "<0" - ïðîäàòü
double stimul;
double spread;
bool Trand, Flat;
bool   MoneyManagement;                 // Change to false to shutdown money management controls.
bool   sound_yes           = TRUE;      //Ðàçðåøèòü çâóêè
bool   is_loss             = false;
static int prevtime        = 0;

//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start() {
 
   if (Time[0] == prevtime) {
      return(0);
   }
   prevtime = Time[0];
   if(IsTradeAllowed()) {
      RefreshRates();
      spread = (Ask - Bid) / Point;
   } else {
      again();
      return(0);
   }
   int OpPzBUY = openPositionsBUY(false);        // Îòêðûòûõ îðäåðîâ áåç îòëîæåííûõ
   int OpPzSELL = openPositionsSELL(false);

   int period    = GetPeriod(History,MaPerBegin,MaPerEnd);
   old_direction = direction;                    //îïðåäåëÿåì íàñòîÿùåå íàïðàâëåíèå
   direction     = GetDirection(period);         //îïðåäåëÿåì òåêóùåå íàïðàâëåíèå
   
   if (old_direction != direction) {
      if (OpPzBUY > 0) 
         if (price_buy+spread*Point < Open[0] || (Time[0]-time_buy)/60 >= Wait*Period())
            CloseAllPos(OP_BUY);
      if (OpPzSELL > 0) 
         if (price_sell-spread*Point > Open[0] || (Time[0]-time_sell)/60 >= Wait*Period())
            CloseAllPos(OP_SELL);
   } else {
      if (direction > 0 && OpPzSELL > 0)  
         if ((Time[0]-time_sell)/60 >= Wait*Period())
            CloseAllPos(OP_SELL);
      if (direction < 0 && OpPzBUY > 0)  
         if ((Time[0]-time_buy)/60 >= Wait*Period())
            CloseAllPos(OP_BUY);
      return(0);
   }

   if (direction > 0 && OpPzBUY == 0) {
      if(AccountFreeMargin() < MarginCutoff) {
         Print("Not enough money for buy to trade Strategy:", ExpertName);
         return(0);
      }
      lotMM=GetLots();
      OpenBuy();
   }

   if (direction < 0 && OpPzSELL == 0) {
      if(AccountFreeMargin() < MarginCutoff) {
         Print("Not enough money for sell to trade Strategy:", ExpertName);
         return(0);
      }
      lotMM=GetLots();
      OpenSell();
   }
   return(0);
}

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init() {
   if (Variant < 0) Variant = 0;
   if (Variant > 2) Variant = 2;
   switch (Variant) {
      case 0: Trand = true;  Flat = true;  break;
      case 1: Trand = true;  Flat = false; break;
      case 2: Trand = false; Flat = true;  break;
   }
   prevtime = Time[0];
   old_balans = AccountBalance();
   MagicNumber=3000 + func_Symbol2Val(Symbol())*100 + func_TimeFrame_Const2Val(Period());
   ExpertName="iK_StDv: " + MagicNumber + " : " + Symbol() + "_" + func_TimeFrame_Val2String(func_TimeFrame_Const2Val(Period()));
   return(0);
}

//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit() {
   return(0);
}

//+------------------------------------------------------------------+
//| OpenBuy                                                          |
//+------------------------------------------------------------------+
int OpenBuy() {
   int err, ticket;

   double myPrice = NormalizeDouble(Ask,Digits);
   if (Close[1] > Open[1]) 
      double myStopLoss = NormalizeDouble(myPrice - ((Open[1]-Low[1])+0.23*(High[1]-Low[1])),Digits);
   else myStopLoss = NormalizeDouble(myPrice - ((Close[1]-Low[1])+0.23*(High[1]-Low[1])),Digits);
   
   ticket=OrderSend(Symbol(),OP_BUY,lotMM,myPrice,Slippage,0,0,ExpertName, MagicNumber);
   if(ticket<=0) {
      err=GetLastError();
      return(0);
   }
   return(1);
}

//+------------------------------------------------------------------+
//| OpenSell                                                         |
//+------------------------------------------------------------------+
int OpenSell() {
   int err, ticket;
   
   double myPrice = NormalizeDouble(Bid,Digits);         
   if (Close[1] > Open[1]) 
      double myStopLoss = NormalizeDouble(myPrice + ((High[1]-Close[1])+0.23*(High[1]-Low[1])),Digits);
   else myStopLoss = NormalizeDouble(myPrice + ((High[1]-Open[1])+0.23*(High[1]-Low[1])),Digits);
   
   ticket=OrderSend(Symbol(),OP_SELL,lotMM,myPrice,Slippage,0,0,ExpertName, MagicNumber);
   if(ticket<=0) {
      err=GetLastError();
      return(0);
   }
   return(1);
}

//+------------------------------------------------------------------------+
//| counts the number of open positions BUY                                    |
//+------------------------------------------------------------------------+
int openPositionsBUY(bool limit = true) {  
   int op =0;
   for(int i=OrdersTotal()-1;i>=0;i--) {
      OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
      if(OrderSymbol()==Symbol()) {
         if(OrderType()==OP_BUY) {
            op++;
            price_buy = OrderOpenPrice();
            time_buy = OrderOpenTime();
         }
         if(limit && OrderType()==OP_BUYLIMIT)op++;
      }
   }
   return(op);
}

//+------------------------------------------------------------------------+
//| counts the number of open positions SELL                                   |
//+------------------------------------------------------------------------+
int openPositionsSELL(bool limit = true) {  
   int op =0;
   for(int i=OrdersTotal()-1;i>=0;i--) {
      OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
      if(OrderSymbol()==Symbol())  {
         if(OrderType()==OP_SELL) {
            op++;
            price_sell = OrderOpenPrice();
            time_sell = OrderOpenTime();
         }
         if(limit && OrderType()==OP_SELLLIMIT)op++;
      }
   }
   return(op);
}

//+------------------------------------------------------------------+
//| Get number of lots for this trade                                |
//+------------------------------------------------------------------+
double GetLots() {
   double lot,
      Min_Lot=MarketInfo(Symbol(),MODE_MINLOT),        // Ìèíèì. êîëè÷. ëîòîâ 
      Max_Lot=MarketInfo(Symbol(),MODE_MAXLOT),        // Ìèíèì. êîëè÷. ëîòîâ 
      Free   =AccountFreeMargin(),                     // Ñâîáîäí ñðåäñòâà
      One_Lot=MarketInfo(Symbol(),MODE_MARGINREQUIRED),// Ñòîèìîñòü 1 ëîòà
      Step   =MarketInfo(Symbol(),MODE_LOTSTEP);       // Øàã èçìåíåí ðàçìåðà
      lot = Lots;
      loss = GetProfitLastClosePos();
      if (loss < 0) lot=MaxRisk*lot;
      if (lot > Max_Lot) {
         lot = Max_Lot;
         Comment("ËÎÒ îãðàíè÷åí ìàêñèìóìîì è ðàâåí ",MathCeil(lot/Step)*Step);
      }
      if (lot*One_Lot > Free) {
         lot = Free/One_Lot;
         Comment("ËÎÒ îãðàíè÷åí ñâîáîäíûìè ñðåäñòâàìè è ðàâåí ",MathCeil(lot/Step)*Step);
      }
      if (lot < Min_Lot) {
         lot=Min_Lot;               // Íå ìåíüøå ìèíèìàëüí
         Comment("ËÎÒ îãðàíè÷åí ìèíèìóìîì è ðàâåí ",MathCeil(lot/Step)*Step);
      }
   RefreshRates();                                 // Îáíîâëåíèå äàííûõ
   Step = MarketInfo(Symbol(),MODE_LOTSTEP);       // Øàã èçìåíåí ðàçìåðà
   lot = MathCeil(lot/Step)*Step;
   return(lot);
}

//+------------------------------------------------------------------+
int GetProfitLastClosePos(string sy="", int mn=-1) {
  datetime t;
  int      i, k=OrdersHistoryTotal(), r=0;
  
  if (sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) {
      if ((OrderSymbol()==sy || sy=="") && (mn<0 || OrderMagicNumber()==mn)) {
        if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
          if (t<OrderCloseTime()) {
            t=OrderCloseTime();
            r=OrderProfit();
          }
        }
      }
    }
  }
  return(r);
}

//+------------------------------------------------------------------+
//| Time frame interval appropriation  function                      |
//+------------------------------------------------------------------+
int func_TimeFrame_Const2Val(int Constant) {
     switch(Constant) {
         case     1: return(1);
         case     5: return(2);
         case    15: return(3);
         case    30: return(4);
         case    60: return(5);
         case   240: return(6);
         case  1440: return(7);
         case 10080: return(8);
         case 43200: return(9);
     }
}

//+------------------------------------------------------------------+
//| Time frame string appropriation  function                        |
//+------------------------------------------------------------------+
string func_TimeFrame_Val2String(int Value) {
    switch(Value) {
        case 1: return("PERIOD_M1");
        case 2: return("PERIOD_M5");
        case 3: return("PERIOD_M15");
        case 4: return("PERIOD_M30");
        case 5: return("PERIOD_H1");
        case 6: return("PERIOD_H4");
        case 7: return("PERIOD_D1");
        case 8: return("PERIOD_W1");
        case 9: return("PERIOD_MN1");
        default: return("undefined " + Value);
    }
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int func_Symbol2Val(string symbol)  {
     if(symbol=="AUDCAD")  {
        return(1);
     } else if(symbol=="AUDJPY") {
        return(2);
     } else if(symbol=="AUDNZD") {
        return(3);
     } else if(symbol=="AUDUSD") {
        return(4);
     } else if(symbol=="CHFJPY") {
        return(5);
     } else if(symbol=="EURAUD") {
        return(6);
     } else if(symbol=="EURCAD") {
        return(7);
     } else if(symbol=="EURCHF") {
        return(8);
     } else if(symbol=="EURGBP") {
        return(9);
     } else if(symbol=="EURJPY") {
        return(10);
     } else if(symbol=="EURUSD") {
        return(11);
     } else if(symbol=="GBPCHF") {
        return(12);
     } else if(symbol=="GBPJPY") {
        return(13);
     } else if(symbol=="GBPUSD") {
        return(14);
     } else if(symbol=="NZDUSD") {
        return(15);
     } else if(symbol=="USDCAD") {
        return(16);
     } else if(symbol=="USDCHF") {
        return(17);
     } else if(symbol=="USDJPY") {
        return(18);
     } else {
        Comment("unexpected Symbol");
        return(0);
     }
}

void CloseAllPos(int typ=2) {
   int l_ord_total_22 = OrdersTotal();
   int l_ord_total_24 = l_ord_total_22;
   for (int l_pos_18 = l_ord_total_22 - 1; l_pos_18 >= 0; l_pos_18--) {
      if (OrderSelect(l_pos_18, SELECT_BY_POS, MODE_TRADES)) {
         ClosePosBySelect(typ);
         l_ord_total_24--;
      }
   }
   if (l_ord_total_24 == 0) return;
} 

void ClosePosBySelect(int typ) {
   bool l_ord_close_0;
   //color l_color_4;
   double l_ord_lots_8;
   double ld_16;
   double ld_24;
   double l_price_32;
   int l_error_40;
   if (OrderType() == OP_BUY || OrderType() == OP_SELL) {
      for (int li_44 = 1; li_44 <= attempt; li_44++) {
         if (!IsTesting() && !IsExpertEnabled() || IsStopped()) break;
         while (!IsTradeAllowed()) Sleep(5000);
         RefreshRates();
         ld_16 = NormalizeDouble(MarketInfo(OrderSymbol(), MODE_ASK), Digits);
         ld_24 = NormalizeDouble(MarketInfo(OrderSymbol(), MODE_BID), Digits);
         if (OrderType() == OP_BUY) {
            l_price_32 = ld_24;
         } else {
            l_price_32 = ld_16;
         }
         l_ord_lots_8 = OrderLots();
         
         if (typ == 2) l_ord_close_0 = OrderClose(OrderTicket(), l_ord_lots_8, l_price_32, Slippage);
         else if (typ == OrderType()) l_ord_close_0 = OrderClose(OrderTicket(), l_ord_lots_8, l_price_32, Slippage);
         
         if (l_ord_close_0) {
            if (!(sound_yes)) break;
            PlaySound(news_wav);
            return;
         }
         l_error_40 = GetLastError();
         if (l_error_40 == 146/* TRADE_CONTEXT_BUSY */) while (IsTradeContextBusy()) Sleep(11000);
         Print("Error(", l_error_40, ") Close ", OrderType(), " ", ErrorDescription(l_error_40), ", try ", li_44);
         Sleep(5000);
      }
   } else Print("Íåêîððåêòíàÿ òîðãîâàÿ îïåðàöèÿ. Close ", OrderType());
}

//+------------------------------------------------------------------+
void again() {
   prevtime = Time[1];
   Sleep(30000);
}

//-------------------------------------------------------------------+
int GetPeriod(int History=140, int MaPerBegin=4, int MaPerEnd=24) {
   double max = 0.0;
   for (int period = MaPerBegin; period <= MaPerEnd; period++) {
      double ok_p = 0.01;
      double ok_m = 0.02;
      for (int i=History; i>=0; i--) {
         bool white_0 = false;
         bool black_0 = false;
         bool white_1 = false;
         bool black_1 = false;
         if (Close[i]  >Open[i])   white_0 = true;
         if (Close[i]  <Open[i])   black_0 = true;
         if (Close[i+1]>Open[i+1]) white_1 = true;
         if (Close[i+1]<Open[i+1]) black_1 = true;
         bool flat = true;
//         if (AveragingPeriod == 0) {
            if (iStdDev(NULL,0,period,0,0,1,i) > iStdDev(NULL,0,period,0,0,1,i+1)) flat = false;
//         } else {
//            if (iCustom(NULL,0,"_StdDev",period,AveragingPeriod,0,i) > iCustom(NULL,0,"_StdDev",period,AveragingPeriod,0,i+1)) flat = false;
//         }
         switch (Variant) {
            case 1:
               if (!flat) {
                  if ((white_0 && white_1) || (black_0 && black_1)) {
                       ok_p = ok_p + 1;
                  } else {
                       ok_m = ok_m + 1;
                  }
               }
               break;
            case 2:
               if (flat) {
                  if ((white_0 && black_1) || (black_0 && white_1)) {
                       ok_p = ok_p + 1;
                  } else {
                       ok_m = ok_m + 1; 
                  }
               }
               break;
            default:
               if (((flat  && ((white_0 && black_1) || (black_0 && white_1)))) ||
                   ((!flat && ((white_0 && white_1) || (black_0 && black_1))))) {
                    ok_p = ok_p + 1;
               } else ok_m = ok_m + 1;
               break;
         }
      }
      if (ok_p/ok_m > max) {
         max = ok_p/ok_m;
         if (max > 1) int per = period;
         else per = 0;
      }
   }
   Comment("History=",History," period=",per," max=",max);
   return(per);
}
//------------------------------------------------------------------+
double GetDirection(int prd) {
   if (prd == 0) return(0);
//   if (AveragingPeriod == 0) {
      double sd0 = iStdDev(NULL,0,prd,0,0,1,0);
      double sd1 = iStdDev(NULL,0,prd,0,0,1,1);
      double stdv = sd0 - sd1;
      if (MathAbs(stdv) <= 0.01*StDvErr*sd0)
         stdv = 0;
//   } else
//      stdv = iCustom(NULL,0,"_StdDev",prd,AveragingPeriod,0,0) - iCustom(NULL,0,"_StdDev",prd,AveragingPeriod,0,1);
   switch (Variant) {
      case  1:
         if (stdv > 0) {
            if (iClose(0,0,1) > iOpen(0,0,1))
               return(1);
            if (iClose(0,0,1) < iOpen(0,0,1))
               return(-1);
         } else return(0);
      case  2:
         if (stdv < 0) {
            if (iClose(0,0,1) > iOpen(0,0,1))
               return(-1);
            if (iClose(0,0,1) < iOpen(0,0,1))
               return(1);
         } else return(0);
      default:
         if (stdv > 0) {
            if (iClose(0,0,1) > iOpen(0,0,1))
               return(1);
            if (iClose(0,0,1) < iOpen(0,0,1))
               return(-1);
         }
         if (stdv < 0) {
            if (iClose(0,0,1) > iOpen(0,0,1))
               return(-1);
            if (iClose(0,0,1) < iOpen(0,0,1))
               return(1);
         }
         if (stdv == 0) {
            return(0);
         }
   }
}

Comments

Markdown supported. Formatting help

Markdown Formatting Guide

Element Markdown Syntax
Heading # H1
## H2
### H3
Bold **bold text**
Italic *italicized text*
Link [title](https://www.example.com)
Image ![alt text](image.jpg)
Code `code`
Code Block ```
code block
```
Quote > blockquote
Unordered List - Item 1
- Item 2
Ordered List 1. First item
2. Second item
Horizontal Rule ---