← Назад

Изменение Order.Balance после того, как заявка получила OrderStates == Done

Михаил, добрый день. Обращаюсь по привычке к Вам, так как не в курсе, поддерживает ли S# еще кто либо. Если я ошибаюсь, поправьте меня.

Михаил, прошу помочь разобраться в следующем. Ситуация:

  1. Проверяю состояние заявки.
  2. Если состояние заявки Active, отменяю асинхронно заявку.
  3. Дожидаюсь события OrdersChanged, когда заявка станет Done.
  4. Проверяю Balance, он равен Volume.
  5. Проверяю в Квике состояние заявки, заявка оказывается полностью удовлетворена. То-есть Balance должен был быть равен нулю в пункте 4.

Если между пунктом 3 и 4 сделать пауза в 1 секунду, то Balance будет равен нулю.

Из этого я могу предположить, что Balance может изменится после того, как заявка приобрела статус Done. Хотя в мануале написано: «Done - заявка более не активна на бирже, и по ней не может прийти ни одно изменение.»

Так ли это? Сталкивались ли Вы с этим?

Комментарии (41)

Вход или Создать аккаунт, Войдите или зарегистрируйтесь, чтобы оставить комментарий

Mikhail Sukhov
Mikhail Sukhov

Maxim: Ситуация:

  1. Проверяю состояние заявки.
  2. Если состояние заявки Active, отменяю асинхронно заявку.
  3. Дожидаюсь события OrdersChanged, когда заявка станет Done.
  4. Проверяю Balance, он равен Volume.
  5. Проверяю в Квике состояние заявки, заявка оказывается полностью удовлетворена. То-есть Balance должен был быть равен нулю в пункте 4.

Если между пунктом 3 и 4 сделать пауза в 1 секунду, то Balance будет равен нулю.

Можете это выразить небольшим кодом для теста?

Maxim
Maxim Автор

Добавляем две синхронизации:


private ManualResetEventSlim waitDone = new ManualResetEventSlim(false);
private ManualResetEventSlim waitActiveOrFailed = new ManualResetEventSlim(false);

В обработчик события Global.Quik.NewOrders добавляем строку waitActiveOrFailed.Set() А в обработчик события Global.Quik.OrdersChanged добавляем строку waitDone.Set();

После соединения с квиком и подпиской на событие, запускаем код:


            Security paperSecurity = null;

            foreach (Security sec in Global.Quik.Securities)
                if (sec.Code == "SBER03")
                    paperSecurity = sec;        
           

            for (int i = 0; i < 10; i++)
            {
                Debug.WriteLine(" ");
                Debug.WriteLine("Start " + i.ToString());

                Order _newOrder = new Order();
                _newOrder.Portfolio = Global.Portfolio;
                _newOrder.Direction = OrderDirections.Buy;
                _newOrder.Security = paperSecurity;
                _newOrder.ExecutionCondition = OrderExecutionConditions.PutInQueue;
                _newOrder.Comment = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffffff");
                _newOrder.Volume = 100;
                _newOrder.Price = paperSecurity.BestAsk.Price + 5;

                
                waitActiveOrFailed.Reset();
                waitDone.Reset();

                Global.Quik.RegisterOrder(_newOrder);

                waitActiveOrFailed.Wait();

                if (_newOrder.State == OrderStates.Active)
                {
                    Global.Quik.CancelOrder(_newOrder);

                    waitDone.Wait();

                    Debug.WriteLine((_newOrder.Volume - _newOrder.Balance).ToString());

                    Thread.Sleep(1000);

                    Debug.WriteLine((_newOrder.Volume - _newOrder.Balance).ToString());
                }

                Debug.WriteLine("TransactionId:" + _newOrder.TransactionId);

                Debug.WriteLine("Finish " + i.ToString());

                Thread.Sleep(1000);
            } 


Получаем результат:


Start 0
0
100
TransactionId:57912511
Finish 0
 
Start 1
0
100
TransactionId:57912513
Finish 1
 
Start 2
0
100
TransactionId:57912515
Finish 2
 
Start 3
0
100
TransactionId:57912517
Finish 3
 
Start 4
0
100
TransactionId:57912519
Finish 4
 
Start 5
0
100
TransactionId:57912521
Finish 5
 
Start 6
0
100
TransactionId:57912523
Finish 6
 
Start 7
0
100
TransactionId:57912525
Finish 7
 
Start 8
0
100
TransactionId:57912527
Finish 8
 
Start 9
0
100
TransactionId:57912529
Finish 9

Mikhail Sukhov
Mikhail Sukhov

Maxim: Добавляем две синхронизации:

private ManualResetEventSlim waitDone = new ManualResetEventSlim(false); private ManualResetEventSlim waitActiveOrFailed = new ManualResetEventSlim(false);


Самое главное упустили - код в OrdersChanged. Прогнал простой тест (советую и Вам так сделать, всего одну строчку вывести):

qt.OrdersChanged += orders => { foreach (var order in orders) { Debug.WriteLine("Id {0} State {1} Balance {2}".Put(order.Id, order.State, order.Balance)); } };


QuikTrader.IsAsyncMode = true.

Везде, где вывод c Done баланс был равен 0 (заявки глубоко в рынок кидал).
Maxim
Maxim Автор

Первоначально в обработчике OrdersChanged просто был один метод: waitDone.Set()

Я это и имел ввиду, кода писал:

В обработчик события Global.Quik.NewOrders добавляем строку waitActiveOrFailed.Set() А в обработчик события Global.Quik.OrdersChanged добавляем строку waitDone.Set();

Теперь обработчик выгладит так:


waitDone.Set();
Debug.WriteLine("OrdersChanged begin");
foreach (var order in orders)
{
   Debug.WriteLine("Id {0} State {1} Balance {2}".Put(order.Id, order.State, order.Balance));
}
Debug.WriteLine("OrdersChanged end");

Обновленный результат вывода привожу ниже. Состояние «State Done» и «Balance 100» в выводе есть. Что говорит о том, что что-то не так.

Забыл упомянуть, этот сценарий наблюдается на тестовом Квике. Если это имеет значение. На реальном пока не тестировал.


Start 0
OrdersChanged begin
0
Id 1076401848 State Done Balance 100
OrdersChanged end
OrdersChanged begin
Id 1076401848 State Done Balance 0
OrdersChanged end
OrdersChanged begin
Id 1076401848 State Done Balance 0
OrdersChanged end
OrdersChanged begin
Id 1076401848 State Done Balance 0
OrdersChanged end
100
OrderId:1076401848
Finish 0
 
Start 1
OrdersChanged begin
Id 1076401877 State Done Balance 100
OrdersChanged end
0
0
OrderId:1076401877
Finish 1
OrdersChanged begin
Id 1076401877 State Done Balance 0
OrdersChanged end
OrdersChanged begin
Id 1076401877 State Done Balance 0
OrdersChanged end
 
Start 2
OrdersChanged begin
Id 1076401900 State Done Balance 100
OrdersChanged end
0
OrdersChanged begin
Id 1076401900 State Done Balance 0
OrdersChanged end
OrdersChanged begin
Id 1076401900 State Done Balance 0
OrdersChanged end
OrdersChanged begin
Id 1076401900 State Done Balance 0
OrdersChanged end
100
OrderId:1076401900
Finish 2
 
