Форум » Консультации по программированию » Программирование. » Ответить

Программирование.

Эдуард: Здравствуйте. Подскажите, почему ордер не открывается? input int Slippage=30; input int Magic=156; input double Lot=0.1; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnTick() { double TP=0; double cena_ma_1=0; cena_ma_1=iMA(_Symbol,0,10,0,0,0,1); int total=OrdersTotal(); for(int i=total-1; i>=0; i--) if(OrderSelect(i,SELECT_BY_POS)) if(OrderSymbol()==Symbol()) { double openB=OrderOpenPrice(); if(openB>cena_ma_1) { int tiket=OrderSend(_Symbol,OP_BUY,Lot,Ask,Slippage,0,TP,NULL,Magic,0,clrBlue); { Alert("Ордер открылся"); } } } }

Ответов - 46, стр: 1 2 3 4 All

evbut: А на основании чего открывается ордер не понятно? Зачем цикл? Если это доливочный ордер, то имеет смысл использовать массив ордеров с маджиком. Доливочный ордер открывается примерно так: Был открыт ордер по какому-то условию и он был добавлен в массив ордеров советника по данному инструменту с маджиком. К нему, уже при других условиях добавляются ордера как-то так if(UseMAFilter == false || Bid > ma) //MA Filter { tArray[T] = OrderSend(Symbol(), OP_BUY, Lots, ask, slip*PipValue, bid - StopLoss*Point*PipValue, 0, Magic); if(tArray[T]<0) {Alert("OrderSend Error: ", GetLastError());} T++;

Scriptong: Эдуард пишет: Здравствуйте. Подскажите, почему ордер не открывается? Эдуард, Вы здесь намешали мух с котлетами. Цикл, который Вы привели, обычно служит для нахождения ордеров по текущему символу. В этом цикле не должно быть команд торговых операций. Попробуйте запустить этот код онлайн на демо-счете, предварительно открыв хотя бы один ордер с ценой открытия выше МАшки. В итоге получите шквал открытых ордеров Buy. В текущем же виде ордер никогда не будет открыт, т. к. Вы сравниваете цену открытия имеющегося ордера с ценой MA. Если ордера нет или если цена его открытия ниже МА, то новый ордер не будет открыт. Сформулируйте, что именно Вы хотели получить от этого кода.

Эдуард: А так, почему на каждом тике открывает ? input int Slippage=30; input int Magic=156; input double Lot=0.1; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnTick() { double TP=0; double ma=0; ma=iMA(_Symbol,0,10,0,0,0,1); if(Open[0]>ma) { int tiket=OrderSend(_Symbol,OP_BUY,Lot,Ask,Slippage,0,TP,NULL,Magic,0,clrBlue); { Alert("Ордер открылся"); } } }


Scriptong: Эдуард пишет: А так, почему на каждом тике открывает ? Потому что Вы именно это и написали в коде: на каждом тике, если цена открытия свечи выше МАшки, то открывать ордер. Чтобы ордер открылся один раз, нужно предварительно произвести проверку, открывались уже ордера на текущей свече или нет. То есть циклом из первого Вашего поста собрать информацию, потом проанализировать ее и только затем выполнять код, приведенный во втором посте.

Эдуард: Не открывает... input int Slippage=30; input int Magic=156; input double Lot=0.1; input double TakeProfit=200; double TP=0; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnTick() { TP=NormalizeDouble(Ask+TakeProfit*_Point,_Digits); TP=NormalizeDouble(Bid-TakeProfit*_Point,_Digits); double ma=0; ma=iMA(_Symbol,0,10,0,0,0,1); int total=OrdersTotal(); for(int i=total-1; i>=0; i--) if(OrderSelect(i,SELECT_BY_POS)) if(OrderSymbol()==Symbol()) { if(OrderType()==OP_BUY && OrderMagicNumber()==Magic) if(Open[0]>ma) { int tiket=OrderSend(_Symbol,OP_BUY,Lot,Ask,Slippage,0,TP,NULL,Magic,0,clrBlue); { Alert("Ордер открылся"); } } } }

Scriptong: Эдуард пишет: Не открывает... Давайте так: что именно нужно?

Эдуард: Scriptong пишет: Когда свеча закрывается выше мувинга - Бай. Когда ниже Селл. Хотелось бы понять, что не так. Код писать не надо, он мне не нужен в принципе.

