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


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


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

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

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


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

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

Теги:


Спасибо:




1 2 3  > >>
Mikhail Sukhov

Фотография
Дата: 25.01.2011
Ответить


Maxim GoTo

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

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


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

Maxim

Фотография
Дата: 25.01.2011
Ответить


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

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


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

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

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);
}




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

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

Фотография
Дата: 27.01.2011
Ответить


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

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



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

Code
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

Фотография
Дата: 27.01.2011
Ответить


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

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

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



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

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» в выводе есть.
Что говорит о том, что что-то не так.

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



Code

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

Фотография
Дата: 27.01.2011
Ответить


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


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

Maxim

Фотография
Дата: 27.01.2011
Ответить


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

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


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

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

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);
}



Результат:
Code

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

Фотография
Дата: 28.01.2011
Ответить


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


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

Mikhail Sukhov

Фотография
Дата: 28.01.2011
Ответить


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


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


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

Maxim

Фотография
Дата: 28.01.2011
Ответить


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

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

Code

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

Фотография
Дата: 08.02.2011
Ответить


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

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

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

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

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

Надеюсь на понимание.
Спасибо.
Спасибо:
1 2 3  > >>

Добавить файлы через драг-н-дроп, , или вставить из буфера обмена.

loading
clippy