Start 3
OrdersChanged begin
0
Id 1076401920 State Done Balance 100
OrdersChanged end
OrdersChanged begin
Id 1076401920 State Done Balance 78
OrdersChanged end
OrdersChanged begin
Id 1076401920 State Done Balance 28
OrdersChanged end
OrdersChanged begin
Id 1076401920 State Done Balance 0
OrdersChanged end
OrdersChanged begin
Id 1076401920 State Done Balance 0
OrdersChanged end
OrdersChanged begin
Id 1076401920 State Done Balance 0
OrdersChanged end
100
OrderId:1076401920
Finish 3
 
Start 4
OrdersChanged begin
Id 1076401942 State Done Balance 100
OrdersChanged end
0
OrdersChanged begin
Id 1076401942 State Done Balance 88
OrdersChanged end
OrdersChanged begin
Id 1076401942 State Done Balance 34
OrdersChanged end
OrdersChanged begin
Id 1076401942 State Done Balance 1
OrdersChanged end
OrdersChanged begin
Id 1076401942 State Done Balance 0
OrdersChanged end
OrdersChanged begin
Id 1076401942 State Done Balance 0
OrdersChanged end
OrdersChanged begin
Id 1076401942 State Done Balance 0
OrdersChanged end
100
OrderId:1076401942
Finish 4
 
Start 5
OrdersChanged begin
Id 1076401958 State Done Balance 100
OrdersChanged end
0
OrdersChanged begin
Id 1076401958 State Done Balance 0
OrdersChanged end
OrdersChanged begin
Id 1076401958 State Done Balance 0
OrdersChanged end
OrdersChanged begin
Id 1076401958 State Done Balance 0
OrdersChanged end
100
OrderId:1076401958
Finish 5
 
Start 6
OrdersChanged begin
Id 1076402004 State Done Balance 100
OrdersChanged end
0
OrdersChanged begin
Id 1076402004 State Done Balance 0
OrdersChanged end
OrdersChanged begin
Id 1076402004 State Done Balance 0
OrdersChanged end
OrdersChanged begin
Id 1076402004 State Done Balance 0
OrdersChanged end
100
OrderId:1076402004
Finish 6
 
Start 7
OrdersChanged begin
Id 1076402026 State Done Balance 100
OrdersChanged end
0
OrdersChanged begin
Id 1076402026 State Done Balance 0
OrdersChanged end
OrdersChanged begin
Id 1076402026 State Done Balance 0
OrdersChanged end
OrdersChanged begin
Id 1076402026 State Done Balance 0
OrdersChanged end
100
OrderId:1076402026
Finish 7
 
Start 8
OrdersChanged begin
Id 1076402094 State Done Balance 100
0
OrdersChanged end
OrdersChanged begin
Id 1076402094 State Done Balance 0
OrdersChanged end
OrdersChanged begin
Id 1076402094 State Done Balance 0
OrdersChanged end
100
OrderId:1076402094
Finish 8
 
Start 9
OrdersChanged begin
Id 1076402236 State Done Balance 100
OrdersChanged end
0
OrdersChanged begin
Id 1076402236 State Done Balance 0
OrdersChanged end
OrdersChanged begin
Id 1076402236 State Done Balance 0
OrdersChanged end
OrdersChanged begin
Id 1076402236 State Done Balance 0
OrdersChanged end
100
OrderId:1076402236
Finish 9

Mikhail Sukhov
Mikhail Sukhov

Maxim: Первоначально в обработчике OrdersChanged просто был один метод: waitDone.Set()

А если убрать все блокировки и просто выводить в лог? Код слишком сложным получился с теми, так с ходу не разобраться, где ошибка.

Maxim
Maxim Автор

А как без использования блокировщика отменять заявку?

Если не дождаться когда заявка станет Active — отменять ее нельзя. Как без блокировщика понять, что заявка перешла в статус Active и ее можно отменить?

Немного подумал и попробовал сделать все без блокировщиков. В результатах все так же есть вариант с «State Done Balance 100».

Вариант тестового кода


Global.Quik.NewOrders += orders => 
{ 
	foreach (var order in orders) 
		Global.Quik.CancelOrder(order);                     
};

Global.Quik.OrdersChanged += orders =>
{
	foreach (var order in orders)
		Debug.WriteLine("Id {0} State {1} Balance {2}".Put(order.TransactionId, order.State, order.Balance));                        
};

Security paperSecurity = null;

foreach (Security sec in Global.Quik.Securities)
	if (sec.Code == "SBER03")
		paperSecurity = sec;            


for (int i = 0; i < 10; i++)
{
	Debug.WriteLine(" ");
	Debug.WriteLine("Start " + i.ToString());

	Order _newOrder = new Order();
	_newOrder.Portfolio = Global.Portfolio;
	_newOrder.Direction = OrderDirections.Buy;
	_newOrder.Security = paperSecurity;
	_newOrder.ExecutionCondition = OrderExecutionConditions.PutInQueue;
	_newOrder.Comment = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffffff");
	_newOrder.Volume = 100;
	_newOrder.Price = paperSecurity.BestAsk.Price + 5;	
	
	Global.Quik.RegisterOrder(_newOrder);
	
	Debug.WriteLine("OrderId:" + _newOrder.TransactionId.ToString());

	Debug.WriteLine("Finish " + i.ToString());

	Thread.Sleep(1000);
}  

Результат:


Start 0
OrderId:62050658
Finish 0
Id 62050658 State Done Balance 100
Id 62050658 State Done Balance 50
Id 62050658 State Done Balance 0
Id 62050658 State Done Balance 0
Id 62050658 State Done Balance 0
 
Start 1
OrderId:62050660
Finish 1
Id 62050660 State Done Balance 100
Id 62050660 State Done Balance 0
Id 62050660 State Done Balance 0
Id 62050660 State Done Balance 0
 
Start 2
OrderId:62050662
Finish 2
Id 62050662 State Done Balance 100
Id 62050662 State Done Balance 0
Id 62050662 State Done Balance 0
Id 62050662 State Done Balance 0
 
Start 3
OrderId:62050664
Finish 3
Id 62050664 State Done Balance 100
Id 62050664 State Done Balance 0
Id 62050664 State Done Balance 0
Id 62050664 State Done Balance 0
 
Start 4
OrderId:62050666
Finish 4
Id 62050666 State Done Balance 100
 
Start 5
OrderId:62050668
Finish 5
Id 62050668 State Done Balance 100
Id 62050666 State Done Balance 0
Id 62050668 State Done Balance 0
Id 62050666 State Done Balance 0
Id 62050668 State Done Balance 0
Id 62050666 State Done Balance 0
Id 62050668 State Done Balance 0
 
Start 6
OrderId:62050670
Finish 6
Id 62050670 State Done Balance 100
Id 62050670 State Done Balance 0
Id 62050670 State Done Balance 0
Id 62050670 State Done Balance 0
 
Start 7
OrderId:62050672
Finish 7
Id 62050672 State Done Balance 100
Id 62050672 State Done Balance 0
Id 62050672 State Done Balance 0
 
Start 8
OrderId:62050674
Finish 8
Id 62050674 State Done Balance 100
Id 62050674 State Done Balance 0
Id 62050674 State Done Balance 0
Id 62050674 State Done Balance 0
 
