Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Если сможем, то добавим функцию, которая сможет выдавать код клавиши, нажатой во время операции drag'n'drop.
Да, панель быстрого вызова будет. Как созреем до реализации - сразу сделаем. Но пока закончим тестер.
входящий поток данных и функция start() индикатора/эксперта.
Котировки приходят по запросу или как-то иначе ?
Если по запросу, то в какой момент он выполняется ?
Очередная котировка приходит независимо от работы
индикатора/эксперта или только после отработки его start() ?
При инициализации эксперта/индикатора вызывается функция init(), а снятии deinit().
Индикатор вызывается на перерасчет когда:
- история сильно изменилась (в первом отображении тоже)
- по приходу ценового тика по этому инструменту
- если бы изменен MQL4 код (например, в редакторе)
Котировки приходят и накапливаются в базах независимо от всего остального, то есть, прием котировок идет в отдельном потоке. После приема котировки посылается уведомление на перерасчет индикаторов. Соответственно, если индикаторы считаются долго (функция start()), то они будут пропускать некоторые уведомления о пересчете. Индикаторы надо всегда стараться писать по экономному с учетом ранее просчитанных баров.
А эксперт может запускать функцию start() только после прихода нового тика. Если эксперт еще не завершил работу, то уведомление пропускается. Эксперт теперь может тратить неограниченное количество времени на себя и использовать функцию Sleep(). Чтобы избежать работы со старыми историческими данными при длительных задержках в эксперте, мы рекомендуем использовать (например не чаще чем раз в секунду) функцию RefreshRates( ).
имхо, лучше бы не во время drag'n'drop, а просто при работе скрипта. Тогда в start() можно было бы поймать нажатую клавишу.
эту же возможность еще лучше было бы использовать при работе экспертов. Например, работает советник, жмем определенную клавишу и советник нам выдает результаты какого нибудь расчета, жмем другую - еще что-нибудь делает.
Хорошо было бы при этом ловить координаты мыши.
Так, "Остапа понесло" (с) :)
Так, "Остапа понесло"
Точно понесло...
1. Некорректно работает ArrayCopy для двумерных массивов. Код копирующий первые (total-1) элементов двумерного масива в конец этого же масива
int i, total = 3; int data[][2]; ArrayResize(data, total); for (i = 0; i < total; i++) { data[i][0] = i; data[i][1] = (i + 10); } for (i = 0; i < total; i++) Print("data[" + i + "]="+ data[i][0] + ", " + data[i][1]); ArrayCopy(data, data, 1, 0, total - 1); Print("-------"); for (i = 0; i < total; i++) Print("data[" + i + "]="+ data[i][0] + ", " + data[i][1]);генерирует вывод
хотя после ArrayCopy должно быть:
Если вместо ArrayCopy копировать руками:
for (i = total-2; i >= 0; i--) { data[i+1][0] = data[i][0]; data[i+1][1] = data[i][1]; }все будет правильно. Также непонятно как проинициализировать двумерный массив при объявлении
int data2[3][2] = {{1, 10}, {2, 11}, {3, 12}};компилятором не понимается.
string orderStr(bool closed=false) { }к этой функции нельзя обратиться как orderStr(), а только как orderStr(state). Если функция юудет объявлена в эксперте - обращайся как хочешь.
3. Highest и Lowest возвращают 1.0 или 2.0, а не реальные цены:
string orderStr(bool closed=false) {}к этой функции нельзя обратиться как orderStr(), а только как orderStr(state). Если функция юудет объявлена в эксперте - обращайся как хочешь.
об этом говорили - типа так должно быть =)
Я что-то сомневаюсь, что такое копирование массива самого в себя разрешено...
Слава в понедельник точнее скажет.
Это правильно - так и задумано.
Эти функции возвращают индексы, а не сами значения. К сожалению, в описании ошибка.
Спасибо что указали на нее.
string orderStr(bool closed=false) { double lots = OrderLots(); string orderStr = "#" + OrderTicket() + " " + orderTypeStr(OrderType()) + " " + p2Str(OrderLots()) + " (" + OrderLots() + ") " + OrderSymbol() + ", open=" + quoteStr(OrderOpenPrice()) + ", sl=" + quoteStr(OrderStopLoss()) + ", tp=" + quoteStr(OrderTakeProfit()) + ", comm=" + OrderComment() + ", exp=" + TimeToStr(OrderExpiration()) + ", openTime=" + TimeToStr(OrderOpenTime()); if (closed) { double points = (OrderClosePrice() - OrderOpenPrice())/Point; if (OrderType() == OP_SELL) points = -points; orderStr = "Profit=" + quoteStr(OrderProfit()) + " (" + DoubleToStr(points, 0) + " points) " + orderStr + ", closeTime=" + TimeToStr(OrderCloseTime()) + ", close=" + quoteStr(OrderClosePrice()) + ", swap=" + quoteStr(OrderSwap()); } return (orderStr); } string p2Str(double value) { return (DoubleToStr(value, 2)); }Но после открытия ордера:
int sendOrder(int type, double price, double slPrice, double tpPrice) { log("Trying send order " + orderTypeStr(type) + " " + Lots + " " + Symbol() + ", price=" + quoteStr(price) + ", slPrice=" + quoteStr(slPrice) + ", tpPrice=" + quoteStr(tpPrice) + ", slippage=" + Slippage + ", Bid=" + quoteStr(Bid) + ", Ask=" + quoteStr(Ask)); int ticket = OrderSend(Symbol(), type, Lots, price, Slippage, slPrice, tpPrice, ORDER_PREFIX, 16384, 0, Red); if (ticket < 0) { int err = logLastError("OrderSend"); switch (err) { case 134: setMarketEnter(-1); break; // not enough money case 135: RefreshRates(); break; // prices changed } } else { log("Order sent: " + orderStr(false)); setMarketEnter(-1); } flushLog(); return (ticket); }получаем следующее описание в логе:
2005.03.25 17:19:59 Order sent: #0 SELL 8.14 (0.00000000) , open=1.2955, sl=1.2955, tp=1.2955, comm=, exp=1970.01.01 00:00, openTime=1970.01.01 00:00
Как видим ticket не инициализирован, время открытия тоже, с OrderLots() - вообще цирк.
После закрытии ордера таже картина:
2005.03.25 18:15:27 Order closed Profit=1.2954 (0 points) #0 BUY 10.55 (0.00000000) , open=1.2954, sl=1.2954, tp=1.2954, comm=, exp=1970.01.01 00:00, openTime=1970.01.01 00:00, closeTime=1970.01.01 00:00, close=1.2954, swap=1.2954
Почему некоторые поля не инициализированы, swap вообще совпадает с close, а OrderLots() - рандомизирован?
для скорости я рекомендую (по возможности) включать код библиотеки в саму программу через #include, а не через импорт #import. Импорт библиотек через #import - это серьезные накладные расходы, сопоставимые с COM. С помощью #include исходный код библиотеки встраивается непосредственно в основной код, тем самым получается экономия на вызовах функций.