Обучение языку MQL4 под MetaTrader 4📌

От xbms, 13 апреля, 2013 в Уголок Программиста

#1851

Как вариант ;)

Спойлер

extern int MagicNumber1 = ;
extern int MagicNumber2 = ;
--------------------------------------
int CloseAll(){
if(CountOrderswithMagic1()==0&&CountOrderswithMagic2()!=0){
for(int i = OrdersTotal()-1;i>=0;i++){
if(OrderSelect(i,SELECT_BY_POS){
if(OrderMagicNumber()==MagicNumber2){
OrderClose(OrdreTicket(),OrderLots()... и.т.д.); }}}}
return(0);}
--------------------------------------------------
int CountOrderswithMagic1(){
int count = 0;
for(int i = OrdersTotal()-1;i>=0;i++){
if(OrderSelect(i,SELECT_BY_POS){
if(OrderMagicNumber()==MagicNumber1){
count ++;}}}
return (count);}
--------------------------------------------------
int CountOrderswithMagic2(){
int count = 0;
for(int i = OrdersTotal()-1;i>=0;i++){
if(OrderSelect(i,SELECT_BY_POS){
if(OrderMagicNumber()==MagicNumber2){
count ++;}}}
return (count);}

#1852

Доброго времени суток уважаемые! Подскажите пожалуйста, как сделать канал вокруг МА, в терминале все просто. В настройках индикатора добавляешь уровни 100 и -100, как они тут же отрисовываются на графике... А каким образом это сделать в советнике?

#1853


Доброго времени суток уважаемые! Подскажите пожалуйста, как сделать канал вокруг МА, в терминале все просто. В настройках индикатора добавляешь уровни 100 и -100, как они тут же отрисовываются на графике... А каким образом это сделать в советнике?



extern int indent = 10; // Отступ от MA , выраженный в пунктах

double MA = iMA(твои настройки);
double MA_UP = MA+ NormalizeDouble(indent*Point, Digits); // верхняя граница канала
double MA_Down = MA- NormalizeDouble(indent*Point, Digits); // нижняя граница канала

Или имеется ввиду рисовать их при тестировании?
Если да, то просто при визуализации кинь шаблон твоей тс на график.

Добавлено: 27-01-2015 10:47:11


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



То есть вот такую функцию можно использовать?
Спойлер


if (FindLastResult() > 0) Print("Последний ордер закрылся с прибылью");
if (FindLastResult()

int FindLastResult()
{
int result = 0;

for (int trade = OrdersTotal()-1; trade>=0; trade--)
{
bool select1 = OrderSelect(trade, SELECT_BY_POS, MODE_TRADES); // bool чтобы не требовалось проверки
if (OrderSymbol() == Symbol() && (OrderMagicNumber() == Magic_143256 ))
{
if (OrderType() == OP_SELL)
{
double open = OrderOpenPrice();
double close = OrderClosePrice();

if (open - close >=0) result = 1;
if (open - close }

if (OrderType() == OP_BUY)
{
double open = OrderOpenPrice();
double close = OrderClosePrice();

if (open - close if (open - close > 0) result = -1;
}
}
}
return(result);
}



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

Изменено 27 января, 2015 пользователем oleguitar

#1854

Благодарю вас oleguitar! Это как раз то что нужно!!! :)

#1855

друзья кто подскажет как переписать урок 5 на новый билд

#1856
oleguitar, ну вроде что-то типа этого нужно:

Спойлер

double FindLastResult()
{
for (int trade = OrdersTotal()-1; trade>=0; trade--)
{
if (OrderSelect(trade, SELECT_BY_POS, MODE_HISTORY))
{
if (OrderSymbol() == Symbol() && (OrderMagicNumber() == Magic_143256 ))
{
if (OrderType() == OP_SELL || OrderType() == OP_BUY)
{
result = OrderProfit() + OrderSwap() + OrderCommission();
break;
}
}
}
}
return(result);
}



Только переменную result, нужно объявить на глобальном уровне с типом double, ну а дальше проводите сравнение, какое значение у переменной, (>0) или (
#1857

вот в этом месте:

Спойлер

if (CountTradesHistory() == 0 && CountTrades() == 0)
{
ticket = OrderSend (Symbol(), OP_BUY, Lots, Ask, Slippage, 0, 0, "Buy", Magic, 0, Blue);
if (ticket > 0)
{
TP = NormalizeDouble (Ask + TakeProfit * Point, Digits);
SL = NormalizeDouble (Bid - StopLoss * Point, Digits);
OrderModify (ticket, OrderOpenPrice(), SL, TP, 0);


надо сделать так: ИМХО
Спойлер

if(OrderSend (Symbol(), OP_BUY, Lots, Ask, Slippage, 0, 0, "Buy", Magic, 0, Blue)){
TP = NormalizeDouble (Ask + TakeProfit * Point, Digits);
SL = NormalizeDouble (Bid - StopLoss * Point, Digits);
for(int i = OrdersTotal()-1;i>=0;i++){
if(OrderSelect(i,SELECT_BY_POS)){
if(OrderMagicNumber() == /*твой меджик/* && OrderSymbol()==Symbol()){
if(OrderTakeProfit() != TP && OrderStopLoss() != SL){
OrderModify(OrderTicket(), OrderOpenPrice(), SL, TP, 0);}}}}}


Функции OrderModify() и OrderOpenPrice() могут быть использованы только после того, как ордер выбран функцией OrderSelect()
а вот это: "if(OrderTakeProfit() != TP && OrderStopLoss() != SL)" нужно, чтобы он не модифицировал ордер на каждом тике.

Изменено 28 января, 2015 пользователем Whitebars

#1858

Привет!

Может быть, кто-то знает, что означает это ошибка и как это исправить ?

'2223503': order buy 0.10 EURUSD opening at 1.13389 sl: 0.00000 tp: 0.00000 failed [Hedge is prohibited]

Спасибо

#1859

error code 149 ("Hedge is prohibited") that is returned to a client at the attempt to open an opposite position to an existing one if hedging is prohibited.

промт перевёл так: ошибка 149 ( " хеджирования запрещено " ) , который возвращается клиенту при попытке открыть противоположную позицию к уже существующей , если хеджирование запрещено.

#1860

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

Спасибо

( Sorry Google translate :) )

#1861

наверно от брокера зависит..

#1862

Возможно, в данном ДЦ локирование/хэджирование (открытие встречной позиции до закрытия имеющейся) запрещено.

ДЦ американский?

#1863

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

Спасибо

#1864

1. перед тем как открыть позицию на buy, удалить позиции на sell на этом инструменте
2. открыть встречную позицию по инструменту с высоким уровнем корреляции к вашему инструменту
(/v-pomosch-treyderu/4/statya-korrelyatsiya-valyut/212/?do=findComment&comment=183638)
3. сменить ДЦ
больше ничего в голову не приходит

Изменено 28 января, 2015 пользователем Whitebars

#1865

Спасибо что-то буду делать .

#1866

Доброе время суток. Помогите кто сможет. в сове выдает вот такую белиберду-
order buy 0.01 EURUSD opening at market sl: 1.12234 tp: 1.13949 failed [Invalid S/L or T/P]
order buy market 0.01 EURUSD sl: 1.12234 tp: 1.13949


Исправте кто умеет будте добры.

Stat_Euclidean_Metric.mq47 скач.

#1867
SVBond, проблема похоже проявляется на ECN счёте, а то так бегло посмотрел код, там параметры SL и TP заданы сразу при установке ордера?
#1868

Подскажите, в чем я не прав?

Спойлер


//+------------------------------------------------------------------+
//| Безубыток по пипсам |
//+------------------------------------------------------------------+
void BEOnPips()
{
double PriceBEBuy=0;
double PriceBESell=0;
if (BEOnPips&&(OrdExist(OP_BUY)>0||OrdExist(OP_SELL)>0))
{
for(int i=OrdersTotal()-1; i>=0; i--)
{
if (!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
if (OrderMagicNumber()!=magic||OrderSymbol()!=Symbol()) continue;
PriceBEBuy=0;
PriceBESell=0;
if (OrderType()==OP_BUY)
{
if(OrdExist(OP_BUY)>1) PriceBEBuy=PriceBE(OP_BUY);
if(OrdExist(OP_BUY)==1) PriceBEBuy=NormalizePrice(OrderOpenPrice()+BEPlus*PricePoint);
if(Ask>PriceBEBuy+PipsToBE*PricePoint&&(OrderStopLoss() {
Print("PriceBEBuy=",PriceBEBuy,", OrderOpenPrice()=",OrderOpenPrice(),", Ask=",Ask);
if(!OrderModify(OrderTicket(),OrderOpenPrice(),PriceBEBuy,OrderTakeProfit(),0,Green)) Print("Ошибка перевода бая в безубыток по пипсам!");
else Print("Перевели в БУ при достижении профита ",PipsToBE," пунктов");
}
}
if (OrderType()==OP_SELL)
{
if(OrdExist(OP_SELL)>1) PriceBESell=PriceBE(OP_SELL);
if(OrdExist(OP_SELL)==1) PriceBESell=NormalizePrice(OrderOpenPrice()-BEPlus*PricePoint);
if(BidPriceBESell||OrderStopLoss()==0))
{
Print("OP_SELL PriceBE=",PriceBESell,", OrderOpenPrice()=",OrderOpenPrice(),", Bid=",Bid);
if(!OrderModify(OrderTicket(),OrderOpenPrice(),PriceBESell,OrderTakeProfit(),0,Green)) Print("Ошибка перевода селла в безубыток по пипсам!");
else Print("Перевели в БУ при достижении профита ",PipsToBE," пунктов");
}
}
}
}
return;
}
//+------------------------------------------------------------------+



Выдает кучу ошибок 1 и 130.
При печати Print("PriceBEBuy=",PriceBEBuy,", OrderOpenPrice()=",OrderOpenPrice(),", Ask=",Ask); вместо цены открытия ордера бай выдает цену открытия ранее открытого селла.
Пример:
PriceBEBuy=130.681, OrderOpenPrice()=130.651, Ask=131.872
Висят три ордера в продаже, печатаем что творится с баем - цена открытия взята с ордера селл...

Как вообще такое возможно, мы же допускаем к обработке только OP_BUY:
if (OrderType()==OP_BUY)
{
........................
}
Это мистика или я уже совсем с катушек съехал??? Может я не вижу какой то совсем очевидной и глупой ошибки?

а может я уже умер и мучаюсь в аду, типа это моя пытка? :-?

Изменено 31 января, 2015 пользователем Silentspec

#1869
Silentspec, что-то не понял вот эту строчку:

if (BEOnPips&&(OrdExist(OP_BUY)>0||OrdExist(OP_SELL)>0))

для чего и как тут используется BEOnPips?
#1870

BEOnPips - это включатель бу, тру фэлс флажок, Ордэкзист - счетчик существования своих позиций по сторонам - по магику и паре

#1871

Понятно, но ведь в этом условии он не проверяется на состояние или я что-то не врубаюсь?

#1872

BEOnPips - это тру
!BEOnPips - это фэлс
Все, парни, разобрался:)
У меня внутри цикла for вызывалась функция PriceBE(OP_BUY), в которой тоже был перебор ордеров. Оказывается, так делать нельзя:)

Вот, выкладываю рабочий вариант. Функция MoveBEOnPips() переводит в безубыток на заданном количестве пунктов прибыли от цены безубытка PipsToBE,
при этом ей пофиг сколько открыто ордеров. Например, 10 в бай, 6 в селл. Функция переведет в безубыток всю партию из 10 баев и всю партию из 6 селлов. Естественно, если у нас только один ордер бай или селл, функция тоже будет переводить в безубыток.
В придачу две сервисные функции: int OrdExist(int direction) - возвращает кол-во открытых ордеров заданного направления (direction=OP_BUY, OP_SELL), double PriceBE(int dir) - возвращает цену безубытка (1-селл, 0-бай, -1 - все).

Спойлер



extern int BEPlus = 30; // Уровень прибыли в пипсах, который фиксируется при безубытке
extern bool BEOnPips = true; // Включение безубытка по пипсам
extern int PipsToBE = 200; // Уровень прибыли в пипсах, после которого переводим в безубыток

//+------------------------------------------------------------------+
//| Безубыток по пипсам |
//+------------------------------------------------------------------+
void MoveBEOnPips()
{
double PriceBEBuy=PriceBE(OP_BUY);
double PriceBESell=PriceBE(OP_SELL);
int BuyOrders=OrdExist(OP_BUY);
int SellOrders=OrdExist(OP_SELL);

if (BEOnPips&&(OrdExist(OP_BUY)>0||OrdExist(OP_SELL)>0))
{
for(int i=OrdersTotal(); i>=0; i--)
{
if (!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
if (OrderMagicNumber()!=magic||OrderSymbol()!=Symbol()) continue;
if (OrderType()==OP_BUY)
{
if(BuyOrders==1) PriceBEBuy=NormalizeDouble(OrderOpenPrice()+BEPlus*PricePoint,Digits);
if(Ask>PriceBEBuy+PipsToBE*PricePoint&&(OrderStopLoss() {
if(!OrderModify(OrderTicket(),OrderOpenPrice(),PriceBEBuy,OrderTakeProfit(),0,Green)) Print("Ошибка перевода бая в безубыток по пипсам!");
else Print("Перевели в БУ при достижении профита ",PipsToBE," пунктов");
}
}
if (OrderType()==OP_SELL)
{
if(SellOrders==1) PriceBESell=NormalizeDouble(OrderOpenPrice()-BEPlus*PricePoint,Digits);
if(BidPriceBESell+10*PricePoint||OrderStopLoss()==0))
{
if(!OrderModify(OrderTicket(),OrderOpenPrice(),PriceBESell,OrderTakeProfit(),0,Green)) Print("Ошибка перевода селла в безубыток по пипсам!");
else Print("Перевели в БУ при достижении профита ",PipsToBE," пунктов");
}
}
}
}
return;
}
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Возвращает количество ордеров заданного направления |
//+------------------------------------------------------------------+
int OrdExist(int direction)
{
int OrdCount=0;
if (OrdersTotal()>0)
{
for(int i=OrdersTotal(); i>=0; i--)
{
if (!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
if (OrderMagicNumber()!=magic||OrderSymbol()!=Symbol()) continue;
if (OrderType()==direction) OrdCount++;
}
}
return (OrdCount);
}

//+------------------------------------------------------------------+
//| Функция расчитывает цену безубытка сети ордеров |
//| в заданном направлении |
//+------------------------------------------------------------------+
double PriceBE(int dir)
{
double BEPrice=0;
double MyBEPrice=0;
double BuyLots=0;
double SellLots=0;
double BuyProfit=0;
double SellProfit=0;
double BuyLevel=0;
double SellLevel=0;
if(OrdExist(OP_BUY)>0||OrdExist(OP_SELL)>0)
{
for(int i=OrdersTotal(); i>=0; i--)
{
if (!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
if (OrderMagicNumber()!=magic||OrderSymbol()!=Symbol()) continue;
if(OrderType()==OP_BUY)
{
BuyLots=BuyLots+OrderLots();
BuyProfit=BuyProfit+OrderProfit()+OrderCommission()+OrderSwap();
}
if(OrderType()==OP_SELL)
{
SellLots=SellLots+OrderLots();
SellProfit=SellProfit+OrderProfit()+OrderCommission()+OrderSwap();
}
}
}
double TickValue=MarketInfo(Symbol(),MODE_TICKVALUE);
if (BuyLots>0) BuyLevel=NormalizeDouble(Bid-(BuyProfit/(TickValue*BuyLots)*Point),Digits); else BuyLevel=0;
if (SellLots>0) SellLevel=NormalizeDouble(Ask+(SellProfit/(TickValue*SellLots)*Point),Digits); else SellLevel=0;
if ((BuyLots-SellLots)>0) BEPrice=NormalizeDouble(Bid-((BuyProfit+SellProfit)/(TickValue*(BuyLots-SellLots))*Point),Digits);
if ((SellLots-BuyLots)>0) BEPrice=NormalizeDouble(Ask+((BuyProfit+SellProfit)/(TickValue*(SellLots-BuyLots))*Point),Digits);
if(dir==OP_BUY) MyBEPrice=BuyLevel;
if(dir==OP_SELL) MyBEPrice=SellLevel;
if(dir==-1) MyBEPrice=BEPrice;
return(NormalizeDouble(MyBEPrice,Digits));
}
//+------------------------------------------------------------------+



Изменено 31 января, 2015 пользователем Silentspec

#1873


Это мистика или я уже совсем с катушек съехал??? Может я не вижу какой то совсем очевидной и глупой ошибки?
а может я уже умер и мучаюсь в аду, типа это моя пытка? :-?

Я думаю ты в аду :d
После if (OrderType()==OP_BUY) у тебя есть процедура - PriceBE(OP_BUY); что это за зверь? если там есть перебор ордеров, то ты свою прогу никогда не отладишь...
#1874

Да уже разобрался:)
В посте сверху в спойлере рабочий вариант, там же приведена и функция PriceBE(int direction), и она использует перебор ордеров. Не подумал чего-то, что перебор в переборе будет сводить алгоритм с ума, если второй перебор отдельной функцией... Но вот оно так оказывается. Вывел результат выполнения PriceBE в отдельные переменные для каждого направления вне цикла перебора ордеров, все конечно же заработало. Сейчас уже смешно, но сидел гадал, что не так, целый день :))

Короче говоря, MoveBEOnPips() отлично работает для перевода в безубыток через PipsToBE пипсов прибыли единичных ордеров и серий ордеров в сеточных стратегиях (при усреднениях, когда цена идет против нас), при этом перевод в бу при существовании нескольких ордеров в разные стороны будет вестись отдельно для бай и селл. В следующем варианте будет возможность выставлять безубыток для совокупной позиции (бай+селл), это может пригодиться при работе с локированием как единичных ордеров, так и целых сеток (например, у нас висит 8 безнадежных ордеров в селл в общей сложности на объем 1 лот, затем советник решает их локировать ордером бай на 1,2 лота, после того, как от уровня безубытка общей позиции будет пройдено PipsToBE пипсов, произойдет подтягивание стопов по всем позициям на уровень совокупного безубытка). Также хочу прикрутить еще одну фишку - перевод в безубыток при доливочной сетке, то есть когда мы доливаемся по тренду. В этом случае перевод в бу будет осуществляться по последнему открытому ордеру (самому верхнему для бая и самому нижнему для селла), отсчет PipsToBE пипсов прибыли будет вестись соответственно от него. Идеология такая. Открываемся например в бай, цена идет вверх, мы бай переводим в бу на PipsToBE пипсов, поступает еще один сигнал в бай, открываем сделку. Когда цена уйдет снова вверх от последнего ордера на PipsToBE пипсов, мы переведем последний ордер в бу, а стоп предыдущего подтянется туда же. Теперь при развороте цены второй ордер закроется по бу, а первый в прибыли, равной расстоянию между двумя ордерами. Если кому интересно, могу выложить конечный вариант.

Изменено 31 января, 2015 пользователем Silentspec

#1875
oleguitar, ну что-то правда с болезни не совсем то Вам насоветовал, не знаю сделали вы что-то или нет, а то всё отмалчиваетесь, но вот такой вариант будет лучше:

Спойлер

double FindLastResult()
{
double result = 0;

for (int trade = OrdersTotal()-1; trade>=0; trade--)
{
if (OrderSelect(trade, SELECT_BY_POS, MODE_HISTORY))
{
if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic_143256)
{
if (OrderType() == OP_SELL || OrderType() == OP_BUY)
{
result = OrderProfit() + OrderSwap() + OrderCommission();
break;
}
}
}
}
return(result);
}



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

Для публикации сообщений создайте учётную запись или авторизуйтесь

Перейти к списку тем
Форум · 2.0.20260627.0025