Scriptong: Эдуард пишет: Когда свеча закрывается выше мувинга - Бай. В частностях у Вас все верно. А вот собрано - неверно. Так, условие открытия написано верно: double ma = iMA(...); if (Open[0] > ma) { // Открыть Buy } if (Open[0] < ma) { // Открыть Sell } Эдуард пишет: Хотелось бы понять, что не так. Не так то, что перед открытием необходимо проверить наличие уже открытых ордеров на текущей свече. Иначе Вы на каждом тике будете открывать новый ордер. Для определения времени последнего открытого ордера используйте код наподобие такого: datetime GetLastOpenOrderTime() { datetime lastOpenOrderTime = 0; for (int i = OrdersTotal() - 1; i >= 0; i--) { if (!OrderSelect(i, SELECT_BY_POS)) continue; if (OrderSymbol() != Symbol()) continue; if (OrderType() != OP_BUY && OrderType() != OP_SELL) continue; if (OrderMagicNumber() != i_magicNumber) continue; lastOpenOrderTime = (datetime)MathMax(lastOpenOrderTime, OrderOpenTime()); } return lastOpenOrderTime; } Поэтому перед открытие нового ордера проверяйте время открытия последнего ордера путем сравнения времени открытия свечи и результата, который вернула функция GetLastOpenOrderTime(). datetime lastTime = GetLastOpenOrderTime(); if (lastTime >= Time[0]) { // Новый ордер открывать нельзя, т. к. на этой свече уже был открыт ордер } Эдуард пишет: Код писать не надо, он мне не нужен в принципе. Тогда непонятно, зачем сюда пишете... Здесь ведь именно коды и обсуждаются.

Эдуард: Буду разбираться. Спасибо.

Эдуард: Почему выдает ошибку ? void OnTick() { int tiket=0; if(OP_BUY==0) tiket=OrderSend(_Symbol,OP_BUY,0.1,Ask,10,0,0,NULL,123,0,clrBlue); if(tiket>=0)return(true); else return(false); if(OP_SELL==0) tiket=OrderSend(_Symbol,OP_SELL,0.1,Bid,10,0,0,NULL,123,0,clrRed); if( tiket>=0)return(true); else return(false); }

Scriptong: Эдуард пишет: Почему выдает ошибку ? Имеется в виду ошибка компиляции? Если да, то компилятор указывает на то, что функция OnTick имеет тип void (т. е. без типа), а в теле функции четыре функции return возвращают значение. Нужно убрать возврат значения.

Эдуард: Когда надо делать перебор ордеров ? 1. Когда открываем ордера. 2. Закрываем. 3. Модифицируем. Когда еще ?

Scriptong: Эдуард пишет: Когда надо делать перебор ордеров ? Один раз в начале обработки события Tick или любого другого события. Собираем свои ордера в массив, а потом уже работаем с этим массивом. После выполнения любой торговой операции, если она успешна, необходимо вернуться к месту входа в функцию обработки события. Таким образом, сбор информации будет проведен еще один раз. И так до тех пор, пока не будет в очереди торговых операций, либо любая выполненная торговая операция приведет к ошибке. В случае ошибки (опять же - нужно обработать саму ошибку) следует закончить обработку события и ждать следующего события.

Эдуард: Подскажите на примере части кода. Какое условие прописать, чтобы ордера на одном уровне открывались так: Бай/Селл, то есть чередовались. if(Tipordera(Magik)==1 && Ask>=LastPrice+step*_Point && LastPrice>0 && (Magik)) { tiket=OrderSend(_Symbol,OP_BUY,Lot,Ask,Slippage,0,0,"",Magik,0,clrBlue); LastPrice=Ask; }

Scriptong: Эдуард пишет: Подскажите на примере части кода. Какое условие прописать, чтобы ордера на одном уровне открывались так: Бай/Селл, то есть чередовались. Не существует какого-то условия, чтобы его написал - и получил желаемое. Чаще всего, как и в этом случае, требуется составление целого алгоритма. Насколько я понял задачу, требуется: 1. После открытия первого ордера, например, Buy, ожидаем его закрытия по стопу, профиту или по рынку (принудительное закрытие). 2. По закрытию ордера ожидаем возврата цены к уровню открытия Buy и открываем Sell. 3. Ожидание закрытия Sell. 4. Ожидание возврата цены к уровню открытия Sell и открытие Buy. Такой алгоритм нужен? Даже если он, то это несколько сотен строк кода. Ну и в самом алгоритме еще такой момент не предусмотрен: а что, если цена не вернется к начальному уровню открытия?



полная версия страницы