Перейти к содержанию
Форекс Форум трейдеров Академии «MasterForex-V»

Создание Советника


Рекомендуемые сообщения

Советник создаётся так же, как и индикатор или скрипт, только и всего, что нужно указать что вы создаёте советник и ввести нужные аргументы.

 

Начнём мы эту тему с очень простой вещи. Это будет даже не советник, а иммитация советника. Он нам очень пригодится для отладки индикаторов.

 

Там всего несколько строчек:

[MQL]

int start() {

string mm, dd, hh, mi;

if(Month()<10) mm = "0"+Month(); else mm = Month();

if(Day()<10) dd = "0"+Day(); else dd = Day();

if(Hour()<10) hh = "0"+Hour(); else hh = Hour();

if(Minute()<10) mi = "0"+Minute(); else mi = Minute();

Comment("Дата: "+Year()+"-"+mm+"-"+dd+" "+hh+":"+mi+" Цена: ",NormalizeDouble(Bid,2));

return(0);

}

[/MQL]

Всё, что он делает, так это выводит вычисленную дату и текущую цену. Можно было бы и этого не делать, но всё-таки надо было его (наш первый советник) чем-то занять! :biggrin:

 

Работает он просто: кидаете его на график и запускаете тестер с визуализацией. Всё, теперь можно в окно визуализации тестера кинуть свой индикатор и проследить на истории как он работает...

Ссылка на комментарий
Поделиться на другие сайты

  • Ответов 200
  • Создана
  • Последний ответ

Топ авторов темы

Топ авторов темы

Изображения в теме

Уважаемый Liv, а дальше вы будете вести эту ветку? какой-нибудь пример по советнику, котрый открывает и закрывает сделки при определенных условиях????

 

я вот например хочу написать эксперт, который при совпадении 3-х индикаторов будет открывать сделки в нужную сторону... но, к сожеленнию, у меня не получаеться пока, можно ли внутри индикаторов присвоить каждому состоянию цифру 1 или 0, а потом создать эксперт в который автоматически будет поступать сигнал от 3-х индикаторов (и если все три единицы - то бай, если все три нуля - то закрывать бай и открывать селл, а если вразнобой цифры, то ничего не менять)

 

Может пример такого кода??? научите??? а Вообще большое спасибо за ветку :) :wub:

Ссылка на комментарий
Поделиться на другие сайты

LiV, Помогите, вставить в этого эксперта возможность закрытия всех ордеров в заданое время суток?

 

extern double Lots=0.1;

extern int Profit=20;

extern int Stop=55;

extern int Slippage=5;

extern string Symb="*";

extern string StartTime="06:00";

datetime TimeStart;

double stoplevel,profitlevel;

string SMB;

bool trade=false;

 

 

int start()

{

int i,b,SL,BL;

BL=b+50;

 

TimeStart=StrToTime(StartTime);

 

 

if(CurTime()<TimeStart || CurTime()>TimeStart+300) { trade=false; return(0); }

 

if(trade) return(0);

 

if(((iClose(SMB,PERIOD_D1,1)+iHigh(SMB,PERIOD_D1,1 )+iLow(SMB,PERIOD_D1,1))/3)<iClose(SMB,PERIOD_D1,1)) b=OP_BUY ;

else b=OP_SELL;

 

if(b==OP_BUY)

{

 

if(Stop==0) stoplevel=0; else stoplevel=MarketInfo(SMB,MODE_ASK)-Stop*MarketInfo(SMB,MODE_POINT);

 

if(Profit==0) profitlevel=0; else profitlevel=MarketInfo(SMB,MODE_ASK)+Profit*Market Info(SMB,MODE_POINT);

i=OrderSend(SMB,OP_BUY,Lots,MarketInfo(SMB,MODE_AS K),Slippage,stoplevel,profitlevel,NULL,MAGIC,0,Red );

 

if(i!=-1) trade=true;

 

}

 

if(b==OP_SELL)

{

if(Stop==0) stoplevel=0; else stoplevel=MarketInfo(SMB,MODE_BID)+Stop*MarketInfo (SMB,MODE_POINT);

if(Profit==0) profitlevel=0; else profitlevel=MarketInfo(SMB,MODE_BID)-Profit*MarketInfo(SMB,MODE_POINT);

i=OrderSend(SMB,OP_SELL,Lots,MarketInfo(SMB,MODE_B ID),Slippage,stoplevel,profitlevel,NULL,MAGIC,0,Bl ue);

if(i!=-1) trade=true;

}

return(0);

}

 

