This script is designed to automatically place and manage pending "Buy Limit" and "Sell Limit" orders in the Forex market based on the Parabolic SAR indicator. Think of it as a robot that watches the market for you and sets up potential trades automatically.
Here's a breakdown of what the script does:
-
Setting Up: The script starts by defining a set of customizable settings. These settings include things like the timeframe to analyze (e.g., 4 hours), how sensitive the Parabolic SAR indicator is, the size of potential stop losses and take profits (risk management), the lot size for each trade, and a "magic number" to identify orders created by this specific script. It also includes preferences for visual and audio alerts.
-
Watching for New Market Data: The script constantly monitors the market for new price data. It specifically looks for the start of a new "bar" or period on the chart, based on the selected timeframe. This ensures that it only acts when there's fresh information.
-
Calculating the Parabolic SAR: The script uses the Parabolic SAR indicator to identify potential entry points. The Parabolic SAR is a tool used to determine potential trend direction and reversal points in the market. The script calculates the SAR value based on the chosen timeframe and sensitivity settings.
-
Checking for Order Opportunities:
- Buy Limit Orders: The script checks if the Parabolic SAR value is below the low price of the current bar, and checks if the current price is higher than the Parabolic SAR value. If it is, and there isn't already a "Buy Limit" order open, it calculates where to place a new "Buy Limit" order. A "Buy Limit" order is an order to buy if the price drops to a certain level.
- Sell Limit Orders: Conversely, the script checks if the Parabolic SAR value is above the high price of the current bar, and checks if the current price is lower than the Parabolic SAR value. If it is, and there isn't already a "Sell Limit" order open, it calculates where to place a new "Sell Limit" order. A "Sell Limit" order is an order to sell if the price rises to a certain level.
-
Placing or Modifying Orders:
- If the script finds a valid opportunity to place a buy or sell limit order and there isn't one already, it places the order with the specified lot size, entry price (based on the Parabolic SAR), stop loss, and take profit levels.
- If a buy or sell limit order exists, the script checks if the current price is still higher/lower than the Parabolic SAR indicator. If it is, it updates (modifies) the existing order to reflect the current SAR price, adjusting the entry price, stop loss, and take profit levels accordingly.
-
Error Handling: The script includes some error handling to manage potential problems like incorrect stop loss levels, connectivity issues, or trading restrictions. It will attempt to correct price levels and retry placing the order a certain number of times. It also incorporates alerts and notifications if critical errors occur.
In simple terms, this script uses the Parabolic SAR indicator to automatically place pending orders, either buying if the price drops to a certain level or selling if the price rises to a certain level, attempting to profit from anticipated price movements. It also manages these orders, adjusting them as the market changes, while considering risk management through stop-loss and take-profit levels.
//+------------------------------------------------------------------+
//| ytg_Parabolic_exp.mq4 |
//| Yuriy Tokman |
//| yuriytokman@gmail.com |
//+------------------------------------------------------------------+
#property copyright "Yuriy Tokman"
#property link "yuriytokman@gmail.com"
extern int timeframe = 240;
extern double step = 0.009;
extern double maximum = 0.2;
extern int StopLoss = 500; // Ðàçìåð ñòîïà â ïóíêòàõ
extern int TakeProfit = 500; // Ðàçìåð òåéêà â ïóíêòàõ
extern double Lotsi = 0.1;
extern int MagicNumber = 28081975; //Ìàãè÷åñêîå ÷èñëî îðäåðîâ
color clOpenBuy = LightBlue; // Öâåò çíà÷êà îòêðûòèÿ ïîêóïêè
color clOpenSell = LightCoral; // Öâåò çíà÷êà îòêðûòèÿ ïðîäàæè
color clCloseBuy = Blue; // Öâåò çíà÷êà çàêðûòèÿ ïîêóïêè
color clCloseSell = Coral; // Öâåò çíà÷êà çàêðûòèÿ ïðîäàæè
extern int Slippage = 30; // Ïðîñêàëüçûâàíèå öåíû
extern int NumberOfTry = 5; // Êîëè÷åñòâî òîðãîâûõ ïîïûòîê
bool UseSound = True; // Èñïîëüçîâàòü çâóêîâîé ñèãíàë
string NameFileSound = "expert.wav"; // Íàèìåíîâàíèå çâóêîâîãî ôàéëà
int NumberAccount = 0; // Íîìåð òîðãîâîãî ñ÷¸òà
bool ShowComment = True; // Ïîêàçûâàòü êîììåíòàðèé
//------- Ãëîáàëüíûå ïåðåìåííûå ñîâåòíèêà -------------------------------------+
bool gbDisabled = False; // Ôëàã áëîêèðîâêè ñîâåòíèêà
bool gbNoInit = False; // Ôëàã íåóäà÷íîé èíèöèàëèçàöèè
//------- Ïîäêëþ÷åíèå âíåøíèõ ìîäóëåé -----------------------------------------+
#include <stdlib.mqh> // Ñòàíäàðòíàÿ áèáëèîòåêà ÌÒ4
//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int init()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{
int dg=MarketInfo(OrderSymbol(), MODE_DIGITS);
double parab = NormalizeDouble(iSAR(Symbol(),timeframe,step,maximum,0),dg);
double sl=0, tp=0,ti=0,new_sl,new_tp;
double SPREAD = MarketInfo(Symbol(),MODE_SPREAD);//Ñïðýä â ïóíêòàõ
double STOPLEVEL = MarketInfo(Symbol(),MODE_STOPLEVEL);
double low = iLow(Symbol(),timeframe,0);
double high = iHigh(Symbol(),timeframe,0);
double mp=MarketInfo(Symbol(), MODE_POINT);
double pa=MarketInfo(Symbol(), MODE_ASK);
double pb=MarketInfo(Symbol(), MODE_BID);
//----
if(NevBar())
{
//-------------------------------------------------------------buy
if(!ExistOrders(NULL,OP_BUYLIMIT,MagicNumber) && parab<low && pb>parab+STOPLEVEL*mp)//îðäåðà íåò
{//óñòàíàâëèâàåì
if (StopLoss >0) sl=parab-StopLoss*mp; else sl=0;
if (TakeProfit>0) tp=parab+TakeProfit*mp; else tp=0;
SetOrder(NULL,OP_BUYLIMIT,Lotsi,parab,sl,tp,MagicNumber,0);
}
if(ExistOrders(NULL,OP_BUYLIMIT,MagicNumber) && pb>parab+STOPLEVEL*mp)//îðäåð åñòü
{//ìîäèôèöèðóåì
ti = TicketPos(NULL,OP_BUYLIMIT,MagicNumber);
if (OrderSelect(ti, SELECT_BY_TICKET))
{
if (StopLoss >0) sl=parab-StopLoss*mp; else sl=0;
if (TakeProfit>0) tp=parab+TakeProfit*mp; else tp=0;
ModifyOrder(parab,sl,tp,Turquoise);
}
}
//--------------------------------------------------------------sell
if(!ExistOrders(NULL,OP_SELLLIMIT,MagicNumber) && parab>high && pa<parab-STOPLEVEL*mp)//îðäåðà íåò
{//óñòàíàâëèâàåì
if (StopLoss >0) sl=parab+StopLoss*mp; else sl=0;
if (TakeProfit>0) tp=parab-TakeProfit*mp; else tp=0;
SetOrder(NULL,OP_SELLLIMIT,Lotsi,parab,sl,tp,MagicNumber,0);
}
if(ExistOrders(NULL,OP_SELLLIMIT,MagicNumber) && pa<parab-STOPLEVEL*mp)//îðäåð åñòü
{//ìîäèôèöèðóåì
ti = TicketPos(NULL,OP_SELLLIMIT,MagicNumber);
if (OrderSelect(ti, SELECT_BY_TICKET))
{
if (StopLoss >0) sl=parab+StopLoss*mp; else sl=0;
if (TakeProfit>0) tp=parab-TakeProfit*mp; else tp=0;
ModifyOrder(parab,sl,tp,Turquoise);
}
}
//-----------------------------------------------------------------
}
//----
return(0);
}
//+------------------------------------------------------------------+
//+----------------------------------------------------------------------------+
// Ôóíêöèÿ êîíòðîëÿ íîâîãî áàðà |
//-----------------------------------------------------------------------------+
bool NevBar(){
static int PrevTime=0;
if (PrevTime==iTime(Symbol(),timeframe,0)) return(false);
PrevTime=iTime(Symbol(),timeframe,0);
return(true);}
//+----------------------------------------------------------------------------+
//| Àâòîð : Êèì Èãîðü Â. aka KimIV, http://www.kimiv.ru |
//+----------------------------------------------------------------------------+
//| Âåðñèÿ : 12.03.2008 |
//| Îïèñàíèå : Âîçâðàùàåò ôëàã ñóùåñòâîâàíèÿ îðäåðîâ. |
//+----------------------------------------------------------------------------+
//| Ïàðàìåòðû: |
//| sy - íàèìåíîâàíèå èíñòðóìåíòà ("" - ëþáîé ñèìâîë, |
//| NULL - òåêóùèé ñèìâîë) |
//| op - îïåðàöèÿ (-1 - ëþáîé îðäåð) |
//| mn - MagicNumber (-1 - ëþáîé ìàãèê) |
//| ot - âðåìÿ îòêðûòèÿ ( 0 - ëþáîå âðåìÿ óñòàíîâêè) |
//+----------------------------------------------------------------------------+
bool ExistOrders(string sy="", int op=-1, int mn=-1, datetime ot=0) {
int i, k=OrdersTotal(), ty;
if (sy=="0") sy=Symbol();
for (i=0; i<k; i++) {
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
ty=OrderType();
if (ty>1 && ty<6) {
if ((OrderSymbol()==sy || sy=="") && (op<0 || ty==op)) {
if (mn<0 || OrderMagicNumber()==mn) {
if (ot<=OrderOpenTime()) return(True);
}
}
}
}
}
return(False);
}
//+----------------------------------------------------------------------------+
//+----------------------------------------------------------------------------+
//| Àâòîð : Êèì Èãîðü Â. aka KimIV, http://www.kimiv.ru |
//+----------------------------------------------------------------------------+
//| Âåðñèÿ : 13.03.2008 |
//| Îïèñàíèå : Óñòàíîâêà îðäåðà. |
//+----------------------------------------------------------------------------+
//| Ïàðàìåòðû: |
//| sy - íàèìåíîâàíèå èíñòðóìåíòà (NULL èëè "" - òåêóùèé ñèìâîë) |
//| op - îïåðàöèÿ |
//| ll - ëîò |
//| pp - öåíà |
//| sl - óðîâåíü ñòîï |
//| tp - óðîâåíü òåéê |
//| mn - Magic Number |
//| ex - Ñðîê èñòå÷åíèÿ |
//+----------------------------------------------------------------------------+
void SetOrder(string sy, int op, double ll, double pp,
double sl=0, double tp=0, int mn=0, datetime ex=0) {
color clOpen;
datetime ot;
double pa, pb, mp;
int err, it, ticket, msl;
string lsComm=WindowExpertName()+" "+GetNameTF(Period());
if (sy=="" || sy=="0") sy=Symbol();
msl=MarketInfo(sy, MODE_STOPLEVEL);
if (op==OP_BUYLIMIT || op==OP_BUYSTOP) clOpen=clOpenBuy; else clOpen=clOpenSell;
if (ex>0 && ex<TimeCurrent()) ex=0;
for (it=1; it<=NumberOfTry; it++) {
if (!IsTesting() && (!IsExpertEnabled() || IsStopped())) {
Print("SetOrder(): Îñòàíîâêà ðàáîòû ôóíêöèè");
break;
}
while (!IsTradeAllowed()) Sleep(5000);
RefreshRates();
ot=TimeCurrent();
ticket=OrderSend(sy, op, ll, pp, Slippage, sl, tp, lsComm, mn, ex, clOpen);
if (ticket>0) {
if (UseSound) PlaySound(NameFileSound); break;
} else {
err=GetLastError();
if (err==128 || err==142 || err==143) {
Sleep(1000*66);
if (ExistOrders(sy, op, mn, ot)) {
if (UseSound) PlaySound(NameFileSound); break;
}
Print("Error(",err,") set order: ",ErrorDescription(err),", try ",it);
continue;
}
mp=MarketInfo(sy, MODE_POINT);
pa=MarketInfo(sy, MODE_ASK);
pb=MarketInfo(sy, MODE_BID);
// Íåïðàâèëüíûå ñòîïû
if (err==130) {
switch (op) {
case OP_BUYLIMIT:
if (pp>pa-msl*mp) pp=pa-msl*mp;
if (sl>pp-(msl+1)*mp) sl=pp-(msl+1)*mp;
if (tp>0 && tp<pp+(msl+1)*mp) tp=pp+(msl+1)*mp;
break;
case OP_BUYSTOP:
if (pp<pa+(msl+1)*mp) pp=pa+(msl+1)*mp;
if (sl>pp-(msl+1)*mp) sl=pp-(msl+1)*mp;
if (tp>0 && tp<pp+(msl+1)*mp) tp=pp+(msl+1)*mp;
break;
case OP_SELLLIMIT:
if (pp<pb+msl*mp) pp=pb+msl*mp;
if (sl>0 && sl<pp+(msl+1)*mp) sl=pp+(msl+1)*mp;
if (tp>pp-(msl+1)*mp) tp=pp-(msl+1)*mp;
break;
case OP_SELLSTOP:
if (pp>pb-msl*mp) pp=pb-msl*mp;
if (sl>0 && sl<pp+(msl+1)*mp) sl=pp+(msl+1)*mp;
if (tp>pp-(msl+1)*mp) tp=pp-(msl+1)*mp;
break;
}
Print("SetOrder(): Ñêîððåêòèðîâàíû öåíîâûå óðîâíè");
}
Print("Error(",err,") set order: ",ErrorDescription(err),", try ",it);
Print("Ask=",pa," Bid=",pb," sy=",sy," ll=",ll," op=",GetNameOP(op),
" pp=",pp," sl=",sl," tp=",tp," mn=",mn);
if (pa==0 && pb==0) Message("SetOrder(): Ïðîâåðüòå â îáçîðå ðûíêà íàëè÷èå ñèìâîëà "+sy);
// Áëîêèðîâêà ðàáîòû ñîâåòíèêà
if (err==2 || err==64 || err==65 || err==133) {
gbDisabled=True; break;
}
// Äëèòåëüíàÿ ïàóçà
if (err==4 || err==131 || err==132) {
Sleep(1000*300); break;
}
// Ñëèøêîì ÷àñòûå çàïðîñû (8) èëè ñëèøêîì ìíîãî çàïðîñîâ (141)
if (err==8 || err==141) Sleep(1000*100);
if (err==139 || err==140 || err==148) break;
// Îæèäàíèå îñâîáîæäåíèÿ ïîäñèñòåìû òîðãîâëè
if (err==146) while (IsTradeContextBusy()) Sleep(1000*11);
// Îáíóëåíèå äàòû èñòå÷åíèÿ
if (err==147) {
ex=0; continue;
}
if (err!=135 && err!=138) Sleep(1000*7.7);
}
}
}
//+----------------------------------------------------------------------------+
//| Îïèñàíèå : Âîçâðàùàåò íàèìåíîâàíèå òàéìôðåéìà |
//+----------------------------------------------------------------------------+
//| Ïàðàìåòðû: |
//| TimeFrame - òàéìôðåéì (êîëè÷åñòâî ñåêóíä) (0 - òåêóùèé ÒÔ) |
//+----------------------------------------------------------------------------+
string GetNameTF(int TimeFrame=0) {
if (TimeFrame==0) TimeFrame=Period();
switch (TimeFrame) {
case PERIOD_M1: return("M1");
case PERIOD_M5: return("M5");
case PERIOD_M15: return("M15");
case PERIOD_M30: return("M30");
case PERIOD_H1: return("H1");
case PERIOD_H4: return("H4");
case PERIOD_D1: return("Daily");
case PERIOD_W1: return("Weekly");
case PERIOD_MN1: return("Monthly");
default: return("UnknownPeriod");
}
}
//| Îïèñàíèå : Âîçâðàùàåò íàèìåíîâàíèå òîðãîâîé îïåðàöèè |
//+----------------------------------------------------------------------------+
//| Ïàðàìåòðû: |
//| op - èäåíòèôèêàòîð òîðãîâîé îïåðàöèè |
//+----------------------------------------------------------------------------+
string GetNameOP(int op) {
switch (op) {
case OP_BUY : return("Buy");
case OP_SELL : return("Sell");
case OP_BUYLIMIT : return("Buy Limit");
case OP_SELLLIMIT: return("Sell Limit");
case OP_BUYSTOP : return("Buy Stop");
case OP_SELLSTOP : return("Sell Stop");
default : return("Unknown Operation");
}
}
//+----------------------------------------------------------------------------+
//| Îïèñàíèå : Âûâîä ñîîáùåíèÿ â êîììåíò è â æóðíàë |
//+----------------------------------------------------------------------------+
//| Ïàðàìåòðû: |
//| m - òåêñò ñîîáùåíèÿ |
//+----------------------------------------------------------------------------+
void Message(string m) {
Comment(m);
if (StringLen(m)>0) Print(m);
}
//+----------------------------------------------------------------------------+
//| Àâòîð : Êèì Èãîðü Â. aka KimIV, http://www.kimiv.ru |
//+----------------------------------------------------------------------------+
//| Âåðñèÿ : 28.11.2006 |
//| Îïèñàíèå : Ìîäèôèêàöèÿ îäíîãî ïðåäâàðèòåëüíî âûáðàííîãî îðäåðà. |
//+----------------------------------------------------------------------------+
//| Ïàðàìåòðû: |
//| pp - öåíà óñòàíîâêè îðäåðà |
//| sl - öåíîâîé óðîâåíü ñòîïà |
//| tp - öåíîâîé óðîâåíü òåéêà |
//| cl - öâåò çíà÷êà ìîäèôèêàöèè |
//+----------------------------------------------------------------------------+
void ModifyOrder(double pp=-1, double sl=0, double tp=0, color cl=CLR_NONE) {
bool fm;
double op, pa, pb, os, ot;
int dg=MarketInfo(OrderSymbol(), MODE_DIGITS), er, it;
if (pp<=0) pp=OrderOpenPrice();
if (sl<0 ) sl=OrderStopLoss();
if (tp<0 ) tp=OrderTakeProfit();
pp=NormalizeDouble(pp, dg);
sl=NormalizeDouble(sl, dg);
tp=NormalizeDouble(tp, dg);
op=NormalizeDouble(OrderOpenPrice() , dg);
os=NormalizeDouble(OrderStopLoss() , dg);
ot=NormalizeDouble(OrderTakeProfit(), dg);
if (pp!=op || sl!=os || tp!=ot) {
for (it=1; it<=NumberOfTry; it++) {
if (!IsTesting() && (!IsExpertEnabled() || IsStopped())) break;
while (!IsTradeAllowed()) Sleep(5000);
RefreshRates();
fm=OrderModify(OrderTicket(), pp, sl, tp, 0, cl);
if (fm) {
if (UseSound) PlaySound(NameFileSound); break;
} else {
er=GetLastError();
pa=MarketInfo(OrderSymbol(), MODE_ASK);
pb=MarketInfo(OrderSymbol(), MODE_BID);
Print("Error(",er,") modifying order: ",ErrorDescription(er),", try ",it);
Print("Ask=",pa," Bid=",pb," sy=",OrderSymbol(),
" op="+GetNameOP(OrderType())," pp=",pp," sl=",sl," tp=",tp);
Sleep(1000*10);
}
}
}
}
//+----------------------------------------------------------------------------+
//| Àâòîð : Êèì Èãîðü Â. aka KimIV, http://www.kimiv.ru |
//+----------------------------------------------------------------------------+
//| Âåðñèÿ : 19.02.2008 |
//| Îïèñàíèå : Âîçâðàùàåò òèêåò ïîñëåäíåé îòêðûòîé ïîçèöèè èëè -1 |
//+----------------------------------------------------------------------------+
//| Ïàðàìåòðû: |
//| sy - íàèìåíîâàíèå èíñòðóìåíòà ("" - ëþáîé ñèìâîë, |
//| NULL - òåêóùèé ñèìâîë) |
//| op - îïåðàöèÿ (-1 - ëþáàÿ ïîçèöèÿ) |
//| mn - MagicNumber (-1 - ëþáîé ìàãèê) |
//+----------------------------------------------------------------------------+
int TicketPos(string sy="", int op=-1, int mn=-1) {
datetime o;
int i, k=OrdersTotal(), r=-1;
if (sy=="0") sy=Symbol();
for (i=0; i<k; i++) {
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if (OrderSymbol()==sy || sy=="") {
if (OrderType()==OP_BUYLIMIT || OrderType()==OP_SELLLIMIT) {
if (op<0 || OrderType()==op) {
if (mn<0 || OrderMagicNumber()==mn) {
if (o<OrderOpenTime()) {
o=OrderOpenTime();
r=OrderTicket();
}
}
}
}
}
}
}
return(r);
}
Comments