Вот это место попалось:Обсуждалось где-то в этом разделе.
http://fxgeneral.com...p?showtopic=998
Можно ещё там уточниться.
Отправлено 22 February 2011 - 03:38
Вот это место попалось:Обсуждалось где-то в этом разделе.
Отправлено 28 February 2011 - 01:12
void func( int p1, int p2 = 0, int p3 = 0, int p4 = 0 ) { ... } ... // вызовы: func( 2 ); func( 2, 3 ); func( 2, 3, 4 );
void func( int p1, int p2, int p3, int p4 ) { ... }- в начало файла советника впишем (описание функции):
#import "lib.ex4" void func( int p1, int p2 = 0, int p3 = 0, int p4 = 0 ); #import- в точке вызова:
func( 2 );- и вот тут-то нарываемся на ошибку ("неправильное число параметров функции").
Отправлено 28 February 2011 - 02:44
Ещё раз о недокументированных возможностях...
Но если раньше я описал некоторые возможности, то теперь у меня вопрос, ответ на который я нигде не могу найти... Возможно кто-то может подсказать?
Иначе придётся его выяснять экспериментально, что не хотелось бы...
Но вот вопрос! Если задаётся позиция i в списке ордеров, то этот список, естественно, упорядочен по какому-то признаку... достаточно естественно, чтобы это было время закрытия-удаления - OrderCloseTime()...
Вот и вопрос: по какому признаку упорядоченными будут "вываливаться" ордера в показанном цикле? Если по времени закрытия, то в возрастающем или убывающем порядке? какой будет получен при i==0 : самый старый или самый последний?
int HistoryOrdersList( double &order[][], int iMagic ) { string sSymbol = Symbol(); int k = OrdersHistoryTotal(), cnt = 0; ArrayResize( order, k ); for( int i = 0; i < k; i++ ) { if( OrderSelect( i, SELECT_BY_POS, MODE_HISTORY ) ) { if( OrderSymbol() != sSymbol ) continue; if( iMagic != 0 && OrderMagicNumber() != iMagic ) continue; if( OrderCloseTime() == 0 ) continue; if( OrderType() != OP_BUY && OrderType() != OP_SELL ) continue; order[ cnt ][ 0 ] = OrderTicket(); ... order[ cnt ][ 4 ] = OrderOpenTime(); order[ cnt ][ 5 ] = OrderCloseTime(); cnt++; } } ArrayResize( order, cnt ); return ( cnt ); }
2011.02.28 01:31:36 2011.02.25 22:59 h1 EURUSD,H1: 2010.02.19 08:00:00 ... 2010.02.25 03:00:00
2011.02.28 01:31:36 2011.02.25 22:59 h1 EURUSD,H1: 2010.02.22 05:00:00 ... 2010.02.24 07:00:00
2011.02.28 01:31:36 2011.02.25 22:59 h1 EURUSD,H1: 2010.02.23 01:00:00 ... 2010.02.23 11:00:00
Отправлено 28 February 2011 - 21:11
Если не ошибаюсь, то порядок сортировки ордеров в истории счета задает сам пользователь (вкладка история счета, если кликнуть например на "тип" - ордера будут отсортированы по типу).
Лучше, на мой взгляд, занести ордера в массив и сортировать как удобно (по времени открытия/закрытия), по крайней мере я так делаю обычно. Это надежнее, чем зависеть от каких-либо других факторов.
OrderSelect( 0, SELECT_BY_POS, MODE_HISTORY )А если нужен самый старый закрытый ордер, то:
OrderSelect( OrdersHistoryTotal() -1, SELECT_BY_POS, MODE_HISTORY )Вместо того, чтобы перелопачивать всю историю из N ордеров, и вы бирать из неё единственный меня интересующий.
Отправлено 28 February 2011 - 21:21
В продолжение вчерашенего сообщения...
#include <mmlib.mqh> #define Magic 77777777 int nBars = 0, nStart; int aOpen[] = { 10, 30, 50, 70, 90 }, aClose[] = { 200, 180, 160, 140, 120 }, aPrint[] = { 100, 220 }, aTick[]; //--------------------------------------------------------------------- void init() { ArrayResize( aTick, ArraySize( aOpen ) ); ArrayInitialize( aTick, 0 ); } //--------------------------------------------------------------------- int start() { if( nBars == 0 ) nStart = Bars; if( nBars == Bars ) return; else nBars = Bars; // начался новый бар ... int i, nDelay = Bars - nStart; for( i = 0; i < ArraySize( aOpen ); i++ ) { if( aOpen[ i ] == nDelay ) { aTick[ i ] = OrderSend( Symbol(), OP_SELL, 1, NormalizeDouble( Bid, Digits ), 3, 0, 0, "", Magic ); Print( "bar:", nDelay, " открытие #", aTick[ i ] ); } if( aClose[ i ] == nDelay ) { bool Ansv; if( aTick[ i ] > 0 ) { Ansv = OrderSelect( aTick[ i ], SELECT_BY_TICKET); Ansv = OrderClose( aTick[ i ], OrderLots(), NormalizeDouble( Ask, Digits ), 3 ); Print( "bar:", nDelay, " закрытие #", aTick[ i ] ); aTick[ i ] = 0; } } } for( i = 0; i < ArraySize( aPrint ); i++ ) { double ord[][ Parm_Number ]; if( aPrint[ i ] != nDelay ) continue; int n, j; n = ActiveOrdersList( ord, 0, Magic ); Print( "открытых ордеров в работе : ", n ); for( j = 0; j < n; j++ ) Print( "#", ord[ j ][ Parm_Ticket ], " : ", TimeToStr( ord[ j ][ Parm_OpenTime ], TIME_DATE | TIME_SECONDS ) ); n = HistoryOrdersList( ord, 0, Magic ); Print( "закрытых ордеров в истории : ", n ); for( j = 0; j < n; j++ ) Print( "#", ord[ j ][ Parm_Ticket ], " : ", TimeToStr( ord[ j ][ Parm_OpenTime ], TIME_DATE | TIME_SECONDS ), " ... ", TimeToStr( ord[ j ][ Parm_CloseTime ], TIME_DATE | TIME_SECONDS ) ); } } //---------------------------------------------------------------------Сами функции получения как закрытых, так и текущих активных ордеров - вот они:
#define Parm_Number 7 #define Parm_Ticket 0 #define Parm_Type 1 #define Parm_Lots 2 #define Parm_OpenPrice 3 #define Parm_ClosePrice 4 #define Parm_OpenTime 5 #define Parm_CloseTime 6 #define Parm_Profit 7 void SetParam( double& order[][], int n ) { order[ n ][ Parm_Ticket ] = OrderTicket(); order[ n ][ Parm_Type ] = OrderType(); order[ n ][ Parm_Lots ] = OrderLots(); order[ n ][ Parm_OpenPrice ] = OrderOpenPrice(); order[ n ][ Parm_ClosePrice ] = OrderClosePrice(); order[ n ][ Parm_OpenTime ] = OrderOpenTime(); order[ n ][ Parm_CloseTime ] = OrderCloseTime(); order[ n ][ Parm_Profit ] = OrderProfit(); } int HistoryOrdersList( double& order[][ Parm_Number ], int iNum, int iMagic ) { string sSymbol = Symbol(); int total = OrdersHistoryTotal(), cnt = 0; ArrayResize( order, total ); for( int i = 0; i < total; i++ ) { if( OrderSelect( i, SELECT_BY_POS, MODE_HISTORY ) == false ) continue; if( OrderSymbol() != sSymbol ) continue; if( iMagic != 0 && OrderMagicNumber() != iMagic ) continue; if( OrderCloseTime() == 0 ) continue; if( OrderType() != OP_BUY && OrderType() != OP_SELL ) continue; SetParam( order, cnt ); cnt++; if( iNum != 0 && cnt == iNum ) break; } ArrayResize( order, cnt ); return (cnt); } int ActiveOrdersList( double& order[][ Parm_Number ], int iNum, int iMagic ) { string sSymbol = Symbol(); int total = OrdersTotal(), cnt = 0; ArrayResize( order, total ); for( int i = 0; i < total; i++ ) { if( OrderSelect( i, SELECT_BY_POS, MODE_TRADES ) == false ) continue; if( OrderSymbol() != sSymbol ) continue; if( iMagic != 0 && OrderMagicNumber() != iMagic ) continue; if( OrderCloseTime() != 0 ) continue; if( OrderType() != OP_BUY && OrderType() != OP_SELL ) continue; SetParam( order, cnt ); cnt++; if( iNum != 0 && cnt == iNum ) break; } ArrayResize( order, cnt ); return (cnt); }
2011.02.28 17:05:28 2010.02.22 04:00 h1 EURUSD,H1: #1 : 2010.02.09 08:00:00 ... 2010.02.19 07:00:00
2011.02.28 17:05:28 2010.02.22 04:00 h1 EURUSD,H1: #2 : 2010.02.10 04:00:00 ... 2010.02.18 11:00:00
2011.02.28 17:05:28 2010.02.22 04:00 h1 EURUSD,H1: #3 : 2010.02.11 00:00:00 ... 2010.02.17 15:00:00
2011.02.28 17:05:28 2010.02.22 04:00 h1 EURUSD,H1: #4 : 2010.02.11 20:00:00 ... 2010.02.16 19:00:00
2011.02.28 17:05:28 2010.02.22 04:00 h1 EURUSD,H1: #5 : 2010.02.12 16:00:00 ... 2010.02.15 23:00:00
...
2011.02.28 17:05:28 2010.02.15 03:00 h1 EURUSD,H1: #5 : 2010.02.12 16:00:00
2011.02.28 17:05:28 2010.02.15 03:00 h1 EURUSD,H1: #4 : 2010.02.11 20:00:00
2011.02.28 17:05:28 2010.02.15 03:00 h1 EURUSD,H1: #3 : 2010.02.11 00:00:00
2011.02.28 17:05:28 2010.02.15 03:00 h1 EURUSD,H1: #2 : 2010.02.10 04:00:00
2011.02.28 17:05:28 2010.02.15 03:00 h1 EURUSD,H1: #1 : 2010.02.09 08:00:00
...
Отправлено 01 March 2011 - 11:42
1. Список открытых ордеров (MODE_TRADES) упорядочен (от индекса 0 и далее) в порядке убывания даты-времени открытия (0 - самый последний).
1. Список закрытых ордеров (MODE_HISTORY) упорядочен (от индекса 0 и далее) в порядке убывания даты-времени закрытия (0 - самый последний) - времена открытия их при этом могут "рассыпаться" в произвольном порядке.
Думаю, что теперь этот вопрос - исчерпывающе ясен.
OrderSelect( 0, SELECT_BY_POS, MODE_HISTORY )- будут возвращать самый старый ордер, и при повторных вызовах будет всегда константой, а:
OrderSelect( OrdersHistoryTotal() -1, SELECT_BY_POS, MODE_HISTORY )- будет возвращать самый последний ордер, и при повторных вызовах будет (может) обновляться (если между вызовами были операции с ордерами).
Отправлено 08 March 2011 - 01:39
Отправлено 14 March 2011 - 00:59
ВАШИ НЕДОКУМЕНТИРОВАННЫЕ ВОЗМОЖНОСТИ ПРИ НАПИСАНИИ СОВЕТНИКОВ НА MQL4
Отправлено 28 March 2011 - 09:55
Отправлено 31 March 2011 - 14:47
О-о-о-очень интересную возможность для программирования советников подсказали вот здесь:
Запуск/остановка советника
5. ... и советник выполняет то, что ему положено по данному "письму".
Отправлено 31 March 2011 - 14:59
А зачем так напрягаться? Письмо советнику можно отправить с помощью глобальных переманных. Я в BlueDream так и делаю.
Отправлено 31 March 2011 - 15:08
Ну а с другого компьютера за 15 км. - вы тоже отошлёте письмо "с помощью глобальных переменных"(с) ?
Тут как-раз интерес способа выплывает из-за клиент-серверности работы терминалов MT4, и того, что роботом можно управлять (вообще-то неограниченно сложно) через сигналы, доставляемые ему с сервера.
Отправлено 31 March 2011 - 17:22
И для хорошего может пригодиться.Для хорошего советника это не требуется - он же автомат.
Отправлено 01 April 2011 - 05:56
А зачем так напрягаться? Письмо советнику можно отправить с помощью глобальных переманных. Я в BlueDream так и делаю.
Отправлено 01 April 2011 - 08:02
мне интересно как именно в ручную можно в ордере магик проставить? комментарий пожалуйста, а магик то как? а если советник не использует комментарии т.е. игнорирует их, а обработка идет по магику и символу... тут придется сначала читать открытые ордера, а затем писать робота с тем же магиком... имхо заморочка лишняя...О-о-о-очень интересную возможность для программирования советников подсказали вот здесь:
Запуск/остановка советника
- возможность управлять работой советника по ходу его работы!
Хотя это не возможность MQL4 получается, а возможность клиент-серверной организации работы с ДЦ... Применить этот трюк можно в самых разнообразных целях! а выглядит он в 2-х словах так:
1. работает советник на какой-то паре ... долго работает...
2. входим в другое окно этой же валютной пары (а можно даже с другого MT4 и другого компьютера)...
3. и открываем (вручную!) отложенный ордер лимит или стор, с каким-то зарезервированным заранее MAGIC или с коментарием строго оговоренным... ордер открываем с "дикими" параметрами, который никогда не сработает...
4. советник в цикле start() очередном просматривает открытые ордера ... видит "меченный" (по MAGIC или COMMENT), и понимает, что это ему "письмо" ... ордер этот он при этом удаляет...
5. ... и советник выполняет то, что ему положено по данному "письму".