int init()

{

int i;

 

if(Symb=="*") SMB=Symbol(); else SMB=Symb;

return(0);

}

 

int deinit() { return(0); }

//+------------------------------------------------------------------+

Ссылка на комментарий
Поделиться на другие сайты

LiV, Помогите, вставить в этого эксперта возможность закрытия всех ордеров в заданое время суток?

Это не очень сложно.

 

Воспользуемся скриптом, который уже выставлялся на нашем форуме - закрытие всех ордеров.

 

Сначала нужно указать некоторые параметры:

 

// это время закрытия всех ордеров

extern string CloseTime="22:00";

// этот параметр отсутствовал в советнике, хотя и должен был быть

extern int MAGIC=77777;

 

Теперь функция закрытия всех ордеров, которые открыл этот советник:

 

[MQL]

//////////////////////////////////////////////////////////////////////

void CloseAll() {

int total = OrdersTotal();

for(int i=total-1;i>=0;i--) {

OrderSelect(i, SELECT_BY_POS);

if(OrderMagicNumber() == MAGIC) {

int type = OrderType();

 

bool result = false;

 

switch(type) {

case OP_BUY:

result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_BID), 5, Red );

break;

case OP_SELL:

result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_ASK), 5, Red );

break;

}

if(result == false) {

Alert("Order " , OrderTicket() , " failed to close. Error:" , GetLastError() );

}

}

}

}

[/MQL]

Как вы заметили, здесь будут закрываться только те ордера, которые открылись именно этим советником. Для этого стоит проверка так называемого Магического числа (MAGIC). В этот параметр записывается любое целое число. Например, номер вашего торгового счёта.... или дата вашего рождения! :blush: Это позволяет торговать параллельно советнику не мешая друг другу.

 

Ну и осталось только вставить в функцию start() следующий код (где-нибудь в самое начало):

 

[MQL]

datetime TimeClose = StrToTime(CloseTime);

if(TimeCurrent() > TimeClose) {

CloseAll();

return(0);

}

[/MQL]

 

Ну, а весь полностью файл представлен здесь:

new_expert.zip

Ссылка на комментарий
Поделиться на другие сайты

Привет!

Какой именно индикатор? Как его использовать - визуально или не визуально?

Нужно же сразу говорить, что интересует!

Ссылка на комментарий
Поделиться на другие сайты

Привет!

Какой именно индикатор? Как его использовать - визуально или не визуально?

Нужно же сразу говорить, что интересует!

Индикатор Heiken AshiR. Использовать не визуально. Спасибо, что откликнулись. Загружать файл не разрешает форум, поэтому показываю его код.

//

//| Heiken AshiR.mq4 |

//|

//---- отрисовка индикатора в отдельном окне

#property indicator_separate_window

//---- количество индикаторных буферов

#property indicator_buffers 2

//---- цвета индикатора

#property indicator_color1 Lime

#property indicator_color2 Red

//---- верхнее и нижнее ограничение шкалы окна индикатора

#property indicator_maximum 1.1

#property indicator_minimum 0.9

//---- толщина индикаторных линий

#property indicator_width1 1

#property indicator_width2 1

//---- ВХОДНЫЕ ПАРАМЕТРЫ ИНДИКАТОРА

extern int Simbol=110;

//---- индикаторные буферы

double HighBuffer[];

double LowBuffer [];

//+------------------------------------------------------------------+

//| Heiken AshiR initialization function |

//+------------------------------------------------------------------+

int init()

