Here's a breakdown of what the provided MetaTrader script does, explained in simple terms for someone who isn't a programmer:
Overall Goal:
This script is designed to automatically trade on the Forex market. It aims to identify potential buying and selling opportunities based on a combination of technical indicators and then execute trades automatically. It also manages existing trades, closing them when certain conditions are met.
Key Components and Logic:
-
Settings: The script starts with several settings you can adjust. These control things like:
- Lots: The size of the trades it will make. Think of this as how much money you're betting on each trade.
- Maximum Risk: How much of your account balance the script is willing to risk on a single trade.
- Decrease Factor: Modifies lot size depending on consecutive losing trades.
-
Channel Identification: The script attempts to identify a channel on the price chart. A channel is essentially a trendline showing the direction the price is moving. It identifies high and low points (fractals) and draws trend lines to define the channel.
-
Laguerre Indicator: A custom indicator is employed to assess market direction and momentum. This indicator helps to confirm potential entry and exit points.
-
Juice Indicator: Another custom indicator that is used to show market strength.
-
CCI Indicator: Another custom indicator used for buying and selling signals.
-
Trade Entry (Opening Positions):
- The script continuously checks several conditions to see if it should open a "buy" (long) or "sell" (short) trade.
- Buy Conditions: It looks for situations where the channel indicator shows a bullish (upward) trend, where the Laguerre indicator suggests the price is oversold and ready to rise, Juice Indicator signals, and there isn't already an open "buy" trade.
- Sell Conditions: It looks for situations where the channel indicator shows a bearish (downward) trend, where the Laguerre indicator suggests the price is overbought and ready to fall, Juice Indicator signals, and there isn't already an open "sell" trade.
- If all the conditions are met, the script automatically places a trade (either buy or sell). *Stop Loss: Also defines the maximum risk for each operation
-
Trade Exit (Closing Positions):
-
The script also continuously monitors any open trades it has placed.
-
Buy Trade Exit: If a "buy" trade is open, it checks if the price has reached the upper edge of the identified channel. If it has, it closes the trade to take profits. Or it will close if a medium value is reached.
-
Sell Trade Exit: If a "sell" trade is open, it checks if the price has reached the lower edge of the identified channel. If it has, it closes the trade to take profits. Or it will close if a medium value is reached.
-
-
Money Management:
- The script includes a basic form of money management. It checks your account balance before placing trades to ensure you have enough funds to cover the trade. It will calculate a lot size based on available margin and risk settings. *Decreasing Lot Size: Will change the lot size depending on consecutive losing trades.
In Simple Terms:
The script is like a robot trader that:
- Looks at the price chart and tries to draw lines showing the current trend.
- Uses several indicators (Laguerre) to decide if the price is likely to go up or down soon.
- If it sees a good opportunity (based on the trend and indicators), it automatically places a "buy" or "sell" trade.
- It watches the trade and closes it when the price reaches a certain level to take profits, or if the medium channel values is reached.
- It tries to manage the risk by only betting a small percentage of your account balance on each trade, and changes the lot size depending on loses.
//+------------------------------------------------------------------+
//| Starter.mq4 |
//| Copyright © 2005, MetaQuotes Software Corp. |
//| http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, MetaQuotes Software Corp."
#property link "http://www.metaquotes.net"
#define MAGICMA 20050610
// H1 FXOE-Juice
extern double Lots = 1;
extern double MaximumRisk = 0.12; //11
extern double DecreaseFactor = 3;
//extern double Profit = 11; //9
extern double StopLoss = 400;
extern double JuiceLevel = 0.0005;
double DownLagLine = 0.15;
double UpLagLine = 0.75;
double MidLagLine = 0.45;
double spread = 1.5;
bool RTs = false;
bool RTb = false;
//+-Channel
double ExtMapBuffer1[];
extern int AllBars=240;
int BarsForFract=0;
int CurrentBar=0;
double Step=0;
int B1=-1,B2=-1;
int UpDown=0;
double P1=0,P2=0,PP=0;
int i=0,AB=300,BFF=0;
int ishift=0;
double iprice=0;
datetime T1,T2;
//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int init()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
void DelObj()
{
ObjectDelete("TL1");
ObjectDelete("TL2");
ObjectDelete("MIDL");
ObjectDelete("A1");
ObjectDelete("A2");
ObjectDelete("A3");
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
double channel()
{
int counted_bars=IndicatorCounted();
string Com = "",TL1="TL1",TL2="TL2";
//----
if ((AllBars==0) || (Bars<AllBars)) AB=Bars; else AB=AllBars; //AB-êîëè÷åñòâî îáñ÷èòûâàåìûõ áàðîâ
if (BarsForFract>0)
BFF=BarsForFract;
else
{
switch (Period())
{
case 1: BFF=12; break;
case 5: BFF=48; break;
case 15: BFF=24; break;
case 30: BFF=24; break;
case 60: BFF=12; break;
case 240: BFF=15; break;
case 1440: BFF=10; break;
case 10080: BFF=6; break;
default: DelObj(); return(-1); break;
}
}
CurrentBar=2; //ñ÷èòàåì ñ òðåòüåãî áàðà, ÷òîáû ôðàêòàë "çàêðåïèëñÿ
B1=-1; B2=-1; UpDown=0;
while(((B1==-1) || (B2==-1)) && (CurrentBar<AB))
{
//UpDown=1 çíà÷èò ïåðâûé ôðàêòàë íàéäåí ñâåðõó, UpDown=-1 çíà÷èò ïåðâûé ôðàêòàë
//íàéäåí ñíèçó, UpDown=0 çíà÷èò ôðàêòàë åù¸ íå íàéäåí.
//Â1 è Â2 - íîìåðà áàðîâ ñ ôðàêòàëàìè, ÷åðåç íèõ ñòðîèì îïîðíóþ ëèíèþ.
//Ð1 è Ð2 - ñîîòâåòñòâåííî öåíû ÷åðåç êîòîðûå áóäåì ëèíèþ ïðîâîäèòü
if((UpDown<1) && (CurrentBar==Lowest(Symbol(),Period(),MODE_LOW,BFF*2+1,CurrentBar-BFF)))
{
if(UpDown==0) { UpDown=-1; B1=CurrentBar; P1=Low[B1]; }
else { B2=CurrentBar; P2=Low[B2];}
}
if((UpDown>-1) && (CurrentBar==Highest(Symbol(),Period(),MODE_HIGH,BFF*2+1,CurrentBar-BFF)))
{
if(UpDown==0) { UpDown=1; B1=CurrentBar; P1=High[B1]; }
else { B2=CurrentBar; P2=High[B2]; }
}
CurrentBar++;
}
if((B1==-1) || (B2==-1)) {DelObj(); return(-1);} // Çíà÷èò íå íàøëè ôðàêòàëîâ ñðåäè 300 áàðîâ 8-)
double B1_=Time[B1], P1_=P1, B2_=Time[B2], P2_=P2;
Step=(P2-P1)/(B2-B1);//Âû÷èñëèëè øàã, åñëè îí ïîëîæèòåëüíûé, òî êàíàë íèñõîäÿùèé
P1=P1-B1*Step; B1=0;//ïåðåñòàâëÿåì öåíó è ïåðâûé áàð ê íóëþ
//À òåïåðü îïîðíóþ òî÷êó ïðîòèâîïîëîæíîé ëèíèè êàíàëà.
ishift=0; iprice=0;
if(UpDown==1)
{
PP=Low[2]-2*Step;
for(i=3;i<=B2;i++)
{
if(Low[i]<PP+Step*i) { PP=Low[i]-i*Step; }
}
if(Low[0]<PP) {ishift=0; iprice=PP;}
if(Low[1]<PP+Step) {ishift=1; iprice=PP+Step;}
if(High[0]>P1) {ishift=0; iprice=P1;}
if(High[1]>P1+Step) {ishift=1; iprice=P1+Step;}
}
else
{
PP=High[2]-2*Step;
for(i=3;i<=B2;i++)
{
if(High[i]>PP+Step*i) { PP=High[i]-i*Step;}
}
if(Low[0]<P1) {ishift=0; iprice=P1;}
if(Low[1]<P1+Step) {ishift=1; iprice=P1+Step;}
if(High[0]>PP) {ishift=0; iprice=PP;}
if(High[1]>PP+Step) {ishift=1; iprice=PP+Step;}
}
//Òåïåðü ïåðåñòàâèì êîíå÷íóþ öåíó è áàð íà ÀÂ, ÷òîáû ëèíèè êàíàëà ðèñîâàëèñü ïîäëèííåå
P2=P1+AB*Step;
T1=Time[B1]; T2=Time[AB];
Com=StringConcatenate("SHI=",NormalizeDouble(MathAbs(P1-PP)/Point,0));
//Åñëè íå áûëî ïåðåñå÷åíèÿ êàíàëà, òî 0, èíà÷å ñòàâèì ïñèñó.
//SetIndexValue(ishift,iprice);
//if(iprice!=0) ExtMapBuffer1[ishift]=iprice;
if((T1-T2)*(P1-P2)*(PP-P1)>0)
{
TL1="TL2";
TL2="TL1";
}
DelObj();
ObjectCreate(TL1,OBJ_TREND,0,T2,PP+Step*AB,T1,PP);
ObjectSet(TL1,OBJPROP_COLOR,ForestGreen);
ObjectSet(TL1,OBJPROP_WIDTH,2);
ObjectSet(TL1,OBJPROP_STYLE,STYLE_SOLID);
ObjectSetText(TL1,Com);
ObjectCreate(TL2,OBJ_TREND,0,T2,P2,T1,P1);
ObjectSet(TL2,OBJPROP_COLOR,ForestGreen);
ObjectSet(TL2,OBJPROP_WIDTH,2);
ObjectSet(TL2,OBJPROP_STYLE,STYLE_SOLID);
ObjectSetText(TL2,Com);
ObjectCreate("MIDL",OBJ_TREND,0,T2,(P2+PP+Step*AB)/2,T1,(P1+PP)/2);
ObjectSet("MIDL",OBJPROP_COLOR,ForestGreen);
ObjectSet("MIDL",OBJPROP_WIDTH,1);
ObjectSet("MIDL",OBJPROP_STYLE,STYLE_DOT);
//ObjectCreate("A1",OBJ_ARROW,0,B1_,P1_);
// ObjectSet("A1",OBJPROP_COLOR,Red);
// ObjectSet("A1",OBJPROP_ARROWCODE,164);
//ObjectCreate("A2",OBJ_ARROW,0,B2_,P2_);
// ObjectSet("A2",OBJPROP_COLOR,Red);
// ObjectSet("A2",OBJPROP_ARROWCODE,164);
//ObjectCreate("A3",OBJ_ARROW,0,T2,P2);
// ObjectSet("A3",OBJPROP_COLOR,Red);
// ObjectSet("A3",OBJPROP_ARROWCODE,164);
//Comment("SHI=",NormalizeDouble(MathAbs(P1-PP)/Point,0));
//Comment("Point=",MathLog(1/Point)/MathLog(10));
//MoveObject("TL1",OBJ_TRENDLINE,B2,PP+Step*AB,B1,PP,ForestGreen,2,STYLE_SOLID);
//MoveObject("TL2",OBJ_TRENDLINE,B2,P2,B1,P1,ForestGreen,2,STYLE_SOLID);
//MoveObject("MIDL",OBJ_TRENDLINE,B2,(P2+PP+Step*AB)/2,B1,(P1+PP)/2,ForestGreen,1,STYLE_DOT);
//----
return(0);
}
//+------------------------------------------------------------------+
//| Calculate optimal lot size |
//+------------------------------------------------------------------+
double LotsOptimized()
{
double lot=Lots;
int orders=HistoryTotal(); // history orders total
int losses=0; // number of losses orders without a break
//---- select lot size
lot=NormalizeDouble(AccountFreeMargin()*MaximumRisk/500,1);
//---- calcuulate number of losses orders without a break
if(DecreaseFactor>0)
{
for(int i=orders-1;i>=0;i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false) { Print("Error in history!"); break; }
if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL) continue;
//----
if(OrderProfit()>0) break;
if(OrderProfit()<0) losses++;
}
if(losses>1) lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1);
}
//---- return lot size
if(lot<1) lot=1;
if(lot>1000) lot=1000;
return(lot);
}
double LaGuerre(double gamma, int shift)
{
double RSI;
double L0[100];
double L1[100];
double L2[100];
double L3[100];
double CU, CD;
for (int i=shift+99; i>=shift; i--)
{
L0[i] = (1.0 - gamma)*Close[i] + gamma*L0[i+1];
L1[i] = -gamma*L0[i] + L0[i+1] + gamma*L1[i+1];
L2[i] = -gamma*L1[i] + L1[i+1] + gamma*L2[i+1];
L3[i] = -gamma*L2[i] + L2[i+1] + gamma*L3[i+1];
CU = 0;
CD = 0;
if (L0[i] >= L1[i]) CU = L0[i] - L1[i];
else CD = L1[i] - L0[i];
if (L1[i] >= L2[i]) CU = CU + L1[i] - L2[i];
else CD = CD + L2[i] - L1[i];
if (L2[i] >= L3[i]) CU = CU + L2[i] - L3[i];
else CD = CD + L3[i] - L2[i];
if (CU + CD != 0) RSI = CU / (CU + CD);
}
return(RSI);
}
//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{
double Laguerre, LaguerrePrev;
double Alpha;
double MA, MAprevious;
double Juice, Tmp;
double TrendGreen, TrendRed;
double ChanUp, ChanMid, ChanDown;
double ChanUpPrev, ChanMidPrev, ChanDownPrev;
int cnt, ticket, total;
bool est_s, est_b, ChanSell, ChanBuy;
channel();
Laguerre=iCustom(NULL, 0, "Laguerre", 0, 0);
LaguerrePrev=iCustom(NULL, 0, "Laguerre", 0, 1);
Alpha=iCCI(NULL, 0, 14, PRICE_MEDIAN, 0);
Juice=iCustom(NULL,0,"Juice",0,0);
TrendGreen=iCustom(NULL,0,"i_Trend",0,0);
TrendRed=iCustom(NULL,0,"i_Trend",1,0);
ChanUp=ObjectGet("TL1",OBJPROP_PRICE2);
ChanMid=ObjectGet("MIDL",OBJPROP_PRICE2);
ChanDown=ObjectGet("TL2",OBJPROP_PRICE2);
ChanUpPrev=ObjectGet("TL1",OBJPROP_PRICE1);
ChanMidPrev=ObjectGet("MIDL",OBJPROP_PRICE2);
ChanDownPrev=ObjectGet("TL2",OBJPROP_PRICE2);
ChanBuy=false;
ChanSell=false;
if(ChanUp<ChanDown)
{ChanUp=ChanUp+ChanDown; ChanDown=ChanUp-ChanDown; ChanUp=ChanUp-ChanDown;}
if(ChanUpPrev<ChanDownPrev)
{ChanUpPrev=ChanUpPrev+ChanDownPrev; ChanDownPrev=ChanUpPrev-ChanDownPrev; ChanUpPrev=ChanUpPrev-ChanDownPrev;}
if(ChanUp>ChanUpPrev && ChanDown>ChanDownPrev) {ChanBuy=true;}
if(ChanUp<ChanUpPrev && ChanDown<ChanDownPrev) {ChanSell=true;}
if(Juice<=0)
{
RTs=true;
RTb=true;
}
total=OrdersTotal();
est_s=true;
est_b=true;
// Print("Laguerre=", Laguerre, " LaguerrePrev=", LaguerrePrev, " TrendRed=", TrendRed, " TrendGreen=", TrendGreen, " Alpha=", Alpha, " Juice=", Juice);
// Print("Up =", ChanUp , " Mid =", ChanMid, " Down =", ChanDown);
// Print("UpPrev=", ChanUpPrev, " MidPrev=", ChanMidPrev, " DownPrev=", ChanDownPrev);
for(cnt=0;cnt<total;cnt++)
{
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
if((OrderType()==OP_SELL) && (OrderSymbol()==Symbol())) est_s=false;
if((OrderType()==OP_BUY) && (OrderSymbol()==Symbol())) est_b=false;
}
// if(total<1)
{
// no opened orders identified
if(AccountFreeMargin()<(1000*Lots))
{
Print("We have no money. Free Margin = ", AccountFreeMargin());
return(0);
}
// check for long position (BUY) possibility
if((TrendGreen>TrendRed) &&
(LaguerrePrev<=DownLagLine) &&
(Laguerre>DownLagLine) &&
est_b && Juice>JuiceLevel && Step>0) //(Alpha<-5) &&
{
ticket=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,Ask-StopLoss*Point,0,"15minsystem",16384,0,Green);
RTb=false;
}
// check for short position (SELL) possibility
if((TrendRed>TrendGreen) &&
(LaguerrePrev>=UpLagLine) &&
(Laguerre<UpLagLine) &&
est_s && Juice>JuiceLevel && Step<0) //(Alpha>5) &&
{
ticket=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,Bid+StopLoss*Point,0,"15minsystem",16384,0,Red);
RTs=false;
}
}
// it is important to enter the market correctly,
// but it is more important to exit it correctly...
for(cnt=0;cnt<total;cnt++)
{
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
if(OrderType()<=OP_SELL && // check for opened position
OrderSymbol()==Symbol()) // check for symbol
{
if(OrderType()==OP_BUY) // long position is opened
{
// should it be closed?
if(Bid>=ChanUp)
{
OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet); // close position
return(0); // exit
}
if(RTb)
{
if(Bid>=ChanMid)
{
OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet); // close position
RTb=false;
return(0); // exit
}
}
}
else // go to short position
{
// should it be closed?
if(Ask<=ChanDown)
{
OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet); // close position
return(0); // exit
}
if(RTs)
{
if(Ask<=ChanMid)
{
OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet); // close position
RTs=false;
return(0); // exit
}
}
}
}
}
return(0);
}
// the end.
Comments