АвторСообщение





Сообщение: 877
Настроение: нормальное
Зарегистрирован: 20.10.14
Откуда: Россия
Репутация: 0
ссылка на сообщение  Отправлено: 13.10.16 14:47. Заголовок: Программирование.


Здравствуйте. Подскажите, почему ордер не открывается?

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("Ордер открылся");
}
}
}
}


Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 46 , стр: 1 2 3 4 All [только новые]







Сообщение: 886
Настроение: нормальное
Зарегистрирован: 20.10.14
Откуда: Россия
Репутация: 0
ссылка на сообщение  Отправлено: 25.10.16 09:34. Заголовок: Такой алгоритм нужен..



 цитата:
Такой алгоритм нужен? Даже если он, то это несколько сотен строк кода.
Ну и в самом алгоритме еще такой момент не предусмотрен: а что, если цена не вернется к начальному уровню открытия?



Имеются ввиду ордера, которые находятся в рынке. Если цена идет вверх и должен открыться Бай, но на этом уровне уже есть Бай, то не должен открывать - сейчас открывает.
Вот я и спрашиваю, какое дополнительное условие прописать в коде открытия ордеров. чтобы на одном уровне ордера чередовались.
Сформулируйте логику словами - я сам напишу.

Спасибо: 0 
ПрофильЦитата Ответить





Сообщение: 2368
Зарегистрирован: 03.03.13
Откуда: Украина, Каменское (Днепродзержинск)
Репутация: 3
ссылка на сообщение  Отправлено: 25.10.16 16:19. Заголовок: Эдуард пишет: Вот я..


Эдуард пишет:

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


Еще раз: не существует такого условия, это целый алгоритм.
В идеале требуется:
    1. Найти все ордера, открытые экспертом и записать их в массив.
    2. Обработать полученный массив и выяснить, где нужно установить/открыть ордер, а где - нет.

Обычно для этой цели я произвожу нумерацию ордеров, чтобы можно было отличать их друг от друга. Номер ордера кодирую в поле MagicNumber ордера. Например, если идентификатор ордеров эксперта 345, то в поле MagicNumber записываю 345 * 100 + 1 = 34501. Такая запись означает, что ордер открыт экспертом с идентификатором 345. Номер ордера в серии - 1.
Работа с ордерами, если стратегия сеточная, это достаточно сложная вещь.


Спасибо: 0 
ПрофильЦитата Ответить





Сообщение: 887
Настроение: нормальное
Зарегистрирован: 20.10.14
Откуда: Россия
Репутация: 0
ссылка на сообщение  Отправлено: 25.10.16 10:17. Заголовок: Надо сделать перебор..


Надо сделать перебор ордеров, запомнить уровень, запомнить тип последнего ордера и если при открытии текущего ордера типы совпадают, то не открывать ордер того же типа - так ?


Спасибо: 0 
ПрофильЦитата Ответить





Сообщение: 888
Настроение: нормальное
Зарегистрирован: 20.10.14
Откуда: Россия
Репутация: 0
ссылка на сообщение  Отправлено: 05.11.16 19:19. Заголовок: Подскажите пожалуйст..


Подскажите пожалуйста, может есть другой способ открывать ордера на уровнях?

bool OrderDist(int type)
{
bool dist=false;
RefreshRates();
for (int j=0; j<ArrayRange(massiv_o,0); j++)
{
if(NormalizeDouble(massiv_o[j], _Digits)>0 && (MathAbs(Bid-NormalizeDouble(massiv_o[j], _Digits))/_Point)<=10)
{
dist=true;
break;
}
}
for(int i=0; i<OrdersTotal(); i++)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) && OrderMagicNumber()==Magik)
if(OrderSymbol()==_Symbol)
if(((MathAbs(Bid-OrderOpenPrice())/_Point)<=step/2) && Tipordera(Magik)==type) dist=false;
}
return(dist);
}

Спасибо: 0 
ПрофильЦитата Ответить





Сообщение: 2378
Зарегистрирован: 03.03.13
Откуда: Украина, Каменское (Днепродзержинск)
Репутация: 3
ссылка на сообщение  Отправлено: 06.11.16 17:18. Заголовок: Эдуард пишет: Подск..


