This script is designed to automatically trade on the financial markets based on the relationship between two moving averages. Here's a breakdown of its logic:
-
Initialization: When the script starts, it doesn't perform any special setup tasks, indicated by the empty
init()
function. -
Moving Average Calculation: The core of the script relies on two types of moving averages, a "fast" one and a "slow" one, calculated using historical price data. Moving averages smooth out price fluctuations to identify trends. The "fast" moving average is more sensitive to recent price changes, while the "slow" moving average reflects a longer period and is less reactive. The script uses "Exponential Moving Averages" (EMA) calculated on the open price of each period.
-
Order Counting: The script counts how many buy (OP_BUY) and sell (OP_SELL) orders are currently open for the specific financial instrument (e.g., EURUSD). It only considers orders that are related to the specific currency pair the script is attached to.
-
Decision Making: The script compares the values of the fast and slow moving averages.
-
If the "fast" moving average is higher than the "slow" moving average, it indicates a potential upward trend. The script then closes all existing sell orders and, if there are no existing buy orders, opens a new buy order.
-
Conversely, if the "fast" moving average is lower than the "slow" moving average, it suggests a potential downward trend. The script closes all existing buy orders and, if there are no existing sell orders, opens a new sell order.
-
-
Order Execution: The
Buy()
andSell()
functions handle the process of opening new trade orders. These functions specify the details of the trade, such as the size of the trade (Lots), the price, and acceptable slippage (the difference between the requested price and the actual execution price). They also include error handling and logging to monitor the trading process. -
Order Closing: The
CloseOrders()
function closes all existing orders of a specific type (buy or sell). It iterates through all open orders, checks if they match the specified type and currency pair, and then closes them using theCloseOrder()
function. TheCloseOrder()
function sends a request to close an existing order. It includes error handling and logging to keep track of successful and failed attempts. -
Slippage: A slippage parameter is used to tolerate small differences between the requested execution price of an order and the price that is actually executed on the market. This helps to ensure that orders are more likely to be filled, even if the price fluctuates slightly.
In essence, the script attempts to capitalize on short-term price trends by buying when the fast moving average is above the slow moving average and selling when the fast moving average is below the slow moving average. It tries to ensure that only one order in each direction (buy or sell) is open at any given time.
#property copyright "Copyright © 2005-2006, RickD"
#property link "http://e2e-fx.net"
#include <stdlib.mqh>
#include <stderror.mqh>
#define major 1
#define minor 0
extern double Lots = 0.1;
extern int Slippage = 3;
extern int FastP = 5;
extern int SlowP = 20;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void init () {
}
void deinit() {
}
void start() {
if (!IsTesting()) Comment("Version: ", major, ".", minor);
double FastMA = iMA(NULL, 0, FastP, 0, MODE_EMA, PRICE_OPEN, 0);
double SlowMA = iMA(NULL, 0, SlowP, 0, MODE_EMA, PRICE_OPEN, 0);
int BuyCnt = 0;
int SellCnt = 0;
int cnt = OrdersTotal();
for (int i = 0; i < cnt; i++) {
if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
if (OrderSymbol() != Symbol()) continue;
int type = OrderType();
if (type == OP_BUY) BuyCnt++;
if (type == OP_SELL) SellCnt++;
}
double price, sl, tp;
if (FastMA > SlowMA) {
CloseOrders(OP_SELL);
if (BuyCnt == 0) {
price = Ask;
sl = 0;
tp = 0;
Buy(Symbol(), Lots, price, Slippage, sl, tp, 0);
}
}
if (FastMA < SlowMA) {
CloseOrders(OP_BUY);
if (SellCnt == 0) {
price = Bid;
sl = 0;
tp = 0;
Sell(Symbol(), Lots, price, Slippage, sl, tp, 0);
}
}
}
void CloseOrders(int type) {
int cnt = OrdersTotal();
for (int i=cnt-1; i>=0; i--) {
if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
if (OrderSymbol() != Symbol()) continue;
int type2 = OrderType();
if (type != type2) continue;
if (type == OP_BUY) CloseOrder(OrderTicket(), OrderLots(), Bid, Slippage);
if (type == OP_SELL) CloseOrder(OrderTicket(), OrderLots(), Ask, Slippage);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int SleepOk = 2000;
int SleepErr = 6000;
int Buy(string symbol, double lot, double price, int slip, double sl, double tp, int magic, string comment="") {
RefreshRates();
int dig = MarketInfo(symbol, MODE_DIGITS);
price = NormalizeDouble(price, dig);
sl = NormalizeDouble(sl, dig);
tp = NormalizeDouble(tp, dig);
string _lot = DoubleToStr(lot, 1);
string _price = DoubleToStr(price, dig);
string _sl = DoubleToStr(sl, dig);
string _tp = DoubleToStr(tp, dig);
Print("Buy \"", symbol, "\", ", _lot, ", ", _price, ", ", slip, ", ", _sl, ", ", _tp, ", ", magic, ", \"", comment, "\"");
int res = OrderSend(symbol, OP_BUY, lot, price, slip, sl, tp, comment, magic);
if (res >= 0) {
Sleep(SleepOk);
return (res);
}
int code = GetLastError();
Print("Error opening BUY order: ", ErrorDescription(code), " (", code, ")");
Sleep(SleepErr);
return (-1);
}
int Sell(string symbol, double lot, double price, int slip, double sl, double tp, int magic, string comment="") {
RefreshRates();
int dig = MarketInfo(symbol, MODE_DIGITS);
price = NormalizeDouble(price, dig);
sl = NormalizeDouble(sl, dig);
tp = NormalizeDouble(tp, dig);
string _lot = DoubleToStr(lot, 1);
string _price = DoubleToStr(price, dig);
string _sl = DoubleToStr(sl, dig);
string _tp = DoubleToStr(tp, dig);
Print("Sell \"", symbol, "\", ", _lot, ", ", _price, ", ", slip, ", ", _sl, ", ", _tp, ", ", magic, ", \"", comment, "\"");
int res = OrderSend(symbol, OP_SELL, lot, price, slip, sl, tp, comment, magic);
if (res >= 0) {
Sleep(SleepOk);
return (res);
}
int code = GetLastError();
Print("Error opening SELL order: ", ErrorDescription(code), " (", code, ")");
Sleep(SleepErr);
return (-1);
}
bool CloseOrder(int ticket, double lot, double price, int slip) {
RefreshRates();
int dig = MarketInfo(OrderSymbol(), MODE_DIGITS);
string _lot = DoubleToStr(lot, 1);
string _price = DoubleToStr(price, dig);
Print("CloseOrder ", ticket, ", ", _lot, ", ", _price, ", ", slip);
bool res = OrderClose(ticket, lot, price, slip);
if (res) {
Sleep(SleepOk);
return (res);
}
int code = GetLastError();
Print("CloseOrder failed: ", ErrorDescription(code), " (", code, ")");
Sleep(SleepErr);
return (false);
}
Comments