Как кодировать? - страница 299

 

Пользовательский ввод времени на MQL4

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

Вот тот же код в Метастоке

{Customer Inputs}

Dy:=Input("Day",1,31,1);

Mn:=Input("Month",1,12,1);

Yr:=Input("Year",2000,2012,2010);

{Time Calculation}

Time:=Dy=DayOfMonth() AND Mn=Month() AND Yr=Year();

{Formula}

Start:= ValueWhen(1,Time,CLOSE);

{Output}

Start;

И вот результат

Я надеюсь сделать то же самое на MQL4

 

Попробуйте вот так:

#property indicator_chart_window

extern string startFrom = "2012.07.06 00:00";

int init() { return(0); }

int deinit() { ObjectDelete("hLine"); return(0); }

int start()

{

string name = "hLine";

int barShift = iBarShift(NULL,0,StrToTime(startFrom));

ObjectCreate(name,OBJ_TREND,0,0,0,0,0);

ObjectSet(name,OBJPROP_PRICE1,Close);

ObjectSet(name,OBJPROP_PRICE2,Close);

ObjectSet(name,OBJPROP_TIME1,Time);

ObjectSet(name,OBJPROP_TIME2,Time[0]);

return (0);

}

Просто скопируйте и вставьте его в какой-нибудь индикатор (это уже работающий индикатор) и прикрепите его к графику.

kappari:
Возможно ли написать код на MQL4, который может нарисовать горизонтальную линию, начиная с определенного пользователем бара и до конца графика?

Вот тот же код в Metastock

{Customer Inputs}

Dy:=Input("Day",1,31,1);

Mn:=Input("Month",1,12,1);

Yr:=Input("Year",2000,2012,2010);

{Time Calculation}

Time:=Dy=DayOfMonth() AND Mn=Month() AND Yr=Year();

{Formula}

Start:= ValueWhen(1,Time,CLOSE);

{Output}

Start;

И вот результат

Я надеюсь сделать то же самое с MQL4.
 
mladen:
Попробуйте вот так:
#property indicator_chart_window

extern string startFrom = "2012.07.06 00:00";

int init() { return(0); }

int deinit() { ObjectDelete("hLine"); return(0); }

int start()

{

string name = "hLine";

int barShift = iBarShift(NULL,0,StrToTime(startFrom));

ObjectCreate(name,OBJ_TREND,0,0,0,0,0);

ObjectSet(name,OBJPROP_PRICE1,Close);

ObjectSet(name,OBJPROP_PRICE2,Close);

ObjectSet(name,OBJPROP_TIME1,Time);

ObjectSet(name,OBJPROP_TIME2,Time[0]);

return (0);

}
Просто скопируйте и вставьте его в какой-нибудь индикатор (это уже рабочий индикатор) и прикрепите его к графику.

Вы лучшие, спасибо большое, Младен.

 

Привет, Младен,

Не могли бы вы рассказать мне больше об обосновании функций здесь? Я все еще не совсем понимаю. Спасибо

Терранс

mladen:
Попробуйте эту функцию :
int countOpenedOrders(int type)

{

int openedOrders = 0;

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

{

if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == false) break;

if(OrderSymbol() != Symbol()) continue;

if(OrderMagicNumber() != MagicNumber) continue;

if(OrderType() == type) openedOrders++;

}

return(openedOrders);

}

[/PHP]

To count opened buy orders, call it like this :

int openedBuys = countOpened(OP_BUY);

to count opened sell orders, call it like this :

[PHP]int openedSells = countOpened(OP_SELL);
и затем вы можете проверить
:if openedBuys==0 open buy

if openedSells==0 open sell

 

tkuan77

Вы хотели ограничить количество ордеров до 1 покупки и 1 продажи за раз.

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

пример :

int openedBuys = countOpened(OP_BUY); if (openedBuys==0) code for open a buy order

если openBuys не равен 0, вы не открываете новый ордер на покупку. Та же логика применима к продаже (это второй пример в этом посте).

