Price Data Components
Orders Execution
Indicators Used
Miscellaneous
0
Views
0
Downloads
0
Favorites
_SHELL[ea]Name_Ron_MT4_v17a
//+--------+
//|Shell_16
//+--------+
#property copyright "Ron Thompson"
#property link "http://www.lightpatch.com/forex"
// This EA is NEVER to be SOLD individually
// This EA is NEVER to be INCLUDED as part of a collection that is SOLD
/*
---Martingale---
If enabled (MartingaleStyle greater than 1) the system will increase lot sizes when there is a loss.
This is an attempt to recover the previous loss, and make money on the current trade.
The failure of Martingale will come when you don't have enough money to support the steps anymore,
and you lose everything, AND MORE, because FOREX trades on MARGIN!!!.
---MartingaleStyle---
Allows you to pick the type of Martingale you are comfortible with.
0 == NO LOSS RECOVERY
1 == pure Martingale
2 == Modified Martingale - starts after 2 losses
3 == Fibonacci - growth by Fibo numbers, requires 2 wins to recover the total loss
4 == Martingale partial, starts after 5 losses
NOTE! The largest lot is controlled by MODE_MAXLOT and will NOT be exceeded
---Starting Balance---
The formula for Lots is AccountBalance() / StartingBalance
Lets say your AccountBalance() is currently 550$
if you want to trade 10.0 lots, put 55 into StartingBalance 550 / 55 = 10
if you want to trade 1.0 lots, put 550 into StartingBalance 550 / 550 = 1
if you want to trade 0.5 lots, put 1100 into StartingBalance 550 / 1100 = 0.5
if you want to trade 0.1 lots, put 5500 into StartingBalance 550 / 5500 = 0.1
if you want to trade 0.01 lots, put 55000 into StartingBalance 550 / 55000 = 0.01
---ProfitMade---
The amount of pips you expect to make on EACH TRADE
---LossLimit---
The amount of pips you can afford to lose on EACH TRADE
---Basket---
In DOLLARS, this will close all trades after so much profit or loss
---BreakEven---
Move the stoploss to break-even once the trade is in profit by 'breakeven' pips
---TrailStop---
Follow price action with a stoploss, keeping the stoploss within 'TrailStop' pips
---Lot Increase---
LotIncreasement grows the lot size based on your starting balance, risking more money
when you have more money. It is built in, based on Starting Balance and LotResolution,
and is independent of the Martingale process.
---LotResolution---
This controls the Lot size of step your broker/account can support
If set to 1, then your lot size is increased in 0.1 steps as your account grows
If set to 2, then your lot size is increased in 0.01 steps as your account grows
IBFX supports LotResolution of 2
*/
// EA SPECIFIC
// user input
extern int MartingaleStyle = 0 ;
extern double StartingBalance = 1000 ;
extern double ProfitMade = 0 ;
extern double BasketProfit = 0 ;
extern double LossLimit = 0 ;
extern double BasketLoss = 0 ;
extern double BreakEven = 0 ;
extern double TrailStop = 0 ;
extern bool LotIncrease = true ;
extern int LotResolution = 1 ;
extern bool KillLogging = true ;
// Trade control
double Lots; // size of trades, calculated in init()
double lotsi; // used for Martingale loss recovery
int Slippage=2; // how many pips of slippage can you tolorate
bool TradeAllowed=true; // used to manage trades
int loopcount; // count of order attempts
int maxloop=25; // maximum number of attempts to handle errors
int LL2SL=10; // LossLimit to StopLoss server spread
int maxOrders; // statistic for maximum numbers or orders open at one time
double maxLots; // Largest lot size ever opened
int MagicNumber = 142537; // allows multiple experts to trade on same account
string TradeComment = "_shell16.txt"; // where to log information
// Bar handling
datetime bartime=0; // used to determine when a bar has moved
int bartick=0; // number of times bars have moved
// Loss Recovery
int lotptr=0; // array pointer for Loss Recovery
int maxptr=9; // maximum Loss Recovery array element
int Step[10]; // how to step the IStep pointer
// used for verbose error logging
#include <stdlib.mqh>
//+-------------+
//| Custom init |
//|-------------+
// Called ONCE when EA is added to chart or recompiled
int init()
{
if(LotResolution<1 || LotResolution>2) LotResolution=1;
Lots=NormalizeDouble(AccountBalance()/StartingBalance,LotResolution);
lotsi=Lots;
logwrite(TradeComment,"LotIncrease ACTIVE Account balance="+AccountBalance()+" Lots="+Lots+" StartingBalance="+StartingBalance);
// NO LOSS RECOVERY
if (MartingaleStyle==0)
{
logwrite(TradeComment,"Loss Recovery Style = 0 - NONE");
Step[0]=1;
Step[1]=1;
Step[2]=1;
Step[3]=1;
Step[4]=1;
Step[5]=1;
Step[6]=1;
Step[7]=1;
Step[8]=1;
Step[9]=1;
}
// Martingale
if (MartingaleStyle==1)
{
logwrite(TradeComment,"Loss Recovery Style = 1 - MART");
Step[0]=1;
Step[1]=2;
Step[2]=4;
Step[3]=8;
Step[4]=16;
Step[5]=32;
Step[6]=64;
Step[7]=128;
Step[8]=256;
Step[9]=512;
}
// Martingale off by 1
if (MartingaleStyle==2)
{
logwrite(TradeComment,"Loss Recovery Style = 1 - MART-MOD");
Step[0]=1;
Step[1]=1;
Step[2]=2;
Step[3]=4;
Step[4]=8;
Step[5]=16;
Step[6]=32;
Step[7]=64;
Step[8]=128;
Step[9]=256;
}
// Fibonacci
if (MartingaleStyle==3)
{
logwrite(TradeComment,"Loss Recovery Style = 3 - FIBO");
Step[0]=1;
Step[1]=1;
Step[2]=2;
Step[3]=3;
Step[4]=5;
Step[5]=8;
Step[6]=13;
Step[7]=21;
Step[8]=34;
Step[9]=55;
}
// Martingale Partial
if (MartingaleStyle==4)
{
logwrite(TradeComment,"Loss Recovery Style = 4 - MART-PART");
Step[0]=1;
Step[1]=1;
Step[2]=1;
Step[3]=1;
Step[4]=2;
Step[5]=4;
Step[6]=8;
Step[7]=16;
Step[8]=32;
Step[9]=64;
}
logwrite(TradeComment,"Init Complete");
Comment(" ");
}
//+----------------+
//| Custom DE-init |
//+----------------+
// Called ONCE when EA is removed from chart
int deinit()
{
// always indicate deinit statistics
logwrite(TradeComment,"MAX number of orders "+maxOrders);
logwrite(TradeComment,"Max Lots is "+maxLots);
logwrite(TradeComment,"DE-Init Complete");
Comment(" ");
}
//+-----------+
//| Main |
//+-----------+
// Called EACH TICK and each Bar[]
int start()
{
int cnt=0;
int gle=0;
int ticket=0;
int OrdersPerSymbol=0;
// stoploss and takeprofit and close control
double SL=0;
double TP=0;
double CurrentProfit=0;
double CurrentBasket=0;
// direction control
bool BUYme=false;
bool SELLme=false;
double MaCurrent;
double MaPrevious;
//safety counter
int loopcount=0;
OrdersPerSymbol=0;
for(cnt=OrdersTotal();cnt>=0;cnt--)
{
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
if( OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber) OrdersPerSymbol++;
}
// keep some statistics
if(OrdersPerSymbol>maxOrders) maxOrders=OrdersPerSymbol;
// Lot increasement based on AccountBalance
if(LotIncrease)
{
Lots=NormalizeDouble(AccountBalance()/StartingBalance,LotResolution);
if( Lots>MarketInfo(Symbol(), MODE_MAXLOT) ) Lots=MarketInfo(Symbol(), MODE_MAXLOT);
}
if(Lots>maxLots) maxLots=Lots;
//uncomment for MULTIPLE trades per bar
//if(OrdersPerSymbol==0) TradeAllowed=true;
// bar counting
if(bartime!=Time[0])
{
bartime=Time[0];
bartick++;
//uncomment for SINGLE trade per bar
if(OrdersPerSymbol==0) TradeAllowed=true;
//+-----------------------------+
//| Code here will execute once |
//| at the OPEN of a NEW BAR |
//+-----------------------------+
MaCurrent= iMA(Symbol(),0,59,0,MODE_LWMA,PRICE_OPEN,0);
MaPrevious=iMA(Symbol(),0,59,0,MODE_LWMA,PRICE_OPEN,1);
// MA is rising
if(MaPrevious<MaCurrent) BUYme=true;
// MA is falling
if(MaPrevious<MaCurrent) SELLme=true;
//+------------+
//| End Insert |
//+------------+
}
//+-----------------------------+
//| Insert your indicator here |
//| And set either BUYme or |
//| SELLme true to place orders |
//+-----------------------------+
//+------------+
//| End Insert |
//+------------+
//ENTRY LONG (buy, Ask)
if( TradeAllowed && BUYme)
{
OpenBuy();
}
//ENTRY SHORT (sell, Bid)
if( TradeAllowed && SELLme)
{
OpenSell();
}
//
// Order Management
//
// Basket profit or loss - count the profit/loss
// from this EA & Symbol()& magicnumber only
// calculation can be done in PIPS or DOLLARS
CurrentBasket=0;
for(cnt=OrdersTotal();cnt>=0;cnt--)
{
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
if( OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
{
// add up pips
//if(OrderType()==OP_BUY ) CurrentBasket=CurrentBasket+( Close[0]-OrderOpenPrice() );
//if(OrderType()==OP_SELL ) CurrentBasket=CurrentBasket+( (Close[0]-OrderOpenPrice()) * (-1) );
//add up dollars
if(OrderType()==OP_BUY ) CurrentBasket=CurrentBasket+( OrderProfit() );
if(OrderType()==OP_SELL ) CurrentBasket=CurrentBasket+( OrderProfit() );
}
}
if( BasketProfit>0 && CurrentBasket>=BasketProfit ) CloseEverything();
if( BasketLoss >0 && CurrentBasket<=BasketLoss*(-1) ) CloseEverything();
for(cnt=OrdersTotal();cnt>=0;cnt--)
{
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
if( OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber )
{
if(OrderType()==OP_BUY)
{
CurrentProfit=(Bid-OrderOpenPrice()) ;
//
// Modify for break even
//=======================
//
// OrderStopLoss will be equal to OrderOpenPrice if this event happens
// thus it will only ever get executed one time per ticket
if( BreakEven>0 )
{
if (CurrentProfit >= BreakEven*Point && OrderOpenPrice()>OrderStopLoss())
{
SL=OrderOpenPrice()+(Ask-Bid);
TP=OrderTakeProfit();
OrderModify(OrderTicket(),OrderOpenPrice(),SL,TP, White);
gle=GetLastError();
if(gle==0)
{
logwrite(TradeComment,"MODIFY BUY BE Ticket="+OrderTicket()+" SL="+SL+" TP="+TP);
}
else
{
logwrite(TradeComment,"-----ERROR----- MODIFY BUY BE Bid="+Bid+" error="+gle+" "+ErrorDescription(gle));
}
}
}
//
// check for trailing stop
//=========================
//
// This starts trailing after 'TrailStop' pips of profit
if( TrailStop>0 && Close[0]>OrderOpenPrice()+(TrailStop*Point) )
{
if( OrderStopLoss() < Bid-(TrailStop*Point) )
{
SL=Bid-(TrailStop*Point);
TP=OrderTakeProfit();
OrderModify(OrderTicket(),OrderOpenPrice(),SL,TP,0,White);
gle=GetLastError();
if(gle==0)
{
logwrite(TradeComment,"MODIFY BUY TS Ticket="+OrderTicket()+" SL="+SL+" TP="+TP);
}
else
{
logwrite(TradeComment,"-----ERROR----- MODIFY BUY TS Bid="+Bid+" error="+gle+" "+ErrorDescription(gle)+" ");
}
}
}
// Did we make a profit
//======================
if(ProfitMade>0 && CurrentProfit>=(ProfitMade*Point))
{
CloseBuy("PROFIT");
lotsi=Lots;
lotptr=0;
}
// Did we take a loss
//====================
if(LossLimit>0 && CurrentProfit<=(LossLimit*(-1)*Point))
{
CloseBuy("LOSS");
lotptr++;
if(lotptr>maxptr) lotptr=0;
if(MartingaleStyle>0)
{
lotsi=NormalizeDouble(Lots*Step[lotptr],LotResolution);
logwrite(TradeComment,"BUY lotptr="+lotptr+" Step="+Step[lotptr]);
}
}
} // if BUY
if(OrderType()==OP_SELL)
{
CurrentProfit=(OrderOpenPrice()-Ask);
//logwrite(TradeComment,"SELL CurrentProfit="+CurrentProfit/Point+" CurrentBasket="+CurrentBasket/Point);
//
// Modify for break even
//=======================
//
// OrderStopLoss will be equal to OrderOpenPrice if this event happens
// thus it will only ever get executed one time per ticket
if( BreakEven>0 )
{
if (CurrentProfit >= BreakEven*Point && OrderOpenPrice()<OrderStopLoss())
{
SL=OrderOpenPrice()-(Ask-Bid);
TP=OrderTakeProfit();
OrderModify(OrderTicket(),OrderOpenPrice(),SL,TP, Red);
gle=GetLastError();
if(gle==0)
{
logwrite(TradeComment,"MODIFY SELL BE Ticket="+OrderTicket()+" SL="+SL+" TP="+TP);
}
else
{
logwrite(TradeComment,"-----ERROR----- MODIFY SELL BE Ask="+Ask+" error="+gle+" "+ErrorDescription(gle));
}
}
}
//
// check for trailing stop
//=========================
//
// This starts trailing after 'TrailStop' pips of profit
if( TrailStop>0 && Close[0]<OrderOpenPrice()-(TrailStop*Point) )
{
if( OrderStopLoss() > Ask+(TrailStop*Point) )
{
SL=Ask+(TrailStop*Point);
TP=OrderTakeProfit();
OrderModify(OrderTicket(),OrderOpenPrice(),SL,TP,0,Red);
gle=GetLastError();
if(gle==0)
{
logwrite(TradeComment,"MODIFY SELL TS Ticket="+OrderTicket()+" SL="+SL+" TP="+TP);
}
else
{
logwrite(TradeComment,"-----ERROR----- MODIFY SELL TS Ask="+Ask+" error="+gle+" "+ErrorDescription(gle));
}
}
}
// Did we make a profit
//======================
if( ProfitMade>0 && CurrentProfit>=(ProfitMade*Point) )
{
CloseSell("PROFIT");
lotsi=Lots;
lotptr=0;
}
// Did we take a loss
//====================
if( LossLimit>0 && CurrentProfit<=(LossLimit*(-1)*Point) )
{
CloseSell("LOSS");
lotptr++;
if(lotptr>maxptr) lotptr=0;
if(MartingaleStyle>0)
{
lotsi=NormalizeDouble(Lots*Step[lotptr],LotResolution);
logwrite(TradeComment,"SELL lotptr="+lotptr+" Step="+Step[lotptr]);
}
}
} //if SELL
} // if(OrderSymbol)
} // for
} // start()
//+-----------------+
//| CloseEverything |
//+-----------------+
// Closes all OPEN and PENDING orders
int CloseEverything()
{
int i;
for(i=OrdersTotal();i>=0;i--)
{
OrderSelect(i, SELECT_BY_POS);
if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
{
if(OrderType()==OP_BUY) CloseBuy ("BASKET");
if(OrderType()==OP_SELL) CloseSell("BASKET");
if(OrderType()==OP_BUYLIMIT) OrderDelete( OrderTicket() );
if(OrderType()==OP_SELLLIMIT) OrderDelete( OrderTicket() );
if(OrderType()==OP_BUYSTOP) OrderDelete( OrderTicket() );
if(OrderType()==OP_SELLSTOP) OrderDelete( OrderTicket() );
}
Sleep(1000);
} //for
} // closeeverything
// log data to a file name passed in
// print everything regardless of log setting
void logwrite (string filename, string mydata)
{
int myhandle;
string gregorian=TimeToStr(CurTime(),TIME_DATE|TIME_SECONDS);
Print(mydata+" "+gregorian);
// don't log anything if testing or if user doesn't want it
if(IsTesting()) return(0);
if(KillLogging) return(0);
myhandle=FileOpen(Symbol()+"_"+filename, FILE_CSV|FILE_WRITE|FILE_READ, ";");
if(myhandle>0)
{
FileSeek(myhandle,0,SEEK_END);
FileWrite(myhandle, mydata+" "+gregorian);
FileClose(myhandle);
}
}
//ENTRY LONG (buy, Ask)
void OpenBuy()
{
int gle=0;
int ticket=0;
double SL=0;
double TP=0;
int loopcount;
// PLACE order is independent of MODIFY order.
// This is mandatory for ECNs and acceptable for retail brokers
loopcount=0;
while(true)
{
// place order - NO TP OR SL
ticket=OrderSend(Symbol(),OP_BUY,lotsi,Ask,Slippage,0,0,TradeComment,MagicNumber,White);
gle=GetLastError();
if(gle==0)
{
logwrite(TradeComment,"BUY PLACED Ticket="+ticket+" Ask="+Ask+" Lots="+lotsi);
TradeAllowed=false;
break;
}
else
{
logwrite(TradeComment,"-----ERROR----- Placing BUY order: Lots="+lotsi+" Bid="+Bid+" Ask="+Ask+" ticket="+ticket+" Err="+gle+" "+ErrorDescription(gle));
RefreshRates();
Sleep(500);
// give up after loopcount tries
loopcount++;
if(loopcount>maxloop)
{
logwrite(TradeComment,"-----ERROR----- Giving up on placing BUY order");
return(gle);
}
}
}//while - place order
// modify the order for users TP & SL
loopcount=0;
while(true)
{
if(LossLimit ==0) SL=0; else SL=Ask-((LossLimit+LL2SL)*Point );
if(ProfitMade==0) TP=0; else TP=Ask+((ProfitMade+LL2SL)*Point );
OrderModify(ticket,OrderOpenPrice(),SL,TP,0,White);
gle=GetLastError();
if(gle==0)
{
logwrite(TradeComment,"BUY MODIFIED Ticket="+ticket+" Ask="+Ask+" Lots="+lotsi+" SL="+SL+" TP="+TP);
break;
}
else
{
logwrite(TradeComment,"-----ERROR----- Modifying BUY order: Lots="+lotsi+" SL="+SL+" TP="+TP+" Bid="+Bid+" Ask="+Ask+" ticket="+ticket+" Err="+gle+" "+ErrorDescription(gle));
RefreshRates();
Sleep(500);
loopcount++;
if(loopcount>maxloop)
{
logwrite(TradeComment,"-----ERROR----- Giving up on modifying BUY order");
return(gle);
}
}
}//while - modify order
}//BUYme
//ENTRY SHORT (sell, Bid)
void OpenSell()
{
int gle=0;
int ticket=0;
double SL=0;
double TP=0;
int loopcount;
// PLACE order is independent of MODIFY order.
// This is mandatory for ECNs and acceptable for retail brokers
loopcount=0;
while(true)
{
ticket=OrderSend(Symbol(),OP_SELL,lotsi,Bid,Slippage,0,0,TradeComment,MagicNumber,Red);
gle=GetLastError();
if(gle==0)
{
logwrite(TradeComment,"SELL PLACED Ticket="+ticket+" Bid="+Bid+" Lots="+lotsi);
TradeAllowed=false;
break;
}
else
{
logwrite(TradeComment,"-----ERROR----- placing SELL order: Lots="+lotsi+" SL="+SL+" TP="+TP+" Bid="+Bid+" Ask="+Ask+" ticket="+ticket+" Err="+gle+" "+ErrorDescription(gle));
RefreshRates();
Sleep(500);
loopcount++;
if(loopcount>maxloop)
{
logwrite(TradeComment,"-----ERROR----- Giving up on placing SELL order");
return(gle);
}
}
}//while
// modify the order for users TP & SL
loopcount=0;
while(true)
{
if(LossLimit ==0) SL=0; else SL=Bid+((LossLimit+LL2SL)*Point );
if(ProfitMade==0) TP=0; else TP=Bid-((ProfitMade+LL2SL)*Point );
OrderModify(ticket,OrderOpenPrice(),SL,TP,0,Red);
gle=GetLastError();
if(gle==0)
{
logwrite(TradeComment,"SELL MODIFIED Ticket="+ticket+" Bid="+Bid+" Lots="+lotsi+" SL="+SL+" TP="+TP);
TradeAllowed=false;
break;
}
else
{
logwrite(TradeComment,"-----ERROR----- modifying SELL order: Lots="+lotsi+" SL="+SL+" TP="+TP+" Bid="+Bid+" Ask="+Ask+" ticket="+ticket+" Err="+gle+" "+ErrorDescription(gle));
RefreshRates();
Sleep(500);
loopcount++;
if(loopcount>maxloop)
{
logwrite(TradeComment,"-----ERROR----- Giving up on placing SELL order");
return(gle);
}
}
}//while
}//SELLme
void CloseBuy (string myInfo)
{
int gle;
int cnt;
int OrdersPerSymbol;
int loopcount=0;
string bTK=" Ticket="+OrderTicket();
string bSL=" SL="+OrderStopLoss();
string bTP=" TP="+OrderTakeProfit();
string bPM;
string bLL;
string bER;
bPM=" PM="+ProfitMade;
bLL=" LL="+LossLimit;
while(true)
{
OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,White);
gle=GetLastError();
bER=" error="+gle+" "+ErrorDescription(gle);
if(gle==0)
{
logwrite(TradeComment,"CLOSE BUY "+myInfo+ bTK + bSL + bTP + bPM + bLL);
break;
}
else
{
logwrite(TradeComment,"-----ERROR----- CLOSE BUY "+myInfo+ bER +" Bid="+Bid+ bTK + bSL + bTP + bPM + bLL);
RefreshRates();
Sleep(500);
}
loopcount++;
if(loopcount>maxloop)
{
logwrite(TradeComment,"-----ERROR----- Giving up on closing SELL order");
return(gle);
}
}//while
}
void CloseSell (string myInfo)
{
int gle;
int cnt;
int OrdersPerSymbol;
int loopcount=0;
string sTK=" Ticket="+OrderTicket();
string sSL=" SL="+OrderStopLoss();
string sTP=" TP="+OrderTakeProfit();
string sPM;
string sLL;
string sER;
sPM=" PM="+ProfitMade;
sLL=" LL="+LossLimit;
while(true)
{
OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,Red);
gle=GetLastError();
sER=" error="+gle+" "+ErrorDescription(gle);
if(gle==0)
{
logwrite(TradeComment,"CLOSE SELL "+myInfo + sTK + sSL + sTP + sPM + sLL);
break;
}
else
{
logwrite(TradeComment,"-----ERROR----- CLOSE SELL "+myInfo+ sER +" Ask="+Ask+ sTK + sSL + sTP + sPM + sLL);
RefreshRates();
Sleep(500);
}
loopcount++;
if(loopcount>maxloop)
{
logwrite(TradeComment,"-----ERROR----- Giving up on closing SELL order");
return(gle);
}
}//while
}
Comments
Markdown Formatting Guide
# H1
## H2
### H3
**bold text**
*italicized text*
[title](https://www.example.com)

`code`
```
code block
```
> blockquote
- Item 1
- Item 2
1. First item
2. Second item
---