[ea]BollTrade_Ron_MT4_v03c1

Author: Ron Thompson
Price Data Components
Series array that contains open time of each bar
Orders Execution
Checks for the total of open ordersIt automatically opens orders when conditions are reachedIt Closes Orders by itself
Indicators Used
Moving average indicatorStandard Deviation indicator
Miscellaneous
Uses files from the file systemIt writes information to file
2 Views
0 Downloads
0 Favorites

Profitability Reports

AUD/USD Oct 2024 - Jan 2025
30.00 %
Total Trades 3694
Won Trades 0
Lost trades 0
Win Rate 0.00 %
Expected payoff -2.68
Gross Profit 4178.45
Gross Loss -14069.09
Total Net Profit -9890.64
-100%
-50%
0%
50%
100%
GBP/CAD Oct 2024 - Jan 2025
0.00 %
Total Trades 0
Won Trades 0
Lost trades 0
Win Rate 0.0 %
Expected payoff 0.00
Gross Profit 0.00
Gross Loss 0.00
Total Net Profit 0.00
-100%
-50%
0%
50%
100%
GBP/USD Oct 2024 - Jan 2025
0.00 %
Total Trades 1398
Won Trades 0
Lost trades 1398
Win Rate 0.00 %
Expected payoff -7.12
Gross Profit 0.00
Gross Loss -9950.04
Total Net Profit -9950.04
-100%
-50%
0%
50%
100%
[ea]BollTrade_Ron_MT4_v03c1
//+------+
//|BollTrade
//+------+
#property copyright "Ron Thompson"
#property link      "http://www.lightpatch.com/forex"

//3c1 - updated logwrite to latest version with dates - no change
//3c1 - changed iBands to MA plus/minus Deviation     - no change
//3c1 - removed all equity statistics                 - no change
//3c1 - lot increase always active (uses MAX_LOT)     - no change
//3c1 - removed CurrentBasket                         - no change
//3c1 - removed OpenOrdersBUY & SELL  tracking        - no change
//3c1 - added Margin requirement                      - no change
//3c1 - corrected all the order open code             - no change
//3c1 - added CloseBuy & Sell to correct errors       - no change
//3c1 - removed OneOrderOnly                          - no change

// At this point, this is as pure and error-free version of BollTrader
// that you can have. The next step will be to integrate everything
// from the news avoidance system.  On to v03c2



// user input
extern double StartingBalance= 10000;    // lot size control during LotIncrease
extern double MinFreeMarginPct=   25.0;  // margin available before trading
extern double ProfitMade   =       8;    // how much money do you expect to make
extern double LossLimit    =      35;    // how much loss can you tolorate
extern double BDistance    =      14;    // plus how much
extern int    BPeriod      =      15;    // Bollinger period
extern int    Deviation    =       2.0;  // Bollinger deviation

// non-external flag settings
int    Slippage=2;                       // how many pips of slippage can you tolorate
bool   KillLogging=false;                // turn off all logging
bool   logging=true;                     // log data or not
bool   logerrs=true;                     // log errors or not
bool   logtick=false;                    // log tick data while orders open (or not)

// naming and numbering
int    MagicNumber  = 200607121116;      // allows multiple experts to trade on same account
string TradeComment = "_bolltrade_v03c1.txt";

// Bar handling
datetime bartime=0;                      // used to determine when a bar has moved
int      bartick=0;                      // number of times bars have moved

// Trade control & statistics
double Lots;                             // size of trades
double LotResolution=2;                  // lot increase increment 1=0.1 2=0.01
bool   TradeAllowed=true;                // used to manage trades
int    maxOrders;                        // statistic for maximum numbers or orders open at one time
int    L2L=10;                           // real to server difference for order masking

// order loop control and limit
int loopcount;
int maxloop=25;

// used for verbose error logging
#include <stdlib.mqh>


//+-------------+
//| Custom init |
//|-------------+
// Called ONCE when EA is added to chart or recompiled