{

//---- Стиль исполнения графика виде символов

SetIndexStyle(0,DRAW_ARROW);

SetIndexStyle(1,DRAW_ARROW);

//---- Определение стиля точечных объектов

SetIndexArrow(0,Simbol);

SetIndexArrow(1,Simbol);

//---- 2 индикаторных буфера использованы для счёта

SetIndexBuffer(0,HighBuffer);

SetIndexBuffer(1,LowBuffer );

//---- установка значений индикатора, которые не будут видимы на графике

SetIndexEmptyValue(0,0);

SetIndexEmptyValue(1,0);

//---- имена для окон данных и лэйбы для субъокон

IndicatorShortName("Heiken Ashi");

SetIndexLabel (0,"Heiken Ashi");

SetIndexLabel (1,"Heiken Ashi");

//---- установка номера бара, начиная с которого будет отрисовываться индикатор

SetIndexDrawBegin(0,1);

SetIndexDrawBegin(1,1);

//----

 

return(0);

}

//+------------------------------------------------------------------+

//| Heiken AshiR iteration function |

//+------------------------------------------------------------------+

int start()

{

//---- Введение переменных с плавающей точкой

double Trend;

//----+ Введение целых переменных и получение уже подсчитанных баров

int MaxBar,limit,counted_bars=IndicatorCounted();

//---- проверка на возможные ошибки

if (counted_bars<0)return(-1);

//---- последний подсчитанный бар должен быть пересчитан

if (counted_bars>0) counted_bars--;

//---- определение номера самого старого бара, начиная с которого будет произедён пересчёт новых баров

MaxBar=Bars-2;

limit=(Bars-1-counted_bars);

//---- инициализация нуля

if (limit>MaxBar)

{

limit=MaxBar;

HighBuffer[bars-1]=0;

LowBuffer [bars-1]=0;

}

//----

for (int bar=limit; bar>=0;bar--)

{

Trend = iCustom(NULL,0,"Heiken Ashi#",1,bar)-iCustom(NULL,0,"Heiken Ashi#",0,bar);

if (Trend>0){HighBuffer[bar]=1; LowBuffer [bar]=0;}

if (Trend<0){LowBuffer [bar]=1; HighBuffer[bar]=0;}

}

return(0);

}

//+---------------------------------------------------------------------------------+

Ссылка на комментарий
Поделиться на другие сайты

В принципе, из всего исходного текста этого индикатора достаточно ввести в советник только несколько строк:

1. в самом начале обявить массивы:

double HighBuffer[];

double LowBuffer[];

 

2. а затем в функции start() сделать расчёт:

int MaxBar,limit,counted_bars=IndicatorCounted();

//---- проверка на возможные ошибки

if (counted_bars<0)return(-1);

//---- последний подсчитанный бар должен быть пересчитан

if (counted_bars>0) counted_bars--;

//---- определение номера самого старого бара, начиная с которого будет произедён пересчёт новых баров

MaxBar=Bars-2;

limit=(Bars-1-counted_bars);

//---- инициализация нуля

if (limit>MaxBar)

{

limit=MaxBar;

HighBuffer[bars-1]=0;

LowBuffer [bars-1]=0;

}

//----

for (int bar=limit; bar>=0;bar--)

{

Trend = iCustom(NULL,0,"Heiken Ashi#",1,bar)-iCustom(NULL,0,"Heiken Ashi#",0,bar);

if (Trend>0){HighBuffer[bar]=1; LowBuffer [bar]=0;}

if (Trend<0){LowBuffer [bar]=1; HighBuffer[bar]=0;}

}

После этого можно использовать массивы HighBuffer и LowBuffer для своих расчётов в советнике.

 

 

Второй способ заключается в том, чтобы сам этот индикатор скомпиллировать - получить файл "Heiken AshiR.ex4" и уже его использовать:

CurValue1 = iCustom(NULL,0,"Heiken AshiR",0,bar);

CurValue2 = iCustom(NULL,0,"Heiken AshiR",1,bar);

Как, вероятно, уже понятно, эти переменные будут содержать значения соответствующих массивов индикатора на определённом баре.