Start 9
OrderId:62050676
Finish 9
Id 62050676 State Done Balance 100
Id 62050676 State Done Balance 0
Id 62050676 State Done Balance 0
Id 62050676 State Done Balance 0


Mikhail Sukhov
Mikhail Sukhov

Maxim: Немного подумал и попробовал сделать все без блокировщиков. В результатах все так же есть вариант с «State Done Balance 100».

Тоже поймал такую ситуацию. С воспроизведением проблема. В начале стабильно приходил Done с балансом 100. Теперь стабильно Done с балансом 0. Видимо еще ситуация со стаканом значение имеет.

Mikhail Sukhov
Mikhail Sukhov

Mikhail Sukhov:

Maxim: Немного подумал и попробовал сделать все без блокировщиков. В результатах все так же есть вариант с «State Done Balance 100».

Тоже поймал такую ситуацию. С воспроизведением проблема. В начале стабильно приходил Done с балансом 100. Теперь стабильно Done с балансом 0. Видимо еще ситуация со стаканом значение имеет.

Ошибку добавил в список багов так как она подтвердилась. Пока не буду ее искать, так как сейчас занимаюсь релизом 3.0. Выпущу на след. неделе. После этого начну анализировать код. + к вам просьба небольшая. Так сказать отвергнуть предположения о неправильных данных в ДДЕ. Можете подписаться на событие PreProcessDdeData, и посмотреть, идет ли там совместно ненулевой баланс вместе с состоянием matched. Если в этом виноват сам Квик, то это будет уже сложнее поправить.

Maxim
Maxim Автор

Состояние matched не обнаружил. Везде где наблюдался случай «State Done Balance 100» была ситуация, которая описана ниже.

Сначала было событие OrdersChanged с «Balance 100». После этого событие PreProcessDdeData с «FILLED». После этого событие OrdersChanged с«Balance 0».


Id 58247606 State Done Balance 100

String: заявки
Row: 0
		   Column: 0 Object: 1077843467
		   Column: 1 Object: SBER03
		   Column: 2 Object: QJSIM
		   Column: 3 Object: 112.41
		   Column: 4 Object: 100
		   Column: 5 Object: 0
		   Column: 6 Object: B
		   Column: 7 Object: FILLED
		   Column: 8 Object: 16:19:27
		   Column: 9 Object: 
		   Column: 10 Object: NL0011100043
		   Column: 11 Object: LSQ
		   Column: 12 Object: qtest061/S#
		   Column: 13 Object: 58247606
		   Column: 14 Object: 28.01.2011
		   Column: 15 Object: 3747

Id 58247606 State Done Balance 0

Этого достаточно или надо еще что либо проверить?

Maxim
Maxim Автор

Михаил, добрый день.

Рассматривали ли Вы более подробно данную проблему? Есть ли какой либо прогресс?

Понимаю, что Вы придерживаетесь своего плана. Но все же считаю ошибку достаточно весомой, что бы задать эти вопросы.

Без решения этой ошибки я не могу продолжить работать и использовать робота.

Как временно обойти данную ситуацию придумать не могу. Как понять, что заявка уже отработана и по ней не будет никаких изменений?

Надеюсь на понимание. Спасибо.

Mikhail Sukhov
Mikhail Sukhov

Maxim: Михаил, добрый день.

Рассматривали ли Вы более подробно данную проблему? Есть ли какой либо прогресс?

Да, я нашел закономерность. Выложу 3.0.1 в конце недели.

Maxim
Maxim Автор

Михаил, вечер добрый.

К сожалению сообщаю, что данная ошибка не устранена окончательно. В процессе торгов появляются случаи, когда заявка имеет статус Done, но значение разницы Volume - Balance больше нуля, но меньше, чем реальный объем сделок прошедших в Квике по этой заявке.

С данной ситуацией я уже столкнулся в третий раз.

К сожалению не удается произвести данную ошибку на тестовом Квике. Возможно связано с тем, что поведение тестового Квика и реального отличаются.

Прошу Вас обратить внимание на данную ошибку и еще раз проанализировать Ваш код. Немного удручает, что программа продает или покупает не то количество бумаг, которое необходимо. Со своей стороны постараюсь добиться повторяемости ошибки в тестовом Квике.

alexhat
alexhat

Добрый день, Михаил. Я обнаружил при работе (в боевом режиме с боевым квиком) аналогичную проблему. Зарегистрировался и нашел этот топик.

Ситуация такая (используется версия библиотеки 2.6.2 и асинхронный режим):

  1. Зарегистрирован ордер на продажу (SBER-RTSST)
  2. приходит сообщение об изменении ордера с новым статусом OrderStates.Done, при этом Balance = Volume
  3. Спустя некоторый промежуток времени приходит сообщение о новой сделке по этому ордеру
  4. Еще через некоторое время - сообщение об изменении ордера, где уже Balance = 0

В реальности алгоритмом выставляются подряд 2 ордера (по 2 разным инстументам) и при этом по второму ордеру этой "ошибки" нет - уже на втором шаге Balance = 0, но при этом после выставления заявки не приходит начальное сообщение NewOrders (сразу OrdersChanged - хотя здесь я не до конца уверен, м.б. это какая-то ошибка в моем коде).

Проблема очень критична, поскольку между пунктами 2 и 3 алгоритм успевает учесть этот ордер, т.к. уже не ждет по нему сделок. Нужен какой-то work-around.

С уважением, Алексей.

Maxim
Maxim Автор

alexhat: используется версия библиотеки 2.6.2

В 3.0.1 частично эта проблема была решена. Рекомендую обновить библиотеку, хоть проблема и не решена окончательно.

alexhat
alexhat

Боюсь обновлятся, т.к. объем работы для перетестирования всего очень большой. Если других шансов нет, то конечно придется.

Но, как вы пишите, проблема в не была окончательно решена, поэтому я решил узнать, есть ли возможности обхода. К.м.к, если есть возможность как-то получить точную информацию о том есть ли по ордеру в статусе Done еще не пришедшие сделки (или, например, окончательное общее число сделок на бирже) - то я смогу скорректировать приходящий статус ордера в своем алгоритме, анализируя количество еще непришедших сделок.

Mikhail Sukhov
Mikhail Sukhov

Давайте проинспектируем проблему:

  1. QuikTrader.IsAyncMode?
  2. Такие заявки снимаются, перерегистрируются или только регистрируются?
  3. Логи NewOrders OrdersChanged PreProcessDdeData.
alexhat
alexhat

Добрый день, Михаил.

  1. QuikTrader.IsAyncMode = true
  2. Только регистрируются
  3. Я обновился с 2.6.2 до 3.0.19 и сейчас ошибка не возникает (тут правда есть момент, что ошибка происходила пока я был в отпуске на весьма слабой машине у меня дома (т.е. в виндовой виртуальной машине, под VirtualBox), сейчас я на работе и здесь на родном виндовом сервере с производительностью проблем нет). Если я снова увижу эту проблему на своем сервере, какой код вставить в обработчики сообщений NewOrders OrdersChanged PreProcessDdeData для логирования?
Mikhail Sukhov
Mikhail Sukhov