int init()
  {
   Lots=AccountBalance()/StartingBalance;
   logwrite(TradeComment,"LotIncrease ACTIVE Account balance="+AccountBalance()+" Lots="+Lots+" StartingBalance="+StartingBalance);

   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,"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;
   
   // direction control
   bool BUYme=false;
   bool SELLme=false;
      

   // bar counting
   if(bartime!=Time[0]) 
     {
      bartime=Time[0];
      bartick++; 
     }

   // Lot increasement based on AccountBalance when expert is started
   // this will trade 1.0, then 1.1, then 1.2 etc as account balance grows
   // or 0.9 then 0.8 then 0.7 as account balance shrinks 
   Lots=NormalizeDouble(AccountBalance()/StartingBalance,LotResolution);
   if( Lots>MarketInfo(Symbol(),MODE_MAXLOT) ) Lots=MarketInfo(Symbol(),MODE_MAXLOT);
   
   OrdersPerSymbol=0;
   for(cnt=OrdersTotal();cnt>=0;cnt--)
     {
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
      if( OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
        {
         OrdersPerSymbol++;
        }
     }
   if(OrdersPerSymbol==0) TradeAllowed=true;
   
   // keep some statistics
   if(OrdersPerSymbol>maxOrders) maxOrders=OrdersPerSymbol;

     
   //+-----------------------------+
   //| Insert your indicator here  |
   //| And set either BUYme or     |
   //| SELLme true to place orders |
   //+-----------------------------+


   double ma = iMA(Symbol(),0,BPeriod,0,MODE_SMA,PRICE_OPEN,0);
   double stddev = iStdDev(Symbol(),0,BPeriod,0,MODE_SMA,PRICE_OPEN,0);   
   double bup = ma+(Deviation*stddev);
   double bdn = ma-(Deviation*stddev);

   if(Close[0]>bup+(BDistance*Point)) SELLme=true;
   if(Close[0]<bdn-(BDistance*Point))  BUYme=true;
   

   //+------------+
   //| End Insert |
   //+------------+

   //ENTRY LONG (buy, Ask) 
   if( OrdersPerSymbol==0 && TradeAllowed && BUYme )
     {
      while(true)
        {
         if( AccountFreeMargin()< (AccountBalance()*(MinFreeMarginPct/100)) )
           {
            if(logging) logwrite(TradeComment,"Your BUY equity is too low to trade");
            break;
           }
                   
         if(LossLimit ==0) SL=0; else SL=Ask-((LossLimit+L2L)*Point );
         if(ProfitMade==0) TP=0; else TP=Ask+((ProfitMade+L2L)*Point );
         ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,Slippage,SL,TP,TradeComment,MagicNumber,White);
         gle=GetLastError();
         if(gle==0)
           {
            if(logging) logwrite(TradeComment,"BUY Ticket="+ticket+" bdn="+bdn+" Ask="+Ask+" Lots="+Lots+" SL="+SL+" TP="+TP);
            TradeAllowed=false;
            break;
           }
            else 
           {
            if(logerrs) logwrite(TradeComment,"-----ERROR-----  opening BUY order: Lots="+Lots+" SL="+SL+" TP="+TP+" Bid="+Bid+" Ask="+Ask+" ticket="+ticket+" Err="+gle+" "+ErrorDescription(gle)); 
           }

            RefreshRates();
            Sleep(500);

            loopcount++;
            if(loopcount>maxloop) break;           
           
        }//while   
     }//BUYme
        

   //ENTRY SHORT (sell, Bid)
   if( OrdersPerSymbol==0 && TradeAllowed && SELLme )
     {
      while(true)
        {
         if( AccountFreeMargin()< (AccountBalance()*(MinFreeMarginPct/100)) )
           {
            if(logging) logwrite(TradeComment,"Your BUY equity is too low to trade");
            break;
           }
           
         if(LossLimit ==0) SL=0; else SL=Bid+((LossLimit+L2L)*Point );
         if(ProfitMade==0) TP=0; else TP=Bid-((ProfitMade+L2L)*Point );
         ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,Slippage,SL,TP,TradeComment,MagicNumber,Red);
         gle=GetLastError();
         if(gle==0)
           {
            if(logging) logwrite(TradeComment,"SELL Ticket="+ticket+" bup="+bup+" Bid="+Bid+" Lots="+Lots+" SL="+SL+" TP="+TP);
            TradeAllowed=false;
            break;
           }
            else 
           {
            if(logerrs) logwrite(TradeComment,"-----ERROR-----  opening SELL order: Lots="+Lots+" SL="+SL+" TP="+TP+" Bid="+Bid+" Ask="+Ask+" ticket="+ticket+" Err="+gle+" "+ErrorDescription(gle)); 
           }
           
            RefreshRates();
            Sleep(500);

            loopcount++;
            if(loopcount>maxloop) break;           
           
        }//while
     }//SELLme

     
   //
   // Order Management
   //
   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() ;
            if(logtick) logwrite(TradeComment,"BUY  CurrentProfit="+CurrentProfit/Point);

            // Did we make a profit or loss
            if(ProfitMade>0 && CurrentProfit>=(ProfitMade*Point))        CloseBuy("PROFIT");
            if( LossLimit>0 && CurrentProfit<=(LossLimit*(-1)*Point)  )  CloseBuy("LOSS");

           } //if BUY


         if(OrderType()==OP_SELL)
           {
            CurrentProfit=OrderOpenPrice()-Ask;
            if(logtick) logwrite(TradeComment,"SELL CurrentProfit="+CurrentProfit/Point);

            // Did we make a profit or loss
            if( ProfitMade>0 && CurrentProfit>=(ProfitMade*Point) )      CloseSell("PROFIT");
            if( LossLimit>0 && CurrentProfit<=(LossLimit*(-1)*Point) )   CloseSell("LOSS");

           } //if SELL
           
        } // if(OrderSymbol)
        
     } // for

  } // start()


