This script is designed to automatically trade on the Forex market using the MetaTrader platform. It attempts to combine elements of two trading strategies. Here's a breakdown of its logic:
Overall Strategy:
The script uses a combination of the Commodity Channel Index (CCI) indicator and a modified grid trading approach. It aims to open buy or sell orders based on CCI levels, and then potentially open additional orders if the initial trade goes against the script.
1. Initial Order Placement (CCI-Based):
- The script checks the value of the CCI indicator. The CCI measures how far the current price deviates from the average price.
- If the CCI value is above a certain level (defined by the input
L1
), the script places a "buy" order (predicting the price will go up). - If the CCI value is below another level (defined by the input
L2
), the script places a "sell" order (predicting the price will go down). - These initial orders have preset stop-loss and take-profit levels, which determine when the trade will automatically close to limit losses or secure profits.
2. "Grid" Trading Logic (Order Opening if Losing):
- The script also has a secondary strategy that acts if the initial trade is losing money.
- It checks if the current profit of open trades (with a specific "magic number" to identify trades managed by this script) is below a certain negative threshold (
OpenT
).OpenT
is effectively a tolerance or an allowed loss. - If the loss threshold is breached, the script attempts to open another order, either a buy or sell, depending on the position direction. This new order is placed at a certain distance based on price levels from the recent past, that are calculated on a certain amount of recent bars.
- This is similar to a grid strategy, where additional positions are opened as the price moves against the initial trade.
- It calculates these grid levels based on the highest and lowest prices within a certain number of recent bars (
N_MaxBar
) and aDelta
value to determine the distance between the current price and the new order placement.
3. Order Management (Closing Existing Orders):
- The script constantly monitors open orders.
- It checks the CCI value again.
- If the CCI moves in the opposite direction of the initial signal (e.g., was a buy, but now CCI is very low), the script will attempt to close the existing order. This utilizes different levels for CCI (
L3
,L4
,L5
,L6
). - The aim here is to cut losses if the market moves against the original prediction.
Important Points:
- Magic Numbers: The script uses "magic numbers" (
magic
andMAGICNUM
) to identify orders that it has opened itself. This is important to avoid interfering with other trading scripts or manual trades. - Input Parameters: The script relies heavily on input parameters that can be adjusted by the user. These include things like lot sizes, stop-loss and take-profit levels, CCI periods, and distance between orders.
- Error Handling: The script includes some error handling, printing messages if it fails to open or close orders.
In summary: This script is designed to place initial trades based on the CCI indicator, and then potentially open additional trades if those initial trades are losing money. It also has logic to close trades if the CCI signal changes or when certain CCI levels are reached. This is designed to capitalize on perceived market trends, but can also increase risk if the market behaves unexpectedly.
#property copyright "Copyright © 2009, Victor Chebotariov"
#property link "http://www.chebotariov.com"
#define magic 1052009
#define MAGICNUM 14052009
//+------------------------------------------------------------------+
//| SU.mq4 |
//| Copyright © 2009, murnail |
//| mailto:murnail@yandex.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009, murnail"
#property link "mailto:murnail@yandex.ru"
//Ïîïûòêà îáúåäåíèòü ÑÑI_TRADER è ñâîé ïåðâûé âàðèàíò, ãäå Ñåëë è Áàé îòä. ñîâåòíèêè...
//---- input parameters
extern double OpenT = 50;
extern double Lot = 0.6;
extern double Lot2 = 0.5;
extern double TakeProfit = 410;
extern int StopLoss = 150;
extern int N_MaxBar = 1000;
extern double Delta = 50000;
extern string t="Íàñòðîéêè èíäèêàòîðîâ";
extern int period = 580;
extern int L1 = 100;
extern int L2 = 240;
extern int L3 = 300;
extern int L4 = 250;
extern int L5 = 270;
extern int L6 = 280;
extern int slippage=3;
//extern int TakeProfit_L = 70; // Óðîâåíü òåéêïðîôèò â ïóíêòàõ
//extern int StopLoss_L = 147; // óðîâåíü ñòîïëîññ â ïóíêòàõ
//extern int TakeProfit_S = 50; // Óðîâåíü òåéêïðîôèò â ïóíêòàõ
//extern int StopLoss_S = 257; // óðîâåíü ñòîïëîññ â ïóíêòàõ
//+------------------------------------------------------------------+
//| CCI_TRADER expert start function |
//+------------------------------------------------------------------+
//********************
//ïîäñ÷åò òåêóùåãî êîëè÷åñòâà îòêðûòûõ ïîçèöèé íà ïîêóïêó
int CalcNumLongs()
{
int nLongs = 0;
for (int i = 0; i < OrdersTotal(); i++) {
int resL = OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
if (resL == 0) {
Print ("Îøèáêà ïðè âûáîðå îðäåðà: ", GetLastError());
return;
}
if (OrderSymbol() == Symbol() && OrderMagicNumber() == MAGICNUM
&& OrderType() == OP_BUY) nLongs++;
}
return (nLongs);
}
//ïîäñ÷åò òåêóùåãî êîëè÷åñòâà îòêðûòûõ ïîçèöèé íà ïðîäàæó
int CalcNumShorts()
{
int nShorts = 0;
for (int iS = 0; iS < OrdersTotal(); iS++) {
int resS = OrderSelect(iS, SELECT_BY_POS, MODE_TRADES);
if (resS == 0) {
Print ("Îøèáêà ïðè âûáîðå îðäåðà: ", GetLastError());
return;
}
if (OrderSymbol() == Symbol() && OrderMagicNumber() == MAGICNUM
&& OrderType() == OP_SELL) nShorts++;
}
return (nShorts);
}
//ïîïûòêà îòêðûòü íîâûé îðäåð
void CheckForOpen()
{
bool found = false;
//ïîèñê ïîñëåäíåãî îòêðûòîãî îðäåðà íà ïîêóïêó
for (int i = OrdersTotal() - 1; i >= 0; i--) {
int res = OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
if (res == 0) {
Print ("Îøèáêà ïðè âûáîðå îðäåðà: ", GetLastError());
return;
}
if (OrderMagicNumber() == MAGICNUM &&
OrderSymbol() == Symbol() && OrderType() == OP_BUY) {
found = true; //...íàøëè ïîñëåäíèé îòêðûòûé îðäåð íà ïîêóïêó
break;
//ïîèñê ïîñëåäíåãî îòêðûòîãî îðäåðà íà ïðîäàæó
}
if (OrderMagicNumber() == MAGICNUM &&
OrderSymbol() == Symbol() && OrderType() == OP_SELL) {
found = true; //...íàøëè ïîñëåäíèé îòêðûòûé îðäåð íà ïðîäàæó
break;
}
if (!found) {
Print ("Îøèáêà: íå ñìîãëè íàéòè îæèäàåìîãî îòêðûòîãî îðäåðà íà ïîêóïêó: ", GetLastError());
return;
}
//åñëè óáûòîê ïðåâûøàåò çíà÷åíèå ïåðåìåííîé OpenT, îòêðûâàåì îðäåð íà ïîêóïêó
if (OrderProfit() <= OpenT)
Print ("Óáûòîê ïðåâûñèë çíà÷åíèå, îòêðûâàåì íîâûé îðäåð");
{
double Min = Close[ArrayMinimum(Close, N_MaxBar, 1)];
Print (Bid, " ", Min - Delta * Point);
res = OrderSend (Symbol(), OP_BUY, Lot, Ask, 3, Min - Delta * Point, Ask + TakeProfit * Point, "", MAGICNUM, 0, Blue);
if (res == 0) {
Print ("Îøèáêà îòêðûòèÿ îðäåðà íà ïîêóïêó: ",GetLastError());
return;
}
if (!found) {
Print ("Îøèáêà: íå ñìîãëè íàéòè îæèäàåìîãî îòêðûòîãî îðäåðà íà ïðîäàæó: ", GetLastError());
return;
}
}
}
//åñëè óáûòîê ïðåâûøàåò çíà÷åíèå ïåðåìåííîé OpenT, îòêðûâàåì îðäåð íà ïðîäàæó
if (OrderProfit() <= OpenT) {
Print (OrderProfit());
double Max = Close[ArrayMaximum(Close, N_MaxBar, 1)];
Print (Bid, " ", Max + Delta * Point);
res = OrderSend (Symbol(), OP_SELL, Lot, Bid, 3, Max + Delta * Point, Bid - TakeProfit * Point, "", MAGICNUM, 0, Red);
if (res == 0) {
Print ("Îøèáêà îòêðûòèÿ îðäåðà íà ïðîäàæó: ",GetLastError());
return;
}
if (!found) {
Print ("Îøèáêà: íå ñìîãëè íàéòè îæèäàåìîãî îòêðûòîãî îðäåðà íà ïîêóïêó: ", GetLastError());
return;
}
}
}
//********************
//ÍÀ×ÀËÎ ÐÀÁÎÒÛ
int start()
{
//----
double val = iCCI(NULL ,0,period,PRICE_TYPICAL,0);
int ticket, cnt, total=OrdersTotal();
if(total<1)
{
if(val>L1)
{
ticket=OrderSend(Symbol(),OP_BUY,Lot2,Ask,slippage,Ask-StopLoss*Point,
Ask+TakeProfit*Point,"CCI_TRADER",magic,0,Green);
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("BUY order opened : ",OrderOpenPrice());
//*****************
{
//ïðîâåðêà íåîáõîäèìûõ óñëîâèé äëÿ òîðãîâëè
if (Bars < N_MaxBar || IsTradeAllowed() == false) return;
Print ("Îòêðûòûõ îðäåðîâ Áàé íåò ");
//åñëè íåò îòêðûòûõ ïîçèöèé, îòêðûâààåì ïîçèöèþ íà ïîêóïêó
if (CalcNumLongs() == 0) {
double Min = Close[ArrayMinimum(Close, N_MaxBar, 1)];
Print (Bid, " ", Min - Delta * Point);
int resL = OrderSend (Symbol(), OP_BUY, Lot, Ask, 3, Min - Delta * Point, Ask + TakeProfit * Point, "", MAGICNUM, 0, Blue);
Print ("Îòêðûëè îðäåð Ñåëë");
if (resL == 0) {
Print ("Îøèáêà îòêðûòèÿ îðäåðà íà ïîêóïêó: ",GetLastError());
return;
}
}
else CheckForOpen();
return;
}
//*****************
}
else
{
Print("Error opening BUY order : ",GetLastError());
return(0);
}
}
else if(val<-L2)
{
ticket=OrderSend(Symbol(),OP_SELL,Lot2,Bid,slippage,Bid+StopLoss*Point,
Bid-TakeProfit*Point,"CCI_TRADER",magic,0,Red);
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("SELL order opened : ",OrderOpenPrice());
//*************
{
//ïðîâåðêà íåîáõîäèìûõ óñëîâèé äëÿ òîðãîâëè
if (Bars < N_MaxBar || IsTradeAllowed() == false) return;
Print ("Îòêðûòûõ îðäåðîâ Ñåëë íåò ");
//åñëè íåò îòêðûòûõ ïîçèöèé, îòêðûâààåì ïîçèöèþ íà ïðîäàæó
if (CalcNumShorts() == 0) {
double Max = Close[ArrayMaximum(Close, N_MaxBar, 1)];
Print (Bid, " ", Max + Delta * Point);
int resS = OrderSend (Symbol(), OP_SELL, Lot, Bid, 3, Max + Delta * Point, Bid - TakeProfit * Point, "", MAGICNUM, 0, Red);
Print ("Îòêðûëè îðäåð Ñåëë");
if (resS == 0) {
Print ("Îøèáêà îòêðûòèÿ îðäåðà íà ïðîäàæó: ",GetLastError());
return;
}
}
else CheckForOpen();
return;
}
//*************
}
else
{
Print("Error opening SELL order : ",GetLastError());
return(0);
}
}
}
if (OrderMagicNumber()==magic)
{
if(OrderType()<=OP_SELL && // check for opened position
OrderSymbol()==Symbol()) // check for symbol
{
if(OrderType()==OP_BUY) // long position is opened
{
// should it be closed?
if(val<-L3)
{
OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet); // close position
return(0); // exit
}
}
else // go to short position
{
// should it be closed?
if(val>L4)
{
OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet); // close position
return(0); // exit
}
}
}
}
for(cnt=0;cnt<total;cnt++)
{
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
if(OrderType()<=OP_SELL && // check for opened position
OrderSymbol()==Symbol()) // check for symbol
{
if(OrderType()==OP_BUY) // long position is opened
{
// should it be closed?
if(val<-L5)
{
OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet); // close position
return(0); // exit
}
}
else // go to short position
{
// should it be closed?
if(val>L6)
{
OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet); // close position
return(0); // exit
}
}
}
}
//----
return(0);
}
//+------------------------------------------------------------------+
Comments