Здорово. Это примерно именно то к чему я стремился на данном этапе.. Единственное, что докупаться позиция начинает почему то не через каждые 50 пунктов(+- проскальзывание допустим) а опять(как и в предыдущих версиях кода) через непонятный(пока что) мне алгоритм.? )
P.S. Если на будущее, необходимо будет докупаться по 2,3,4 и т.д. кругу - это надо будет для каждого, отдельно взятого круга создавать свой "If" ? (Или это уже совсем другая история и там надо будет, что то более хитроумное изобретать?) Что мне сейчас первое в голову приходит так это не умножать лот(0.01) на 2 а умножать его на какой то коэффициент, который должен будет менятся в зависимости от того, cколько уже на данный момент было сделано доливок. (или сколько лотов куплено уже к настоящему моменту.) + условие для наращивания позиции необходимо будет как то модифицировать(если это возможно.), что бы оно было одно на все случаи жизни и постоянно могло доливаться с разными коэффициентами лотов. (я в правильном направлении двигаюсь?)
... (Пытался просматривать код в одном из советников по мартину, но тот код мне непонятен + написан он однозначно неправильно с точки зрения оформления, как мне кажется. ...
О да! Точно. Зеленый свисток надо заменить синим бурлюкатором.
Код подправил. Разберитесь хорошо с исправленным кодом.
Вроде бы разобрался с кодом. Но есть моменты: )
Позиция по прежнему отказывается докупаться по тем параметрам, которые прописаны в коде. ) То есть по идее(в данном случае) доливаться должна сделка через каждые 100 пунктов(против себя) + удвоенным лотом. Проверка на истории показывает, что позиция не удваивается а утраивается. (начиная с момента наращивания объема.) + докупка осуществляется не через каждые 100 пунктов а через 50-90 пунктов +-(в зависимости от случая.)
P.S. Ещё хотел выяснить такой момент для себя:
У вас есть такой кусок кода:
if (PositionSelect(Symbol()))
{
double priceOpen = PositionGetDouble(POSITION_PRICE_OPEN);
double posTP = PositionGetDouble(POSITION_TP);
Print(" Количество открытых позиций: ", PositionsTotal());
Print(" Цена в сделке, подтверждённая брокером : ", DoubleToString(priceOpen, 5));
Print(" Тэйк-Профит позиции : ", DoubleToString(posTP, 5));
Print(" ");
}
Мне не совсем понятно, зачем здесь осуществляется проверка "If" ?
Какую цель она преследует?
Почему допустим нельзя прописать тоже самое без проверки? )
И точно так же не до конца ясно, что возвращает вот этот код:
if (!OrderCalcMargin(request.type, request.symbol, request.volume, request.price, margin))
return(false);
Он возвращает ложь тогда, когда не хватает средств на маржу?
(Или в чем состоит суть "ЛЖИ" в данной операции?)
По функции OrderCalcMargin() откройте справку и прочтите ее.
Не бойтесь пользоваться справкой, это только убыстрит процесс обучения программированию.
Да уже по 10 раз перечитал до этого по поводу этой(и не только этой) функции. Написано: "Возвращает true в случае успеха, иначе false." Вот и все. А что такое успех или не успех в данном случае мне не ясно. (по этому и задал вопрос что означает "ложь" в данном случае.)
P.S. На счет всего остального постараюсь разобраться. (Спасибо за подсказки и написанный код.) Просто после последней версии вашего кода я подумал, что позиция должна докупаться по нормальному объему и цене т.к. вы написали что "Подправили код." Если бы сказали сразу что он не будет работать идеально - я бы не задавал лишних вопросов в последнем сообщении и попытался бы в первую очередь понять почему это происходит. )
После разбора справки, думаю что нижеприведенный код Вам понятен до последнего символа:
Спасибо за разъяснения. На счет данного примера теперь всё ясно. Я только сейчас понял, что в справке помечены [in] или [out] - параметры которые я должен прописать и параметры которые функция должна вернуть. Правда вот такое обозначение [in,out] мне не ясно до сих пор.. ) (возможно, что структура может и принимать и возвращать значения в тех или иных ситуациях..)
1. Насчет наращивания позиции подсказка: сколько будет 1 + 2 ? Или так 1 + 1*2 ?
2. Отличается ли цена открытия существующей позиции после доливки? Если отличается то почему?
3. Какая цена является отправной для увеличения объема позиции? Где эти данные в коде?
В общем за сегодня просидел над этим кодом уже часов 7-8 наверное в сумме. ) Все что пришло на ум(пока что) оказалось не эффективным. Не смог понять причины изменения цены докупки(начиная с 3-го круга) и точно также не понял причину изменения объема лота. С объемом можно в принципе разобраться при помощи изменения коэффициента. (Изменив число 2 на 1) Цену 2-ой докупки можно нормализовать путём высчитывания операций не по биду(как было в коде) а по аску. Но, как я уже сказал ранее, после 3-го круга проблема все равно имеет место. В итоге у меня получился вот такой код:
//+------------------------------------------------------------------+//| My_Practics.mq5 |//+------------------------------------------------------------------+#property copyright"Mike_Kharkov"#property link"https://www.fl.ru/users/Yamaradg/"#property version"1.00"double COEF = 1.0; //коэффициент кратности увеличения лотаint DELTA = 100; //количество пунктов прохода цены для уведичения позиции//+------------------------------------------------------------------+//| Expert initialization function |//+------------------------------------------------------------------+intOnInit()
{
/*
Print(" Тикет сделки:" , result.deal);
Print(" Ордер: ", result.order);
Print(" Обьём: " , result.volume);
Print(" Цена в сделке, подтверждённая брокером: " , result.price);
Print(" Текущая рыночная цена предложения (цены реквоты): " , result.bid);
Print(" Текущая рыночная цена спроса (цены реквоты): " , result.ask);
Print(" Комментарий брокера к операции (по умолчанию заполняется расшифровкой: " , result.comment);
Print(" Идентификатор запроса, проставляемый терминалом при отсылке на торговый сервер: " , result.request_id);
*///---//---return(INIT_SUCCEEDED);
}//---------------------------------------------------------------------------+//+------------------------------------------------------------------+//| Expert deinitialization function |//+------------------------------------------------------------------+voidOnDeinit(constint reason)
{
//---
}//---------------------------------------------------------------------------+//+------------------------------------------------------------------+//| Expert tick function |//+------------------------------------------------------------------+voidOnTick()
{
int positions_total = PositionsTotal();
//---блок первоначального окрытия позиции по текущей ценеif(PositionsTotal() < 1)
{
double prc = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
double lot = 0.01;
// вызов функции формирования торгового запросаbool isOpen = SendOrder(prc, lot);
if (isOpen)
{
Print(" Первоначальное открытие ");
if (PositionSelect(Symbol()))
{
double priceOpen = PositionGetDouble(POSITION_PRICE_OPEN);
double posTP = PositionGetDouble(POSITION_TP);
Print(" Количество открытых позиций: ", PositionsTotal());
Print(" Цена в сделке, подтверждённая брокером : ", DoubleToString(priceOpen, 5));
Print(" Тэйк-Профит позиции : ", DoubleToString(posTP, 5));
Print(" ");
}
}
return;
}
//---блок наращивания существующей позицииdouble posPriceOpen = 0;
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double posVolume = 0.01;
// узнаем цену открытия и совокупный объем позицииif (PositionSelect(Symbol()))
{
posPriceOpen = PositionGetDouble(POSITION_PRICE_OPEN);
posVolume = PositionGetDouble(POSITION_VOLUME);
}
// условие для наращивания позицииif( ask <= posPriceOpen - DELTA * _Point && PositionsTotal() == 1)
{
double prc = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
//увеличим размер позиции на коэффициентdouble lot = posVolume * COEF;
// вызов функции формирования торгового запросаbool isOpen = SendOrder(prc, lot);
if (isOpen)
{
Print(" Увеличение объема позиции ");
if (PositionSelect(Symbol()))
{
posPriceOpen = PositionGetDouble(POSITION_PRICE_OPEN);
posVolume = PositionGetDouble(POSITION_VOLUME);
double posTP = PositionGetDouble(POSITION_TP);
Print(" Количество открытых позиций_2: ", PositionsTotal());
Print(" Оъем открытой позиции : ", DoubleToString(posVolume, 2));
Print(" Цена в сделке, подтверждённая брокером : ", DoubleToString(posPriceOpen, 5));
Print(" Тэйк-Профит позиции : ", DoubleToString(posTP, 5));
Print(" ");
}
}
return;
}
//---
}//---------------------------------------------------------------------------+//функция формирующая торговый запрос на открытие позиции//и проверки результата открытияbool SendOrder(double price, double volume)
{
MqlTradeRequest request = {0};
MqlTradeResult result = {0};
//---заполняем поля торгового запроса
request.action = TRADE_ACTION_DEAL; // Тип выполняемого действия
request.symbol = _Symbol; // Имя торгового инструмента
request.volume = volume; // Запрашиваемый объем сделки в лотах
request.price = price; // Цена
request.type = ORDER_TYPE_BUY; // Тип ордера
request.tp = price + 100*_Point; // Цена, по которой сработает Take Profit ордер при движении цены в благоприятном направлении
request.sl = 0; // Цена, по которой сработает Stop Loss ордер при движении цены в неблагоприятном направлении
request.type_filling = ORDER_FILLING_FOK; // Тип ордера по исполнению
request.type_time = ORDER_TIME_GTC;
//---проверим хватает ли средств для открытия позицииdouble margin = 0.0;
if (!OrderCalcMargin(request.type, request.symbol, request.volume, request.price, margin))
return(false);
if (margin > AccountInfoDouble(ACCOUNT_FREEMARGIN))
return(false);
//---отправка запроса на сервер и проверка результата отправкиif (OrderSend(request,result))
return(true);
elsePrint(__FUNCTION__," При выставлении ордера произошла ошибка. Error = ",GetLastError());
return(false);
}//---------------------------------------------------------------------------+
И вот такие результаты(в плане цен и объемов) на истории:
То есть мне не понятно(и пока идеи даже нет) почему цена именно после 3-го круга (а не после 2-го допустим, когда начинается блок наращивания существующей позиции) становится с дельтой в 2 раза меньшей, чем у предыдущих 2-х цен. Задать какой то параметр(или функцию) высчитывания цены докупки именно из текущей цены(при помощи PositionGetDouble(POSITION_PRICE_CURRENT) к примеру) тоже оказалось невозможным.(хотя это и логично конечно.) P.S. Вот такие вот дела пока что. ) Возможно завтра ещё что то(какая то идея) на ум придёт - но пока, в любом случае, мои варианты исчерпаны..
То есть мне не понятно(и пока идеи даже нет) почему цена именно после 3-го круга
(а не после 2-го допустим, когда начинается блок наращивания существующей позиции) становится с дельтой в 2 раза меньшей, чем у предыдущих 2-х цен.
Вы используете PositionPriceOpen. Это усредненная цена всех сделок (т.е. имеющейся позиции), а не цена последней сделки. Читайте про неттинг, ордера, позиции, сделки. То же самое с объемами.
Wahoo: Вы используете PositionPriceOpen. Это усредненная цена всех сделок (т.е. имеющейся позиции), а не цена последней сделки.
Это я понимаю - но почему следующие сделки докупаются не по цене, которая ниже 100 пунктов от предыдущей усреднённой, а по цене, которая ниже на 50 пунктов? P.S. Мне например и надо, что бы позиция докупалась через каждые 100 пунктов(в данном случае) именно по усреднённой цене. (а не по цене последней сделки.) Или вы хотите сказать, что в данном случае всё именно так и проиcходит?
P.S. Щас ещё раз внимательно посчитал и понял что действительно это все дело докупается именно по средней цене. (просто в графе именно средняя цена нигде не указывается и нужно считать самому..)
Wahoo: Это усредненная цена всех сделок (т.е. имеющейся позиции), а не цена последней сделки. Читайте про неттинг, ордера, позиции, сделки. То же самое с объемами.
Насчет последней сделки. Вчера и сегодня пытался использовать ссылку которая есть в вышеизложенном сообщении. И попробовал сделать вот такой вариант:
//---блок наращивания существующей позицииdouble posPriceOpen = 0;
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double posVolume = 0.01;
// узнаем цену открытия и совокупный объем позицииif (PositionSelect(Symbol()))
{
posPriceOpen = SymbolInfoDouble(_Symbol, SYMBOL_LAST);
posVolume = PositionGetDouble(POSITION_VOLUME);
}
// условие для наращивания позицииif( ask <= posPriceOpen - DELTA * _Point && PositionsTotal() == 1)
{
double prc = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
//увеличим размер позиции на коэффициентdouble lot = posVolume * COEF;
// вызов функции формирования торгового запросаbool isOpen = SendOrder(prc, lot);
if (isOpen)
{
Print(" Увеличение объема позиции ");
if (PositionSelect(Symbol()))
{
posPriceOpen = SymbolInfoDouble(_Symbol, SYMBOL_LAST);
posVolume = PositionGetDouble(POSITION_VOLUME);
double posTP = PositionGetDouble(POSITION_TP);
Print(" Количество открытых позиций_2: ", PositionsTotal());
Print(" Оъем открытой позиции : ", DoubleToString(posVolume, 2));
Print(" Цена в сделке, подтверждённая брокером : ", DoubleToString(posPriceOpen, 5));
Print(" Тэйк-Профит позиции : ", DoubleToString(posTP, 5));
Print(" ");
}
}
return;
}
//---
То есть этим кодом я хотел докупаться отталкиваясь от цены последней докупки. Но позиция в этом варианте вообще перестала докупаться.
Хотя в принте
Print(" Цена в сделке, подтверждённая брокером : ", DoubleToString(posPriceOpen, 5));
в журнале такая цена существует. Почему же тогда условие на неё не ориентируется и позиция не докупается соответственно?
P.S. На счет журнала - я в принципе постоянно так и делаю. Пользуюсь принтами и смотрю как это выводится потом..
Попробуйте нижеприведенный код:
Единственное, что докупаться позиция начинает почему то не через каждые 50 пунктов(+- проскальзывание допустим) а опять(как и в предыдущих версиях кода) через непонятный(пока что) мне алгоритм.? )
P.S. Если на будущее, необходимо будет докупаться по 2,3,4 и т.д. кругу - это надо будет для каждого, отдельно взятого круга создавать свой "If" ?
(Или это уже совсем другая история и там надо будет, что то более хитроумное изобретать?)
Что мне сейчас первое в голову приходит так это не умножать лот(0.01) на 2 а умножать его на какой то коэффициент, который должен будет менятся в зависимости от того, cколько уже на данный момент было сделано доливок.
(или сколько лотов куплено уже к настоящему моменту.)
+ условие для наращивания позиции необходимо будет как то модифицировать(если это возможно.), что бы оно было одно на все случаи жизни и постоянно могло доливаться с разными коэффициентами лотов.
(я в правильном направлении двигаюсь?)
... (Пытался просматривать код в одном из советников по мартину, но тот код мне непонятен + написан он однозначно неправильно с точки зрения оформления, как мне кажется.
...
Код подправил. Разберитесь хорошо с исправленным кодом.
Но есть моменты: )
Позиция по прежнему отказывается докупаться по тем параметрам, которые прописаны в коде. )
То есть по идее(в данном случае) доливаться должна сделка через каждые 100 пунктов(против себя) + удвоенным лотом.
Проверка на истории показывает, что позиция не удваивается а утраивается.
(начиная с момента наращивания объема.)
+ докупка осуществляется не через каждые 100 пунктов а через 50-90 пунктов +-(в зависимости от случая.)
P.S. Ещё хотел выяснить такой момент для себя:
У вас есть такой кусок кода:
По функции OrderCalcMargin() откройте справку и прочтите ее.
Не бойтесь пользоваться справкой, это только убыстрит процесс обучения программированию.
Написано:
"Возвращает true в случае успеха, иначе false."
Вот и все.
А что такое успех или не успех в данном случае мне не ясно.
(по этому и задал вопрос что означает "ложь" в данном случае.)
P.S. На счет всего остального постараюсь разобраться.
(Спасибо за подсказки и написанный код.)
Просто после последней версии вашего кода я подумал, что позиция должна докупаться по нормальному объему и цене т.к. вы написали что "Подправили код."
Если бы сказали сразу что он не будет работать идеально - я бы не задавал лишних вопросов в последнем сообщении и попытался бы в первую очередь понять почему это происходит. )
После разбора справки, думаю что нижеприведенный код Вам понятен до последнего символа:
Я только сейчас понял, что в справке помечены [in] или [out] - параметры которые я должен прописать и параметры которые функция должна вернуть.
Правда вот такое обозначение [in,out] мне не ясно до сих пор.. )
(возможно, что структура может и принимать и возвращать значения в тех или иных ситуациях..)
Вы не разобрались с кодом.
1. Насчет наращивания позиции подсказка: сколько будет 1 + 2 ? Или так 1 + 1*2 ?
2. Отличается ли цена открытия существующей позиции после доливки? Если отличается то почему?
3. Какая цена является отправной для увеличения объема позиции? Где эти данные в коде?
В общем за сегодня просидел над этим кодом уже часов 7-8 наверное в сумме. )
То есть мне не понятно(и пока идеи даже нет) почему цена именно после 3-го кругаВсе что пришло на ум(пока что) оказалось не эффективным.
Не смог понять причины изменения цены докупки(начиная с 3-го круга) и точно также не понял причину изменения объема лота.
С объемом можно в принципе разобраться при помощи изменения коэффициента. (Изменив число 2 на 1)
Цену 2-ой докупки можно нормализовать путём высчитывания операций не по биду(как было в коде) а по аску.
Но, как я уже сказал ранее, после 3-го круга проблема все равно имеет место.
В итоге у меня получился вот такой код:
(а не после 2-го допустим, когда начинается блок наращивания существующей позиции)
становится с дельтой в 2 раза меньшей, чем у предыдущих 2-х цен.
Задать какой то параметр(или функцию) высчитывания цены докупки именно из текущей цены(при помощи PositionGetDouble(POSITION_PRICE_CURRENT) к примеру)
тоже оказалось невозможным.(хотя это и логично конечно.)
P.S. Вот такие вот дела пока что. )
Возможно завтра ещё что то(какая то идея) на ум придёт - но пока, в любом случае, мои варианты исчерпаны..
(а не после 2-го допустим, когда начинается блок наращивания существующей позиции)То есть мне не понятно(и пока идеи даже нет) почему цена именно после 3-го круга
становится с дельтой в 2 раза меньшей, чем у предыдущих 2-х цен.
Вы используете PositionPriceOpen. Это усредненная цена всех сделок (т.е. имеющейся позиции), а не цена последней сделки.
P.S. Мне например и надо, что бы позиция докупалась через каждые 100 пунктов(в данном случае) именно по усреднённой цене.
(а не по цене последней сделки.)
Или вы хотите сказать, что в данном случае всё именно так и проиcходит?
P.S. Щас ещё раз внимательно посчитал и понял что действительно это все дело докупается именно по средней цене.
(просто в графе именно средняя цена нигде не указывается и нужно считать самому..)
Это усредненная цена всех сделок (т.е. имеющейся позиции), а не цена последней сделки. Читайте про неттинг, ордера, позиции, сделки. То же самое с объемами.
Вчера и сегодня пытался использовать ссылку которая есть в вышеизложенном сообщении.
И попробовал сделать вот такой вариант:
То есть этим кодом я хотел докупаться отталкиваясь от цены последней докупки.
Но позиция в этом варианте вообще перестала докупаться.
Хотя в принте
в журнале такая цена существует.Почему же тогда условие на неё не ориентируется и позиция не докупается соответственно?
P.S. На счет журнала - я в принципе постоянно так и делаю.
Пользуюсь принтами и смотрю как это выводится потом..
То есть этим кодом я хотел докупаться отталкиваясь от цены последней сделки.