Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
для всех экспертов существует только один торговый поток. правильным решением будет строительство собственной системы семафоров на глобальных переменных.
я запустил 4 эксперта на 4 минутках. за 10 минут работы 7 раз ошибка 139
для всех экспертов существует только один торговый поток. правильным решением будет строительство собственной системы семафоров на глобальных переменных.
я запустил 4 эксперта на 4 минутках. за 10 минут работы 7 раз ошибка 139
Не могли бы вы, хотя бы в общих чертах, рассказать, какой должна быть эта система семафоров?
1. В частности, как должна совершаться сделка, чтобы не мешать другим.
2. Слипы, проверки, таймауты (которых обещали, что нет в многопотоковом МТ, ну да ладно)
Ну и наконец. Не сочтите за упрек. У вас есть учебник. В нем приведен эксперт. Покажите мне там эти семафоры.
Вот мой эксперт. Прост, как трусы за рубль двадцать. Каждый час перевернуть позицию. Если Вы действительно заботитесь о трейдерах и о доходах брокеров (не знаю, кто как, а я хочу сначала получить стабильно работающий эксперт, а затем переходить с демо на реал), то пожалуйста, на примере этого моего эксперта, покажите, как НАДО делать правильно.
С уважением,
Кварк
П.С. Вопрос о происхождении ошибки 2, 6, 138 и 4109, которые тоже иногда вылезают, остается открытым.
сегодня обсуждали аналогичную проблему на английском форуме "Trade Dispatcher: all trade context is busy"
Прочитал я англоязычную ветку. Н-да... Этим ребятам надо срочно учить русский.
Это не аналогичная, это та же самая проблема. Правда, ошибки 2, 6, 138 и 4109 они пока не получили. Речь шла только о 139.
Смысла в IsTradeAllowed я не вижу, если честно. Слава сам же объяснил, как десять экспертов получают добро от этой функции, после чего дружно кидаются торговать, и обламываются все, кроме первого.
Куда лучше было бы сделать очередь запросов, где они бы накапливались, жили некоторое время, и либо исполнялись, либо удалялись. Но это все мечты.
Скорее, придется делать глобальную переменную nTrading, например, и писать в нее мн торгующего в данный момент эксперта. Закономерный вопрос - а что делать остальным экспертам? Опять назад, к МТ3 с его pending ордерами... или есть другие идеи?
Кстати, можно и без глобальной переменной, достаточно чего-то вроде
if(nPending == OP_BUY) nPending = Buy(); else if(nPending == OP_SELL) nPending = Sell();где Buy() и Sell() возвращают OP_BUY / OP_SELL при неудаче и -1 в случае успеха.
Минусы очевидны - брокер получит десять ордеров на открытие (закрытие), вместо одного. Если это автомат, все хорошо. Если человек - он обидится. Хуже, если автомат и человек действуют по разной логике. Например, у автомата нет очереди (как нам объяснил Слава, один поток, и ордера конкурируют, вместо того, чтобы строиться в очередь), а у человека есть. Тогда, начав торговать в реале, трейдер прогорит, и даже не поймет почему, ведь его уверяли (меня - на семинаре-презентации в Альпари), что нет никакой разницы между демо и реалом.
Второй вариант - каждому эксперту и валюте присваивается свой мн, так, что сочетание эксперт + валюта уникально. Затем пишем код так, что эксперт с мн 1 торгует в первую секунду, с мн 7 - в седьмую и т.д. после открытия бара. Это даст системе секунду на сделку.
Вопрос Славе - хватит ли секунды, чтобы избежать проблемы?
Минусы очевидны, о них вам расскажут скальперы - пипсовики :)
Уважаемые разработчики (и все-все-все). Спасибо за разъяснения. В этом и предыдущих постах остались неотвеченные вопросы. Жду ответа.
Кварк
//+------------------------------------------------------------------+ //| TestQuark.mq4 | //| Copyright © 2005, MetaQuotes Software Corp. | //| http://www.metaquotes.net | //+------------------------------------------------------------------+ #property copyright "Copyright © 2005, MetaQuotes Software Corp." #property link "http://www.metaquotes.net" double dStopLoss; int nHoursToHold; datetime timePrev = 0; int nSlip = 5; double dLotSize = 0.1; int nMagic = 0; string SemaphoreName="TradeSemaphore"; ////////////////// int init () { if(!GlobalVariableCheck(SemaphoreName)) GlobalVariableSet(SemaphoreName,0.0); timePrev = 0; dStopLoss = 110 * Point; nHoursToHold = 1; if(Symbol() == "EURUSD") nMagic = 1; else if(Symbol() == "EURJPY") nMagic = 2; else if(Symbol() == "USDCHF") nMagic = 3; else if(Symbol() == "GBPUSD") nMagic = 4; else if(Symbol() == "GBPJPY") nMagic = 5; else if(Symbol() == "GBPCHF") nMagic = 6; else if(Symbol() == "USDJPY") nMagic = 7; else if(Symbol() == "AUDUSD") nMagic = 8; else if(Symbol() == "EURGBP") nMagic = 9; else if(Symbol() == "USDCAD") nMagic = 10; else if(Symbol() == "EURCHF") nMagic = 11; else if(Symbol() == "EURAUD") nMagic = 12; timePrev += nMagic; // Open nMagic seconds after the new bar return(0); } // ------ int deinit() { return(0); } // ------ int start() { if(Bars < 5) return(0); // The previous bar just closed bool bIsBarEnd = false; if(timePrev != Time[0] + nMagic) bIsBarEnd = true; timePrev = Time[0] + nMagic; if(!bIsBarEnd) return(0); // ------ int nSignal = GetSignal(); bool bSemaphored=false; while(!IsStopped()) { if(GlobalVariableGet(SemaphoreName)==0.0) { GlobalVariableSet(SemaphoreName,1.0); bSemaphored=true; break; } Sleep(1000); } if(nSignal == OP_BUY) Buy(); else if(nSignal == OP_SELL) Sell(); for(int nCnt = OrdersTotal() - 1; nCnt >= 0; nCnt--) { OrderSelect(nCnt, SELECT_BY_POS, MODE_TRADES); if(OrderMagicNumber() == nMagic) { if(CurTime() - OrderOpenTime() > (nHoursToHold - 1) * 60 * 60) { if(OrderType() == OP_BUY) OrderClose(OrderTicket(), OrderLots(), Bid, nSlip, Aqua); else if(OrderType() == OP_SELL) OrderClose(OrderTicket(), OrderLots(), Ask, nSlip, OrangeRed); } } } if(bSemaphored) GlobalVariableSet(SemaphoreName,0.0); return(0); } // ------ void Sell() { if(AccountFreeMargin() < 500) return; dLotSize = GetLotSize(); int nResult = OrderSend(Symbol(), OP_SELL, dLotSize, Bid, nSlip, Bid + dStopLoss, 0, "Friday", nMagic, 0, OrangeRed); if(nResult == -1) { int nError = GetLastError(); Alert(Symbol() + ", " + nError); } } // ------ void Buy() { if(AccountFreeMargin() < 500) return; dLotSize = GetLotSize(); int nResult = OrderSend(Symbol(), OP_BUY, dLotSize, Ask, nSlip, Ask - dStopLoss, 0, "Friday", nMagic, 0, Aqua); if(nResult == -1) { int nError = GetLastError(); Alert(Symbol() + ", " + nError); } } // ------ double GetLotSize() { double dLot = 0.1; return(dLot); } // ------ int GetSignal() { int nSignal; if(MathMod(Hour(), 2) == 0) nSignal = OP_BUY; else nSignal = OP_SELL; return(nSignal); } //+------------------------------------------------------------------+если сделать функцию установки значения глобальной переменной при условии наличия в этой переменной определённого значения, чтобы не было конструкции
if(GlobalVariableGet(SemaphoreName)==0.0) { GlobalVariableSet(SemaphoreName,1.0); bSemaphored=true; break; }тогда будет 100 процентов надёжности
что-то типа
if(GlobalVariableSetOnCondition(SemaphoreName, 1.0, 0.0)==true) { bSemaphored=true; break; }нет. стопы отрабатываются на сервере. а в нашем случае идёт конкуренция за экспертный торговый поток клиента
А на счёт очереди - у меня была идея сделать эксперта, исполняющего ордера, записанные в файле. А всеми остальными экспертами просто писАть в этот файл приказы.
Но это не очень просто, как для меня ( в смысле, грамотно реализовать )... Но попробовать можно. Общими усилиями =))
Вот этот пассаж я не понял:
если сделать функцию установки значения глобальной переменной при условии наличия в этой переменной определённого значения, чтобы не было конструкции
if(GlobalVariableGet(SemaphoreName)==0.0)
{
GlobalVariableSet(SemaphoreName,1.0);
bSemaphored=true;
break;
}
Теперь насчет логики этого дела. Вы уж извините, что пристаю, но...
Если я правильно понял, мы сидим в цикле while до тех пор, пока не удастся выставить семафор. Так? Потом торгуем, зная, что кроме нас никто не торгует. Потом возвращаем семафор к исходному состоянию.
Вопрос: как работает while(!IsStopped()) ? Из хелпа не совсем понятно, я-то думал, это проверка на Allow Live Trading.
Вопрос: эти while и Sleep не будут тормозить систему?
Вопрос: будет ли Sleep и семафор корректно обрабатываться в режиме тестирования?
Еще по логике. Между установкой и снятием семафора, у нас две (максимум) возможности работы с ордерами. Сначала Buy() или Sell() и потом, ниже, CloseOrder(). Не будут ли эти две "активности" конкурировать друг с другом, хоть внутри эксперта, но также, как если бы экспертов было два? Или процесс гарантированно линеен, и пока Buy() не вернется, до CloseOrder() дело не дойдет?
Заранее спасибо.
Кварк
нет. стопы отрабатываются на сервере. а в нашем случае идёт конкуренция за экспертный торговый поток клиента
Я неправильно выразился. Надо ли OrderSend(OP_BUYSTOP... тоже окружать кодом, устанавливающим и снимающим семафоры? Глупый вопрос. Надо, конечно.
Переделал торговые ф-ции (подключил свою библиотеку) и повесил на другую евру - м15. Мейджик, есс-но, поменял.
Ближе к ночи скажу, что получилось ;)