This script is designed to automatically trade in the Forex market using the MetaTrader platform. It works by analyzing price charts and trying to predict whether the price of a currency pair will go up or down. Here's a breakdown of what it does:
1. Initial Setup:
- Configuration: It starts by reading settings that the user can adjust, like how much money to risk on each trade (
Lots
), how much price slippage to tolerate (Slippage
), a comment to attach to orders (Order_Comment
), and some colors for visual cues. - Currency Pairs: The script has a predefined list of currency pairs it can trade (like EURUSD, GBPCHF, etc.). It checks if the current chart's currency pair is in this list and, if so, uses specific settings (
SSP
,SSK
) tailored for that pair. These settings are used later for calculations. - Unique Identifier: The script creates a unique "magic number" which is used to identify the script's trades and prevent conflicts with other automated trading programs.
2. Core Logic (The start()
function):
- Logging: The script creates a log file to record its actions, like when it opens or closes trades, along with some additional information about the profit from the trades and the time the action happened.
- Lot Size Check: It makes sure that the
Lots
value the user entered is valid according to the broker's minimum requirements (e.g., it can't be less than 0.01 if the minimum lot size is 0.01). - New Bar Detection: The script waits for a new price bar (or candlestick) to form on the chart before making any trading decisions. This ensures it's acting on the most recent price information.
- Trend Analysis:
- Ichimoku Cloud: It uses the Ichimoku Kinko Hyo indicator, a complex technical analysis tool, to determine the current trend. The Ichimoku Cloud is made up of lines that can show support and resistance levels, as well as potential trend direction. The script is using the Ichimoku cloud to determine if the price will go up or down
- Moving Averages: The script also looks at two moving averages (Long and Short) and if the Short moving average is higher than the long one the indicator indicates a bull ( buy) trend and if it is the other way a Bear (sell) trend.
- Parabolic SAR (PSAR): It uses the Parabolic SAR indicator to identify potential trend reversals.
- Relative Strength Index (RSI): The RSI indicator is used to evaluate if an asset is overbought or oversold, offering insights into potential buying or selling opportunities based on momentum.
- Order Management:
- Closing Existing Trades: If the script has an open trade, it checks if the trend has reversed (e.g., it was a buy order, but now the indicator shows a sell trend). If the trend has reversed, it closes the existing trade to lock in profits or minimize losses.
- Opening New Trades: If there are no open trades or the script is allowed to open more trades based on the configuration, it checks the current trend. If the indicator signals a buy trend, it opens a buy order. If it signals a sell trend, it opens a sell order. The Moving average trend must corroborate with the Ichimoku trend.
- Information Display: The script shows information on the chart, like the current price, date, volatility, and values from the Ichimoku indicator.
3. Technical Indicators (Functions like TrendDetection()
, MATrend()
, getPSarTrend()
, getRSITrend()
):
- These functions calculate the values of various technical indicators (Ichimoku Cloud, Moving Averages, Parabolic SAR, RSI). The script uses these values to determine the current trend and make trading decisions. The Ichimoku cloud is the primary source for trend detection
4. Utility Functions:
TotalOpenOrders()
: Counts how many trades the script currently has open.SelectTheOrder()
: Selects an open order placed by the script.NewBar()
: Determines if a new bar has formed on the chart.createMagicNumber()
: This function calculates a numeric identifier for the script by summing the ASCII values of the characters in the currency pair symbol.logInfo()
The script logs information to the log file for analysisStoreCurrentProfit()
Store the current profit to analysisgetProfitAsString()
Returns a string with the profit report
In essence, this script is an automated trading system that uses technical analysis indicators to identify trading opportunities and automatically open and close trades in an attempt to profit from price movements in the Forex market.
//+------------------------------------------------------------------+
//| simplefx.mq4 |
//| Copyright © 2007, GLENNBACON.COM LLC |
//| http://www.GetForexSoftware.com |
//+------------------------------------------------------------------+
// Shift of moving average
#define Shift 1
// Trend Detection function
#define TREND_BUY 11
#define TREND_SELL 22
#define TREND_CLOSE 33
//parametros Medias moveis
int Long_MA_Period = 200;
int Long_MA_Method = 0;
int Long_MA_Applied_Price = 4;
int Short_MA_Period = 50;
int Short_MA_Method = 0;
int Short_MA_Applied_Price = 4;
#define MABULL 111111
#define MABEAR 222222
// Input variables
extern double Lots = 0.30;
extern int Slippage = 3;
extern string Order_Comment = "EL FODEURO";
extern color Order_Arrow_Color = Green;
extern double PercentMargin = 0.005;
extern int NOGOVolatility = 200;
extern int SMALLGOVolatility = 100;
extern int SSP = 34; // bars - calculating period
extern int SSK = 29; // tolerance of second line
// Global variables
int Total_Open_Orders = 1; // we only want to open one order at a time and only manage the one order
int cnt = 0; // counter variable, used in for() loops
bool init_variables; // init variable when program starts
datetime PreviousBar; // record the candle/bar time
int NowTrend = TREND_CLOSE;
int Magic = 1;
string pairs[9] ;
int SSPS[9] ;
int SSKS[9];
int logHandler;
string logFileName;
double profits[1];
int profitIdx = 1;
int lastSARTrend;
//Indicators
double ExtMapBuffer1[];
double ExtMapBuffer2[];
double Wal1[];
double Wal2[];
double ExtMapBuffer4[];
int i, i1, i2, shift;
double SsMax, SsMin, SsMax05, SsMin05, Rsmin, Rsmax, Tsmin, Tsmax;
int val1, val2, AvgRange;
bool uptrend, old;
double iClose0,iClose1,iIchi,iLine1,iLine2;
int init()
{
init_variables = true; // Allows us to init variables in the start function because
// we cannot do this in the init function because the variables
// use values from the chart ~
logFileName = StringConcatenate( Symbol() , ".log") ;
pairs[0] = "EURUSD";
pairs[1] = "GBPCHF";
pairs[2] = "EURJPY";
pairs[3] = "USDJPY";
pairs[4] = "GBPUSD";
pairs[5] = "EURGBP";
pairs[6] = "CADCHF";
pairs[7] = "GBPJPY";
pairs[8] = "EURCHF";
/*
Pair Time SSP SSK
CADJPY 4H 48 36
EURCHF 4H 72 50
USDCAD 4H 24 60
USDCHF 4H 34 29
*/
SSPS[8] = 72;
SSKS[8] =50;
SSPS[7] = 36;
SSKS[7] =29;
SSPS[6] = 62;
SSKS[6] =52;
SSPS[5] = 44;
SSKS[5] =38;
SSPS[0] = 34;
SSKS[0] =34;
SSPS[0] = 34;
SSKS[0] =34;
SSPS[1] = 34;
SSKS[1] =29;
SSPS[2] = 36;
SSKS[2] =29;
SSPS[3] = 34;
SSKS[3] =29;
SSPS[4] = 44;
SSKS[4] =36;
int i;
for(i=0;i<ArraySize(pairs) ;i++ ) {
if ( pairs[i] == Symbol() ) {
SSP = SSPS[i];
SSK = SSKS[i];
Print("SSP=", SSP);
Print("SSK=",SSK);
break;
}
}
/*
Pair Time SSP SSK
EURGBP 4H 44 38
CADCHF 4H 62 52
CADJPY 4H 48 36
GBPUSD 4H 44 36
GBPCHF 4H 34 29
GBPJPY 4H 36 29
EURUSD 4H 34 34
EURCHF 4H 72 50
EURJPY 4H 72 36
USDCAD 4H 24 60
USDCHF 4H 34 29
USDJPY 4H 34 29
*/
Magic = createMagicNumber();
return(0);
}
int deinit()
{
// clear chart when EA is removed
ObjectsDeleteAll();
return(0);
}
int start()
{
logHandler=FileOpen(logFileName, FILE_CSV | FILE_READ | FILE_WRITE , ';');
FileSeek(logHandler, 0, SEEK_END);
if(logHandler<1)
{
Print("file error the last error is ", GetLastError());
return (false);
}
// make sure trader has set Lots to at least the minimum lot size of the broker and
// we will normalize the Lots variable so we can properly open an order
if(MarketInfo(Symbol(),MODE_MINLOT) == 0.01)
{
Lots = NormalizeDouble(Lots,2);
if(Lots < 0.01)
{
Comment("The variable Lots must be 0.01 or greater to open an order. ");
return(0);
}
}
if(MarketInfo(Symbol(),MODE_MINLOT) == 0.1)
{
Lots = NormalizeDouble(Lots,1);
if(Lots < 0.1)
{
Comment("The variable Lots must be 0.1 or greater to open an order. ");
return(0);
}
}
if(MarketInfo(Symbol(),MODE_MINLOT) == 1)
{
Lots = NormalizeDouble(Lots,0);
if(Lots < 1)
{
Comment("The variable Lots must be 1 or greater to open an order. ");
return(0);
}
}
// init variables when the expert advisor first starts running
if(init_variables == true)
{
PreviousBar = Time[0]; // record the current canle/bar open time
// place code here that you only wnat to run one time
MathSrand(TimeLocal());
init_variables = false; // change to false so we only init variable once
// Magic = MathRand();
}
// perform analysis and open orders on new candle/bar
if(NewBar() == true)
{
NowTrend = TrendDetection();
int MATrend = MATrend();
int SARTrend = getPSarTrend();
int RSITrend = getRSITrend();
string rsi = StringConcatenate(iRSI(NULL,0,14,PRICE_CLOSE,0),";",iRSI(NULL,0,14,PRICE_CLOSE,1));
// only perform analysis and close order if we only have one order open
if(TotalOpenOrders() == Total_Open_Orders && SelectTheOrder() == true)
{
StoreCurrentProfit();
logInfo(logHandler,getProfitAsString(OrderTicket(),OrderProfit(), RSITrend,MATrend,SARTrend,rsi));
if((OrderType()) == OP_BUY && ((NowTrend == TREND_SELL) || (NowTrend == TREND_CLOSE)))
{
logInfo(logHandler,StringConcatenate("SAIDACOMPRA",";",Symbol(),";",OrderTicket(),";",OrderProfit(),";",TimeLocal()));
OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,Order_Arrow_Color);
}
if((OrderType() == OP_SELL) && ((NowTrend == TREND_BUY) || (NowTrend == TREND_CLOSE)))
{
logInfo(logHandler,StringConcatenate("SAIDAVENDA",";",Symbol(),";",OrderTicket(),";",OrderProfit(),";",TimeLocal()));
logInfo(logHandler,getProfitAsString(OrderTicket(),OrderProfit(), RSITrend,MATrend,SARTrend,rsi));
OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,Order_Arrow_Color);
}
}
// only perform analysis and open new order if we have not reached our Total_Open_Orders max
if(TotalOpenOrders() < Total_Open_Orders)
{
int tickOrder ;
// open buy
if(NowTrend == TREND_BUY)
{
// open order
if ( MATrend == MABULL) {
tickOrder = OrderSend(Symbol(),OP_BUY,Lots,Ask,Slippage,0,0,Order_Comment,Magic,0,Order_Arrow_Color);
Print("Comprei " , Symbol() );
PlaySound("alert2.wav");
logInfo(logHandler,StringConcatenate("Compra",";",Symbol(),";",tickOrder,";",rsi,";",SARTrend,";",TimeLocal()));
Print(" SAR TREND compra " , SARTrend);
Print(" RSI TREND compra " , RSITrend);
}
else {
Print(" O Sinal do ichimoku nao foi confirmado pela MA na compra" );
}
}
// open sell
if(NowTrend == TREND_SELL)
{
// open order
if ( MATrend== MABEAR) {
tickOrder = OrderSend(Symbol(),OP_SELL,Lots,Bid,Slippage,0,0,Order_Comment,Magic,0,Order_Arrow_Color);
Print("Vendi " , Symbol() );
PlaySound("alert2.wav");
logInfo(logHandler,StringConcatenate("VENDA",";",Symbol(),";",tickOrder,";",rsi,";",SARTrend,";",TimeLocal()));
Print(" SAR TREND venda " , SARTrend);
Print(" RSI TREND venda " , RSITrend);
//Print(" O indicador MA esta a confirmar o sinal do ichimoku na venda " );
}
else {
Print(" O Sinal do ichimoky nao foi confirmado pela MA na venda " );
}
}
}
/*
Print("Date: ",Month(),"-",Day(),"-",Year()," Server Time: ",Hour(),":",Minute(),":",Seconds(),
" volatility:", AvgRange,
" iClose0: ",iClose0,
" iClose1: ",iClose1,
" iIchi: ",iIchi,
" iLine1: ",iLine1,
" iLine2: ",iLine2,
" Trend: ",NowTrend);
*/
Display_Info();
}
lastSARTrend = SARTrend;
FileClose(logHandler);
return(0);
}
/////////////////////////////////////////////////////////////////////////
// Common functions //
///////////////////////////////////////////////////////////////////////
void StoreCurrentProfit() {
profits[profitIdx-1] = OrderProfit();
profitIdx++;
ArrayResize(profits,profitIdx);
}
string getProfitAsString(int orderTicket ,double profit , int matrend,int rsitrend, int sartrend,string rsi ) {
return (StringConcatenate("PROFITREPORT;", orderTicket, ";", profit, ";", matrend,";",rsitrend,";",sartrend,";",rsi));
}
void logInfo(int handle, string value) {
//Print(" handle ", handle);
Print( value);
FileWrite(handle,value);
}
// This function returns the total amount of orders the expert advisor has open
int TotalOpenOrders()
{
cnt=OrdersTotal();
int TotalOpenOrders = 0;
if(cnt==0)
{
return(0);
}
else
{
for(;cnt>=0;cnt--)
{
RefreshRates();
OrderSelect(cnt,SELECT_BY_POS);
if(OrderMagicNumber()==Magic)
{
TotalOpenOrders++;
}
}
}
return(TotalOpenOrders);
}
// This function finds the open order and selects it
int SelectTheOrder()
{
cnt=OrdersTotal();
if(cnt==0)
{
return(false);
}
else
{
for(;cnt>=0;cnt--)
{
RefreshRates();
OrderSelect(cnt,SELECT_BY_POS);
if(OrderMagicNumber()==Magic)
{
return(true);
}
}
}
return(false);
}
// This function return the value true if the current bar/candle was just formed
bool NewBar()
{
if(PreviousBar<Time[0])
{
PreviousBar = Time[0];
return(true);
}
else
{
return(false);
}
return(false); // in case if - else statement is not executed
}
// is trend up/bullish or is it down/bearish
int TrendDetection()
{
double topLine,bottomLine;
if (iClose1 == 0)
iClose1 = iClose(NULL,0,10);
else
iClose1 = iClose0;
iClose0 = iClose(NULL,0,0);
AIchimoku();
if (iLine1 > iLine2)
{
topLine = iLine1;
bottomLine = iLine2;
}
else
{
topLine = iLine2;
bottomLine = iLine1;
}
if ((iClose0 > iIchi) && (iClose1 < iIchi))
return(TREND_BUY);
if ((iClose0 < iIchi) && (iClose1 > iIchi))
return(TREND_SELL);
if ((iClose0 < topLine ) && (iClose0 > bottomLine))
return(TREND_CLOSE);
if (AvgRange < NOGOVolatility )
{
if ((iClose0 > topLine) && (iClose0 > iClose1))
if (((iClose0-topLine)/iClose0)<PercentMargin)
return(TREND_BUY);
if ((iClose0 < bottomLine) && (iClose0 < iClose1))
if (((bottomLine-iClose0)/bottomLine)<PercentMargin)
return(TREND_SELL);
}
// flat no trend return 0
return(0);
}
int MATrend()
{
// BULL trend
if(iMA(NULL,0,Short_MA_Period,0,Short_MA_Method,Short_MA_Applied_Price,0) > iMA(NULL,0,Long_MA_Period,0,Long_MA_Method,Long_MA_Applied_Price,0) && iMA(NULL,0,Short_MA_Period,0,Short_MA_Method,Short_MA_Applied_Price,1) > iMA(NULL,0,Long_MA_Period,0,Long_MA_Method,Long_MA_Applied_Price,1))
{
return(MABULL);
}
// BEAR trend
if(iMA(NULL,0,Short_MA_Period,0,Short_MA_Method,Short_MA_Applied_Price,0) < iMA(NULL,0,Long_MA_Period,0,Long_MA_Method,Long_MA_Applied_Price,0) && iMA(NULL,0,Short_MA_Period,0,Short_MA_Method,Short_MA_Applied_Price,1) < iMA(NULL,0,Long_MA_Period,0,Long_MA_Method,Long_MA_Applied_Price,1))
{
return(MABEAR);
}
// flat no trend return 0
return(0);
}
void Display_Info()
{
Comment("Price: ",NormalizeDouble(Bid,4),"\n",
"Date: ",Month(),"-",Day(),"-",Year()," Server Time: ",Hour(),":",Minute(),":",Seconds(),"\n",
"volatility: ", AvgRange,"\n",
"iClose0: ",DoubleToStr(iClose0,4),"\n",
"iClose1: ",DoubleToStr(iClose1,4),"\n",
"iIchi: ",DoubleToStr(iIchi,4),"\n",
"iLine1: ",DoubleToStr(iLine1,4),"\n",
"iLine2: ",DoubleToStr(iLine2,4),"\n",
"TotalOrders : ",TotalOpenOrders(),"\n");
return(0);
}
bool CheckIfOrderExists(string symbol, int orderType ) {
cnt=OrdersTotal();
if(cnt==0)
{
return(false);
}
else
{
for(;cnt>=0;cnt--)
{
RefreshRates();
OrderSelect(cnt,SELECT_BY_POS);
Print ( OrderSymbol(), " ",OrderMagicNumber(), " ", Magic);
if ( OrderSymbol() == symbol && OrderType() == orderType ) return (true);
}
}
return(false);
}
int getPSarTrend() {
if(iSAR(NULL,0,0.02,0.2,1)<Low[1] && iSAR(NULL,0,0.02,0.2,0)>High[0])
{
return (TREND_SELL);
}
if(iSAR(NULL,0,0.02,0.2,1)>High[1] && iSAR(NULL,0,0.02,0.2,0)<Low[0])
{
return (TREND_BUY);
}
else return(0);
}
int getRSITrend() {
double RSI[8]; // 6
double EMA, EMA1;
double RSI1[8];
ArraySetAsSeries(RSI, true); // 1
for (int x=0; x<=7;x++)
{
RSI[x]=iRSI(NULL,0,8,PRICE_CLOSE,x);
}
EMA=iMAOnArray(RSI,0,8,0,MODE_EMA,0); // 2
for (x=1; x<=8;x++)
{
RSI1[x]=iRSI(NULL,0,8,PRICE_CLOSE,x);
}
EMA1=iMAOnArray(RSI1,0,8,0,MODE_EMA,1); // 2
if (EMA<RSI[0] && EMA1>RSI[0]) return(TREND_BUY);
else if (EMA>RSI[0] && EMA1<RSI[0] ) return(TREND_SELL) ;
else return (0);
}
int createMagicNumber() {
string symbol = Symbol();
int t = 0 ;
for(int i=0;i<StringLen(symbol);i++) {
t += StringGetChar(symbol,i);
}
return (t);
}
void AIchimoku()
{
// maximum of previous SSP bars period
SsMax = High[iHighest(NULL, 0, MODE_HIGH, SSP, 0)];
// minimum of previous SSP bars period
SsMin = Low[iLowest(NULL, 0, MODE_LOW, SSP, 0)];
// maximum of SSP bars period for SSK bars from begin
SsMax05 = High[iHighest(NULL, 0, MODE_HIGH, SSP, 0 + SSK)];
// maximum of SSP bars period for SSK bars from begin
SsMin05 = Low[iLowest(NULL, 0, MODE_LOW, SSP, 0 + SSK)];
iLine1 = (SsMax + SsMin) / 2;
iLine2 = (SsMax05+SsMin05) / 2;
val1 = ExtMapBuffer1[1] / Point;
val2 = ExtMapBuffer2[1] / Point;
//----
Rsmax = High[iHighest(NULL, 0, MODE_HIGH, SSP*2, 0)];
Rsmin = Low[iLowest(NULL, 0, MODE_LOW, SSP*2, 0)];
AvgRange = (Rsmax / Point) - (Rsmin / Point);
//----
Tsmax = High[iHighest(NULL, 0, MODE_HIGH, SSP*1.62, 0)];
Tsmin = Low[iLowest(NULL, 0, MODE_LOW, SSP*1.62, 0)];
iIchi = (Tsmax + Tsmin) / 2;
}
Comments