void logwrite (string filename, string mydata)
  {
   int myhandle;
   string gregorian=TimeToStr(CurTime(),TIME_DATE|TIME_SECONDS);

   // don't log anything if testing or if user doesn't want it
   //if(IsTesting()) return(0);
   //if(KillLogging) return(0);

   //Print(mydata);
   
   myhandle=FileOpen(Symbol()+"_"+filename, FILE_CSV|FILE_WRITE|FILE_READ, ";");
   if(myhandle>0)
     {
      FileSeek(myhandle,0,SEEK_END);
      FileWrite(myhandle, mydata+" "+gregorian);
      FileClose(myhandle);
     }
  } 

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)
        {
         if(logging) logwrite(TradeComment,"CLOSE BUY "+myInfo+ bTK + bSL + bTP + bPM + bLL);
         break;
        }
       else 
        {
         if(logerrs) logwrite(TradeComment,"-----ERROR----- CLOSE BUY "+myInfo+ bER +" Bid="+Bid+ bTK + bSL + bTP + bPM + bLL);
         RefreshRates();
         Sleep(500);
        }


      // sometimes an order close is delayed, or a gap jumps to the LL2SL on the server
      // This keeps a server-closed order from hanging here
      OrdersPerSymbol=0;
      for(cnt=OrdersTotal();cnt>=0;cnt--)
        {
         OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
         if( OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber) OrdersPerSymbol++;
        }
   
      if(OrdersPerSymbol==0) break;

      loopcount++;
      if(loopcount>maxloop) break;
                     
     }//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)
        {
         if(logging) logwrite(TradeComment,"CLOSE SELL "+myInfo + sTK + sSL + sTP + sPM + sLL);
         break;
        }
      else 
        {
         if(logerrs) logwrite(TradeComment,"-----ERROR----- CLOSE SELL "+myInfo+ sER +" Ask="+Ask+ sTK + sSL + sTP + sPM + sLL);
         RefreshRates();
         Sleep(500);
        }

      // sometimes an order close is delayed, or a gap jumps to the LL2SL on the server
      // This keeps a server-closed order from hanging here
      OrdersPerSymbol=0;
      for(cnt=OrdersTotal();cnt>=0;cnt--)
        {
         OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
         if( OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber) OrdersPerSymbol++;
        }
   
      if(OrdersPerSymbol==0) break;
                    
      loopcount++;
      if(loopcount>maxloop) break;
                 
     }//while                 
  }    
  

Comments

Markdown supported. Formatting help

Markdown Formatting Guide

Element Markdown Syntax
Heading # H1
## H2
### H3
Bold **bold text**
Italic *italicized text*
Link [title](https://www.example.com)
Image ![alt text](image.jpg)
Code `code`
Code Block ```
code block
```
Quote > blockquote
Unordered List - Item 1
- Item 2
Ordered List 1. First item
2. Second item
Horizontal Rule ---