tkuan77:
Привет, Младен,

Не могли бы вы рассказать мне больше об обосновании функций здесь? Я все еще не совсем понимаю. Спасибо

Терранс
 

Привет, Младен,

Возможно, я неправильно выразился. Я пытаюсь добиться того, чтобы при выполнении критериев покупки срабатывала покупка, а при повторном выполнении критериев покупки срабатывала еще одна покупка или продажа при выполнении критериев продажи. Однако максимальная сделка, которую я буду иметь в любой момент времени, будет равна 2.

Я уже пробовал ваш метод и все еще сталкиваюсь с тем, что система открывает 2 сделки одновременно, поэтому я попытался ограничить ее с помощью функции Bars с той же проблемой открытия советником 2 сделок одновременно.

В чем может быть причина? Может ли это быть связано с моей логикой?

С уважением,

Терранс

mladen:
tkuan77

Вы хотели ограничить ордера до 1 покупки и 1 продажи за раз.

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

пример :

int openedBuys = countOpened(OP_BUY); if (openedBuys==0) code for open a buy order
если openBuys равен чему угодно, кроме 0, вы не открываете новый ордер на покупку. Та же логика применима и к продаже (это второй пример в этом посте)
 

Вы можете добавить проверку, был ли уже открыт ордер какого-либо типа на текущем баре, и таким образом вы предотвратите открытие нового ордера на следующем тике. Если да (на текущем баре был открыт ордер), то новый ордер не открывается. Если нет, то вы можете открыть новый ордер. Вот функция, которая может посчитать вам ордера типа rewuired, открытые на текущем баре.

int countOpenedOnACurrentBar(int type)

{

int openedAtBar = 0;

datetime startTime = Time[0];

datetime endTime = Time[0]+Period()*60;

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

{

if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == false) break;

if(OrderMagicNumber() != MagicNumber) continue;

if(OrderSymbol() != Symbol()) continue;

if(OrderType() != type) continue;

if(OrderOpenTime()=endTime) continue;

openedAtBar++;

break;

}

return(openedAtBar);

}

tkuan77:
Привет, Младен,

Возможно, я неправильно выразился. Я пытаюсь добиться того, чтобы при выполнении критериев покупки срабатывала покупка, а при повторном выполнении критериев покупки срабатывала еще одна покупка или продажа при выполнении критериев продажи. Однако максимальная сделка, которую я буду иметь в любой момент времени, будет равна 2.

Я уже пробовал ваш метод и все еще сталкиваюсь с тем, что система открывает 2 сделки одновременно, поэтому я попытался ограничить ее с помощью функции Bars с той же проблемой открытия советником 2 сделок одновременно.

В чем может быть причина? Может ли это быть связано с моей логикой?

С уважением,

Терранс
 
tkuan77:
Привет, Младен,

Возможно, я неправильно выразился. Я пытаюсь добиться того, чтобы при выполнении критериев покупки срабатывала покупка, а при повторном выполнении критериев покупки срабатывала еще одна покупка или продажа при выполнении критериев продажи. Однако максимальная сделка, которую я буду иметь в любой момент времени, будет равна 2.

Я уже пробовал ваш метод и все еще сталкиваюсь с тем, что система открывает 2 сделки одновременно, поэтому я попытался ограничить ее с помощью функции Bars с той же проблемой открытия советником 2 сделок одновременно.

В чем может быть причина? Может ли это быть связано с моей логикой?

С уважением,

Терранс

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

 

Спасибо Mladen за помощь, однако я просто хочу уточнить у вас, нужно ли помещать код перед функцией long/short, между ними или где-то еще? Потому что постоянно выскакивает ошибка, и я не могу найти ее источник. И должно ли MagicNumber быть целым числом?

Терранс

total = OrdersTotal();

if(total < 2)

