Ордера идентифицировать собираюсь по магику (каждый ордер свой уникальный магик).
Зачем каждому свой магик? Или я что-то не догоняю или обсуждать пока что нечего.
|
Уникальный номер у каждого ордера - это его OrderTicket() и манипуляции с уникальным Магиком вызывают непонятки... :(
Ваша сверхзадача неясна, а точнее не ясен её смысл.
Уникальный номер у каждого ордера - это его OrderTicket() и манипуляции с уникальным Магиком вызывают непонятки... :(
Ваша сверхзадача неясна, а точнее не ясен её смысл.
На NDD отложка может открываться частями и закрываться тоже частями может, при этом тикет меняется. (Alpari)
Соответственно ордер теряет свою уникальность. Мне нужно точно знать почему и когда ордер открылся (отложка) для того
чтобы в динамике пересчитывать каждому ордеру TP, SL или просто
закрывать потому что цена пошла не по моему ожидаемому сценарию.
В Massiv помимо параметров ордера еще сохраняется и информация Почему и Когда, взятая из блока принятия решений.
Ниже Цитата: Источник https://www.mql5.com/ru/articles/1390
Прежде, чем перейти к примеру обработки событий, необходимо
напомнить, что существуют специфические ситуации, при которых
интуитивно ожидаемый порядок событий не соблюдается.
Во-первых, есть некоторые дилеры (например, банки со своей спецификой учёта), которые в конце торгового дня принудительно закрывают все открытые ордера и тут же, в начале следующего дня, открывают такие же ордера, но по курсу, отличающемуся от текущего на несколько десятых пункта. Этими долями пункта в экономику ордера закладывается своп. Сам своп в терминале всегда отражается нулевым. C точки зрения экономики дилеры ничего не нарушают. Нам в этой ситуации важно то, что вновь открываемым ордерам присваиваются новые номера, никак не связанные с предыдущими.
Во-вторых, частичное закрытие отдельно взятого ордера (у всех дилеров) осуществляется как бы в два этапа. На первом этапе ордер закрывается полностью, а на втором - открывается новый ордер уменьшенной стоимости, но уже с новым номером. При этом номер исходного ордера прописывается в комментарий нового ордера.
В-третьих, аналогичная специфика возникает и при закрытии одного
ордера за счёт другого, если эти ордера имеют разную стоимость.
Фактически в этом случае повторяется ситуация частичного закрытия
одного из ордеров.
А вот еще информация к размышлению: тикеты размножаются... (Обратите внимание на обьемы позиций !!!)
2012.03.19 19:28:50 open #1323587278 buy limit 0.80 XAUUSD at 1651.05 tp: 1656.05 ok
После этого в отчете видно 2 открытых ордера с разным объемом в сумме равным 0.8
Ticket Open Time Type Size Item Price S / L T / P Close Time Price Commission Taxes Swap Profit
1323587278 2012.03.20 10:11 buy 0.01 xauusd 1651.05 0.00 1656.05 2012.03.20 17:01 1656.05 -0.10 0.00 0.00 5.00
1323621997 2012.03.20 10:11 buy 0.79 xauusd 1651.05 0.00 1656.05 2012.03.20 17:01 1656.05 -7.90 0.00 0.00 395.00
Я думаю, что для получения ответов, вам лучше разбить свой вопрос на меньшие и более конкретные части.
С вашей постановкой вопроса ответа вы вряд ли дождётесь.
// 1. Сортируем массив по типу ордера [][6] <= 10. У кого тип больше либо равен 10 в конец массива (закрытые ордера)
здесь проблема в массиве или в способе сортировки?
// 2. В первой части массива (открытые ордера) ищем самый маленький MagicNumber (Massiv[][7])
затруднения вызывает массив или сам поиск? и что значит " В первой части массива "?
// 3. Сортирум вторую часть массива (закрытые ордера у которых тип [][6]<=10) по магику и удал. с самыми старыми магиками.)
смотри п.п 1 и п.п 2
// 4. пишем данные нового ордера и A, B, Razmer... в массив.
на какое место, а оно у вас есть свободное?
Мне кажется, что ваша схема на данный момент неработоспособна. Выделите каждый пункт в отдельную функцию и с ним работайте.
Или может смысл вашего вопроса в технологии передачи массива в функцию?
Массив, это просто таблица для хранения данных, в вашем случае размер таблицы 101Х15.
Для сортировки:
1.счётчик=0; (указатель индекса элемента массива same номера строки таблицы)
2. Возмите данные из ячейки с номером= счётчик;
3. Сравните со всеми ячейками подряд до первого меньшего.
- Если не нашли меньшего поместите данные в ячейку под номером =счётчик (значение из этой ячейки сохранить на освободившееся место), счётчик++
- Если нашли меньшее, Возьмите меньшее перейдите к п 3.
Массив, это просто таблица для хранения данных, в вашем случае размер таблицы 101Х15.
Для сортировки:
1.счётчик=0; (указатель индекса элемента массива same номера строки таблицы)
2. Возмите данные из ячейки с номером= счётчик;
3. Сравните со всеми ячейками подряд до первого меньшего.
- Если не нашли меньшего поместите данные в ячейку под номером =счётчик (значение из этой ячейки сохранить на освободившееся место), счётчик++
- Если нашли меньшее, Возьмите меньшее перейдите к п 3.
Я на рынке уже не новичек. MQL тоже вроде как освоил, но с массивами я пока впадаю в ступор (документацию трудно понять). Поэтому и прошу помощи у профи.
Попробую обьяснить задачу иначе. Имеем массив в котором будет храниться информация об ордерах открытых и закрытых и их параметрах + переменные.
функция должна удалить старые закрытые ордера и занести новый ордер в массив.(Интересуют примеры кода, я практик с теорией у меня туго.)
Должно получиться так:
пор.номер/магик/тип ордера/
1 // 56 // 0
2 // 34 // 1 // у этого ордера самый маленький магик(34)из открытых ордеров
3 // 63 // 4
4 // 51 // 4
5 // 68 // 14
6 // 29 // 10 // Этот нужно удалить 29<34 магик
7 // 37 // 12
8 // 31 // 11 // Этот нужно удалить 31<34 магик
9 ....
с 1 по 4 ордера открыты. тип ордера <10 (тип ордера меняется в другом блоке сравнения ордеров.Если ордер закрывается или удаляется к типу ордера +10)
самый маленький магик(34) у 2 ордера
c 5 по 8 ордеры закрыты. тип ордера =>10
у ордеров 6 и 8 магик меньше 34 и они уже закрыты(тип =>10). их нужно удалить.
(Наверно сортируем)
ПИШЕМ новый ордер в массив.
Уходим...
Пожалуйсто напишите пример кода...
Вот пример кода из моего советника.
//+------- //+------------------------------------------------------------------+ //| valenok2003@mail.ru 19.02.2012 //+------------------------------------------------------------------+ //| lock_buy() локирование длинных позиций //+------------------------------------------------------------------+ bool lock_buy(){ string _Function = "lock_buy():"; //----------------- int _Cnt = 0; int _Ticket, _Record_Num; double _Lot_Base_Order; bool _RET = true; bool _SUCCES_SET_LOCK = true; //---- проверка внешних сигналов управляющих локами ------------------ if(GlobalVariableGet(GV_Ignore_Lock_BUY) == YES) return(true); //-------------------------------------------------------------------- // необходимо локировать ордера на каждом тике, так как локи могут закрываться, например, по outloss for(int _i = OrdersTotal()-1; _i >= 0; _i--) { // берём очередной ордер OrderSelect(_i, SELECT_BY_POS, MODE_TRADES); if(OrderSymbol() == Symbol() && OrderType() == OP_BUY && check_magic(OrderMagicNumber(), _Function)) { _Lot_Base_Order = OrderLots(); // запоминаем лот базового ордера bool _EXIST_RECORD_BASE_ORDER = false; //----------------- // ищем запись об ордере в массиве for(int _n = 0; _n < MAX_ORDERS; _n++){ // если запись о базовом существует if(Buy_Base_Tickets[_n] == OrderTicket()) { _EXIST_RECORD_BASE_ORDER = true; _Record_Num = _n; break; } } // если нет записи о базовом ордере создаём её на первом свободном месте if(!_EXIST_RECORD_BASE_ORDER) { for(_n = 0; _n < MAX_ORDERS; _n++){ if(Buy_Base_Tickets[_n] == 0) { Buy_Base_Tickets[_n] = OrderTicket(); Buy_Lock_Tickets[_n] = 0; _Record_Num = _n; break; } } } //----------------- // если существует соответствующая базовому запись о локирующем ордере if(Buy_Lock_Tickets[_Record_Num] != 0) { // и сам локирущий существует if(OrderSelect(Buy_Lock_Tickets[_Record_Num], SELECT_BY_TICKET)) { // и он ещё не закрыт if(OrderCloseTime() <= 0) { // и соответствует лоту базового // то переходим к следующему базовому ордеру if(_Lot_Base_Order == OrderLots())continue; } } } //----------------- // если доехали до сюда то лока не существует Buy_Lock_Tickets[_Record_Num] = 0; //----------------- bool _SUCCES = false; // ищем ордер оппозит среди локов с лотом равным лоту базового for(int _z = OrdersTotal()-1; _z >= 0; _z--) { OrderSelect(_z, SELECT_BY_POS, MODE_TRADES); // если нашли подходящий ордер if(OrderSymbol() == Symbol() && OrderType() == OP_SELL && _Lot_Base_Order == OrderLots() && OrderMagicNumber() == Lock_Magic) { bool _BUSY_ORDER_LOCK = false; bool _GO_NEXT_BASE = false; // проверка - не учтён ли он в другой паре for(_n = 0; _n < MAX_ORDERS; _n++){ if(Buy_Lock_Tickets[_n] == OrderTicket()) { if(_n == _Record_Num) { _GO_NEXT_BASE = true; _SUCCES = true; break; } if(Buy_Base_Tickets[_n] != 0) { _BUSY_ORDER_LOCK = true; break; } } } // если используется в разрабатываемой паре, переходим к следующему базовому if(_GO_NEXT_BASE) break; // если он занят (учтён в другой паре) переходим к следующему локу if(_BUSY_ORDER_LOCK) continue; // если свободен else { // ставим его в пару базовому ордеру Buy_Lock_Tickets[_Record_Num] = OrderTicket(); _SUCCES = true; } } } // если не нашли подходящий локовый ордер - открываем новый if(!_SUCCES) { _Ticket = open_order_sell(_Lot_Base_Order,"Lock for "+Buy_Base_Tickets[_Record_Num]+" Mgc="+Lock_Magic, Lock_Magic); if(_Ticket > 0) { Buy_Lock_Tickets[_Record_Num] = _Ticket; } else _SUCCES_SET_LOCK = false; } } } //if(_SUCCES_SET_LOCK) output_mov_string("локи для BUY установлены",Clr_Report); //----------------- return(_SUCCES_SET_LOCK); } //+------------------------------------------------------------------+ //+-------
Только я работаю не с одним массивом размерностью (MAX_ORDERS х N), а создаю N массивов размерностью (MAX_ORDERS х 1), тогда я имею возможность каждому массиву приписать мнемоническое имя, что в дальнейшем облегчет мне понимание кода. Рзбираться и запоминать в какой ячейке какие данные записаны будет сложнее, чем, например, иметь массивы Tickets[ MAX_ORDERS ], Magic[ MAX_ORDERS ], OpenPrice[ MAX_ORDERS ];
Но ещё раз хочу вам повторить - учет ордеров уже существует в терминале и намного выгоднее ИМХО использовать уже существующие функции терминала, потому что вы хотите дублировать работу, которая уже проделана за вас. Вы всегда можете извлечь любую информацию о любом ордере как из открытых так и из истории.
ЗЫ. Критики моего кода щас найдутся - не обращайте внимания.
ЗЫ.ЗЫ Обратите внимание, я в массиве храню только тикеты для возможности учета локирующих ордеров, все же прочие данные добываются из терминала.
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
В процесе написания советника потребовалось запоминать промежуточные данные на основании которых принимаются торговые решения.(А,B,C... время выставления ордера)
Ордера идентифицировать собираюсь по магику (каждый ордер свой уникальный магик).
В момент инициализации советник загружает резервную копию масива,
и в процесе работы сохраняет резервную копию. Советник с явным контролем открытия бара, поэтому диск запросами не перегрузит.
Куски кода для работы смассивами и файлами взяты отсюда https://forum.mql4.com/ru/28948#256425 (резервное копирование. Спасибо Integer'у!!!)
и отсюда https://www.mql5.com/ru/articles/1390
Задача описана в конце кода. Помогите !!! под номерами 1-4 ( void ZapOrdMas() ) .