alexhat: Если я снова увижу эту проблему на своем сервере, какой код вставить в обработчики сообщений NewOrders OrdersChanged PreProcessDdeData для логирования?

Чтобы можно было потом логи понять.

alexhat
alexhat

Mikhail Sukhov:

alexhat: Если я снова увижу эту проблему на своем сервере, какой код вставить в обработчики сообщений NewOrders OrdersChanged PreProcessDdeData для логирования?

Чтобы можно было потом логи понять.

Я новичек в этой теме (stock#), прошу простить. поскольку я не знаю что именно в этих логах нужно выводить, можно дать конкретный пример кода?

Mikhail Sukhov
Mikhail Sukhov

alexhat: Я новичек в этой теме (stock#), прошу простить. поскольку я не знаю что именно в этих логах нужно выводить, можно дать конкретный пример кода?

Номер заявки, транзакции, объем, баланс, состояние... Может еще что-то попутно понадобиться, так сложно сказать. Вы начните, там и видно будет.

Maxim
Maxim Автор
  1. QuikTrader.IsAyncMode = true
  2. Заявки регистрируются, а потом снимаются.
  3. Настроил логирование, но как теперь выяснилось, оно работало не совсем коректно. В частности, нет информации по PreProcessDdeData и в OrdersChanged нет времени. Оставлю пока информацию, которую собрал. Переделаю логирование и соберу более полную информацию.

Безрезультатно пытаюсь повторить эту ошибку в тестовом Квике. Михаил, а может эта ошибка быть вызвана некоректным поведением брокерского сервера?

Первая заявка:

NewOrders

InitDate 2011-04-25 18:36:44.4077500 Date 0001-01-01 00:00:00.0000000 CancelDate NULL Price 101.72 Volume 2927 Balance 2927 Id 1973988474 TransactionId 66671920 Direction S StockName SBER03 State Active Status Accepted ExecutionCondition PutInQueue Type Limit

OrdersChanged

TransactionId: 66671920 Balance: 1992 Volume: 2927 State: Active TransactionId: 66671920 Balance: 1992 Volume: 2927 State: Active TransactionId: 66671920 Balance: 782 Volume: 2927 State: Active TransactionId: 66671920 Balance: 782 Volume: 2927 State: Active TransactionId: 66671920 Balance: 782 Volume: 2927 State: Done TransactionId: 66671920 Balance: 742 Volume: 2927 State: Done TransactionId: 66671920 Balance: 732 Volume: 2927 State: Done

Вторая заявка:

NewOrders

InitDate 2011-04-25 18:37:22.2358750 Date 0001-01-01 00:00:00.0000000 CancelDate NULL Price 101.66 Volume 7884 Balance 7884 Id 1973994793 TransactionId 66671954 Direction S StockName SBER03 State Active Status Accepted ExecutionCondition PutInQueue Type Limit

OrdersChanged

Line 232: OrdersChanged TransactionId: 66671954 Balance: 7874 Volume: 7884 State: Active Line 233: OrdersChanged TransactionId: 66671954 Balance: 7874 Volume: 7884 State: Active Line 235: OrdersChanged TransactionId: 66671954 Balance: 7874 Volume: 7884 State: Active Line 237: OrdersChanged TransactionId: 66671954 Balance: 7374 Volume: 7884 State: Active Line 238: OrdersChanged TransactionId: 66671954 Balance: 7294 Volume: 7884 State: Active Line 239: OrdersChanged TransactionId: 66671954 Balance: 7294 Volume: 7884 State: Active Line 240: OrdersChanged TransactionId: 66671954 Balance: 7264 Volume: 7884 State: Active Line 241: OrdersChanged TransactionId: 66671954 Balance: 7164 Volume: 7884 State: Active Line 242: OrdersChanged TransactionId: 66671954 Balance: 7164 Volume: 7884 State: Active Line 243: OrdersChanged TransactionId: 66671954 Balance: 7064 Volume: 7884 State: Active Line 244: OrdersChanged TransactionId: 66671954 Balance: 6994 Volume: 7884 State: Active Line 245: OrdersChanged TransactionId: 66671954 Balance: 6994 Volume: 7884 State: Active Line 246: OrdersChanged TransactionId: 66671954 Balance: 6994 Volume: 7884 State: Active Line 247: OrdersChanged TransactionId: 66671954 Balance: 6864 Volume: 7884 State: Active Line 248: OrdersChanged TransactionId: 66671954 Balance: 6764 Volume: 7884 State: Active Line 249: OrdersChanged TransactionId: 66671954 Balance: 6714 Volume: 7884 State: Active Line 250: OrdersChanged TransactionId: 66671954 Balance: 6714 Volume: 7884 State: Active Line 251: OrdersChanged TransactionId: 66671954 Balance: 6584 Volume: 7884 State: Active Line 252: OrdersChanged TransactionId: 66671954 Balance: 6484 Volume: 7884 State: Active Line 253: OrdersChanged TransactionId: 66671954 Balance: 6474 Volume: 7884 State: Active Line 254: OrdersChanged TransactionId: 66671954 Balance: 6474 Volume: 7884 State: Active Line 255: OrdersChanged TransactionId: 66671954 Balance: 6304 Volume: 7884 State: Active Line 256: OrdersChanged TransactionId: 66671954 Balance: 6304 Volume: 7884 State: Active Line 257: OrdersChanged TransactionId: 66671954 Balance: 6256 Volume: 7884 State: Active Line 258: OrdersChanged TransactionId: 66671954 Balance: 6256 Volume: 7884 State: Active Line 259: OrdersChanged TransactionId: 66671954 Balance: 6239 Volume: 7884 State: Active Line 260: OrdersChanged TransactionId: 66671954 Balance: 6239 Volume: 7884 State: Active Line 261: OrdersChanged TransactionId: 66671954 Balance: 6139 Volume: 7884 State: Active Line 262: OrdersChanged TransactionId: 66671954 Balance: 6089 Volume: 7884 State: Active Line 263: OrdersChanged TransactionId: 66671954 Balance: 6039 Volume: 7884 State: Active Line 264: OrdersChanged TransactionId: 66671954 Balance: 6039 Volume: 7884 State: Active Line 265: OrdersChanged TransactionId: 66671954 Balance: 5735 Volume: 7884 State: Active Line 266: OrdersChanged TransactionId: 66671954 Balance: 5735 Volume: 7884 State: Active Line 267: OrdersChanged TransactionId: 66671954 Balance: 5175 Volume: 7884 State: Active Line 268: OrdersChanged TransactionId: 66671954 Balance: 5175 Volume: 7884 State: Active Line 269: OrdersChanged TransactionId: 66671954 Balance: 5045 Volume: 7884 State: Active Line 270: OrdersChanged TransactionId: 66671954 Balance: 4435 Volume: 7884 State: Active Line 271: OrdersChanged TransactionId: 66671954 Balance: 4312 Volume: 7884 State: Active Line 272: OrdersChanged TransactionId: 66671954 Balance: 4312 Volume: 7884 State: Active Line 273: OrdersChanged TransactionId: 66671954 Balance: 4312 Volume: 7884 State: Done Line 275: OrdersChanged TransactionId: 66671954 Balance: 4159 Volume: 7884 State: Done Line 276: OrdersChanged TransactionId: 66671954 Balance: 4041 Volume: 7884 State: Done

Maxim
Maxim Автор

1)Михаил, а в каком свойстве класса Order находится информация из столбца «Состояние» Квика?

2)Заметил следующее. При отмене заявки в Квике заполняется столбик «Снята(время)». Но на момент, когда состояние заявки становится Order.State == Done, свойство Order.CancelTime остается неопределенным. Это происходит не всегда. Из 16 отмененных заявок в 4 заявках свойство Order.CancelTime все же определилось. Из этого могу предположить, что все таки после того, как Order.State стал Done, заявки изменяются.

  1. Так же заметил, что в некоторых заявках после того, как Order.State стал Done, свойство Order.Time равно «0001-01-01 00:00:00.0000000». Что аналогично второму пункту свидетельствует о том, что заявка изменяется после того, как получила Order.State == Done.
