This script, designed for the MetaTrader platform, is an automated trading system, often called an "Expert Advisor" or EA, built to execute trades based on specific price patterns. Here's a breakdown of its logic in plain language:
Overall Strategy:
The EA operates using a core principle of identifying potential buy or sell opportunities based on the relationship between the current price and the price movement of previous time periods (bars on a chart). It has two primary strategies that are used for trading:
-
Variation 0: This strategy looks at a single previous bar. It analyzes where the bar opened and closed in relation to its overall price range. If the previous bar opened near the bottom of its range and closed near the top, the script will try to place a sell order just above the previous bar's highest price. Conversely, if the previous bar opened near the top and closed near the bottom, it will try to place a buy order just below the previous bar's lowest price.
-
Variation 1: This strategy identifies "inside bars," where the price range of the immediately preceding bar is smaller than the range of the bars before it. If the EA identifies an inside bar, it looks at where the current bar opens in relation to yesterday?s bar range. If today's bar opens near the bottom of yesterday's range, it tries to place a buy order. If today's bar opens near the top of yesterday's range, it tries to place a sell order.
Key Components and Logic:
-
Initialization (init()): When the script starts, it sets up a file to keep a log of its trades and activities. It checks if the file exists.
-
Deinitialization (deinit()): When the script is stopped, it closes the log file.
-
Main Execution (start()): This is the heart of the script, where the trading decisions are made:
- Trading Permissions: The script first verifies that automated trading is allowed on the platform and that there are no errors.
- Open Trade Check: Then, it determines if there are any open trades with the EA's ID number. It shows a warning if it finds more than one trade open at a time. It will also run a CheckForClose function on any open position.
- Trading Logic: If there are no open trades, the script calculates the high and low prices of the previous period or the bar range and triggers a trade with one of the two possible strategy options described above.
-
Order Placement (OpenOrder()): If the script determines a buy or sell order should be placed, it sends a request to the trading platform to open a new order, with some extra parameters described below. It also logs the trade information in the file.
-
Position Determination (DetermineOpenPositions()): This function counts how many buy and sell trades are currently open that are associated with this EA. This is important to ensure that the EA doesn't accidentally open multiple trades when it shouldn't.
-
Order Management (CheckForClose()): This function manages any open positions. It checks if a trade has reached a certain profit level and then moves the stop-loss to lock in some of that profit. Also, it can be configured to move the stop-loss up/down if the price moves in favor of the trade, to continue locking in profits (trailing stop).
-
Lot Size Optimization (LotOptimized()): This function manages trade size based on account balance and risk. If enabled, it calculates the trade size (lot) based on the available funds in your account and the specified risk percentage. If the previous trades were losses, the script decreases the trade volume.
Important Parameters:
The script has several adjustable settings:
- Variation: This parameter toggles between the two trading strategies described above.
- Stoploss, TakeProfit: These determine the levels at which a trade will automatically close to limit losses or secure profits, respectively.
- TrailingStop: This enables a trailing stop-loss, which automatically adjusts the stop-loss level as the price moves in a favorable direction, aiming to maximize potential profits while limiting risk.
- LockProfit: This parameter defines how far into profit a trade must move before the stop-loss order is adjusted to lock in some profit.
- LockOutLossValue: This value defines how far into loss the trade must move before the stoploss is adjusted.
- Lots: This specifies the trading volume.
- Magic Number: A unique identifier used to distinguish trades opened by this script from those opened manually or by other scripts.
In summary: This script is designed to automate trading by analyzing price patterns and placing buy or sell orders based on predefined rules. It includes risk management features like stop-loss, take-profit, trailing stop, and lot size optimization. It also keeps a log of its activities to help you track its performance.
/*-----------------------------+
| |
| Shared by www.Aptrafx.com |
| |
+------------------------------*/
//+------------------------------------------------------------------+
//| The 20's v0.30 |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, TraderSeven"
#property link "TraderSeven@gmx.net"
#include <stdlib.mqh> // Include this file in case of needing to retrieve error descriptions
// \\|// +-+-+-+-+-+-+-+-+-+-+-+ \\|//
// ( o o ) |T|r|a|d|e|r|S|e|v|e|n| ( o o )
// ~~~~oOOo~(_)~oOOo~~~~ +-+-+-+-+-+-+-+-+-+-+-+ ~~~~oOOo~(_)~oOOo~~~~
// This EA has 2 main parts.
// Variation=0
// If previous bar opens in the lower 20% of its range and closes in the upper 20% of its range then sell on previous high+10pips.
// If previous bar opens in the upper 20% of its range and closes in the lower 20% of its range then buy on previous low-10pips.
//
// Variation=1
// The previous bar is an inside bar that has a smaller range than the 3 bars before it.
// If todays bar opens in the lower 20% of yesterdays range then buy.
// If todays bar opens in the upper 20% of yesterdays range then sell.
//
//01010100 01110010 01100001 01100100 01100101 01110010 01010011 01100101 01110110 01100101 01101110
#define Magic_Num 1002 // ID for The20s Strategy
#define Buy 1
#define Sell 0
extern int Variation=0;
extern int Stoploss=50;
extern int TrailingStop=5;
extern int LockProfit=30;
extern int TakeProfit=100;
extern int LockOutLossValue=10;
extern bool LockInProfit=False;
extern bool LockOutLoss=False;
extern bool LotOptimized=False;
extern bool OverwriteLog=False;
extern int Slippage=3;
extern double Lots=0.1;
extern double MaximumRisk=0.02;
extern double DecreaseFactor=3;
bool LockInProfitFlag;
bool LockOutLossFlag;
int LastTrade=-1, FileHandle;
int init()
{
if(OverwriteLog==True)
FileHandle = FileOpen("20sExpert.txt",FILE_WRITE);
else
FileHandle = FileOpen("20sExpert.txt",FILE_READ|FILE_WRITE);
FileSeek(FileHandle,0,SEEK_END);
if(FileHandle<1)
{
Print("File 20sExpert.txt error: ", GetLastError());
return(-1);
}
return(0);
}
int deinit()
{
FileClose(FileHandle);
return(0);
}
int start()
{
int h = TimeHour(CurTime());
int m = TimeMinute(CurTime());
int BuyPositions,SellPositions;
double LastBarsRange,Top20,Bottom20;
if(IsTradeAllowed()==False)
{
Print("Error 1: Expert Advisor not allowed to trade");
return(-1);
}
if(LockProfit<=LockOutLossValue && LockInProfit==True && LockOutLoss==True)
{
Print("LockProfit must be greater than LockOutLossValue");
return(-1);
}
if(DetermineOpenPositions(BuyPositions, SellPositions)>1)
Print("Warning: Multiple trades open simultaneously [",BuyPositions+SellPositions,"]");
if(BuyPositions+SellPositions==1)
CheckForClose(BuyPositions,SellPositions);
if(BuyPositions+SellPositions==0)
{
LastBarsRange=(High[1]-Low[1]);
Top20=High[1]-(LastBarsRange*0.20);
Bottom20=Low[1]+(LastBarsRange*0.20);
if(Variation==0 && h==0 && m==0)
{
if(Open[1]>=Top20 && Close[1]<=Bottom20 && Low[0]<=Low[1]+10*Point)
OpenOrder(Buy);
else if(Open[1]<=Bottom20 && Close[1]>=Top20 && High[0]>=High[1]+10*Point)
OpenOrder(Sell);
}
else if(Variation==1 && h==0 && m==0)
{
if((High[4]-Low[4])>LastBarsRange && (High[3]-Low[3])>LastBarsRange && (High[2]-Low[2])>LastBarsRange && High[2]>High[1] && Low[2]<Low[1])
{
if(Open[0]<=Bottom20)
OpenOrder(Buy);
if(Open[0]>=Top20)
OpenOrder(Sell);
}
}
}
}
int OpenOrder(bool OpenType)
{
if(OpenType==Buy && LastTrade!=DayOfYear())
{
if(OrderSend(Symbol(),OP_BUY,LotOptimized(),Ask,Slippage,Ask-Stoploss*Point,Ask+TakeProfit*Point,"The 20's Strategy",Magic_Num,0,Blue) == -1)
{
Print("OP_BUY, Err = (", GetLastError(),") ",ErrorDescription(GetLastError()));
return(-1);
}
else
{
FileWrite(FileHandle,"Buy @ "+TimeToStr(CurTime(),TIME_DATE|TIME_MINUTES)+": "+Symbol()+" Vol: "+LotOptimized()+" Balance: "+AccountBalance());
LastTrade=DayOfYear();
LockOutLossFlag=False;
LockInProfitFlag=False;
}
}
else if(OpenType==Sell && LastTrade!=DayOfYear())
{
if(OrderSend(Symbol(),OP_SELL,LotOptimized(),Bid,Slippage,Bid+Stoploss*Point,Bid-TakeProfit*Point,"The 20's Strategy",Magic_Num,0,Red) == -1)
{
Print("OP_SELL, Err = (", GetLastError(),") ",ErrorDescription(GetLastError()));
return(-1);
}
else
{
FileWrite(FileHandle,"Sell @ "+TimeToStr(CurTime(),TIME_DATE|TIME_MINUTES)+": "+Symbol()+" Vol: "+LotOptimized()+" Balance: "+AccountBalance());
LastTrade=DayOfYear();
LockOutLossFlag=False;
LockInProfitFlag=False;
}
}
return(0);
}
int DetermineOpenPositions(int& BuyPositions, int& SellPositions)
{
int i;
for(i=0;i<OrdersTotal();i++)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==False)
break;
if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic_Num)
{
if(OrderType()==OP_BUY)
BuyPositions++;
if(OrderType()==OP_SELL)
SellPositions++;
}
}
if(BuyPositions+SellPositions==0)
{
LockInProfitFlag=False;
LockOutLossFlag=False;
}
return(BuyPositions+SellPositions);
}
int CheckForClose(int& BuyPositions, int& SellPositions)
{
for(int i=0; i<OrdersTotal(); i++)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false)
break;
if(OrderMagicNumber()!=Magic_Num || OrderSymbol()!=Symbol())
continue;
if(OrderType()==OP_BUY)
{
if(LockOutLossFlag==False && LockOutLoss==True)
{
if(Bid-OrderOpenPrice()>=LockOutLossValue*Point && OrderStopLoss()<OrderOpenPrice())
{
OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice(),OrderTakeProfit(),0,Black);
LockOutLossFlag=True;
}
}
if(LockInProfitFlag==False && LockInProfit==True)
{
if(Bid-OrderOpenPrice()>=LockProfit*Point)
LockInProfitFlag=True;
}
if((Bid-OrderOpenPrice()>TrailingStop*Point && (LockInProfit==True && LockInProfitFlag==True)) || (Bid-OrderOpenPrice()>TrailingStop*Point && LockInProfit==False))
{
if(OrderStopLoss()<Bid-Point*TrailingStop)
{
OrderModify(OrderTicket(),OrderOpenPrice(),Bid-TrailingStop*Point,OrderTakeProfit(),0,Black);
return(0);
}
}
}
else if(OrderType()==OP_SELL)
{
if(LockOutLossFlag==False && LockOutLoss==True)
{
if(OrderOpenPrice()-Ask>=LockOutLossValue*Point && OrderStopLoss()>OrderOpenPrice())
{
OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice(),OrderTakeProfit(),0,Black);
LockOutLossFlag=True;
}
}
if(LockInProfitFlag==False && LockInProfit==True)
{
if(OrderOpenPrice()-Ask>=LockProfit*Point)
LockInProfitFlag=True;
}
if((OrderOpenPrice()-Ask>TrailingStop*Point && (LockInProfit==True && LockInProfitFlag==True)) || (OrderOpenPrice()-Ask>TrailingStop*Point && LockInProfit==False))
{
if(OrderStopLoss()>Ask+TrailingStop*Point || OrderStopLoss()==0)
{
OrderModify(OrderTicket(),OrderOpenPrice(),Ask+TrailingStop*Point,OrderTakeProfit(),0,Black);
return(0);
}
}
}
}
return(0);
}
double LotOptimized()
{
double lot=Lots;
int orders=HistoryTotal(); // history orders total
int losses=0; // number of losses orders without a break
if(LotOptimized==True)
{
lot=NormalizeDouble(AccountFreeMargin()*MaximumRisk/1000.0,1);
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);
if(lot<0.1)
lot=0.1;
return(lot);
}
else
return(Lots);
int h = TimeHour(CurTime());
int m = TimeMinute(CurTime());
Comment(h,":",m);
if(h==23 && m>=55)
{
OrderSelect(0, SELECT_BY_POS);
if(OrderType()==OP_BUY)
{
OrderClose(OrderTicket(),1,Bid,1000*Point);
}
if(OrderType()==OP_SELL)
{
OrderClose(OrderTicket(),1,Ask,1000*Point);
}
}
}
Comments