Ссылка на комментарий
Поделиться на другие сайты

В принципе, из всего исходного текста этого индикатора достаточно ввести в советник только несколько строк:

.....

А как указать, чтобы советник не открывал сделки когда цвет индикатора и направление открытия сделки не совпадают и открывал только когда они совпадают?

post-1859-1189140345_thumb.jpg

Ссылка на комментарий
Поделиться на другие сайты

А как указать, чтобы советник не открывал сделки когда цвет индикатора и направление открытия сделки не совпадают и открывал только когда они совпадают?

Ну, это просто...

Зная, что первый индикатор - зелёный, а второй красный можно делать проверку на ненулевое значение. Следовательно, если

CurValue1 = iCustom(NULL,0,"Heiken AshiR",0,bar);

больше нуля, значит линия зелёная и, соответственно, только BUY

 

и наоборот, если

CurValue2 = iCustom(NULL,0,"Heiken AshiR",1,bar);

больше нуля, значит линия красная и только SELL

Ссылка на комментарий
Поделиться на другие сайты

  • 3 недели спустя...

Помогите создать советника.

 

Описание.

 

Советник должен работать только с двумя ордерами одновременно и от определенных, вручную заданых уровней.

Например, если цена идёт снизу вверх, то на определенном уровне поствить 2 ордера, которые соотвественно в етом случае должны сработать, как buy stop и sell limit. (и наоборот, если цена идёт сверху вниз)

TP должен быть задан также вручную. Как определенный уровень цены!

LS 20 pips от уровня покупки, продажи , в обе стороны. Если сработал лось, или ТП , то покупка, или продажа, должна быть совершена на том же уровне ещё раз. При ТП естественно сразу в обе стороны опять.

 

В общем в етом смысле должна быть вся програма, где можно задавать уровни откуда происходят покупки, продажи , TPs, вручную, но что бы операции совершались автоматически.

Уровни определенный переиод времени остаются фиксированые, меняются только по усмотрению юзера проги, поетому нужно задавать их вручную.

 

Уровней можно вводить безконечно много.

 

 

Мануально стратегия получается, но риск - пропустить часть движения.

 

Если кто может, помогите плз, или объясните, как такое можно соорудить?

 

Заранее благодарен :excl:

Ссылка на комментарий
Поделиться на другие сайты

Liv приветствую.

 

У меня такой вопрос, у тебя нет случайно такого советника, или его сделать, который бы работал по такому принципу, по открытой сделке ждет когда прибыль будет + 10 п, советник выставляет стоп-лос на уровне + 1 п, и потом включается трейлинг стоп 25 п

Ссылка на комментарий
Поделиться на другие сайты

Привет!

У меня советников нет, я торгую только на демо, а в этом случае советник бессмылен!

Но немного позднее мы займёмся созданием советников...

Просто сейчас у меня катастрофически не хватает времени!

Ссылка на комментарий
Поделиться на другие сайты

  • 1 месяц спустя...

Всем привет.

 

Liv подскажи пожалуйста.

Нет уже сил.

Есть советник. В нем не првильно реализовано закрытие ордеров по достижению условия MA1>MA2.

Что неправильно и как переделать. Вот код.

 

//+------------------------------------------------------------------+

//| Sidus_EA_VII.mq4 |

//| Copyright © 2006, MetaQuotes Software Corp. |

//| http://www.metaquotes.net |

//+------------------------------------------------------------------+

#property copyright "Copyright © 2006, MetaQuotes Software Corp."

#property link "http://www.metaquotes.net"

 

#define MAGIC 1828212

extern double TakeProfit = 70;

extern double StopLoss = 35;

extern double TrailingStop = 10;

extern double Lots = 0.1;

extern double MaximumRisk = 0.05;

extern double DecreaseFactor = 2;

extern int Slippage = 0;

extern string Name_Expert = "Sidus_EA_VII";

double spread = 1.5;

 

void deinit() {

Comment("");

}

//+------------------------------------------------------------------+

//| |