Mikhail Sukhov
Mikhail Sukhov

Maxim: 1)Михаил, а в каком свойстве класса Order находится информация из столбца «Состояние» Квика?

Order.State

Maxim: 2)Заметил следующее. При отмене заявки в Квике заполняется столбик «Снята(время)». Но на момент, когда состояние заявки становится Order.State == Done, свойство Order.CancelTime остается неопределенным. Это происходит не всегда. Из 16 отмененных заявок в 4 заявках свойство Order.CancelTime все же определилось. Из этого могу предположить, что все таки после того, как Order.State стал Done, заявки изменяются.

  1. Так же заметил, что в некоторых заявках после того, как Order.State стал Done, свойство Order.Time равно «0001-01-01 00:00:00.0000000». Что аналогично второму пункту свидетельствует о том, что заявка изменяется после того, как получила Order.State == Done.

Нужны логи из ДДЕ.

Maxim
Maxim Автор

Mikhail Sukhov: Order.State

Но зная Order.State нельзя определить, была ли отменена заявка, правильно? Получается, что единственный признак того, что заявка была отменена, это наличие Order.CancelTime? Или я ошибаюсь?

Maxim
Maxim Автор

Mikhail Sukhov: Нужны логи из ДДЕ.

  1. Неверное время Order.Time «0001-01-01 00:00:00.0000000»

В файле можно найти данные из OrdersChanged и PreProcessDdeData: эксель

Данные из NewOrders


InitDate	2011-04-26 12:20:32.0277086
Date	0001-01-01 00:00:00.0000000
CancelDate	NULL
Price	102.22
Volume	39
Balance	39
Id	259271
TransactionId	44300176
Direction	B
StockName	SBER03
State	Active
Status	Accepted
ExecutionCondition	CancelBalance
Type	Limit

InitDate	2011-04-26 12:20:32.9495954
Date	0001-01-01 00:00:00.0000000
CancelDate	NULL
Price	102.22
Volume	39
Balance	39
Id	259356
TransactionId	44300177
Direction	B
StockName	SBER03
State	Active
Status	Accepted
ExecutionCondition	CancelBalance
Type	Limit

В этих данных можно посмотреть на заявки 44300176 и 44300177. После того, как Order.State поменялся на Done, в заявке 44300176 свойство Order.Time было «2011-04-26 12:20:31.0000000». Тогда как, в заявке 44300177 свойство Order.Time было «0001-01-01 00:00:00.0000000».

Просмотрев DDE данные, заметил, что в первом случае данные PreProcessDdeData приходят перед тем, как появится событие OrdersChanged. Во втором случае перед первым OrdersChanged данные из PreProcessDdeData не приходят.

  1. Время Order.CancelTime отсутствует, а должно быть.

В файле можно найти данные из OrdersChanged и PreProcessDdeData: эксель

Данные из NewOrders:


InitDate	2011-04-26 12:21:34.1535038
Date	0001-01-01 00:00:00.0000000
CancelDate	NULL
Price	102.13
Volume	39
Balance	39
Id	260883
TransactionId	44300189
Direction	S
StockName	SBER03
State	Active
Status	Accepted
ExecutionCondition	CancelBalance
Type	Limit


InitDate	2011-04-26 12:21:38.5910606
Date	0001-01-01 00:00:00.0000000
CancelDate	NULL
Price	102.18
Volume	1
Balance	1
Id	260975
TransactionId	44300190
Direction	S
StockName	SBER03
State	Active
Status	Accepted
ExecutionCondition	PutInQueue
Type	Limit

В этих данных можно посмотреть на заявки 44300189 и 44300190. После того, как Order.State поменялся на Done, в заявке 44300189 свойство Order.CancelTime было «2011-04-26 12:21:34.0000000». Тогда как, в заявке 44300190 свойство Order.CancelTime было пустым.

В данных DDE можно увидеть, что событие первое событие OrdersChanged , когда Order.State поменялся на Done, происходит самопроизвольно, без поступления данных из DDE. Это мое предположение, могу и ошибаться.

Mikhail Sukhov
Mikhail Sukhov

У меня файлы не скачиваются.

Maxim
Maxim Автор

Mikhail Sukhov: У меня файлы не скачиваются.

Можно скачать по номерам: 5286502 и 5286555 http://www.webfile.ru/

Mikhail Sukhov
Mikhail Sukhov

Ок, по данным все ок. По выводу в сообщении тоже все нормально. Я пропустил проблему? Если да, куда смотреть?

Serg
Serg

Maxim, вы могли бы выложить свой проект для детального разбора?

Maxim
Maxim Автор

Serg: Maxim, вы могли бы выложить свой проект для детального разбора?