Эдуард пишет:

 цитата:
Подскажите пожалуйста, может есть другой способ открывать ордера на уровнях?


По кускам кода никто ничего не сможет сказать. Так, в этом коде непонятно, что есть massiv_o (как он объявлен и как и чем заполняется), что такое функция Tipordera, что такое переменная step? То есть Вы, находясь в своем контексте рассуждений, задаете вопрос, на который невозможно ответить, не зная этого самого контекста.

Также непонятно, почему задается вопрос о необходимости открытия ордера, но ведется работа с уже открытыми ордерами?

Спасибо: 0 
ПрофильЦитата Ответить





Сообщение: 889
Настроение: нормальное
Зарегистрирован: 20.10.14
Откуда: Россия
Репутация: 0
ссылка на сообщение  Отправлено: 06.11.16 21:20. Заголовок: По кускам кода никто..



 цитата:
По кускам кода никто ничего не сможет сказать. Так, в этом коде непонятно, что есть massiv_o (как он объявлен и как и чем заполняется), что такое функция Tipordera, что такое переменная step? То есть Вы, находясь в своем контексте рассуждений, задаете вопрос, на который невозможно ответить, не зная этого самого контекста.

Также непонятно, почему задается вопрос о необходимости открытия ордера, но ведется работа с уже открытыми ордерами?




for (int j=0; j<ArrayRange(massiv_o,0); j++)// объявлен глобально определяет количество цен ордеров в массиве, строит виртуально сетку на расстоянии шага (step), после открытия первого ордера.

if(NormalizeDouble(massiv_o[j], _Digits)>0 && (MathAbs(Bid-NormalizeDouble(massiv_o[j], _Digits))/_Point)<=10)// 10 это в пунктах погрешность вверх/вниз, когда можно выставить ордер.

Тип ордера, он и есть тип ордера if(OrderType()==OP_BUY) tipordera=0;
if(OrderType()==OP_SELL) tipordera=1;

Вопрос в том, можно ли это сделать проще и надежней ?

Спасибо: 0 
ПрофильЦитата Ответить





