//+-------------------------------------------------------------------------------------+ //| Support&Resistance.mq4 | //| Scriptong | //| scriptong@mail.ru | //+-------------------------------------------------------------------------------------+ #property copyright "Scriptong" #property link "scriptong@mail.ru" //---- input parameters extern double Lots = 0.1; extern string OpenOrderSound = "ok.wav"; extern int MagicNumber = 875; extern color SupportColor = Blue; // Öâåò óðîâíÿ ïîääåðæêè extern color ResistanceColor = Red; // Öâåò óðîâíÿ ñîïðîòèâëåíèÿ bool Activate, FreeMarginAlert, FatalError; double Tick, Spread, StopLevel, FreezeLevel, MinLot, MaxLot, LotStep, Supp, Resis; datetime LastBar, ChanStart; string SName, RName; //+-------------------------------------------------------------------------------------+ //| expert initialization function | //+-------------------------------------------------------------------------------------+ int init() { FatalError = False; Activate = False; // - 1 - == Ñáîð èíôîðìàöèè îá óñëîâèÿõ òîðãîâëè ======================================== Tick = MarketInfo(Symbol(), MODE_TICKSIZE); // ìèíèìàëüíûé òèê Spread = ND(MarketInfo(Symbol(), MODE_SPREAD)*Point); // òåêóùèé ñïðýä StopLevel = ND(MarketInfo(Symbol(), MODE_STOPLEVEL)*Point); // òåêóùèé óðîâåíü ñòîïîâ FreezeLevel = ND(MarketInfo(Symbol(), MODE_FREEZELEVEL)*Point); // óðîâåíü çàìîðîçêè MinLot = MarketInfo(Symbol(), MODE_MINLOT); // ìèíèìàëüíûé ðàçðåøåííûé îáúåì ñäåëêè MaxLot = MarketInfo(Symbol(), MODE_MAXLOT); // ìàêñèìàëüíûé ðàçðåøåííûé îáúåì ñäåëêè LotStep = MarketInfo(Symbol(), MODE_LOTSTEP); // øàã ïðèðàùåíèÿ îáúåìà ñäåëêè // - 1 - == Îêîí÷àíèå áëîêà ============================================================= // - 2 - == Ïðèâåäåíèå îáúåìà ñäåëêè ê äîïóñòèìîìó è ïðîâåðêà êîððåêòíîñòè îáúåìà ======= Lots = MathRound(Lots/LotStep)*LotStep; // îêðóãëåíèå îáúåìà äî áëèæàéøåãî äîïóñòèìîãî if(Lots < MinLot || Lots > MaxLot) // îáúåì ñäåëêè íå ìåíüøå MinLot è íå áîëüøå MaxLot { Comment("Ïàðàìåòðîì Lots áûë çàäàí íåïðàâèëüíûé îáúåì ñäåëêè! Ñîâåòíèê îòêëþ÷åí!"); return(0); } // - 2 - == Îêîí÷àíèå áëîêà ============================================================= SName = "Support"+MagicNumber; // Èìÿ äëÿ îáúåêòà "ëèíèÿ ïîääåðæêè" RName = "Resistance"+MagicNumber; // Èìÿ äëÿ îáúåêòà "ëèíèÿ ñîïðîòèâëåíèÿ" Activate = True; //---- return(0); } //+-------------------------------------------------------------------------------------+ //| expert deinitialization function | //+-------------------------------------------------------------------------------------+ int deinit() { //---- Comment(""); //---- return(0); } //+-------------------------------------------------------------------------------------+ //| Ïðèâåäåíèå çíà÷åíèé ê òî÷íîñòè îäíîãî òèêà | //+-------------------------------------------------------------------------------------+ double ND(double A) { return(NormalizeDouble(A, Digits)); } //+-------------------------------------------------------------------------------------+ //| Ðàñøèôðîâêà ñîîáùåíèÿ îá îøèáêå | //+-------------------------------------------------------------------------------------+ string ErrorToString(int Error) { switch(Error) { case 2: return("çàôèêñèðîâàíà îáùàÿ îøèáêà, îáðàòèòåñü â òåõïîääåðæêó."); case 5: return("ó âàñ ñòàðàÿ âåðñèÿ òåðìèíàëà, îáíîâèòå åå."); case 6: return("íåò ñâÿçè ñ ñåðâåðîì, ïîïðîáóéòå ïåðåçàãðóçèòü òåðìèíàë."); case 64: return("ñ÷åò çàáëîêèðîâàí, îáðàòèòåñü â òåõïîääåðæêó."); case 132: return("ðûíîê çàêðûò."); case 133: return("òîðãîâëÿ çàïðåùåíà."); case 149: return("çàïðåùåíî ëîêèðîâàíèå."); } } //+-------------------------------------------------------------------------------------+ //| Îæèäàíèå òîðãîâîãî ïîòîêà. Åñëè ïîòîê ñâîáîäåí, òî ðåçóëüòàò True, èíà÷å - False | //+-------------------------------------------------------------------------------------+ bool WaitForTradeContext() { int P = 0; // öèêë "ïîêà" while(IsTradeContextBusy() && P < 5) { P++; Sleep(1000); } // ------------- if(P == 5) return(False); return(True); } //+-------------------------------------------------------------------------------------+ //| "Ïðàâèëüíîå" îòêðûòèå ïîçèöèè | //|  îòëè÷èå îò OpenOrder ïðîâåðÿåò ñîîòíîøåíèå òåêóùèõ óðîâíåé è óñòàíàâëèâàåìûõ | //| Âîçâðàùàåò: | //| 0 - íåò îøèáîê | //| 1 - Îøèáêà îòêðûòèÿ | //| 2 - Îøèáêà çíà÷åíèÿ Price | //| 3 - Îøèáêà çíà÷åíèÿ SL | //| 4 - Îøèáêà çíà÷åíèÿ TP | //| 5 - Îøèáêà çíà÷åíèÿ Lot | //+-------------------------------------------------------------------------------------+ int OpenOrderCorrect(int Type, double Price, double SL, double TP, bool Redefinition = True) // Redefinition - ïðè True äîîïðåäåëÿòü ïàðàìåòðû äî ìèíèìàëüíî äîïóñòèìûõ // ïðè False - âîçâðàùàòü îøèáêó { // - 1 - == Ïðîâåðêà äîñòàòî÷íîñòè ñâîáîäíûõ ñðåäñòâ ==================================== if(AccountFreeMarginCheck(Symbol(), OP_BUY, Lots) <= 0 || GetLastError() == 134) { if(!FreeMarginAlert) { Print("Íåäîñòàòî÷íî ñðåäñòâ äëÿ îòêðûòèÿ ïîçèöèè. Free Margin = ", AccountFreeMargin()); FreeMarginAlert = True; } return(5); } FreeMarginAlert = False; // - 1 - == Îêîí÷àíèå áëîêà ============================================================= // - 2 - == Êîððåêòèðîâêà çíà÷åíèé Price, SL è TP èëè âîçâðàò îøèáêè ==================== RefreshRates(); switch (Type) { case OP_BUY: string S = "BUY"; if (MathAbs(Price-Ask)/Point > 3) if (Redefinition) Price = ND(Ask); else return(2); if (ND(TP-Bid) < StopLevel && TP != 0) if (Redefinition) TP = ND(Bid+StopLevel); else return(4); if (ND(Bid-SL) < StopLevel) if (Redefinition) SL = ND(Bid-StopLevel); else return(3); break; case OP_SELL: S = "SELL"; if (MathAbs(Price-Bid)/Point > 3) if (Redefinition) Price = ND(Bid); else return(2); if (ND(Ask-TP) < StopLevel) if (Redefinition) TP = ND(Ask-StopLevel); else return(4); if (ND(SL-Ask) < StopLevel && SL != 0) if (Redefinition) SL = ND(Ask+StopLevel); else return(3); break; case OP_BUYSTOP: S = "BUYSTOP"; if (ND(Price-Ask) < StopLevel) if (Redefinition) Price = ND(Ask+StopLevel); else return(2); if (ND(TP-Price) < StopLevel && TP != 0) if (Redefinition) TP = ND(Price+StopLevel); else return(4); if (ND(Price-SL) < StopLevel) if (Redefinition) SL = ND(Price-StopLevel); else return(3); break; case OP_SELLSTOP: S = "SELLSTOP"; if (ND(Bid-Price) < StopLevel) if (Redefinition) Price = ND(Bid-StopLevel); else return(2); if (ND(Price-TP) < StopLevel) if (Redefinition) TP = ND(Price-StopLevel); else return(4); if (ND(SL-Price) < StopLevel && SL != 0) if (Redefinition) SL = ND(Price+StopLevel); else return(3); break; case OP_BUYLIMIT: S = "BUYLIMIT"; if (ND(Ask-Price) < StopLevel) if (Redefinition) Price = ND(Ask-StopLevel); else return(2); if (ND(TP-Price) < StopLevel && TP != 0) if (Redefinition) TP = ND(Price+StopLevel); else return(4); if (ND(Price-SL) < StopLevel) if (Redefinition) SL = ND(Price-StopLevel); else return(3); break; case OP_SELLLIMIT: S = "SELLLIMIT"; if (ND(Price - Bid) < StopLevel) if (Redefinition) Price = ND(Bid+StopLevel); else return(2); if (ND(Price-TP) < StopLevel) if (Redefinition) TP = ND(Price-StopLevel); else return(4); if (ND(SL-Price) < StopLevel && SL != 0) if (Redefinition) SL = ND(Price+StopLevel); else return(3); break; } // - 2 - == Îêîí÷àíèå áëîêà ============================================================= // - 3 - == Îòêðûòèå îðäåðà ñ îæèäàíèå òîðãîâîãî ïîòîêà ================================= if(WaitForTradeContext()) // îæèäàíèå îñâîáîæäåíèÿ òîðãîâîãî ïîòîêà { Comment("Îòïðàâëåí çàïðîñ íà îòêðûòèå îðäåðà ", S, " ..."); int ticket=OrderSend(Symbol(), Type, Lots, Price, 3, SL, TP, NULL, MagicNumber, 0);// îòêðûòèå ïîçèöèè // Ïîïûòêà îòêðûòèÿ ïîçèöèè çàâåðøèëàñü íåóäà÷åé if(ticket<0) { int Error = GetLastError(); if(Error == 2 || Error == 5 || Error == 6 || Error == 64 || Error == 132 || Error == 133 || Error == 149) // ñïèñîê ôàòàëüíûõ îøèáîê { Comment("Ôàòàëüíàÿ îøèáêà ïðè îòêðûòèè ïîçèöèè ò. ê. "+ ErrorToString(Error)+" Ñîâåòíèê îòêëþ÷åí!"); FatalError = True; } else Comment("Îøèáêà îòêðûòèÿ ïîçèöèè ", S, ": ", Error); // íåôàòàëüíàÿ îøèáêà return(1); } // --------------------------------------------- // Óäà÷íîå îòêðûòèå ïîçèöèè Comment("Ïîçèöèÿ ", S, " îòêðûòà óñïåøíî!"); PlaySound(OpenOrderSound); return(0); // ------------------------ } else { Comment("Âðåìÿ îæèäàíèÿ îñâîáîæäåíèÿ òîðãîâîãî ïîòîêà èñòåêëî!"); return(1); } // - 3 - == Îêîí÷àíèå áëîêà ============================================================= } //+-------------------------------------------------------------------------------------+ //| Îòîáðàæåíèå ëèíèé ïîääåðæêè è ñîïðîòèâëåíèÿ | //+-------------------------------------------------------------------------------------+ void ShowChannel() { if (Supp != 0 && Resis != 0) // Åñëè óðîâíè îïðåäåëåíû { if (ObjectFind(SName) < 0) // è îáúåêòà ïîääåðæêè íåò, òî ðèñóåì ëèíèþ ïîääåðæêè { ObjectCreate(SName, OBJ_TREND, 0, ChanStart, Supp, Time[0], Supp); ObjectSet(SName, OBJPROP_RAY, False); ObjectSet(SName, OBJPROP_COLOR, SupportColor); } else // åñëè ëèíèÿ ïîääåðæêè óæå åñòü, òî ïðîñòî ïåðåíîñèì åå íà íóæíûé óðîâåíü { ObjectMove(SName, 0, ChanStart, Supp); ObjectMove(SName, 1, Time[0], Supp); } if (ObjectFind(RName) < 0) // åñëè ñîïðîòèâëåíèÿ íåò, òî ðèñóåì ëèíèþ ñîïðîòèâëåíèÿ { ObjectCreate(RName, OBJ_TREND, 0, ChanStart, Resis, Time[0], Resis); ObjectSet(RName, OBJPROP_RAY, False); ObjectSet(RName, OBJPROP_COLOR, ResistanceColor); } else // åñëè ëèíèÿ ñîïðîòèâëåíèÿ óæå åñòü, òî ïðîñòî ïåðåíîñèì åå íà íóæíûé óðîâåíü { ObjectMove(RName, 0, ChanStart, Resis); ObjectMove(RName, 1, Time[0], Resis); } } else // åñëè óðîâíè íå îïðåäåëåíû, òî óäàëÿåì ëèíèè ïîääåðæêè è ñîïðîòèâëåíèÿ { if (ObjectFind(SName) == 0) ObjectDelete(SName); if (ObjectFind(RName) == 0) ObjectDelete(RName); } } //+-------------------------------------------------------------------------------------+ //| Ðàñ÷åò óðîâíåé ïîääåðæêè è ñîïðîòèâëåíèÿ | //+-------------------------------------------------------------------------------------+ void GetLevels() { Supp = 0; Resis = 0; // - 1 - == Ðàñ÷åò äàííûõ èíäèêàòîðà ÀÎ ================================================= double AO1 = iAO(Symbol(), 0, 1); double AO2 = iAO(Symbol(), 0, 2); double AO3 = iAO(Symbol(), 0, 3); // - 1 - == Îêîí÷àíèå áëîêà ============================================================= // - 2 - == Ïîèñê ñîïðîòèâëåíèÿ è ïîääåðæêè â ïîëîæèòåëüíîé çîíå èíäèêàòîðà ÀÎ ========== if (AO1 > 0) if (AO1 < AO2 && AO2 > AO3) // Áûëà êîððåêöèÿ âíèç ïîñëå âîñõîæäåíèÿ { // Ïîèñê áàðà, íà êîòîðîì çíà÷åíèå ÀÎ ñòàíîâèòñÿ îòðèöàòåëüíûì int i = 4; while (AO3 > 0 && i < Bars) { AO3 = iAO(Symbol(), 0, i); i++; } if (i == Bars) return; // åñëè äîøëè äî êîíöà èñòîðèè, òî ýòî îøèáêà // Ðàñ÷åò óðîâíåé Supp = Low[iLowest(Symbol(), 0, MODE_LOW, i-1)]; Resis = High[iHighest(Symbol(), 0, MODE_HIGH, i-1)]; ChanStart = Time[i-2]; // Çàïîìèíàåì âðåìÿ íà÷àëà äëÿ èíäèêàöèè êàíàëà } // - 2 - == Îêîí÷àíèå áëîêà ============================================================= // - 3 - == Ïîèñê ñîïðîòèâëåíèÿ è ïîääåðæêè â îòðèöàòåëüíîé çîíå èíäèêàòîðà ÀÎ ========== if (AO1 < 0) if (AO1 > AO2 && AO2 < AO3) // Áûëà êîððåêöèÿ ââåðõ ïîñëå ïàäåíèÿ { // Ïîèñê áàðà, íà êîòîðîì çíà÷åíèå ÀÎ ñòàíîâèòñÿ ïîëîæèòåëüíûì i = 4; while (AO3 < 0 && i < Bars) { AO3 = iAO(Symbol(), 0, i); i++; } if (i == Bars) return; // åñëè äîøëè äî êîíöà èñòîðèè, òî ýòî îøèáêà // Ðàñ÷åò óðîâíåé Supp = Low[iLowest(Symbol(), 0, MODE_LOW, i-1)]; Resis = High[iHighest(Symbol(), 0, MODE_HIGH, i-1)]; ChanStart = Time[i-2]; // Çàïîìèíàåì âðåìÿ íà÷àëà äëÿ èíäèêàöèè êàíàëà } // - 3 - == Îêîí÷àíèå áëîêà ============================================================= ShowChannel(); // Îòîáðàæåíèå óðîâíåé } //+-------------------------------------------------------------------------------------+ //| Ïðèâåäåíèå çíà÷åíèé ê òî÷íîñòè îäíîãî òèêà | //+-------------------------------------------------------------------------------------+ double NP(double A) { return(MathFloor(A/Tick)*Tick); } //+-------------------------------------------------------------------------------------+ //| Óñòàíîâêà îðäåðîâ, ïîäòÿæêà ñòîïîâ | //+-------------------------------------------------------------------------------------+ bool SetOrders() { // - 1 - == Ðàñ÷åò óðîâíåé âõîäà è âûõîäà èç ñäåëîê ===================================== bool Buy = False, Sell = False; // Ñäåëêè åùå íå íàéäåíû double BuyStop = NP(Resis + Spread + Tick);// Öåíà îòêðûòèÿ äëÿ BuyStop è ñòîïà äëÿ Sell double SellStop = NP(Supp - Tick); // Öåíà îòêðûòèÿ äëÿ SellStop è ñòîïà äëÿ Buy double BuyTake = NP(2*BuyStop - SellStop); // Öåíà äëÿ ïðîôèòà Buy double SellTake = NP(2*SellStop - BuyStop); // Öåíà äëÿ ïðîôèòà Sell // - 1 - == Îêîí÷àíèå áëîêà ============================================================ // - 2 - == Ïîèñê ñâîèõ îðäåðîâ/ïîçèöèé ================================================= for (int i = OrdersTotal()-1; i >= 0; i--) if (OrderSelect(i, SELECT_BY_POS)) if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) // - 2 - == Îêîí÷àíèå áëîêà ============================================================ // - 3 - == Íàéäåí BUY ================================================================== { RefreshRates(); if (OrderType() == OP_BUY) { Buy = True; // Åñëè ó BUY óñòàíîâëåí íåâåðíûé ñòîï, òî èçìåíÿåì ñòîï è ïðîôèò if (ND(OrderStopLoss() - SellStop) != 0 && ND(Bid - StopLevel - SellStop) > 0 && ND(BuyTake - Bid - StopLevel) > 0) if (WaitForTradeContext()) if (!OrderModify(OrderTicket(), 0, SellStop, BuyTake, 0)) return(False); } // - 3 - == Îêîí÷àíèå áëîêà ============================================================ // - 4 - == Íàéäåí BUYSTOP ============================================================== if (OrderType() == OP_BUYSTOP) { Buy = True; // Åñëè ó îðäåðà íåïðàâèëüíàÿ öåíà îòêðûòèÿ, òî èçìåíÿåì öåíó, ñòîï è ïðîôèò if (ND(OrderOpenPrice() - BuyStop) != 0 && ND(BuyStop - Ask - StopLevel) > 0 && ND(OrderOpenPrice() - Ask - FreezeLevel) > 0) if (WaitForTradeContext()) if (!OrderModify(OrderTicket(), BuyStop, SellStop, BuyTake, 0)) return(False); } // - 4 - == Îêîí÷àíèå áëîêà ============================================================ // - 5 - == Íàéäåí SELL ================================================================= if (OrderType() == OP_SELL) { Sell = True; if (ND(OrderStopLoss() - BuyStop) != 0 && ND(BuyStop - Ask - StopLevel) > 0 && ND(Bid - StopLevel - SellTake) > 0) if (WaitForTradeContext()) if (!OrderModify(OrderTicket(), 0, BuyStop, SellTake, 0)) return(False); } // - 5 - == Îêîí÷àíèå áëîêà ============================================================ // - 6 - == Íàéäåí SELLSTOP ============================================================= if (OrderType() == OP_SELLSTOP) { Sell = True; if (ND(OrderOpenPrice() - SellStop) != 0 && ND(Bid - SellStop - StopLevel) > 0 && ND(Bid - OrderOpenPrice() - FreezeLevel) > 0) if (WaitForTradeContext()) if (!OrderModify(OrderTicket(), SellStop, BuyStop, SellTake, 0)) return(False); } } // - 6 - === Îêîí÷àíèå áëîêà ============================================================ // - 7 - == BuyStop èëè Buy íå íàéäåíû - óñòàíîâêà BuyStop ============================== if (!Buy && Ask < Resis) if (OpenOrderCorrect(OP_BUYSTOP, BuyStop, SellStop, BuyTake) > 0) return(False); // - 7 - === Îêîí÷àíèå áëîêà ============================================================ // - 8 - == SellStop èëè Sell íå íàéäåíû - óñòàíîâêà SellStop =========================== if (!Sell && Bid > Supp) if (OpenOrderCorrect(OP_SELLSTOP, SellStop, BuyStop, SellTake) > 0) return(False); // - 8 - === Îêîí÷àíèå áëîêà ============================================================ } //+-------------------------------------------------------------------------------------+ //| Ôóíêöèÿ START ýêñïåðòà | //+-------------------------------------------------------------------------------------+ int start() { // - 1 - == Ðàçðåøåíî ëè ñîâåòíèêó ðàáîòàòü? =========================================== if (!Activate || FatalError) // Îòêëþ÷àåòñÿ ðàáîòà ñîâåòíèêà, åñëè ôóíêöèÿ return(0); // init çàâåðøèëàñü ñ îøèáêîé èëè èìåëà ìåñòî ôàòàëüíàÿ îøèáêà // - 1 - == Îêîí÷àíèå áëîêà ============================================================ // - 2 - == Ñáîð èíôîðìàöèè îá óñëîâèÿõ òîðãîâëè ======================================== Spread = ND(MarketInfo(Symbol(), MODE_SPREAD)*Point); // òåêóùèé ñïðýä StopLevel = ND(MarketInfo(Symbol(), MODE_STOPLEVEL)*Point); // òåêóùèé óðîâåíü ñòîïîâ // - 2 - == Îêîí÷àíèå áëîêà ============================================================ if (LastBar == Time[0]) return(0); // - 3 - == Ðàñ÷åò ïîñëåäíèõ ïîääåðæêè è ñîïðîòèâëåíèÿ ================================== GetLevels(); // - 3 - == Îêîí÷àíèå áëîêà ============================================================ // - 4 - == Óñòàíîâêà îðäåðîâ =========================================================== if (Supp != 0 && Resis != 0) // Óñòàíîâêà îðäåðîâ òîëüêî, åñëè îïðåäåëåíû óðîâíè if (!SetOrders()) return(0); // - 4 - == Îêîí÷àíèå áëîêà ============================================================ LastBar = Time[0]; // Íîâûé áàð "ïîñ÷èòàí" return(0); }
Sample
Analysis
Market Information Used:
Series array that contains open time of each bar
Series array that contains the lowest prices of each bar
Series array that contains the highest prices of each bar
Indicator Curves created:
Indicators Used:
Bill Williams Awesome oscillator
Custom Indicators Used:
Order Management characteristics:
Checks for the total of open orders
It can change open orders parameters, due to possible stepping strategy
Other Features:
It plays sound alerts