Немного исправил код, который упоминал выше. При помощи этого кода на тестовом Квике получилось добиться двух ошибок описанных выше:


  Object quikPreProcessDdeDataLock = new Object();

            _quik.PreProcessDdeData += (String str, IList<IList<Object>> array) =>
            {
                lock (quikPreProcessDdeDataLock)
                {
                    if (str.Contains("все сделки") == false && str.Contains("[стакан]") == false && str.Contains("портфель по бумагам") == false && str.Contains("позиции по бумагам") == false)
                    {
                        Debug.WriteLine("PreProcessDdeData  DateNow:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffffff") + " String: " + str);

                        for (int i = 0; i < array.Count; i++)
                        {
                            Debug.WriteLine("PreProcessDdeData  DateNow:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffffff") + " Row: " + i.ToString());
                            for (int k = 0; k < array[i].Count; k++)
                            {
                                Debug.WriteLine("PreProcessDdeData  DateNow:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffffff") + "           " + "Column: " + k.ToString() + " Object: " + array[i][k].ToString());
                            }
                        }
                    }
                }
            };



            _quik.NewOrders += orders =>
            {
                foreach (var _order in orders)
                {
                    String _query =
                              @"NewOrders 
                                DateNow: {0},      
                                InitDate: {1}, 
                                Date: {2}, 
                                CancelDate: {3}, 
                                Price: {4}, 
                                Volume: {5}, 
                                Balance: {6}, 
                                Id: {7}, 
                                TransactionId: {8}, 
                                Direction: {9}, 
                                StockName: {10},
                                State: {11},
                                Status: {12},
                                ExecutionCondition: {13},
                                Type: {14}";

                    _query = String.Format(
                        _query,
                        DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffffff"),
                        _order.InitializationTime.ToString("yyyy-MM-dd HH:mm:ss.fffffff"),
                        (_order.Time != null ? "'" + _order.Time.ToString("yyyy-MM-dd HH:mm:ss.fffffff") + "'" : "NULL"),
                        (_order.CancelTime.HasValue ? "'" + _order.CancelTime.Value.ToString("yyyy-MM-dd HH:mm:ss.fffffff") + "'" : "NULL"),
                        _order.Price.ToString(),
                        _order.Volume.ToString(),
                        _order.Balance.ToString(),
                        _order.Id.ToString(),
                        _order.TransactionId.ToString(),
                        (_order.Direction == OrderDirections.Buy ? "B" : "S"),
                        _order.Security.Code,
                        _order.State.ToString(),
                        _order.Status.ToString(),
                        _order.ExecutionCondition.ToString(),
                        _order.Type.ToString());

                    Debug.WriteLine(_query);                    

                    _quik.CancelOrder(_order);
                }
            };

            _quik.OrdersChanged += orders =>
            {
                foreach (var order in orders)
                    Debug.WriteLine(
                        "OrdersChanged DateNow:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffffff") + 
                        " TransactionId: " + order.TransactionId + 
                        " Balance: " + order.Balance + 
                        " Volume: " + order.Volume + 
                        " State: " + order.State +
                        " CancelTime: " + order.CancelTime.ToString() + 
                        " Status: " + order.Status +
                        " Time: " + order.Time.ToString("yyyy-MM-dd HH:mm:ss.fffffff"));
            };

            Security paperSecurity = null;

            foreach (Security sec in _quik.Securities)
                if (sec.Code == "SBER03")
                    paperSecurity = sec;            
           
            Debug.WriteLine("Start ");

            Order _newOrder = new Order();
            _newOrder.Portfolio = Global.Portfolio;
            _newOrder.Direction = OrderDirections.Buy;
            _newOrder.Security = paperSecurity;
            _newOrder.ExecutionCondition = OrderExecutionConditions.PutInQueue;
            _newOrder.Comment = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffffff");
            _newOrder.Volume = 150;
            _newOrder.Price = paperSecurity.BestBid.Price;

            _quik.RegisterOrder(_newOrder);

            Debug.WriteLine("OrderId:" + _newOrder.TransactionId.ToString());                         

            Debug.WriteLine("Finish ");


Maxim
Maxim Автор

Не совсем понял, что подразумевается под «свой проект»? Что конкретно не хватает для повторения ошибки? Вопрос касается снятия и выставления заявок. Ничего необычного в моей программе не используется. Выше в этом посту я уже приводил пример куска кода. Правда в этот раз я его не использовал для получения ошибок, но уверен, что этот код даст такие же результаты.

Кстати, насчет первого вопроса есть отдельный пост. http://stocksharp.com/forum/878/Order-Time-vozvrashchaiet-00-00-00-0001-ghoda/

Maxim
Maxim Автор

Я выше писал. Но наверно нить диалога потерялась и запуталась. Напишу суть еще разок.

Глобальная проблема Глобальная проблема заключается в том, что при покупке моя программа покупает или продает больше лотов, чем это необходимо. Делает это она не всегда. На глаз могу сказать, что одна заявка из пяти выполняется некорректно. Причина этого — заявка получила статус Done, программа учла сколько было реализовано в заявке бумаг, а после этого пришли дополнительные сделки. То есть, косяк в том, что заявка изменяется после того, как она получила статус Done. В частности это можно наблюдать в логах OrdersChanged, которые я приводил в этом комментарии: http://stocksharp.com/posts/m/7659/ Собрать полноценный лог (с данными по DDE) по этой ошибке в рабочем Квике пока не получается. Над этим работаю.

Повторить эту ошибку на тестовом Квике у меня не получается. Возможно зависит от того, что тестовый Квик и рабочий ведут себя по разному.

В процессе анализа проблемы на тестовом Квике я заметил две ошибки, которые возможно связаны с глобальной проблемой. И решив эти ошибки решится и глобальная. А может и нет.

Промежуточная ошибка номер Раз — неверное время Order.Time «0001-01-01 00:00:00.0000000» В экселе «44300176 and 44300177.xls» можно посмотреть данные по заявке 44300177. В первой записи , в которой Order.State поменялся на Done, Order.Time равно «0001-01-01 00:00:00.0000000».

2011-04-26 12:20:33.4339766	OrdersChanged    TransactionId: 44300177 Balance: 0 Volume: 39 State: Done CancelTime:  Status: Accepted

В файлике свойства Order.Time не видно. Но это точно так, потому что как только заявка становится Done, она у меня логируется в SQL. И в SQL Order.Time для этой заявки равно «0001-01-01 00:00:00.0000000».

Позже я исправил это упущение и в коде, который я привел раньше, Order.Time логируется в Debug. Но, к сожалению, на момент создания эксель файликов этого изменения еще не было.

Итак, основная мысль, что на момент, когда заявка становится Done время заявки Order.Time некорректно. Эта же ошибка уже встречалась здесь: http://stocksharp.com/forum/878/Order-Time-vozvrashchaiet-00-00-00-0001-ghoda/

Заявка 44300176 в экселике имеет корректное свойство Order.Time. Сравнивая DDE данные для заявок 44300177 и 44300176 я обнаружил, что перед первым событием OrdersChanged когда статус становиться равным Done для заявки 44300176 данные по DDE пришли, а для 44300177 нет. То есть заявка 44300177 произвольно поменяла значение статуса на Done. Это мои предположения, возможно они не верны.

Элемент данных DDE для 44300177, когда статус стал Done, а соответствующих данных DDE нет:


2011-04-26 12:20:33.3871010	PreProcessDdeData   String: мои сделки
2011-04-26 12:20:33.3871010	PreProcessDdeData   Row: 0
2011-04-26 12:20:33.3871010	PreProcessDdeData              Column: 0 Object: 127278
2011-04-26 12:20:33.3871010	PreProcessDdeData              Column: 1 Object: 12:20:33
2011-04-26 12:20:33.3871010	PreProcessDdeData              Column: 2 Object: SBER03
2011-04-26 12:20:33.3871010	PreProcessDdeData              Column: 3 Object: EQBR
2011-04-26 12:20:33.4027262	PreProcessDdeData              Column: 4 Object: 102.19
2011-04-26 12:20:33.4027262	PreProcessDdeData              Column: 5 Object: 39
2011-04-26 12:20:33.4027262	PreProcessDdeData              Column: 6 Object: 259356
2011-04-26 12:20:33.4027262	PreProcessDdeData              Column: 7 Object: 26.04.2011
2011-04-26 12:20:33.4027262	PreProcessDdeData              Column: 8 Object: BUY
2011-04-26 12:20:33.4183514	PreProcessDdeData   String: все сделки
2011-04-26 12:20:33.4183514	PreProcessDdeData   Row: 0
2011-04-26 12:20:33.4183514	PreProcessDdeData              Column: 0 Object: 127273
2011-04-26 12:20:33.4183514	PreProcessDdeData              Column: 1 Object: 12:20:32
2011-04-26 12:20:33.4183514	PreProcessDdeData              Column: 2 Object: SBER03
2011-04-26 12:20:33.4339766	PreProcessDdeData              Column: 3 Object: EQBR
2011-04-26 12:20:33.4339766	PreProcessDdeData              Column: 4 Object: 102.19
2011-04-26 12:20:33.4339766	OrdersChanged    TransactionId: 44300177 Balance: 0 Volume: 39 State: Done CancelTime:  Status: Accepted

Элемент данных DDE для 44300176, когда статус стал Done, но соответствующие данные DDE есть:


2011-04-26 12:20:32.2777118	PreProcessDdeData   String: заявки
2011-04-26 12:20:32.2777118	PreProcessDdeData   Row: 0
2011-04-26 12:20:32.2933370	PreProcessDdeData              Column: 0 Object: 259271
2011-04-26 12:20:32.2933370	PreProcessDdeData              Column: 1 Object: SBER03
2011-04-26 12:20:32.3089622	PreProcessDdeData              Column: 2 Object: EQBR
2011-04-26 12:20:32.3089622	PreProcessDdeData              Column: 3 Object: 102.22
2011-04-26 12:20:32.3089622	PreProcessDdeData              Column: 4 Object: 39
2011-04-26 12:20:32.3245874	PreProcessDdeData              Column: 5 Object: 0
2011-04-26 12:20:32.3245874	PreProcessDdeData              Column: 6 Object: B
2011-04-26 12:20:32.3402126	PreProcessDdeData              Column: 7 Object: FILLED
2011-04-26 12:20:32.3558378	PreProcessDdeData              Column: 8 Object: 12:20:31
2011-04-26 12:20:32.3558378	PreProcessDdeData              Column: 9 Object: 
2011-04-26 12:20:32.3558378	PreProcessDdeData              Column: 10 Object: L01-00000F00
2011-04-26 12:20:32.3558378	PreProcessDdeData              Column: 11 Object: LSW
2011-04-26 12:20:32.3558378	PreProcessDdeData              Column: 12 Object: 6014//S#
2011-04-26 12:20:32.3558378	PreProcessDdeData              Column: 13 Object: 44300176
2011-04-26 12:20:32.3714630	PreProcessDdeData              Column: 14 Object: 26.04.2011
2011-04-26 12:20:32.3714630	PreProcessDdeData              Column: 15 Object: 6014
2011-04-26 12:20:32.3714630	PreProcessDdeData   String: [стакан]SBER03-EQBR
2011-04-26 12:20:32.3714630	PreProcessDdeData   Row: 0
2011-04-26 12:20:32.3870882	PreProcessDdeData              Column: 0 Object: 0
2011-04-26 12:20:32.3870882	PreProcessDdeData              Column: 1 Object: 101.66
2011-04-26 12:20:32.3870882	PreProcessDdeData              Column: 2 Object: 40
2011-04-26 12:20:32.3870882	PreProcessDdeData   Row: 1
2011-04-26 12:20:32.3870882	PreProcessDdeData              Column: 0 Object: 0
2011-04-26 12:20:32.3870882	PreProcessDdeData              Column: 1 Object: 102.03
2011-04-26 12:20:32.4027134	PreProcessDdeData              Column: 2 Object: 94
2011-04-26 12:20:32.4027134	OrdersChanged    TransactionId: 44300176 Balance: 0 Volume: 39 State: Done CancelTime:  Status: Accepted

Промежуточная ошибка номер Два — время Order.CancelTime отсутствует, а должно быть. В экселе «44300189 and 44300190.xls» можно посмотреть данные по заявке 44300190. Когда пришло первое событие OrdersChanged для этой заявки с статусом Done, свойство Order.CancelTime было пустым. В следующем событии это время уже не пустое.


Date	Message
2011-04-26 12:21:39.4660718	OrdersChanged    TransactionId: 44300190 Balance: 1 Volume: 1 State: Active CancelTime:  Status: Accepted
2011-04-26 12:21:39.5754482	OrdersChanged    TransactionId: 44300190 Balance: 1 Volume: 1 State: Active CancelTime:  Status: Accepted
2011-04-26 12:21:44.5286366	OrdersChanged    TransactionId: 44300190 Balance: 1 Volume: 1 State: Done CancelTime:  Status: Accepted
2011-04-26 12:21:45.1848950	OrdersChanged    TransactionId: 44300190 Balance: 1 Volume: 1 State: Done CancelTime: 26.04.2011 12:21:44 Status: Accepted

Аналогично предыдущему случаю, если посмотреть данные DDE то перед третьим событием OrdersChanged данные DDE для заявки не приходят. Из чего я делаю вывод, что заявка меняет статус на Done самопроизвольно:


2011-04-26 12:21:43.8567530	PreProcessDdeData   String: все сделки
2011-04-26 12:21:43.8567530	PreProcessDdeData   Row: 0
2011-04-26 12:21:43.8567530	PreProcessDdeData              Column: 0 Object: 128200
2011-04-26 12:21:43.8723782	PreProcessDdeData              Column: 1 Object: 12:21:43
2011-04-26 12:21:43.8723782	PreProcessDdeData              Column: 2 Object: SBER03
2011-04-26 12:21:43.8723782	PreProcessDdeData              Column: 3 Object: EQBR
2011-04-26 12:21:43.8723782	PreProcessDdeData              Column: 4 Object: 102.12
2011-04-26 12:21:43.8723782	PreProcessDdeData              Column: 5 Object: 10
2011-04-26 12:21:43.8723782	PreProcessDdeData              Column: 6 Object: BUY
2011-04-26 12:21:43.8880034	PreProcessDdeData              Column: 7 Object: 26.04.2011
2011-04-26 12:21:43.8880034	PreProcessDdeData   String: все сделки
2011-04-26 12:21:43.8880034	PreProcessDdeData   Row: 0
2011-04-26 12:21:43.8880034	PreProcessDdeData              Column: 0 Object: 128201
2011-04-26 12:21:43.9036286	PreProcessDdeData              Column: 1 Object: 12:21:43
2011-04-26 12:21:43.9036286	PreProcessDdeData              Column: 2 Object: SBER03
2011-04-26 12:21:43.9036286	PreProcessDdeData              Column: 3 Object: EQBR
2011-04-26 12:21:43.9036286	PreProcessDdeData              Column: 4 Object: 102.12
2011-04-26 12:21:43.9036286	PreProcessDdeData              Column: 5 Object: 2
2011-04-26 12:21:43.9192538	PreProcessDdeData              Column: 6 Object: BUY
2011-04-26 12:21:43.9192538	PreProcessDdeData              Column: 7 Object: 26.04.2011
2011-04-26 12:21:44.5286366	OrdersChanged    TransactionId: 44300190 Balance: 1 Volume: 1 State: Done CancelTime:  Status: Accepted

Итог В этих двух локальных ошибках, на мой взгляд, есть общая черта — заявка изменяется после того, как статус стал Done. Возможно эти ошибки связаны с глобальной ошибкой, а возможно нет.

Mikhail Sukhov
Mikhail Sukhov

Ок, я кажется понял в чем проблема. Буду фиксить.

Но есть ряд моментов, которые нужно прояснить. Order.Time не всегда сразу инициализируется. В асинхронном режиме это чаще всего, потому что callback приходит раньше, чем ответ через ДДЕ. При это callback не несет информацию о времени регистрации.

Что касается записи:

2011-04-26 12:21:39.4660718    OrdersChanged    TransactionId: 44300190 Balance: 1 Volume: 1 State: Active CancelTime:  Status: Accepted
2011-04-26 12:21:39.5754482    OrdersChanged    TransactionId: 44300190 Balance: 1 Volume: 1 State: Active CancelTime:  Status: Accepted
2011-04-26 12:21:44.5286366    OrdersChanged    TransactionId: 44300190 Balance: 1 Volume: 1 State: Done CancelTime:  Status: Accepted
2011-04-26 12:21:45.1848950    OrdersChanged    TransactionId: 44300190 Balance: 1 Volume: 1 State: Done CancelTime: 26.04.2011 12:21:44 Status: Accepted

то судя по логу, ДДЕ не присылал время снятия. Единственно, что тут неправильно - это выставление Done преждевременно. Ошибка, как я понял, в слишком раннем выставлении Done для заявки. По сути это можно трактовать как и правильно поведение (ведь заявка реально была снята). Но неправильность начинается как раз в том случае, если после снятия заявки начинают приходить по ней сделки. И тогда баланс начинает уменьшаться для уже Done заявки. Это я исправлю. Но всегда остается тот вариант, когда Квик пришлет уведомление по ДДЕ для уже Done заявки (например, в Квик добавлена колонки, которые тикают для уже исполненных заявок). Баланс уменьшаться не будет, но OrdersChanged все равно вызовется.

Maxim
Maxim Автор

Mikhail Sukhov: Но есть ряд моментов, которые нужно прояснить. Order.Time не всегда сразу инициализируется. В асинхронном режиме это чаще всего, потому что callback приходит раньше, чем ответ через ДДЕ. При это callback не несет информацию о времени регистрации.

Наверно надо тогда внести пояснение в документацию, о том что в некоторых случаях заявка все таки может изменяться после изменения статуса на Done. Или реализовать так, что бы до появления Order.Time заявка не становилась Done. Или ввести опцию, которая позволяла выбирать из двух вариантов поведения один определенный.

Mikhail Sukhov: Но всегда остается тот вариант, когда Квик пришлет уведомление по ДДЕ для уже Done заявки (например, в Квик добавлена колонки, которые тикают для уже исполненных заявок). Баланс уменьшаться не будет, но OrdersChanged все равно вызовется.

То что придет событие OrdersChanged не страшно на мой взгляд. Главное, что бы поведение заявки совпадало с документацией. Это я о не изменении после Done. В противном случае рассчитываешь на одно, а в реалии получается другое.

Maxim:

Mikhail Sukhov: Order.State Но зная Order.State нельзя определить, была ли отменена заявка, правильно? Получается, что единственный признак того, что заявка была отменена, это наличие Order.CancelTime? Или я ошибаюсь?

Михаил, не ответили на вопрос. Он не критичен, но для общего развития не помешает узнать ответ.

Повторюсь, что все второстепенные ошибки лично для меня пока не критичны. Возможно в будущем и придется с ними столкнутся , если они останутся, но на данные момент они не мешают.

Основная проблема, которая мешает — это в изменении баланса, после того заявка стала Done.

Maxim
Maxim Автор

Михаил, так и не ответили. Спрошу еще раз, что бы закрыть вопрос.

Зная Order.State, нельзя определить, была ли отменена заявка, правильно? Получается, что единственный признак того, что заявка была отменена, это наличие Order.CancelTime? Или я ошибаюсь?

Mikhail Sukhov
Mikhail Sukhov

Maxim: Михаил, так и не ответили. Спрошу еще раз, что бы закрыть вопрос.

Зная Order.State, нельзя определить, была ли отменена заявка, правильно? Получается, что единственный признак того, что заявка была отменена, это наличие Order.CancelTime? Или я ошибаюсь?

Да, можно по Order.CancelTime.

Maxim
Maxim Автор

Михаил, есть ошибка.

При выставлении и быстром снятии заявки статус остается Active.

Кусочек логов. Записи идут в хронологическом порядке (забыл время добавить в лог). Это последние данные по этой заявке.


PreProcessDdeData   String: заявки
PreProcessDdeData   Row: 0
PreProcessDdeData              Column: 0 Object: 446183
PreProcessDdeData              Column: 1 Object: SBER03
PreProcessDdeData              Column: 2 Object: EQBR
PreProcessDdeData              Column: 3 Object: 97.66
PreProcessDdeData              Column: 4 Object: 6
PreProcessDdeData              Column: 5 Object: 6
PreProcessDdeData              Column: 6 Object: B
PreProcessDdeData              Column: 7 Object: KILLED
PreProcessDdeData              Column: 8 Object: 15:02:54
PreProcessDdeData              Column: 9 Object: 15:02:54
PreProcessDdeData              Column: 10 Object: L01-00000F00
PreProcessDdeData              Column: 11 Object: LSQ
PreProcessDdeData              Column: 12 Object: 6014//S#
PreProcessDdeData              Column: 13 Object: 54114804
PreProcessDdeData              Column: 14 Object: 03.05.2011
PreProcessDdeData              Column: 15 Object: 6014
OrdersChanged    TransactionId: 54114804 Balance: 6 Volume: 6 State: Active CancelTime: 03.05.2011 15:02:54 Status: Accepted

Mikhail Sukhov
Mikhail Sukhov

Maxim: Михаил, есть ошибка.

Случаем не это http://stocksharp.com/posts/m/7845/

Maxim
Maxim Автор

Mikhail Sukhov:

Maxim: Михаил, есть ошибка.

Случаем не это http://stocksharp.com/posts/m/7845/

Ситуация вроде похожа. Вроде бы тоже проблема в том, что после отмены заявка не становится Done.

Скачал последнюю версию, запустил. Ситуация не изменилась. Все так же отмененные заявки не становятся Done. Возможно связано стем, что Trader.IsAsyncMode у меня true? В приведенном Вами случае у пользователя Garry был случай с false.

При QuikTrader.CancelOrderInstantly = true все работает нормально.

Отдельный вопрос. А зачем свойство QuikTrader.CancelOrderInstantly ? Если заявка отменилась, то почему сразу не переводить ее в Done? Зачем ждать данных из DDE?

Mikhail Sukhov
Mikhail Sukhov

Maxim: Ситуация вроде похожа. Вроде бы тоже проблема в том, что после отмены заявка не становится Done.

Скачал последнюю версию, запустил.

Сегодня скачали? Может нужно пересобрать проект? Вдруг старые dll закэшировались.

Maxim: Ситуация не изменилась. Все так же отмененные заявки не становятся Done.

Теперь Done будет выставляться только тогда, когда пришел поток ДДЕ с признаком KILLED. Что у вас и происходит по логу.😒

Maxim: Отдельный вопрос. А зачем свойство QuikTrader.CancelOrderInstantly ? Если заявка отменилась, то почему сразу не переводить ее в Done? Зачем ждать данных из DDE?

Чтобы не было вашей ситуации, когда баланс начинает чудесным образом обновляться после отмены.

Maxim
Maxim Автор

Спасибо, Михаил, за ответы и за работу. Чо то я совсем заработался. Надо делать выходные. На последние вопросы и сам смог бы ответить, если бы подумал.

Все работает.