Сообщение: 2381
Зарегистрирован: 03.03.13
Откуда: Украина, Каменское (Днепродзержинск)
Репутация: 3
ссылка на сообщение  Отправлено: 07.11.16 15:27. Заголовок: Эдуард пишет: for (..


Эдуард пишет:

 цитата:
for (int j=0; j<ArrayRange(massiv_o,0); j++)// объявлен глобально определяет количество цен ордеров в массиве, строит виртуально сетку на расстоянии шага (step), после открытия первого ордера.


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

Эдуард пишет:

 цитата:
Тип ордера, он и есть тип ордера if(OrderType()==OP_BUY) tipordera=0;
if(OrderType()==OP_SELL) tipordera=1;


Зачем, если OP_BUY это и есть 0, а OP_SELL - 1?

Эдуард пишет:

 цитата:
Вопрос в том, можно ли это сделать проще и надежней ?


Проще уже некуда. Тем более, что используемый алгоритм явно слишком примитивен для решения поставленной задачи далеко не низкого уровня (средний или даже чуть выше среднего). А вот надежнее - конечно.

Чтобы решить задачу, пора ли открывать новый ордер по сетке, нужно:
    1. Перебрать все открытые ордера из списка рабочих и сохранить свои ордера в массив. Попутно сформировать максимальные и минимальные цены открытых ордеров. Возможно, еще придется вычислять бреши в ордерах.
    2. Вычислить цену открытия следующего ордера на основании максимальной и минимальной цен текущих ордеров.
    3. Проверить, нужно ли теперь открывать ордер (попадает ли он в нужный диапазон цен)?


Таким образом, пп. 2 и 3 никакого отношения к имеющимся ордерам уже не имеют. А в приведенном Вами коде - имеют.

Спасибо: 0 
ПрофильЦитата Ответить



Сообщение: 427
Зарегистрирован: 25.08.13
Репутация: 1
ссылка на сообщение  Отправлено: 12.06.17 22:19. Заголовок: Добрый вечер! Помог..


Добрый вечер!

Помогите разобраться с трейлингом.
1. Открывается ордер к примеру на покупку и выше с шагом step открывается отложенный ордер Butstop:

//--- ордер на покупку
{
if (RSI_2<55 && RSI_1>55 && BuyCount == 0 && SellCount == 0)
{
OrderSend(Symbol(),OP_BUY,0.02,Ask,3,0,0,"",1,0,CLR_NONE);
}
}

//--- отложенный ордер

if (BuyCount > 0 && BuyStopCount==0)
{
OrderSend(Symbol(),OP_BUYSTOP,0.02,Ask+Step*(1+BuyStopCount)*Point,3,0,0,"",1,0,CLR_NONE);
}

2. Идет трейлинг ордера buy:

for (n=0; n<=total; n++)
{
OrderSelect(OrderTicket(),SELECT_BY_POS,MODE_TRADES);
{
if(OrderTicket()!=0 && OrderType()==OP_BUY && Bid>OrderStopLoss()+SL*Point && BuyCount == 1 && SellCount == 0)

OrderModify(OrderTicket(),OrderOpenPrice(),Bid-SL*Point,0,0,CLR_NONE);

else

if(OrderTicket()!=0 && OrderType()==OP_SELL && Ask<OrderStopLoss()-SL*Point && BuyCount == 0 && SellCount == 1)
{

OrderModify(OrderTicket(),OrderOpenPrice(),Ask+SL*Point,0,0,CLR_NONE);
}
}
}

3. Закрывается половина ордера при выполнении условия

//--- Закрытие половины позиции

for (n=0; n<=total; n++)
{
OrderSelect(OrderTicket(),SELECT_BY_POS,MODE_TRADES);
{
if(OrderTicket()!=0 && OrderType()==OP_BUY && OrderLots()==0.02 && Bid>OrderOpenPrice() && SellCount==0 && BuyCount==1 && OrderMagicNumber()==1 && RSI_1>70 && RSI_0<70)

OrderClose(OrderTicket(),0.01,Bid,3,CLR_NONE);

else

if(OrderTicket()!=0 && OrderType()==OP_SELL && OrderLots()==0.02 && BuyCount==0 && SellCount==1 && OrderMagicNumber()==1 && RSI_1<30 && RSI_0>30)
{

OrderClose(OrderTicket(),0.01,Ask,3,CLR_NONE);
}
}
}

И далее остающаяся половина открытого ордера на покупку с лотом 0.01 не тралится. Когда убираешь открытый ордер BuyStop, то трейлинг работает.
Как сделать, чтобы трейлинг работал после закрытия половины позиции при открытом отложенном ордере BuyStop?


Спасибо: 0 
ПрофильЦитата Ответить





Сообщение: 2512
Зарегистрирован: 03.03.13
Откуда: Украина, Каменское (Днепродзержинск)
Репутация: 3
ссылка на сообщение  Отправлено: 13.06.17 20:33. Заголовок: Ошибки во втором и т..


Ошибки во втором и третьем блоках. Ошибки грубые - неправильное использование функции OrderSelect(). Эта функция выбирает ордер по тикету (первый случай) или по индексу в списке (второй случай). В первом случае ей нужно передать индекс строки в списке рабочих ордеров или истории счета, при этом указав вторым параметром SELECT_BY_POS. Во втором случае ей нужно передать уникальный идентификатор ордера (тикет) и вторым параметром указать SELECT_BY_TICKET.
Здесь же видим, что делается попытка передачи тикета (OrderTicket()) и при этом указывается второй параметр SELECT_BY_POS. Уже явное несоответствие.
Далее обращаю внимание на тот факт, что функция OrderTicket() возвращает тикет выбранного ордера. Таким образом, функция никак не может быть аргументом при вызове функции OrderSelect(), которая выполняет этот выбор.
Исходя из того, что в обоих блоках используется цикл перебора ордеров (предположительно по списку рабочих ордеров), следовало бы строку:

 цитата:
OrderSelect(OrderTicket(),SELECT_BY_POS,MODE_TRADES);


заменить на такие строки:

 цитата:
if (!OrderSelect(n, SELECT_BY_POS))
continue;


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

Спасибо: 0 
ПрофильЦитата Ответить



Сообщение: 428
Зарегистрирован: 25.08.13
Репутация: 1
ссылка на сообщение  Отправлено: 14.06.17 20:53. Заголовок: Спасибо Игорь!..


Спасибо Игорь!

Спасибо: 0 
ПрофильЦитата Ответить



Сообщение: 1
Зарегистрирован: 16.06.17
Репутация: 0
ссылка на сообщение  Отправлено: 16.06.17 19:17. Заголовок: Здравствуйте. Прошу ..


Здравствуйте.
Прошу подсказать как реализовать сравнение депо до открытия начальной сделки с текущим балансом эквити. Сова мартинит после убытка и интересует не разница AccountEquity() и AccounBallance(), а разница AccountEquity() и того первого значения AccountBalance() в самом начале серии "догона"(до входа в рынок с начальным лотом). Понятно, что здесь не обойтись без массивов, потому прошу подсказать направление, а лучше с примерами кода, если не затруднит.

Спасибо

Спасибо: 0 
ПрофильЦитата Ответить





Сообщение: 2517
Зарегистрирован: 03.03.13
Откуда: Украина, Каменское (Днепродзержинск)
Репутация: 3
ссылка на сообщение  Отправлено: 19.06.17 17:20. Заголовок: allisbob пишет: Про..


allisbob пишет:

 цитата:
Прошу подсказать как реализовать сравнение депо до открытия начальной сделки с текущим балансом эквити. Сова мартинит после убытка и интересует не разница AccountEquity() и AccounBallance(), а разница AccountEquity() и того первого значения AccountBalance() в самом начале серии "догона"(до входа в рынок с начальным лотом)


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

Спасибо: 0 
ПрофильЦитата Ответить



Сообщение: 2
Зарегистрирован: 16.06.17
Репутация: 0
ссылка на сообщение  Отправлено: 06.07.17 16:53. Заголовок: ... Подскажите, по-в..


... Подскажите, по-возможности, что не так. Вот, в сове хочу добавить умножитель лота при срабатывании SL.

"реализовал" так:


 цитата:

int slippage=10;

int start()
{
...
string txt; static int n;
if (Orders>OrdersTotal()) txt=I();
{
if (txt=="SL" || txt!="TP") {n++; LOT=Lot[n]; if (n>=10) {n=0; LOT=Lot1;}}
if (txt=="TP") {n=0; LOT=Lot1;}
}
Orders=OrdersTotal();
...
return(0);
}



и функция:


 цитата:

string I()
{
string txt=NULL; int a=OrdersHistoryTotal()-1;
if(OrderSelect(a,SELECT_BY_POS,MODE_HISTORY)==true && OrderSymbol()==Symbol() && OrderMagicNumber()==ID)
{
if (MathAbs(OrderStopLoss()-OrderClosePrice())<=_Point*slippage) txt="SL";
if (MathAbs(OrderTakeProfit()-OrderClosePrice())<=_Point*slippage) txt="TP";
}
return(txt);
}



Поставленную задачу это выполняет лишь частично. При закрытии руками или по "SL" происхOдит увеличение последующих лотов, но после закрытия по "TP" лот не сбрасывается до Lot1 а дальше растет... Что предпринять?
Благодарю заранее.

Спасибо: 0 
ПрофильЦитата Ответить





Сообщение: 2527
Зарегистрирован: 03.03.13
Откуда: Украина, Каменское (Днепродзержинск)
Репутация: 3
ссылка на сообщение  Отправлено: 07.07.17 09:41. Заголовок: allisbob пишет: но ..


allisbob пишет:

 цитата:
но после закрытия по "TP" лот не сбрасывается до Lot1 а дальше растет


По приведенным обрывкам кода сложно сказать, что именно не так. По идее, должно работать, если TakeProfit установлен у ордеров. С другой стороны объем по этому коду должен повышаться на каждом новом тике. Ведь условие:

 цитата:
if (txt=="SL" || txt!="TP")


сработает и тогда, когда не было закрытия ордера (переменная txt будет содержать пустую строку). Также нужно заметить, что блок, в котором находится эта строка, не принадлежит условию:

 цитата:
if (Orders>OrdersTotal())


т. е. блок просто сам по себе. С таким же успехом можно убрать эти фигурные скобки - ничего не изменится.

Хотя, конечно, решение задачи подвержено многим "если". К примеру, функция I() будет работать правильно только в тестере. А вот онлайн она может обработать ордер, который просто последний в списке. Ведь сортировать список пользователь может как угодно: по времени открытия, закрытия, по объему и т. д.
Также почему то решено, что проскальзывание у стопа и профита обязательно должно лежать в пределах проскальзывания, задаваемого пользователем. Видимо, в этих мелочах и кроется проблема.

Для поиска последнего закрытого ордера лучше всего сканировать весь список истории счета и находить в нем наибольшее время закрытия:

 цитата:

int GetLastCloseOrderTicket()
{
datetime dtLastTime = 0;
int nLastTicket = -1;
for (int i = OrdersHistoryTotal() - 1; i >= 0; i--)
{
if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
continue;

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

if (m_nMagicNumber != OrderMagicNumber())
continue;

if (OrderCloseTime() > dtLastOrderTime)
{
dtLastTime = OrderCloseTime;
nLastTicket = i;
}
}

return nLastTicket;
}



Далее по полученному тикету определяем причину закрытия:

 цитата:

enum ENUM_CLOSE_REASON
{
CLOSE_REASON_ERROR, // Ошибка определения причины закрытия
CLOSE_REASON_MARKET, // Ордер закрыт "по рынку" - не по SL и не по TP
CLOSE_REASON_TP, // Ордер закрыт по достижении Take Profit
CLOSE_REASON_SL // Ордер закрыт по достижении Stop Loss
};


ENUM_CLOSE_REASON GetCloseReason(int nTicket)
{
if (!OrderSelect(nTicket, SELECT_BY_TICKET) || OrderCloseTime() == 0)
return CLOSE_REASON_ERROR;

if (OrderType() != OP_BUY && OrderType() != OP_SELL)
return CLOSE_REASON_ERROR;

// Ордер Buy
if (OrderType() == OP_BUY)
{
if (OrderTakeProfit() > 0.0 && OrderClosePrice() - OrderTakeProfit() > -DBL_EPSILON)
return CLOSE_REASON_TP;

if (OrderStopLoss() - OrderClosePrice() > -DBL_EPSILON)
return CLOSE_REASON_SL;

return CLOSE_REASON_MARKET;
}

// Ордер Sell
if (OrderTakeProfit() - OrderClosePrice() > -DBL_EPSILON)
return CLOSE_REASON_TP;

if (OrderStopLoss() > 0.0 && OrderClosePrice() - OrderStopLoss() > -DBL_EPSILON)
return CLOSE_REASON_SL;

return CLOSE_REASON_MARKET;
}



Пример использования:

 цитата:

static int nOrdersInHistory = 0;
if (nOrdersInHistory != OrdersHistoryTotal())
{
ENUM_CLOSE_REASON eCloseReason = GetCloseReason(GetLastCloseOrderTicket());
if (eCloseReason == CLOSE_REASON_SL)
{
// увеличение объема
}

if (eCloseReason == CLOSE_REASON_TP)
{
// возврат к начальному объему
}
}

nOrdersInHistory = OrdersHistoryTotal();



Спасибо: 1 
ПрофильЦитата Ответить



Сообщение: 3
Зарегистрирован: 16.06.17
Репутация: 0
ссылка на сообщение  Отправлено: 09.07.17 16:05. Заголовок: Большое спасибо Вам,..


Большое спасибо Вам, Игорь, за объяснение. Правда, у меня целый код совы не намного больше приведенного примера

Теперь хотел бы уточнения: что присваивается переменной dtLastOrderTime?

 цитата:


int GetLastCloseOrderTicket()
{
datetime dtLastTime = 0;
int nLastTicket = -1;
for (int i = OrdersHistoryTotal() - 1; i >= 0; i--)
{
if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
continue;

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

if (m_nMagicNumber != OrderMagicNumber())
continue;

if (OrderCloseTime() > dtLastOrderTime)
{
dtLastTime = OrderCloseTime();
nLastTicket = i;
}
}

return nLastTicket;
}




Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 46 , стр: 1 2 3 4 All [только новые]
Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  2 час. Хитов сегодня: 3
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет