Hello All,
I am in hopes some expert coders can help me along in my quest to build my latest monster.
A big thanks to Kenny Hubbard who helped me with a lot of the programming.
This EA is a combination of several great EA's that I have done well trading with over the last few weeks. NanninBob's 60x90, Snowball EA, and a RENKO trading concept that I have been wanting to put together for some time.
Here is how it works:
1. Grid Trader, opens orders every X distance if trade continues in direction and has opposite direction trade following by X times 2. (e.g. if price goes long, it has a buy stop waiting at let's say 15 pips, then it will open another buy stop at 15 pips, and have a trailing sell stop at 30 pips below that.)
2. Trade is followed by dynamic trailing stop based on % of gain. (e.g. if price moves 10 pips, trailing stop starts, and trails 20% of total price gain which would be 2 pips in this instance, if it moves 40 pips, then trailing stop is 8 pips above/below break-even)
3. No trades by default will be closed out with stop loss and they will be left as Stragglers to be martingale out within so many pips. (e.g. If price goes 200 pips in direction against Straggler trade, then it enters again in same direction of Straggler @ a multiplier to recover that trade.
Pairs I believe that will be best suited:
AUDCAD
AUDNZD
EURGBP
GBPUSD
USDJPY
However, I believe dependent upon optimization that any pair will work.
I am almost through the coding of most functionality, but would like some assistance with the following items:
1. If current buy/sell stop price is within the Grid Distance, do not enter new trade. This saves you from having 4 orders within 2 pips of each other due to an area of high resistance/support. I have coded most of this, but it is not working properly. PLEASE HELP.
2. Stop loss function to enable a jumping stop (RENKO STYLE trading) for added functionality. This is a secondary concept that is different than doing the Straggler trades. This would enter a new order ever grid distance and place a trailing stop X% pips below with a jumping stop of the grid distance. This would be for trending currencies while the original concept with the EA is strictly for ranging currencies.
3. Bug testing, backtesting and overall optimization of EA.
THIS EA IS NOT WORKING AS PLANNED AS IT IS STILL ENTERING MULTIPLE ORDERS WITHIN THE GRID DISTANCE WHICH SKEWS THE RESULTS, SO PLEASE DON'T EVALUATE IT OFF OF A BACKTEST OR WHATEVER YET! WITH THE ITEM #1 COMPLETED, THEN IT IS READY FOR PRIMETIME AND SHOULD WORK (MINUS THE BUGS).
PLEASE HELP!
I am in hopes some expert coders can help me along in my quest to build my latest monster.
A big thanks to Kenny Hubbard who helped me with a lot of the programming.
This EA is a combination of several great EA's that I have done well trading with over the last few weeks. NanninBob's 60x90, Snowball EA, and a RENKO trading concept that I have been wanting to put together for some time.
Here is how it works:
1. Grid Trader, opens orders every X distance if trade continues in direction and has opposite direction trade following by X times 2. (e.g. if price goes long, it has a buy stop waiting at let's say 15 pips, then it will open another buy stop at 15 pips, and have a trailing sell stop at 30 pips below that.)
2. Trade is followed by dynamic trailing stop based on % of gain. (e.g. if price moves 10 pips, trailing stop starts, and trails 20% of total price gain which would be 2 pips in this instance, if it moves 40 pips, then trailing stop is 8 pips above/below break-even)
3. No trades by default will be closed out with stop loss and they will be left as Stragglers to be martingale out within so many pips. (e.g. If price goes 200 pips in direction against Straggler trade, then it enters again in same direction of Straggler @ a multiplier to recover that trade.
Pairs I believe that will be best suited:
AUDCAD
AUDNZD
EURGBP
GBPUSD
USDJPY
However, I believe dependent upon optimization that any pair will work.
I am almost through the coding of most functionality, but would like some assistance with the following items:
1. If current buy/sell stop price is within the Grid Distance, do not enter new trade. This saves you from having 4 orders within 2 pips of each other due to an area of high resistance/support. I have coded most of this, but it is not working properly. PLEASE HELP.
2. Stop loss function to enable a jumping stop (RENKO STYLE trading) for added functionality. This is a secondary concept that is different than doing the Straggler trades. This would enter a new order ever grid distance and place a trailing stop X% pips below with a jumping stop of the grid distance. This would be for trending currencies while the original concept with the EA is strictly for ranging currencies.
3. Bug testing, backtesting and overall optimization of EA.
THIS EA IS NOT WORKING AS PLANNED AS IT IS STILL ENTERING MULTIPLE ORDERS WITHIN THE GRID DISTANCE WHICH SKEWS THE RESULTS, SO PLEASE DON'T EVALUATE IT OFF OF A BACKTEST OR WHATEVER YET! WITH THE ITEM #1 COMPLETED, THEN IT IS READY FOR PRIMETIME AND SHOULD WORK (MINUS THE BUGS).
PLEASE HELP!
Inserted Code
//+------------------------------------------------------------------+
//| REAV_EA.mq4 |
//| Copyright © 2010, Kenny Hubbard |
//| http://www.compu-forex.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2010, Kenny Hubbard"
#property link "http://www.compu-forex.com"
#define NO_RESULT -10
extern int MagicNumber = 100;
extern double Eq_StopLoss = 10000;
extern double Risk = 1; //% of account to risk per 10K account size
extern double Trail_From = 8;
extern double Trail_Max = 50.0;
extern double Trail_Percent = 20;
extern double Grid_Size = 13;
extern double MinimumReEntry = 200;
extern double Multiplier = 1.5; //Martingale multiplier
extern double MinimumProfit = 1; //Minimum profit from martingale recovery
extern int StopLoss = 0; //Stop loss on entries if greater than 0 and if you want to use jumping stop placement of new entries
int
D_Factor = 1,
LotDigits = 1,
Slippage = 3,
Retries = 10;
double
Anchor,
Pip,
Grid_Min = 0,
Grid_Max = 0,
Grid_Ord_OpenPrice[][2], //Creating 2 dimensional array, 0,1 & 0,2 positions to hold the pending short and pending long
Auto_Grid,
NewMultiplierTakeProfit = 0,
NewLotSize = 0;
string
Order_Cmt = "LBM_V1";
//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int init()
{
Pip = Point;
//----
if (Digits == 3|| Digits == 5){D_Factor = 10; Pip *= 10;}
Grid_Size *= Pip;
if (MarketInfo(Symbol(),MODE_LOTSTEP) == 0.01)LotDigits = 2;
Auto_Grid = Grid_Size;
if(MinimumProfit == 0){MinimumProfit = 1;}
MinimumReEntry *= Pip;
MinimumProfit *= Pip;
//----
return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{
int
result = NO_RESULT;
//----
if (!OrdersTotal()){
Print("Making an initial trade");
OrderSend(Symbol(), 4, Get_Lots(Risk), NormalizeDouble(Ask+Auto_Grid,Digits), Slippage, 0 ,0 ,Order_Cmt, MagicNumber, 0, Blue);
OrderSend(Symbol(), 5, Get_Lots(Risk), NormalizeDouble(Bid-Auto_Grid,Digits), Slippage, 0 ,0 ,Order_Cmt, MagicNumber, 0, Blue);
}
Update_Grid(Grid_Min, Grid_Max); //Updating Grid
result = Check_For_Trade(Grid_Min, Grid_Max); //Checking for existing trade
if(result!=NO_RESULT) {Do_Trade(result);} //
Trail_Stop();
Martingale();
double BuyLevel = (Bid - (MinimumReEntry * Pip));
double SellLevel = (Ask + (MinimumReEntry * Pip));
Comment("Buy Level: ", (BuyLevel), "\n",
"Sell Level: ", (SellLevel), "\n",
"Bid :", Bid, "\n",
"Ask :", Ask, "\n",
"Minium Reentry: ", MinimumReEntry, "\n");
//----
return(0);
}
//+------------------------------------------------------------------+
void Martingale() //Function to remove existing straggler orders
{
double CurrentLotSize;
for(int xo = OrdersTotal()-1; xo >=0; xo--)
{
if(OrderSelect(xo,SELECT_BY_POS))
{
RefreshRates();
CurrentLotSize = OrderLots();
if(OrderType() == 0)
{
if(OrderOpenPrice() >= (Bid + (MinimumReEntry)))
{
NewLotSize = Multiplier * CurrentLotSize;
NewMultiplierTakeProfit = Ask + CalculatePreviousLosses(CurrentLotSize,NewLotSize)+MinimumProfit;//Calculate new take profit
if(OrderClose(OrderTicket(),OrderLots(),Ask,99,Red))
{
OrderSend(Symbol(), 0, NormalizeDouble(NewLotSize,LotDigits), Ask, Slippage, 0 , NormalizeDouble(NewMultiplierTakeProfit,Digits) , "Multiplied Order", MagicNumber + 1, 0, Blue);
}
}
}
if(OrderType() == 1)
{
if(OrderOpenPrice() <= (Ask - (MinimumReEntry)))
{
NewLotSize = Multiplier * CurrentLotSize;
NewMultiplierTakeProfit = Bid - CalculatePreviousLosses(CurrentLotSize,NewLotSize)-MinimumProfit;//Calculate new take profit
if(OrderClose(OrderTicket(),OrderLots(),Ask,99,Red))
{
OrderSend(Symbol(), 1, NormalizeDouble(NewLotSize,LotDigits), Bid, Slippage, 0 , NormalizeDouble(NewMultiplierTakeProfit,Digits), "Multiplied Order", MagicNumber + 1, 0, Blue);
}
}
}
}
}
}
//+------------------------------------------------------------------+
double CalculatePreviousLosses(double CurrentLotSize, double FutureLotSize)
{
double TotalNumberOfPipsLost;
double StartingLotSize = Get_Lots(Risk);
while(CurrentLotSize >= StartingLotSize)
{
TotalNumberOfPipsLost = TotalNumberOfPipsLost + ((CurrentLotSize * MinimumReEntry));
CurrentLotSize /= Multiplier; //Counting down
}
TotalNumberOfPipsLost = TotalNumberOfPipsLost / FutureLotSize;
return(TotalNumberOfPipsLost);
}
//+------------------------------------------------------------------+
void Update_Grid(double& Min, double& Max)
{
int
Order_Cnt=0,
Grid_Num = 0;
for(int i=0;i<OrdersTotal();i++){ //Looping through all orders
if(OrderSelect(i,SELECT_BY_POS)){
if(OrderType()>3)Order_Cnt++; //Counting all Orders that are not currently opened
}
else Print("Error Selecting Order = " + GetLastError());
}
ArrayResize(Grid_Ord_OpenPrice,Order_Cnt); //Set the number of rows in the array (Grid_Ord_OpenPrice 2nd dimension) equal to the current # of pending orders (should be 2)
ArrayInitialize(Grid_Ord_OpenPrice,0.0); //Zero'ing out Array to 0.0, if previous orders were added
for(i=0;i<OrdersTotal();i++)
{
if(OrderSelect(i,SELECT_BY_POS))
{
if(OrderType()>3)
{
Grid_Ord_OpenPrice[Grid_Num][0] = OrderOpenPrice();
Grid_Num++;
}
}
else Print("Error Selecting Order = " + GetLastError());
}
ArraySort(Grid_Ord_OpenPrice);
Min = Grid_Ord_OpenPrice[0][0];
Max = Grid_Ord_OpenPrice[Order_Cnt-1][0];
}
//+------------------------------------------------------------------+
int Check_For_Trade(double Min, double Max)
{
int Buy_or_Sell;
if(Ask >= Max + Auto_Grid)
{
Buy_or_Sell = 4;
if(Min_Distance(Buy_or_Sell) == false)
{
return(NO_RESULT);
}
return(OP_BUYSTOP);
}
if(Bid <= Min - Auto_Grid)
{
Buy_or_Sell = 5;
if(Min_Distance(Buy_or_Sell) == false)
{
return(NO_RESULT);
}
return(OP_SELLSTOP);
}
return(NO_RESULT);
}
//+------------------------------------------------------------------+
bool Min_Distance(int Buy_or_Sell)
{
for(int ex = 0; ex < OrdersTotal(); ex++)
{
if(OrderSelect(ex,SELECT_BY_POS))
{
RefreshRates();
if(OrderType() == 4)
{
if(OrderOpenPrice() - Ask <= Auto_Grid)
{
return(false);
}
}
if(OrderType() == 5)
{
if(Bid - OrderOpenPrice() <= Auto_Grid)
{
return(false);
}
}
}
}
return(true);
}
//+------------------------------------------------------------------+
void Do_Trade(int Buy_or_Sell)
{
switch(Buy_or_Sell){
case OP_BUYSTOP: int ticket = OrderSend(Symbol(),OP_BUYSTOP,NormalizeDouble(Get_Lots(Risk),LotDigits),NormalizeDouble(Ask + Auto_Grid,Digits), Slippage,0,0,Order_Cmt,MagicNumber,0,Green);
Delete_Opposite_Trade(5);
ticket = OrderSend(Symbol(),OP_SELLSTOP,NormalizeDouble(Get_Lots(Risk),LotDigits),NormalizeDouble(Bid - 2 * Auto_Grid,Digits), Slippage,0,0,Order_Cmt,MagicNumber,0,Red);
break;
case OP_SELLSTOP: ticket = OrderSend(Symbol(),OP_SELLSTOP,NormalizeDouble(Get_Lots(Risk),LotDigits),NormalizeDouble(Bid - Auto_Grid,Digits), Slippage,0,0,Order_Cmt,MagicNumber,0,Red);
Delete_Opposite_Trade(4);
ticket = OrderSend(Symbol(),OP_BUYSTOP,NormalizeDouble(Get_Lots(Risk),LotDigits),NormalizeDouble(Ask + 2 * Auto_Grid,Digits), Slippage,0,0,Order_Cmt,MagicNumber,0,Green);
break;
default : Alert("Unknown ordertype returned");
break;
}
return;
}
//+------------------------------------------------------------------+
void Delete_Opposite_Trade(int Del_B_S)
{
for(int i=0;i<OrdersTotal();i++){
OrderSelect(i,SELECT_BY_POS);
if(OrderMagicNumber() == MagicNumber){
if(OrderType() == Del_B_S)OrderDelete(OrderTicket());
}
}
}
//+------------------------------------------------------------------+
double Get_Lots(double lRisk)
{
double
Lots = AccountEquity() * lRisk/10000/100;
if (MarketInfo(Symbol(),MODE_MINLOT) > Lots)Lots = MarketInfo(Symbol(),MODE_MINLOT);
if (MarketInfo(Symbol(),MODE_MAXLOT) < Lots)Lots = MarketInfo(Symbol(),MODE_MAXLOT);
return(Lots);
}
//+------------------------------------------------------------------+
bool Trail_Stop()
{
bool
mod,
lresult = false;
double
My_Profit,
My_Trail,
My_SL,
lTrail_Max,
lTrail_From,
Stop_Level;
//----
for (int i = 0; i < OrdersTotal(); i++){
if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if(OrderMagicNumber() == MagicNumber)
{
RefreshRates();
//******************************++++++++++++++++++++++++++++HARDCODED FOR NOW UNTIL BETTER SOLUTION, TO .01 LOTS, FOR UNDER 10K ACCOUNT IT WORKS!*************************
if(OrderComment() == "LBM_V1")
{
lTrail_Max = Trail_Max * Pip;
lTrail_From = Trail_From * Pip;
Stop_Level = MarketInfo(OrderSymbol(),MODE_STOPLEVEL)*Pip;
switch(OrderType()){
case OP_BUY : My_Profit = Bid - OrderOpenPrice();
My_Trail = MathMin(My_Profit * Trail_Percent/100,lTrail_Max);
My_SL = NormalizeDouble(OrderClosePrice()-My_Trail,Digits);
lresult = true;
if(My_Profit > lTrail_From){
if(OrderClosePrice() - My_SL > Stop_Level){
if(OrderStopLoss() < My_SL||OrderStopLoss() == 0)mod = OrderModify(OrderTicket(),OrderOpenPrice(),My_SL,OrderTakeProfit(),0, CLR_NONE);
}
}
break;
case OP_SELL : My_Profit = OrderOpenPrice() - Ask;
My_Trail = MathMin(My_Profit * Trail_Percent/100,lTrail_Max);
My_SL = NormalizeDouble(Ask+My_Trail,Digits);
lresult = true;
if(My_Profit > lTrail_From){
if(My_SL - OrderClosePrice() > Stop_Level){
if(My_SL < OrderStopLoss()||OrderStopLoss() == 0)mod = OrderModify(OrderTicket(),OrderOpenPrice(),My_SL,OrderTakeProfit(),0,CLR_NONE);
}
}
break;
}
if(!mod && GetLastError() > 1)Print("Error entering Trailing Stop - Error " + GetLastError());
}
}
}
else Print("Error selecting order");
}
//----
return(lresult);
}
We are our own best indicator.