This script, named "RollBackInTrend_Expert," is designed to automatically trade on the Metatrader platform. It aims to identify opportunities to enter trades that align with the current trend in the market, specifically when the price momentarily pulls back against that trend. Here's a breakdown of how it works:
1. Initial Setup:
- Defining Parameters: The script starts by defining several adjustable settings (input parameters) that the user can customize. These include:
Lots
: The size of each trade (e.g., 0.1 lots).FastMACD
,SlowMACD
,SignalMACD
: Settings for the MACD indicator, which helps identify trend direction and potential reversals.OpenOrderSound
: The sound to play when a trade is opened.MagicNumber
: A unique identifier for trades managed by this script, helping it distinguish its trades from others.Koeff
: A percentage used to calculate the profit target (take profit) based on the channel width.
- Gathering Market Information: The script gathers essential details about the currency pair it's trading, such as the minimum price change (
Tick
), the spread (difference between buy and sell price), stop levels, and allowable trade sizes. - Error Checking: It verifies that the specified trade size (
Lots
) is within the permissible range allowed by the broker. If not, the script stops running to prevent errors.
2. Identifying the Trend:
- Using Fractals: The script uses "Fractals," which are patterns on a chart that help identify potential turning points in price. It looks for the two most recent up and down fractals. By comparing the position of the fractals, it tries to determine if the price is generally trending upwards, downwards, or sideways.
- MACD Confirmation: In addition to Fractals, the script uses the MACD indicator. MACD helps to understand the momentum and strength of a trend. The script looks for specific patterns in the MACD to confirm the trend direction and identify potential pullback opportunities.
3. Determining Entry Signals (Pullbacks):
- MACD Pullback: The script identifies situations where the MACD indicator suggests a temporary pullback against the prevailing trend.
- Channel Confirmation: It then attempts to draw a channel based on the identified fractals. A channel represents a potential range within which the price is expected to move. It validates to see the calculated channel contains the price movement.
- Entry Conditions: The script only considers opening a trade if:
- The MACD suggests a pullback.
- A trend can be identified with the Fractals.
- The current price is within the lower half of the channel (for a buy signal) or the upper half (for a sell signal).
4. Opening Trades:
- Checking Available Funds: Before opening a trade, the script checks if there are sufficient funds in the trading account to cover the trade.
- Order Placement: If all conditions are met, the script sends an order to the broker to open a trade in the direction of the trend. The script sets stop-loss and take-profit levels:
- Stop-loss: The maximum amount of money the script is willing to risk on the trade. It is based on the fractal levels.
- Take-profit: The target price at which the script will automatically close the trade for a profit. The take profit is a percentage of the channel's width.
- Sound Alert: Plays a sound to notify the user that a trade has been opened.
5. Managing Existing Trades:
- Trailing Stop: The script places a pending order that moves the stop-loss to the position stop-loss, creating a "trailing stop." This automatically adjusts the stop-loss level as the price moves in a favorable direction, helping to lock in profits.
- Closing Opposite Positions: If a new trade signal appears in the opposite direction of an existing trade, the script attempts to close the existing trade before opening the new one.
6. Error Handling:
- Trade Context: It contains trade context validation and retry.
- Fatal Error Detection: The script detects critical errors that prevent it from functioning correctly. If such an error occurs, the script stops trading and displays a message.
- Insufficient Funds Alert: The script shows alert message if there are insufficient funds.
In Summary:
The "RollBackInTrend_Expert" script is an automated trading tool that attempts to capitalize on temporary price pullbacks within established trends. It uses Fractals and MACD to identify trends, waits for a pullback, and then enters a trade in the direction of the trend with pre-defined stop-loss and take-profit levels. The script also includes features to manage existing trades and handle potential errors.
//+-------------------------------------------------------------------------------------+
//| RollBackInTrend_Expert.mq4 |
//| Scriptong |
//| |
//+-------------------------------------------------------------------------------------+
#property copyright "Scriptong"
#property link "scriptong@mail.ru"
//---- input parameters
extern double Lots = 0.1; // Îáúåì îòêðûâàåìîé ïîçèöèè
extern string A1 = "Ïàðàìåòðû èíäèêàòîðà MACD";
extern int FastMACD = 12; // Ïåðèîä áûñòðîé ÌÀ
extern int SlowMACD = 26; // Ïåðèîä ìåäëåííîé ÌÀ
extern int SignalMACD = 9; // Ïåðèîä ñèãíàëüíîé ÌÀ
extern string A2 = "=====================================";
extern string OpenOrderSound = "ok.wav"; // Çâóê äëÿ îòêðûòèÿ ïîçèöèè
extern int MagicNumber = 17589 ; // Ìàãèê ïîçèöèé ñîâåòíèêà
extern double Koeff = 0.85; // ×àñòü øèðèíû êàíàëà, îò êîòîðîé ñ÷èòàåòñÿ öåëü ïîçèöèè
bool Activate, FreeMarginAlert, FatalError;
double Tick, Spread, StopLevel, MinLot, MaxLot, LotStep, UpFractal1, UpFractal2,
DownFractal1, DownFractal2, TP, SL;
datetime LastBar;
int Signal, TypeOrder, LastType, TicketOrder, TU1, TU2, TD1, TD2;
//+-------------------------------------------------------------------------------------+
//| Ôóíêöèÿ èíèöèàëèçàöèè ýêñïåðòà |
//+-------------------------------------------------------------------------------------+
int init()
{
//----
Activate = False;
// - 1 - == Ñáîð èíôîðìàöèè îá óñëîâèÿõ òîðãîâëè ========================================
Tick = MarketInfo(Symbol(), MODE_TICKSIZE); // ìèíèìàëüíûé òèê
Spread = ND(MarketInfo(Symbol(), MODE_SPREAD)*Point); // òåêùèé ñïðýä
StopLevel = ND(MarketInfo(Symbol(), MODE_STOPLEVEL)*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 - == Îêîí÷àíèå áëîêà =============================================================
LastBar = 0;
Activate = True; // Âñå ïðîâåðêè óñïåøíî çàâåðøåíû, âîçâîäèì ôëàã àêòèâèçàöèè ýêñïåðòà
//----
return(0);
}
//+-------------------------------------------------------------------------------------+
//| Ôóíêöèÿ äåèíèöèàëèçàöèè ýêñïåðòà |
//+-------------------------------------------------------------------------------------+
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 OpenOrder(int Type, double Price, double SL, double TP, int Num)
{
// Áëîê ïðîâåðêè äîñòàòî÷íîñòè ñâîáîäíûõ ñðåäñòâ
if(AccountFreeMarginCheck(Symbol(), OP_BUY, Lots) <= 0 || GetLastError() == 134)
{
if(!FreeMarginAlert)
{
Print("Íåäîñòàòî÷íî ñðåäñòâ äëÿ îòêðûòèÿ ïîçèöèè. Free Margin = ",
AccountFreeMargin());
FreeMarginAlert = True;
}
return(False);
}
FreeMarginAlert = False;
// ---------------------------------------------
switch (Type)
{
case OP_BUY: string S = "BUY"; break;
case OP_SELL: S = "SELL"; break;
case OP_BUYSTOP: S = "BUYSTOP"; break;
case OP_SELLSTOP: S = "SELLSTOP"; break;
case OP_BUYLIMIT: S = "BUYLIMIT"; break;
case OP_SELLLIMIT: S = "SELLLIMIT"; break;
}
if(WaitForTradeContext()) // îæèäàíèå îñâîáîæäåíèÿ òîðãîâîãî ïîòîêà
{
Comment("Îòïðàâëåí çàïðîñ íà îòêðûòèå îðäåðà ", S, " ...");
int ticket=OrderSend(Symbol(), Type, Lots, Price, 0,
SL, TP, NULL, MagicNumber*10+Num, 0, CLR_NONE); // îòêðûòèå ïîçèöèè
// Ïîïûòêà îòêðûòèÿ ïîçèöèè çàâåðøèëàñü íåóäà÷åé
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(False);
}
// ---------------------------------------------
// Óäà÷íîå îòêðûòèå ïîçèöèè
Comment("Ïîçèöèÿ ", S, " îòêðûòà óñïåøíî!");
PlaySound(OpenOrderSound);
return(True);
// ------------------------
}
else
{
Comment("Âðåìÿ îæèäàíèÿ îñâîáîæäåíèÿ òîðãîâîãî ïîòîêà èñòåêëî!");
return(False);
}
}
//+-------------------------------------------------------------------------------------+
//| Îæèäàíèå òîðãîâîãî ïîòîêà. Åñëè ïîòîê ñâîáîäåí, òî ðåçóëüòàò True, èíà÷å - False |
//+-------------------------------------------------------------------------------------+
bool WaitForTradeContext()
{
int P = 0;
// öèêë "ïîêà"
while(IsTradeContextBusy() && P < 5)
{
P++;
Sleep(1000);
}
// -------------
if(P == 5)
return(False);
return(True);
}
//+-------------------------------------------------------------------------------------+
//| Íàõîäèì äâà ïîñëåäíèõ íèæíèõ è âåðõíèõ ôðàêòàëà, ïî êîòîðûì îïðåäåëÿåì òåêóùèé òðåíä|
//| (0 - íåò, 1 - âîñõîäÿùèé, 2 - íèñõîäÿùèé) |
//+-------------------------------------------------------------------------------------+
int FindFractals()
{
// - 1 - ======= Ïîèñê ôðàêòàëîâ ========================================================
UpFractal1 = 0;
UpFractal2 = 0;
DownFractal1 = 0;
DownFractal2 = 0;
int i = 3;
while ((UpFractal1 == 0 || UpFractal2 == 0 || DownFractal1 == 0 || DownFractal2 == 0)
&& i < Bars) // öèêë ïðîäîëæàåòñÿ, ïîêà íå áóäóò íàéäåíû âñå ÷åòûðå ôðàêòàëà
{
double Up = iFractals(Symbol(), 0, MODE_UPPER, i); // âåðõíèé ôðàêòàë
double Dn = iFractals(Symbol(), 0, MODE_LOWER, i); // íèæíèé ôðàêòàë
if (Up != 0) // åñëè íà òåêóùåì áàðå åñòü âåðõíèé ôðàêòàë
if (UpFractal1 == 0) // è ýòî ïåðâûé íàéäåííûé âåðõíèé ôðàêòàë
{
UpFractal1 = Up; // ñîõðàíÿåì åãî çíà÷åíèå
TU1 = i; // è çàïîìèíàåì íîìåð áàðà
}
else
if (UpFractal2 == 0) // åñëè ýòî óæå âòîðîé íàéäåííûé âåðõíèé ôðàêòàë
{
UpFractal2 = Up; // òî ñîõðàíÿåì åãî çíà÷åíèå âî âòîðóþ ïåðåìåííóþ
TU2 = i; // è ñíîâà çàïîìèíàåì íîìåð áàðà
}
if (Dn != 0) // åñëè íà òåêóùåì áàðå åñòü íèæíèé ôðàêòàë
if (DownFractal1 == 0) // è ýòî ïåðâûé íàéäåííûé íèæíèé ôðàêòàë
{
DownFractal1 = Dn; // ñîõðàíÿåì åãî çíà÷åíèå
TD1 = i; // è çàïîìèíàåì íîìåð áàðà
}
else
if (DownFractal2 == 0) // åñëè ýòî óæå âòîðîé íàéäåííûé íèæíèé ôðàêòàë
{
DownFractal2 = Dn; // òî ñîõðàíÿåì åãî çíà÷åíèå âî âòîðóþ ïåðåìåííóþ
TD2 = i; // è ñíîâà çàïîìèíàåì íîìåð áàðà
}
i++;
}
// - 1 - ======= Îêîí÷àíèå áëîêà ========================================================
// - 2 - ======= Àíàëèç ïîëó÷åííûõ ðåçóëüòàòîâ ==========================================
if (UpFractal1 == 0 || DownFractal1 == 0 || // Åñëè íå íàéäåí îäèí èç ôðàêòàëîâ,
UpFractal2 == 0 || DownFractal2 == 0)// òî ýòî îøèáêà è ôóíêöèÿ âåðíåò çíà÷åíèå -1
{
Print("Îøèáêà â èñòîðèè. Íå íàéäåí îäèí èç ôðàêòàëîâ!");
return(-1);
}
// Îïðåäåëåíèå òðåíäà
if(UpFractal1 > UpFractal2 && DownFractal1 > DownFractal2)
return(1); // Âîñõîäÿùèé
if(UpFractal1 < UpFractal2 && DownFractal1 < DownFractal2)
return(2); // Íèñõîäÿùèé
// - 2 - ======= Îêîí÷àíèå áëîêà ========================================================
return(0); // íåò òðåíäà
// ------------------
}
//+-------------------------------------------------------------------------------------+
//| Ðàñ÷åò êîýôôèöèåíòîâ K è B â óðàâíåíèè ïðÿìîé ïî äâóì òî÷êàì |
//| Óðàâíåíèå ïðÿìîé Y = K*X + B, ïîýòîìó ñîñòàâèâ ñèñòåìó èç äâóõ óðàâíåíèé, |
//| ìîæíî íàéòè íåèçâåñòíûå K è B, åñëè èçâåñòíû Y1, Y2, X1, X2 |
//+-------------------------------------------------------------------------------------+
void DirectLineCalc(int XB, double YB, int XE, double YE, double &B, double &K)
{
B = (YB*XE - YE*XB)/(XE - XB);
K = (YE - B)/XE;
}
//+-------------------------------------------------------------------------------------+
//| Ðàñ÷åò ñèãíàëà ïî MACD è êàíàëó, îáðàçîâàííîãî ôðàêòàëàìè |
//+-------------------------------------------------------------------------------------+
void GetSignal()
{
Signal = 0; // îáíóëåíèå ñèãíàëà
// - 1 - == Áåðåì çíà÷åíèÿ MACD íà 1-4 áàðàõ ============================================
double MACD1, MACD2, MACD3, MACD4, SMACD;
MACD1 = iMACD(Symbol(), 0, FastMACD, SlowMACD, SignalMACD, PRICE_CLOSE, MODE_MAIN, 1);
MACD2 = iMACD(Symbol(), 0, FastMACD, SlowMACD, SignalMACD, PRICE_CLOSE, MODE_MAIN, 2);
MACD3 = iMACD(Symbol(), 0, FastMACD, SlowMACD, SignalMACD, PRICE_CLOSE, MODE_MAIN, 3);
MACD4 = iMACD(Symbol(), 0, FastMACD, SlowMACD, SignalMACD, PRICE_CLOSE, MODE_MAIN, 4);
SMACD = iMACD(Symbol(), 0, FastMACD, SlowMACD, SignalMACD, PRICE_CLOSE, MODE_SIGNAL, 1);
// - 1 - == Îêîí÷àíèå áëîêà =============================================================
// - 2 - == Ñèãíàë îòêðûòèÿ BUY =========================================================
double DirectB = 0, DirectK = 0;
if (SMACD < MACD1 && MACD1 < MACD2 && MACD2 > MACD3 && MACD3 > MACD4) // îòêàò íà MACD
if (FindFractals() == 1) // ïîñòðîåí âîñõîäÿùèé êàíàë
{
double ThirdFractal = DownFractal1; // â êà÷åñòâå îäíîãî íèæíåãî ôðàêòàëà ñíà÷àëà
int ThirdNumber = TD1; // áåðåì ïåðâûé íèæíèé ôðàêòàë
DirectLineCalc(TU1, UpFractal1, TU2, UpFractal2, DirectB, DirectK); // ðàñ÷åò K è B
double ParallelB = DownFractal1 - DirectK*TD1; // Ðàñ÷åò B íèæíåé ãðàíèöû êàíàëà
if (DownFractal2 < DirectK*TD2+ParallelB)//Åñëè âòîðîé íèæíèé ôðàêòàë íå ïîìåùàåòñÿ
{ // â ïîëó÷åííûé êàíàë, òî ïåðåñ÷èòûâàåì íèæíþþ ãðàíèöó ïî íåìó
ThirdFractal = DownFractal2;
ThirdNumber = TD2;
ParallelB = DownFractal2 - DirectK*TD2;
}
// Ïðîâåðÿåì, ïîïàäàþò ëè öåíû çàêðûòèÿ âñåõ ñâå÷åé â ïîëó÷åííûé êàíàë
for (int i = MathMax(TD2, TU2); i >= MathMax(TD1, TU1); i--)
if (Close[i] < DirectK*i+ParallelB || Close[i] > DirectK*i+DirectB)
{
DirectK = 0; // åñëè íå ïîïàäàþò, òî êàíàë íå ñôîðìèðîâàí
break;
}
// ---------------
if (DirectK != 0 && ND(Bid+StopLevel) < ND((DirectB+ParallelB)/2))
{ // âñå öåíû çàêðûòèÿ ïîïàëè â êàíàë è öåíà íàõîäèòñÿ â íèæíåé ïîëîâèíå êàíàëà
TP = (DirectB-ParallelB)*Koeff+ParallelB;
SL = ThirdFractal-2*Tick;
Signal = 1; // òî ýòî ñèãíàë îòêðûòèÿ BUY
}
}
// - 2 - == Îêîí÷àíèå áëîêà =============================================================
// - 3 - == Ñèãíàë îòêðûòèÿ SELL ========================================================
if (SMACD > MACD1 && MACD1 > MACD2 && MACD2 < MACD3 && MACD3 < MACD4) // îòêàò íà MACD
if (FindFractals() == 2) // ïîñòðîåí íèñõîäÿùèé êàíàë
{
ThirdFractal = UpFractal1; // â êà÷åñòâå îäíîãî âåðõíåãî ôðàêòàëà ñíà÷àëà áåðåì
ThirdNumber = TU1; // ïåðâûé âåðõíèé ôðàêòàë
DirectLineCalc(TD1, DownFractal1, TD2, DownFractal2, DirectB, DirectK); // K è B
ParallelB = UpFractal1 - DirectK*TU1;//Ðàñ÷åò êîýôôèöèåíòà B âåðõíåé ãðàíèöû êàíàëà
if (UpFractal2 > DirectK*TU2+ParallelB)// Åñëè âòîðîé âåðõíèé ôðàêòàë íå ïîìåùàåòñÿ
{ // â ïîëó÷åííûé êàíàë, òî ïåðåñ÷èòûâàåì âåðõíþþ ãðàíèöó ïî íåìó
ThirdFractal = UpFractal2;
ThirdNumber = TU2;
ParallelB = UpFractal2 - DirectK*TU2;
}
// Ïðîâåðÿåì, ïîïàäàþò ëè öåíû çàêðûòèÿ âñåõ ñâå÷åé â ïîëó÷åííûé êàíàë
for (i = MathMax(TD2, TU2); i >= MathMax(TD1, TU1); i--)
if (Close[i] > DirectK*i+ParallelB || Close[i] < DirectK*i+DirectB)
{
DirectK = 0; // åñëè íå ïîïàäàþò, òî êàíàë íå ñôîðìèðîâàí
break;
}
// ---------------
if (DirectK != 0 && ND(Bid-StopLevel) > ND((DirectB+ParallelB)/2))
{ // âñå öåíû çàêðûòèÿ ïîïàëè â êàíàë è öåíà íàõîäèòñÿ â âåðõíåé ïîëîâèíå êàíàëà
SL = ThirdFractal + Spread + 2*Tick;
TP = ParallelB - (ParallelB - DirectB)*Koeff+Spread;
Signal = 2; // òî ýòî ñèãíàë îòêðûòèÿ SELL
}
}
// - 3 - == Îêîí÷àíèå áëîêà =============================================================
}
//+-------------------------------------------------------------------------------------+
//| Óäàëÿåò âñå îòëîæåííèêè òèïà Type. Åñëè óäàëèòü íå óäàëîñü, òî âåðíåò 1. |
//+-------------------------------------------------------------------------------------+
bool CheckPendingsReal(int Type)
{
for (int i = OrdersTotal()-1; i >= 0; i--)
if(OrderSelect(i, SELECT_BY_POS))
if(OrderSymbol() == Symbol() && MathFloor(OrderMagicNumber()/10) == MagicNumber
&& OrderType() > 2) // ïîèñê îòëîæåííîãî îðäåðà
if(OrderType() == Type) // Åñëè îðäåð òèïà Type
{
if (WaitForTradeContext())
{
if (!OrderDelete(OrderTicket())) // òî ïûòàåìñÿ óäàëèòü åãî
return(False); // íå óäàëîñü óäàëèòü - âåðíåì False
}
else
return(False);//âåðíåì False, åñëè íå äîæäàëèñü îñâîáîæäåíèÿ òîðãîâîãî ïîòîêà
}
else
return(False); // âåðíåì False, åñëè íàéäåí îðäåð íå ñîîòâåòñòâóþùèé Type
return(True); // åñëè âñå ÎÊ, òî âåðíåì True
}
//+-------------------------------------------------------------------------------------+
//| Çàêðûâàåò âñå ïîçèöèè òèïà Type. Åñëè çàêðûòü íå óäàëîñü çàêðûòü, òî 1. |
//| Åñëè ïðèñóòñòâóåò ïðîòèâîïîëîæíàÿ, òî âîçâðàùàåò 2.  ñëó÷àå óñïåõà 0. |
//+-------------------------------------------------------------------------------------+
int CheckOrdersReal(int Type)
{
for (int i = OrdersTotal()-1; i >= 0; i--)
if(OrderSelect(i, SELECT_BY_POS))
if(OrderSymbol() == Symbol() && MathFloor(OrderMagicNumber()/10) == MagicNumber
&& OrderType() < 2) // ïîèñê "ñâîåé" ñäåëêè
if(OrderType() == Type) // Åñëè ïîçèöèÿ òèïà Type
{
if (WaitForTradeContext())
{
if(Type == OP_BUY)
double Pr = ND(MarketInfo(Symbol(), MODE_BID));
else
Pr = ND(MarketInfo(Symbol(), MODE_ASK));
if (!OrderClose(OrderTicket(), OrderLots(), Pr, 3))// òî ïûòàåìñÿ çàêðûòü åå
return(1); // íå óäàëîñü çàêðûòü - âåðíåì 1
}
else
return(1);//âåðíåì 1, åñëè íå óäàëîñü äîæäàòüñÿ îñâîáîæäåíèÿ òîðãîâîãî ïîòîêà
}
else
return(2); // âåðíåì 2, åñëè îòêðûòà ïîçèöèÿ, ïðîòèâîïîëîæíàÿ óêàçàííîé
return(0); // åñëè âñå ÎÊ, òî âåðíåì 0
}
//+-------------------------------------------------------------------------------------+
//| Ïîèñê ïåðâè÷íîé ïîçèöèè è óñòàíîâêà åé îòëîæåííèêà |
//+-------------------------------------------------------------------------------------+
bool AddPending()
{
// - 1 - == Ïîèñê ïåðâè÷íîé ïîçèöèè =====================================================
for (int i = OrdersTotal()-1; i >= 0; i--)
if (OrderSelect(i, SELECT_BY_POS))
if (OrderSymbol() == Symbol() && MathMod(OrderMagicNumber(), 10) == 0
&& OrderType() < 2) // ïîèñê ïåðâè÷íîé ïîçèöèè , êîòîðàÿ îòêðûëàñü ïî ñèãíàëó
{
bool Res = False;
int Type = OrderType(); // çàïîìèíàåì åå ïàðàìåòðû
double OpenP = OrderStopLoss();
double TP = MathAbs(OrderOpenPrice()-OrderStopLoss());
double SL = OrderTakeProfit();
// - 1 - == Îêîí÷àíèå áëîêà =============================================================
// - 2 - == Ïîèñê îòëîæåííèêà, êîòîðûé äîëæåí áûòü óñòàíîâëåí íà ñòîïå ïîçèöèè ==========
for (int j = OrdersTotal()-1; j >= 0; j--)
if (OrderSelect(j, SELECT_BY_POS))
if (OrderSymbol() == Symbol() && MathMod(OrderMagicNumber(), 10) == 1
&& OrderType() > 2)
{
Res = True; // îòëîæåííèê íàéäåí, íåò íóæäû åãî óñòàíàâëèâàòü
break;
}
// - 2 - == Îêîí÷àíèå áëîêà =============================================================
// - 3 - == Óñòàíîâêà îòëîæåííîãî îðäåðà ================================================
if (!Res) // åñëè îòëîæåííèê íå íàéäåí, òî óñàíîâèì åãî
{
if (Type == OP_BUY) // åñëè ïåðâè÷íàÿ ïîçèöèÿ äëèííàÿ, òî
{
Type = OP_SELLSTOP; // óñòàíàâëèâàåì SELL STOP
TP = OpenP - TP; // è öåëü îòñòîèò îò öåíû îòêðûòèÿ íà âåëè÷èíó ñòîïà
}
else
{ // åñëè ïåðâè÷íàÿ ïîçèöèÿ êîðîòêàÿ, òî
Type = OP_BUYSTOP; // óñòàíàâëèâàåì BUY STOP
TP = OpenP + TP; // è öåëü îòñòîèò îò öåíû îòêðûòèÿ íà âåëè÷èíó ñòîïà
}
if (!OpenOrder(Type, OpenP, SL, TP, 1)) // åñëè óñòàíîâèòü íå óäàëîñü
return(False); // âîçâðàùàåì False
}
// - 3 - == Îêîí÷àíèå áëîêà =============================================================
break;
}
return(True);
}
//+-------------------------------------------------------------------------------------+
//| Ïîèñê ïåðâè÷íîé ïîçèöèè è óäàëåíèå ñîîòâåòñòâóþùåãî åé îòëîæåííèêà, åñëè ïîçèöèè íåò|
//+-------------------------------------------------------------------------------------+
void DeletePending()
{
for (int i = OrdersTotal()-1; i >= 0; i--)
if (OrderSelect(i, SELECT_BY_POS))
if (OrderSymbol() == Symbol() && MathMod(OrderMagicNumber(), 10) == 1
&& OrderType() > 2) // ïîèñê îòëîæåííîãî îðäåðà
{
bool Res = False;
int Ticket = OrderTicket();
// Ïîèñê ïîçèöèè, ñîîòâåòñòâóþùåé îòëîæåííèêó
for (int j = OrdersTotal()-1; j >= 0; j--)
if (OrderSelect(j, SELECT_BY_POS))
if (OrderSymbol() == Symbol() && MathMod(OrderMagicNumber(), 10) == 0
&& OrderType() < 2)
{
Res = True;
break;
}
// Åñëè îòëîæåííèêà íåò, òî óäàëÿåì
if (!Res)
OrderDelete(Ticket);
// ------------------------------------
break;
}
}
//+-------------------------------------------------------------------------------------+
//| Ôóíêöèÿ START ýêñïåðòà |
//+-------------------------------------------------------------------------------------+
int start()
{
// - 1 - == Ðàçðåøåíî ëè ñîâåòíèêó ðàáîòàòü? ===========================================
if (!Activate || FatalError) // Îòêëþ÷àåòñÿ ðàáîòà ñîâåòíèêà, åñëè ôóíêöèÿ
return(0); // init çàâåðøèëàñü ñ îøèáêîé èëè èìåëà ìåñòî ôàòàëüíàÿ îøèáêà
// - 1 - == Îêîí÷àíèå áëîêà ============================================================
// - 2 - == Óäàëåíèå îòëîæåííîãî îðäåðà ïðè çàêðûòèè ïåðâè÷íîé ïîçèöèè ïî ïðîôèòó =======
DeletePending();
// - 2 - == Îêîí÷àíèå áëîêà ============================================================
// - 3 - == Êîíòðîëü îòêðûòèÿ íîâîãî áàðà ==============================================
if (LastBar == Time[0]) //Åñëè âðåìÿ ïîñ÷èòàííîãî áàðà ðàâíî âðåìåíè òåêóùåãî áàðà
return(0); // òî ýòî îçíà÷àåò, ÷òî íîâûé áàð åùå íå îòêðûëñÿ
// - 3 - == Îêîí÷àíèå áëîêà ============================================================
// - 4 - == Ñáîð èíôîðìàöèè îá óñëîâèÿõ òîðãîâëè ========================================
Spread = ND(MarketInfo(Symbol(), MODE_SPREAD)*Point); // òåêùèé ñïðýä
StopLevel = ND(MarketInfo(Symbol(), MODE_STOPLEVEL)*Point); // òåêóùèé óðîâåíü ñòîïîâ
// - 4 - == Îêîí÷àíèå áëîêà ============================================================
// - 5 - == Ðàñ÷åò òåêóùåãî ñèãíàëà =====================================================
GetSignal();
// - 5 - == Îêîí÷àíèå áëîêà ============================================================
// - 6 - == Îòêðûòèå äëèííîé ïîçèöèè ===================================================
if (Signal == 1)
{
int Res = CheckOrdersReal(OP_SELL); // Ïðîòèâîïîëîæíóþ ïîçèöèþ - çàêðûòü
if (Res == 0) // åñëè íåò îòêðûòûõ ïîçèöèé
{
if (!CheckPendingsReal(OP_BUYSTOP)) return(0); // è íåò îòëîæåííûõ îðäåðîâ
RefreshRates();
if (ND(Bid-SL-StopLevel) > 0)
if (!OpenOrder(OP_BUY, ND(Ask), ND(SL), ND(TP), 0)) // åñëè íå óäàëîñü îòêðûòü
return(0); // òî ïîïðîáóåì ñî ñëåäóþùèì òèêîì
}
if(Res == 1) return(0); //çàêðûòü ïðîòèâîïîëîæíóþ íå âûøëî, æäåì äî ñëåäóþùåãî òèêà
}
// - 6 - == Îêîí÷àíèå áëîêà ============================================================
// - 7 - == Îòêðûòèå êîðîòêîé ïîçèöèè ===================================================
if (Signal == 2)
{
Res = CheckOrdersReal(OP_BUY); // Ïðîòèâîïîëîæíóþ ïîçèöèþ - çàêðûòü
if (Res == 0) // åñëè íåò îòêðûòûõ ïîçèöèé
{
if (!CheckPendingsReal(OP_SELLSTOP)) return(0); // è íåò SELL STOP
RefreshRates();
if (ND(SL-Ask-StopLevel) > 0)
if (!OpenOrder(OP_SELL, ND(Bid), ND(SL), ND(TP), 0))// åñëè íå óäàëîñü îòêðûòü
return(0); // òî ïîïðîáóåì ñî ñëåäóþùèì òèêîì
}
if (Res == 1) return(0);//çàêðûòü ïðîòèâîïîëîæíóþ íå âûøëî, æäåì äî ñëåäóþùåãî òèêà
}
// - 7 - == Îêîí÷àíèå áëîêà ============================================================
// - 8 - == Äîáàâëåíèå îòëîæåííîãî îðäåðà ê ïåðâè÷íîé ïîçèöèè ===========================
if (!AddPending()) return(0);
// - 8 - == Îêîí÷àíèå áëîêà ============================================================
LastBar = Time[0]; // íîâûé áàð "ïîñ÷èòàëè"
//----
return(0);
}
//+------------------------------------------------------------------+
Comments