- www.metatrader5.com
- Защита ордеров несколькими Stop Loss уровнями.
- Советники: Мультивалютный советник на основе кластерного индикатора (третья версия)
- MQL4. Открытие противоположной сделки после стопа
После открытия позиции советником функции работы с ордерами, позициями и сделками могут сообщить только первоначальный стоп лосс. Почему это так и измененный, в следствии модификации позиции, стоп лосс не записывается в неё, а продолжает храниться первоначальный стоп лосс, который был при открытии позиции? Как узнать действительный стоп лосс, который может быть изменен вручную или с помощью OrderSend, пока позиция находится в рынке?
Очень спорное заявление. Как узнать, что Вы говорите правду? (где код?)
А так понимаю идёт речь об этой проблеме:
Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий
Отследить stop loss и take profit
Vladimir Karputov, 2017.08.07 10:04
Задача в общем не нова: попытаться восстановить уровни stop loss и take profit. Проблема в том, что операции модификации НИКАК НЕ ОТРАЖАЮТСЯ в торговой истории.
Но, как говориться, не велика беда начала, нужно с чего то начинать.
В общем сейчас буду что-то такое делать, чтобы выполнялся такой процесс:
- шаг 1: открываем позицию (или BUY или SELL) сразу с установленным уровнем stop loss и take profit
- шаг 2: модификация уровня stop loss (вручную, перетаскиваем поближе к текущей цене)
- шаг 3: ждёмс срабатывания stop loss или take profit
А так понимаю идёт речь об этой проблеме:
Тогда топикстартер, видимо, не очень хорошо излагает свои мысли. Ведь актуальный СЛ позиции можно получить в любой момент времени.
Попросил автора появиться в ветке.
В общем, если более конкретно, то актуальный СЛ нельзя получить с помощью следующих функций:
// У сделки из истории стоп лосса нет, поэтому, попытался получить СЛ ордера, по которому открылась данная сделка HistoryOrderGetDouble(Ticket, ORDER_SL, order_sl); Print("order_sl: ", order_sl); // Но там хранится только первоначальный стоп лосс, само собой
Пробовал получить СЛ позиции в OnTick:
PositionGetDouble(POSITION_SL, pos_sl); Print("pos_sl: ", pos_sl);
Казалось бы, функция для работы с позициями должна дать актуальный СЛ, но нет. Дает всё тот же первоначальный стоп лосс.
У себя в советнике я получаю непосредственно рассчитанный стоп лосс во время модификации позиции, а так же во время её открытия. Но если трейдер передвинет стоп лосс вручную, то советник об этом ничего не "узнает". Вот в чем, собственно, проблема.
Подозреваю, что не соблюдается протокол работы с историческими позициями.
Действительно, непонятно, что автор там делает. Надо смотреть конкретный кусок кода. Как выбирается история, как выбирается позиция, как получается СЛ.
В документации есть еще много разных функций, по одиночке которые мало на что способны. Что за тикет, что за позиция, у чего они запрашиваются - не понятно.
Подозреваю, что не соблюдается протокол работы с историческими позициями.
Действительно, непонятно, что автор там делает. Надо смотреть конкретный кусок кода. Как выбирается история, как выбирается позиция, как получается СЛ.
Привожу функцию из своего советника:
void OnCloseOnSL(){ if(Ticket <= 0) return; if(PositionsTotal() <= 0){ if(!HistorySelect(0, TimeCurrent())) return; int deals_total = HistoryDealsTotal(); if(deals_total <= 0) return; ulong deal_ticket; double close_price, open_price; int digits = (int)SymbolInfoInteger(Symbol_, SYMBOL_DIGITS); ENUM_DEAL_TYPE deal_type; for(int i = deals_total - 1; i >= 0; i--){ deal_ticket = HistoryDealGetTicket(i); if(deal_ticket <= 0) continue; if(HistoryDealGetInteger(deal_ticket, DEAL_MAGIC) != Magic) continue; if(HistoryDealGetString(deal_ticket, DEAL_SYMBOL) != Symbol_) continue; if(HistoryDealGetInteger(deal_ticket, DEAL_ENTRY) != DEAL_ENTRY_OUT) continue; if(HistoryDealGetInteger(deal_ticket, DEAL_POSITION_ID) != Ticket) continue; close_price = NormalizeDouble(HistoryDealGetDouble(deal_ticket, DEAL_PRICE), digits); open_price = NormalizeDouble(HistoryDealGetDouble(Ticket, DEAL_PRICE), digits); PositionSL = NormalizeDouble(PositionSL, digits); if(close_price != PositionSL) continue; // Позиция закрылась по СЛ deal_type = (ENUM_DEAL_TYPE)HistoryDealGetInteger(deal_ticket, DEAL_TYPE); if(deal_type == DEAL_TYPE_BUY){ ProfitPrev = int((close_price - open_price) / Point_); Ticket = 0; PosSign = psNone; } else if(deal_type == DEAL_TYPE_SELL){ ProfitPrev = int((open_price - close_price) / Point_); Ticket = 0; PosSign = psNone; } } } }
Данную функцию вызываю в OnTrade:
void OnTrade(){ //--- EA1.OnCloseOnSL(); }
Переменная Ticket, это идентификатор позиции, которая была открыта с помощью OrderSend. То есть, функция просматривает ордера в истории и находит ИД позиции, с которой связан найденный ордер:
if(HistoryDealGetInteger(deal_ticket, DEAL_POSITION_ID) != Ticket) continue;
Таким образом, получаю цену открытия позиции и собственно ордер и сделку по которым позиция была закрыта.
PositionSL - как я уже говорил, это расчётный стоп лосс, полученный во время открытия и во время модификации позиции, идентификатор которой хранится в переменной Ticket.
Как получить актуальный стоп лосс, не знаю.
Также, когда пытался получить актуальный СЛ в OnTick, получал только первоначальный стоп лосс:
void Run(){ if(PositionSelectByTicket(Ticket){ PositionSL = PositionGetDouble(POSITION_SL); } //... } void OnTick(){ //--- EA1.Run(); }
Как получить актуальный стоп лосс, не знаю.
Позицию сначала выбрать надо, только потом к ней обращаться.
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования