Сделаем торговую версию скрипта, т.е. чтобы скрипт открывал сделку в нужном направлении, а не трейдеру приходилось это делать вручную.
Прежде всего во внешних параметрах нам понадобятся:
- Код: выделить все
input double dblQ = 0.01; // Размер торгового лота
input int intTP = 500; // TP
input int intSL = 500; // SL
input int intSI = 10; // Проскальзывание цены (пнт.)
- размер торгового лота (по умолчанию выставим минимальный объем);
- величина ТП в пунктах;
- величина СЛ в пунктах;
- величина проскальзывания цены в пунктах.
В функции OnStart() нам нужно будет ввести несколько переменных:
- Код: выделить все
int intDir = -1; // Направление торговли (OP_BUY -> 0, OP_SELL - > 1)
int intPos = 0; // Количество позиций, открытых данным скриптом
string strSym = ""; // пара с наибольшим проходом за неделю
double dblSL = 0;
double dblTP = 0;
intDir - переменная типа int соответствующая направлению торговли (0 - покупка, 1- продажа);
intPos - количество позиций, открытых данным скриптом. Здесь нужно уточнить, что в этой версии скрипта появляется мэджик для присвоения его сделкам, открытым данным скриптом, чтобы отличать их от всех остальных сделок, открытых по нужному активу;
strSym - пара с наибольшим проходом за неделю;
А также переменные dblSL и dblTP типа double для расчета уровней цены СЛ и ТП.
Мы будем также пользоваться давно разработанными функциями:
1. Для получения количества открытых позиций:
- Код: выделить все
int f_GetNumberOfPositions(string sy = "", int op = -1, int mn = -1)
{
/*
Версия : 28.10.2015 г.
Описание : Возвращает количество позиций (покупок или продаж или тех и других вместе)
Сторонних ресурсов не использует
Параметры:
sy - наименование инструмента ("" - любой символ, "0"- текущий символ)
op - операция {-1 любая; OP_BUY; OP_SELL}
mn - MagicNumber (-1 - любой маджик)
*/
int i, k = OrdersTotal(), kp = 0;
if(k == 0) return(0); // нет позиций вообще никаких
if(sy == "0") sy = Symbol();
for(i = 0; i < k; i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == sy || sy == "")
{
if(OrderType() == OP_BUY || OrderType() == OP_SELL)
{
if(op < 0 || OrderType() == op)
{
if(mn < 0 || OrderMagicNumber() == mn) kp++;
}
}
}
}
}
return(kp);
}
2. Для открытия позиций:
- Код: выделить все
void f_OpenPosition(string sy, int op, double ll, double sl, double tp, int mn, int si, string co)
{
/*
Версия : 13.09.2015
Описание : Открывает позицию по рыночной цене
Сторонних ресурсов не использует!!!
Параметры:
sy - наименование инструмента ("0" - текущий символ)
op - операция {OP_BUY; OP_SELL}
ll - лот
sl - уровень стоп (0)
tp - уровень тейк (0)
mn - MagicNumber
si - проскальзывание (slippage) (пнт.)
co - комментарий ("" - нет комментария)
*/
double pp;
int int_Tic = 0;
int int_Try = 5; // Количество торговых попыток
bool bol_Sou = true; // Использовать звуковой сигнал
string str_Suc = "ok.wav"; // Звук успеха
string str_Err = "timeout.wav"; // Звук ошибки
bool bol_Sin = true; // Использовать значок открытия сделки?
color clOpen = clrNONE,
clOpenBuy = LightBlue, // Цвет значка открытия покупки
clOpenSell = LightCoral; // Цвет значка открытия продажи
double dbl_Ask,
dbl_Bid;
if(sy == "0") sy = Symbol();
int int_Dig = (int) MarketInfo(sy, MODE_DIGITS);
for(int i = 1; i <= int_Try; i++)
{
if(!IsTesting() && (!IsExpertEnabled() || IsStopped()))
{
Print("OpenPosition(): Остановка работы функции");
break;
}
while(!IsTradeAllowed()) Sleep(5000);
RefreshRates();
if(op == OP_BUY)
{
dbl_Ask = MarketInfo(sy, MODE_ASK);
pp = dbl_Ask;
if(bol_Sin) clOpen = clOpenBuy;
}
else if(op == OP_SELL)
{
dbl_Bid = MarketInfo(sy, MODE_BID);
pp = dbl_Bid;
if(bol_Sin) clOpen = clOpenSell;
}
pp = NormalizeDouble(pp, int_Dig);
int_Tic = OrderSend(sy, op, ll, pp, si, sl, tp, co, mn, 0, clOpen);
if(int_Tic > 0)
{
if(bol_Sou) PlaySound(str_Suc);
Print("Функция OrderSend успешно выполнена");
break;
}
else if(int_Tic < 0)
{
if(bol_Sou) PlaySound(str_Err);
Print("OrderSend завершилась с ошибкой #", GetLastError());
}
}
}
3. Для расчета уровня ТП:
- Код: выделить все
double f_TP(string sy, int tp, int ty, double pr)
{
/*
Описание:
Функция осуществляет расчет уровня ТП
Параметры:
sy - наименование инструмента ("0" - текущий символ)
tp - величина ТП
ty - тип ордера
pr - цена входа или уровень входа (установки ордера)
*/
if(sy == "0") sy = Symbol();
int int_Dig = (int) MarketInfo(sy, MODE_DIGITS);
double dbl_Poi = MarketInfo(sy, MODE_POINT);
if(tp == 0) return(0);
if(ty == OP_BUY || ty == OP_BUYLIMIT || ty == OP_BUYSTOP)
{
return(NormalizeDouble(pr + tp * dbl_Poi, int_Dig));
}
else if(ty == OP_SELL || ty == OP_SELLLIMIT || ty == OP_SELLSTOP)
{
return(NormalizeDouble(pr - tp * dbl_Poi, int_Dig));
}
return(-1);
}
4. Для расчета уровня СЛ:
- Код: выделить все
double f_SL(string sy, int sl, int ty, double pr)
{
/*
Описание:
Функция осуществляет расчет уровня СЛ
Параметры:
sy - наименование инструмента ("0" - текущий символ)
sl - величина СЛ
ty - тип ордера
pr - цена входа или уровень входа (установки ордера)
*/
if(sy == "0") sy = Symbol();
int int_Dig = (int) MarketInfo(sy, MODE_DIGITS);
double dbl_Poi = MarketInfo(sy, MODE_POINT);
if(sl == 0) return(0);
if(ty == OP_BUY || ty == OP_BUYLIMIT || ty == OP_BUYSTOP)
{
return(NormalizeDouble(pr - sl * dbl_Poi, int_Dig));
}
else if(ty == OP_SELL || ty == OP_SELLLIMIT || ty == OP_SELLSTOP)
{
return(NormalizeDouble(pr + sl * dbl_Poi, int_Dig));
}
return(-1);
}
После нахождения индекса максимального элемента массива пройденных расстояний цены по семи валютным парам как в первой версии скрипта и фактического его значения, мы определяем направление торговли нашей позиции:
- Код: выделить все
if(intYmax >= 0) { intDir = 1; } // будем продавать
else if(intYmax < 0) { intDir = 0; } // будем покупать
Наименование символа по которму будет совершать сделку мы также получаем как в первой версии скрипта:
- Код: выделить все
strSym = strMSym[intJmax];
Далее, когда все необходимые значения параметров мы получили, будем осуществлять подготовку к отрытию позиции:
Вначале получаем количество уже открытых позиций, т.е. не открыли ли мы уже позицию ранее и она не закрылась. Тогда нам не нужно открывать новую позицию.
- Код: выделить все
intPos = f_GetNumberOfPositions(strSym, -1, intMagic);
Далее, работаем только с условием, что сделок нет (еще не открыли):
- Код: выделить все
if(intPos == 0) // Если нет сделок еще
{
// RefreshRates();
double dblAsk = MarketInfo(strSym, MODE_ASK);
double dblBid = MarketInfo(strSym, MODE_BID);
if(intDir == 0) // для покупки
{
dblSL = f_SL(strSym, intSL, intDir, dblBid);
dblTP = f_TP(strSym, intTP, intDir, dblAsk);
}
else if(intDir == 1) // для продажи
{
dblSL = f_SL(strSym, intSL, intDir, dblAsk);
dblTP = f_TP(strSym, intTP, intDir, dblBid);
}
f_OpenPosition(strSym, intDir, dblQ, dblSL, dblTP, intMagic, intSI, "");
}
Вначале получаем значения Ask и Bid по нужному нам торговому активу (валютной паре, по которой открываем позицию).
- Код: выделить все
double dblAsk = MarketInfo(strSym, MODE_ASK);
double dblBid = MarketInfo(strSym, MODE_BID);
Далее расчитываем величины ТП и СЛ в зависимости от направления торговой позиции (их расчет разный для покупки и продажи).
- Код: выделить все
if(intDir == 0) // для покупки
{
dblSL = f_SL(strSym, intSL, intDir, dblBid);
dblTP = f_TP(strSym, intTP, intDir, dblAsk);
}
else if(intDir == 1) // для продажи
{
dblSL = f_SL(strSym, intSL, intDir, dblAsk);
dblTP = f_TP(strSym, intTP, intDir, dblBid);
}
Наконец, открываем позицию:
- Код: выделить все
f_OpenPosition(strSym, intDir, dblQ, dblSL, dblTP, intMagic, intSI, "");
В завершении выводим в левый верхний угол окна графика на котором мы запускаем скрипт, информацию также как и в первой версии скрипта:
- Код: выделить все
Comment( "\n", "Размер прошлой недельной свечи (пнт.): ",
"\n", strMSym[0]," = ", intMDeY[0],
"\n", strMSym[1]," = ", intMDeY[1],
"\n", strMSym[2]," = ", intMDeY[2],
"\n", strMSym[3]," = ", intMDeY[3],
"\n", strMSym[4]," = ", intMDeY[4],
"\n", strMSym[5]," = ", intMDeY[5],
"\n", strMSym[6]," = ", intMDeY[6],
"\n", "------------------------",
"\n", "Ymax = ", intYmax,
"\n", "Sym = ", strSym);
Фактически, это справочная информация, информация для проверки. Сделка после выполнения скрипта открывается.
Ниже приведен скрин графика AUDUSD по которому открыта сделка после запуска скрипта (поскольку скрипт запущен в СР, то цена, само-собой, уже далеко ушла от уровня открытия недельной свечи).
Файл скрипта расположен в теме Мажорный Ва-Банк.