Всем привет.
Есть такой кусок кода:
Вопрос:
Почему не срабатывает модификация тейк профита?
(2 принта помеченные оранжевым цветом срабатывают при этом.)
P.S. Буду благодарен за любые советы..
Модифицируете короткую или длинную позицию?
Модифицируете короткую или длинную позицию?
Всем привет.
Есть такой кусок кода:
Вопрос:
Почему не срабатывает модификация тейк профита?
(2 принта помеченные оранжевым цветом срабатывают при этом.)
P.S. Буду благодарен за любые советы..
if(ModifyOrder(prc, price_bid)) bool ModifyOrder(double price, double prc_bid)
Ну нужно по порядку разбираться.
Во-первых, доходит ли исполнение до
//---отправка запроса на сервер и проверка результата отправки if (OrderSend(request,result)) { if ( result.retcode == TRADE_RETCODE_DONE) { return (true); }; };
Поставьте Print перед этим участком, чтобы видеть проходят ли условия по марже.
Во-вторых, Print после OrderSend (перед if (result.retcode)) с выводом result.retcode, и в дополнение else с выводом ошибки GetLastError().
Тогда получим больше деталей об отказе функции.
разные переменные
То есть как я понимаю в одном месте при создании функции я прописываю параметры в виде переменных.
А в другом месте(во время вызова), как мне обьясняли можно уже передавать в это место значение в виде других переменных..
Ну нужно по порядку разбираться.
Во-первых, доходит ли исполнение до
Поставьте Print перед этим участком, чтобы видеть проходят ли условия по марже.
Во-вторых, Print после OrderSend (перед if (result.retcode)) с выводом result.retcode, и в дополнение else с выводом ошибки GetLastError().
Тогда получим больше деталей об отказе функции.
//---проверим хватает ли средств для открытия позиции double margin = 0.0; if (!OrderCalcMargin(request.type, request.symbol, request.volume, request.price, margin)) { Print("Условия по марже"); return(false); } if (margin > AccountInfoDouble(ACCOUNT_FREEMARGIN)) { Print("Условия по марже_2"); return(false); } //---отправка запроса на сервер и проверка результата отправки if (OrderSend(request,result)) { if ( result.retcode == TRADE_RETCODE_DONE) { Print("TRADE_RETCODE_DONE"); return (true); }; }; return(false); };// функция модификации торгового запроса-------------------------------------------------------------------------------------------------+Тестируя на истории в журнале - получил вот такой результат:
Но какой вывод из этого я должен сделать мне пока не понятно? )
Не ужели маржи не хватает для модификации ордера? )
(Она же там вообще ни при чем по идее..)
Изменил код следующим образом:
Тестируя на истории в журнале - получил вот такой результат:
Но какой вывод из этого я должен сделать мне пока не понятно? )
Не ужели маржи не хватает для модификации ордера? )
(Она же там вообще ни при чем по идее..)
Не совсем то о чем я говорил.
//---проверим хватает ли средств для открытия позиции double margin = 0.0; if (!OrderCalcMargin(request.type, request.symbol, request.volume, request.price, margin)) { Print("Условия по марже"); return(false); } Print ("Первое условие по марже - ОК"); if (margin > AccountInfoDouble(ACCOUNT_FREEMARGIN)) { Print("Условия по марже_2"); return(false); } Print ("Второе условие по марже - ОК"); //---отправка запроса на сервер и проверка результата отправки if (OrderSend(request,result)) { Print ("Запрос отправлен, результат:",result.retcode); if ( result.retcode == TRADE_RETCODE_DONE) { Print("TRADE_RETCODE_DONE"); return (true); }; } else { Print("Ошибка при отправке запроса #", GetLastError()); }; return(false); };// функция модификации торгового запроса-------------------------------------------------------------------------------------------------+
Попробуйте так, увидите что по марже оба условия выполняются, далее, возможно OrderSend даст ошибку и увидите "Ошибка при отправке запроса #" с номером ошибки. Далее ищем справку и смотрим по коду ошибки.
Если же получите "Запрос отправлен, результат:" с кодом результата, посмотрите что за код. Могут быть TRADE_RETCODE_PLACED вместо TRADE_RETCODE_DONE...
Попробовал - но вроде получается тоже самое.
А после изменений, код перекомпилировали? выглядит так, будто ваш предыдущий код работает только.
Можите сами проверить.
(если есть желание.)
//+------------------------------------------------------------------+ //| 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 = 222; // количество пунктов прохода цены для уведичения позиции ulong magic_number = 87654321; // магический ордер //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Expert Get history price function | //+------------------------------------------------------------------+ double GetHistoryPrice( const string aSymbol ) { double price_in = 0; double volume_in = 0; if ( PositionSelect( aSymbol ) ) { long pos_id = long( PositionGetInteger( POSITION_IDENTIFIER ) ); if ( pos_id > 0 ) { if ( HistorySelectByPosition( ulong( pos_id ) ) ) { int deals = HistoryDealsTotal(); for( int i = 0; i < deals; i++ ) { ulong deal_ticket = HistoryDealGetTicket( i ); ulong order_ticket = ulong( HistoryDealGetInteger( deal_ticket, DEAL_ORDER ) ); if ( order_ticket > 0 ) { long deal_entry = long( HistoryDealGetInteger( deal_ticket, DEAL_ENTRY ) ); if ( deal_entry == DEAL_ENTRY_IN ) { double price = HistoryDealGetDouble( deal_ticket, DEAL_PRICE ); double volume = HistoryDealGetDouble( deal_ticket, DEAL_VOLUME ); price_in = price_in + price * volume; volume_in = volume_in + volume; } } } if ( volume_in > 0 ) return( NormalizeDouble( price_in / volume_in, _Digits ) ); } else { Print( "Не возможно получить историю позиции по символу ", aSymbol ); } } else { Print( "Не возможно определить идентификатор позиции по символу ", aSymbol ); } } return( 0 ); } //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- //--- return(INIT_SUCCEEDED); }//---------------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- }//---------------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { datetime tm=TimeCurrent(); MqlDateTime stm; TimeToStruct(tm,stm); // вызываем функцию вычисления последнего ордера и преобразовываем результат в 5-ти значное число. double hist_price = GetHistoryPrice(_Symbol); double prc = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double price_bid = SymbolInfoDouble(Symbol(), SYMBOL_BID); double posVolume = PositionGetDouble(POSITION_VOLUME); // Подсчитываем профит текущей позиции double pos_prof_gl = NormalizeDouble(PositionGetDouble(POSITION_PROFIT), 2); if(!PositionSelect(_Symbol)) { pos_prof_gl = 0; }; Print("ТЕКУЩИЙ ПРОФИТ: ", pos_prof_gl); Print("ТЕКУЩИЙ BID: ", price_bid); if(!PositionSelect(_Symbol) && stm.hour >= 1 && stm.hour <= 5) { // вызываем функцию, подсчитывающую кол-во лотов для стартовой сделки double trade_lot = function_trade_lot(AccountInfoDouble(ACCOUNT_BALANCE)); if(SendOrder(prc, trade_lot, pos_prof_gl, price_bid)) { // первоначальная позиция открыта.. Print("Первоначальное открытие"); Print("Час: " +(string)stm.hour); Print("Минута: " +(string)stm.min); Print("Секунда: " +(string)stm.sec); } } else if(pos_prof_gl < 0.10) { // доливка существующей позиции. //увеличим размер позиции на коэффициент double lot = posVolume * COEF; double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); if(ask <= hist_price - DELTA * _Point) { // -------+ вызов функции формирования торгового запроса +--------- if(SendOrder(prc, lot, pos_prof_gl, price_bid)) { Print("Позиция добавлена"); Print("Час: " +(string)stm.hour); Print("Минута: " +(string)stm.min); Print("Секунда: " +(string)stm.sec); } } } else if(pos_prof_gl >= 0.10) { Print("НАДО МОДИФИЦИРОВАТЬ ОРДЕР. Профит равен: ", pos_prof_gl, "-ти" ); // модификация существующей позиции. // -------+ вызов функции формирования торгового запроса +--------- if(ModifyOrder(prc, price_bid)) { Print("ПОЗИЦИИ МОДИФИКАЦИРОВАНА. Тейк профит равен:", price_bid); Print("Час: " +(string)stm.hour); Print("Минута: " +(string)stm.min); Print("Секунда: " +(string)stm.sec); } else { Print("Ошибка Модификации!!!"); } } }; //функция формирующая торговый запрос на открытие позиции и проверку результата открытия -------------------+ bool SendOrder(double price, double volume, double pos_prof, double prc_bid) { if(volume >= 99){ Print("ОШИБКА! Обьем Ордера привысил размер 99 лотов и сейчас ровняется", volume,"-м"); return(false); }; MqlTradeRequest request = {0}; MqlTradeResult result = {0}; //---заполняем поля торгового запроса request.action = TRADE_ACTION_DEAL; // Тип выполняемого действия request.symbol = _Symbol; // Имя торгового инструмента request.magic = magic_number; request.volume = volume; // Запрашиваемый объем сделки в лотах request.price = price; // Цена request.type = ORDER_TYPE_BUY; // Тип ордера request.tp = price + 400*_Point; // Цена, по которой сработает Take Profit ордер при движении цены в благоприятном направлении request.sl = price - 2700*_Point; // Цена, по которой сработает Stop Loss ордер при движении цены в неблагоприятном направлении request.deviation = 0; // Максимально приемлемое отклонение от запрашиваемой цены, задаваемое в пунктах 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)) { if ( result.retcode == TRADE_RETCODE_DONE) { return (true); }; }; return(false); };// функция торгового запроса-------------------------------------------------------------------------------------------------+ //функция формирующая модификацию торгового запроса и проверки результата -------------------+ bool ModifyOrder(double price, double prc_bid) { MqlTradeRequest request = {0}; MqlTradeResult result = {0}; //---заполняем поля торгового запроса request.action = TRADE_ACTION_MODIFY; // Тип выполняемого действия request.symbol = _Symbol; // Имя торгового инструмента request.tp = prc_bid; // Цена, по которой сработает Take Profit ордер при движении цены в благоприятном направлении request.sl = price - 270*_Point; // Цена, по которой сработает Stop Loss ордер при движении цены в неблагоприятном направлении //---проверим хватает ли средств для открытия позиции double margin = 0.0; if (!OrderCalcMargin(request.type, request.symbol, request.volume, request.price, margin)) { Print("Условия по марже"); return(false); } Print ("Первое условие по марже - ОК"); if (margin > AccountInfoDouble(ACCOUNT_FREEMARGIN)) { Print("Условия по марже_2"); return(false); } Print ("Второе условие по марже - ОК"); //---отправка запроса на сервер и проверка результата отправки if (OrderSend(request,result)) { Print ("Запрос отправлен, результат:",result.retcode); if ( result.retcode == TRADE_RETCODE_DONE) { Print("TRADE_RETCODE_DONE"); return (true); }; } else { Print("Ошибка при отправке запроса #", GetLastError()); }; return(false); };// функция модификации торгового запроса-------------------------------------------------------------------------------------------------+ // возвращает цену открытия последнего ордера, где nMode - ORDER_TYPE_BUY/ORDER_TYPE_SELL ----------+ // для позиции с идентификатором PositionID double FindLastPrice(int nMode) { int CntPos; // количество ордеров в истории ulong nTicket; // тикет выбранного ордера из истории ulong OldTicket = 0; // тикет ордера найденного ранее long PosID, PosiID; // идентификатор позиции, к которой относится выбранный ордер //long Magic; // магический номер long Type; // тип найденного ордера (Buy или Sell) double OrderPrice = 0; // найденная цена // идентификатор позиции if((PosiID = PositionGetInteger(POSITION_IDENTIFIER))==0) return(0.0); // создадим список ордеров и сделок, находящихся в истории HistorySelect(0, TimeCurrent()); CntPos = HistoryOrdersTotal(); // количество ордеров в истории // переберем все ордеры истории и отберем те, что относятся к нашей открытой позиции for (int i = 0; i < CntPos; i++) { nTicket = HistoryOrderGetTicket(i); // получим тикет очередного ордера PosID = HistoryOrderGetInteger(nTicket, ORDER_POSITION_ID); // позиция ордера Type = HistoryOrderGetInteger(nTicket, ORDER_TYPE); // тип ордера if ((PosID == PosiID) && (Type == nMode)) { if (nTicket > OldTicket) // этот ордер был открыт позже найденного ранее { OrderPrice = HistoryOrderGetDouble(nTicket, ORDER_PRICE_OPEN); // цена открытия ордера OldTicket = nTicket; // запомним тикет }; }; }; return(OrderPrice); };//---------------------------------------------------------------------------+ // ---- функция подсчета значения стартового лота. ------------------------------+ double function_trade_lot(double account_balance ){ double lot = 0.01; //lot = NormalizeDouble(0.01+MathMax(MathFloor((account_balance-100000)/50000),0)*0.01,2); //lot = MathMin(lot, SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX)); return(lot); };//---------------------------------------------------------------------------+
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Есть такой кусок кода:
Вопрос:
Почему не срабатывает модификация тейк профита?
(2 принта помеченные оранжевым цветом срабатывают при этом.)
P.S. Буду благодарен за любые советы..