//+------------------------------------------------------------------+

int start(){

if(Bars<100){

Print("bars less than 100");

return(0);

}

if(StopLoss<8){

Print("StopLoss less than 10");

return(0);

}

int cnt, ticket, total;

 

double RSI=iRSI(NULL,0,21,PRICE_CLOSE,0);

double Price = iOpen(Symbol(), NULL, 0);

double Trigger=iMA(NULL,0,3,0,MODE_EMA,PRICE_CLOSE,0);

double MA1=iMA(NULL,0,6,0,MODE_EMA,PRICE_CLOSE,0);

double MA2=iMA(NULL,0,9,0,MODE_EMA,PRICE_CLOSE,0);

 

if(AccountFreeMargin()<(1*Lots)){

Print("We have no money. Free Margin = ", AccountFreeMargin());

return(0);

}

if (!ExistPositions()){

 

if ((Price>Trigger) && (MA1>MA2) && (RSI<60)){

 

ticket = OrderSend(Symbol(),OP_BUY, LotsOptimized() ,Ask, 3, Ask - StopLoss*Point,

Ask + TakeProfit*Point, "Sidus_EA_VII", 1828212, 0, Green);

return(0);

if(OrderType()==OP_BUY)

{

if(MA1<MA2) OrderClose(OrderTicket(),OrderLots(),Bid,3,Lime);

}

return(0);

}

 

 

if ((Price<Trigger) && (MA1<MA2) && (RSI>40)){

 

ticket = OrderSend(Symbol(), OP_SELL,LotsOptimized(),Bid, 3, Bid + StopLoss*Point,

Bid - TakeProfit*Point, "Sidus_EA_VII", 1828212, 0, Red);

return(0);

if(OrderType()==OP_SELL)

{

if(MA1>MA2) OrderClose(OrderTicket(),OrderLots(),Ask,3,Lime);

 

}

}

}

TrailingPositionsBuy(TrailingStop);

TrailingPositionsSell(TrailingStop);

return (0);

}

bool ExistPositions() {

for (int i=0; i<OrdersTotal(); i++) {

if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {

if (OrderSymbol()==Symbol() && OrderMagicNumber()==MAGIC) {

return(True);

}

}

}

return(false);

}

void TrailingPositionsBuy(int trailingStop) {

for (int i=0; i<OrdersTotal(); i++) {

if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {

if (OrderSymbol()==Symbol() && OrderMagicNumber()==MAGIC) {

if (OrderType()==OP_BUY) {

if (Bid-OrderOpenPrice()>trailingStop*Point) {

if (OrderStopLoss()<Bid-trailingStop*Point)

ModifyStopLoss(Bid-trailingStop*Point);

}

}

}

}

}

}

void TrailingPositionsSell(int trailingStop) {

for (int i=0; i<OrdersTotal(); i++) {

if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {

if (OrderSymbol()==Symbol() && OrderMagicNumber()==MAGIC) {

if (OrderType()==OP_SELL) {

if (OrderOpenPrice()-Ask>trailingStop*Point) {

if (OrderStopLoss()>Ask+trailingStop*Point || OrderStopLoss()==0)

ModifyStopLoss(Ask+trailingStop*Point);

}

}

}

}

}

}

void ModifyStopLoss(double ldStopLoss) {

bool fm;

fm = OrderModify(OrderTicket(),OrderOpenPrice(),ldStopLoss,OrderTakeProfit(),0,CLR_NONE);

}

 

 

return(0);

 

double LotsOptimized()

{

double lot = Lots;

int orders = HistoryTotal(); // history orders total

int losses = 0; // number of losses orders without a break

//---- select lot size

lot = NormalizeDouble(AccountFreeMargin()*MaximumRisk / 500, 1);

//---- calcuulate number of losses orders without a break

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);

}

//---- return lot size

if(lot < 0.1)

lot = 0.1;

return(lot);

}

//+------------------------------------------------------------------+

 

//+------------------------------------------------------------------+

Ссылка на комментарий
Поделиться на другие сайты


×
×
  • Создать...