{

int countOpenedOnACurrentBar(int type)

{

int openedAtBar = 0;

datetime startTime = Time[0];

datetime endTime = Time[0]+Period()*60;

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

{

if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == false) break;

if(OrderMagicNumber() != MagicNumber) continue;

if(OrderSymbol() != Symbol()) continue;

if(OrderType() != type) continue;

if(OrderOpenTime()=endTime) continue;

openedAtBar++;

break;

}

return(openedAtBar);

}

if(isCrossed == 1 && shortEma > mainshortEma && longEma > mainshortEma)

{

ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,1,Ask-StopLoss*Point,Ask+TakeProfit*Point,

"Мой советник",12345,0,Green);

if(ticket>0)

{

if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))

Print("Открыт ордер BUY : ",OrderOpenPrice());

}

else Print("Ошибка при открытии ордера BUY : ",GetLastError());

return(0);

}

if(isCrossed == 2 && shortEma < mainshortEma && longEma < mainshortEma)

{

ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,1,Bid+StopLoss*Point,Bid-TakeProfit*Point,

"Мой советник",12345,0,Red);

if(ticket>0)

{

if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))

Print(" Открытордер SELL: ",OrderOpenPrice());

}

else Print("Ошибка при открытии ордера SELL : ",GetLastError());

return(0);

}

return(0);

}

mladen:
Можно добавить проверку, был ли уже открыт ордер какого-либо типа на текущем баре, и таким образом предотвратить открытие нового ордера на следующем тике. Если да (на текущем баре был открыт ордер), то новый ордер не открывается. Если нет, то вы можете открыть новый ордер. Вот функция, которая может посчитать ордера типа rewuired, открытые на текущем баре
int countOpenedOnACurrentBar(int type)

{

int openedAtBar = 0;

datetime startTime = Time[0];

datetime endTime = Time[0]+Period()*60;

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

{

if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == false) break;

if(OrderMagicNumber() != MagicNumber) continue;

if(OrderSymbol() != Symbol()) continue;

if(OrderType() != type) continue;

if(OrderOpenTime()=endTime) continue;

openedAtBar++;

break;

}

return(openedAtBar);

}

 

...

Терранс

Это функция. Поместите ее в конец вашего советника и разместите вызовы к ней там, где вы считаете нужным, чтобы проверить, открыт ли уже ордер на текущем баре.

tkuan77:
Спасибо, Младен, за помощь, однако я хочу уточнить у вас, нужно ли помещать код перед функцией long/short, между ними или где-то еще? Потому что, похоже, постоянно выскакивает ошибка, и я не могу найти ее источник. И должно ли MagicNumber быть целым числом?

Terrance

total = OrdersTotal();

if(total < 2)

{

int countOpenedOnACurrentBar(int type)

{

int openedAtBar = 0;

datetime startTime = Time[0];

datetime endTime = Time[0]+Period()*60;

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

{

if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == false) break;

if(OrderMagicNumber() != MagicNumber) continue;

if(OrderSymbol() != Symbol()) continue;

if(OrderType() != type) continue;

if(OrderOpenTime()=endTime) continue;

openedAtBar++;

break;

}

return(openedAtBar);

}

if(isCrossed == 1 && shortEma > mainshortEma && longEma > mainshortEma)

{

ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,1,Ask-StopLoss*Point,Ask+TakeProfit*Point,

"Мой советник",12345,0,Green);

if(ticket>0)

{

if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))

Print("Открыт ордер BUY : ",OrderOpenPrice());

}

else Print("Ошибка при открытии ордера BUY : ",GetLastError());

return(0);

}

if(isCrossed == 2 && shortEma < mainshortEma && longEma < mainshortEma)

{

ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,1,Bid+StopLoss*Point,Bid-TakeProfit*Point,

"Мой советник",12345,0,Red);

if(ticket>0)

{

if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))

Print("Открыт ордер SELL : ",OrderOpenPrice());

}

else Print("Ошибка при открытии ордера SELL : ",GetLastError());

return(0);

}

return(0);

}
Причина обращения: