Вопрос по обработке сделок
Atom Ответить
27.04.2012


Ситуация такая, стратегия отправляет заявки на биржу метод RegisterOrder(Order) и по таймауту или исполнению некого условия снимает через метод Trader.CancelOrder(Order). Учет закрытых позиций и цены происходит при событии появлении новой сделки order.NewTrades() (нужно для работы робота),
По событию снятия заявки .Order.Canceled() или её полного исполнения заявка считается закрытой.

В каждом событии стоит проверка - если статус заявки Done и количество учтенных роботом позиций равно ОбъемЗаявки - БалансЗаявки. То исключаем её из списка робота, и считаем что закрыта, т.е. робот считает что вся информация по заявке получена.
Учитывается ситуация если сделки пришли позже, чем заявка была снята/исполнена, так же есть обработка события неудачной отмены заявки. Код основательно перерыт и перепроверен.

Но иногда примерно с одной-двумя из 500 заявок возникает ситуация когда условие проверки выполняется заявка исключается, но Робот учитывает не все сделки прошедшие по заявке. Как вариант может быть такое, что в какой-то момент статус заявки Done, а баланс по ней ещё может изменится?
В чем может быть причина, может сталкивался кто-то? Уже просто не знаю что с этим делать.
Сейчас все работает на тестовом сервере РТС, Forts Plaza - II.

Теги:


Спасибо:




28 Ответов
1 2  >
Самунджян Артем

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


Александр (ПАА) Перейти

Ситуация такая, стратегия отправляет заявки на биржу метод RegisterOrder(Order) и по таймауту или
Но иногда примерно с одной-двумя из 500 заявок возникает ситуация когда условие проверки выполняется заявка исключается, но Робот учитывает не все сделки прошедшие по заявке. Как вариант может быть такое, что в какой-то момент статус заявки Done, а баланс по ней ещё может изменится?
В чем может быть причина, может сталкивался кто-то? Уже просто не знаю что с этим делать.
Сейчас все работает на тестовом сервере РТС, Forts Plaza - II.

Если я всё правильно понял, то могу посоветовать использовать strategyRule и непосредственно опираться на событие изменения самого ордера , то есть переписать полностью алгоритм на событийную модель.
Если состояние у заявки Done , то никакое изменение по ней прийти уже не может.Попробуй включить логирование , если неизвестно как , я отпишусь...Не совсем понял , как работает "проверка", может быть её можно как-нибудь доработать.
Код


 this.When(_order.Matched())
                            .Do(o =>
                                    {
                                        //алгоритм работы с ордером
                                    });

Спасибо:

Alexander

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


Артём Самунджян Перейти
Если состояние у заявки Done , то никакое изменение по ней прийти уже не может.


Может.
Мы можем done выставить как ответ на заявку по транзакционному потоку, а затем нам пришло изменение по таблице заявок.

В данном случае, как совершенно верно ответил Артём, лучше пользоваться правилами.

И просьба всегда указывать версию при описании проблем. В случае с плазой изменений в 4.1 было крайне много и если пользуетесь 4.0 - совет переходить на 4.1 как можно скорее.
Спасибо:

Александр (ПАА)

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


Спасибо за ответы. В принципе я и так использую событийную модель. Может если кусок кода показать понятнее будет, о чем я.
Происходит это так, в стратегии объявлена публичная функция RegisterOrder(JointRequest order), JointRequest - это собственный класс, в нем содержится Заявка Order и дополнительная информация. Стратегия занимается только тем что регистрирует/снимает заявки и обрабатывает соответствующие события, остальной частью занимается другой класс, который и вызывает Strategy.RegisterOrder или Strategy.CancelOrder.

Код
 public void RegisterOrder(JointRequest order)
        {
            order.State = StateJointRequest.Sended;
            JointRequests.Add(order);
            try
            {
                base.RegisterOrder(order.Order);
                OnJointRequestChanged(order);
                order.Save();
                this
                   .When(order.Order.Matched())
                   .Do((Action)(() => RequestMatched(order)));
                this
                  .When(order.Order.NewTrades())
                  .Do((Action<IEnumerable<MyTrade>>)((newTrades) => NewTradesRequest(order, newTrades)));
            }
            catch  
            {
                order.State = StateJointRequest.None;
            }
        }

        public void NewTradesRequest(JointRequest order,IEnumerable<MyTrade> MyTrades)
        {
            order.ClosePositions(MyTrades);
            //то самое условие
            if (order.Order.State == OrderStates.Done && (order.Order.Volume - order.Order.Balance == order.ClosedCount))
                order.CloseJR();
        }
  public void RequestMatched(JointRequest order)
        {
            //то самое условие
            if (order.Order.State == OrderStates.Done && (order.Order.Volume - order.Order.Balance == order.ClosedCount))
                order.CloseJR();
        }

аналогично и со снятием заявки. ClosedCount считается в order.ClosePositions(MyTrades) считается правильно.

Использую 4.0.23, а где можно скачать 4.1 чтобы перейти? по ссылке с сайта на скачивание вижу только 4.0 и более ранние версии.
Автор топика
Спасибо:

Alexander

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


NewTrades может быть раньше чем order.Matched, а может и нет.
+ выше дал пояснения по тому как баланс может меняться после Done.

4.1 брать с stocksharp.codeplex.com из sources, папка dev\references
Спасибо:

Александр (ПАА)

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


Спасибо, Александр, а как тогда лучше организовать проверку все ли сделки по заявке учтены? С Matched() то понятно там Order.Balance = 0, а если событие Order.Canceled()?
Автор топика
Спасибо:

Alexander

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


Александр (ПАА) Перейти
Спасибо, Александр, а как тогда лучше организовать проверку все ли сделки по заявке учтены? С Matched() то понятно там Order.Balance = 0, а если событие Order.Canceled()?


давайте немного с другой стороны зайдём.
расскажите для чего вам это нужно. мне кажется, подход немного не верный.
Спасибо:

Александр (ПАА)

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


Давайте попробуем. Суть в том что у меня есть много модулей, каждый из который торгует по некоему алгоритму, часто бывает так, что нужно отправить на биржу одновременно несколько заявок от разных модулей, чтобы сократить количество отправляемых заявок а так же исключить встречные заявки от модулей, я составляю одну - которая и отправляется на биржу через стратегию, но после исполнения или снятия этой объединенной заявки информацию по ней необходимо разобрать и вернуть каждому модулю сколько и как исполнилось по нему.
Автор топика
Спасибо:

Alexander

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


тогда не отслеживайте done, а отслеживайте только new trades.
приходит новая сделка - сообщили модулую.
когда у модуля исполненный объём станет равен посланному - считаем что заявка исполнилась полностью.
Спасибо:

Александр (ПАА)

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


А как быть если заявка полностью не исполниться?
Я же снимаю ее по таймауту, и она может либо быть частично исполнена, либо вообще не исполнена...
Автор топика
Спасибо:

Alexander

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


У вас баланс меняется после Done только для снятой заявки?
Спасибо:

Александр (ПАА)

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


По моим наблюдениям только для снятой.
Автор топика
Спасибо:

Alexander

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


Александр (ПАА) Перейти
По моим наблюдениям только для снятой.


В ветке 4.1 точно сделано следующее:
- если мы посылаем CancelOrder - то в ответ на эту транзакцию биржа присылает сколько осталось по балансу в заявке - мы это проставляем и заявка больше не может быть изменена
- если посылаем CancelOrders - групповое снятие - то тут да, может возникнуть что после State = OrderState.Done изменится баланс - я это поправил, будет фикс выложен на codeplex
- для перерегистрации - см. групповое снятие - тоже поправлено

Вообще после того как стал OrderState.Done баланс меняться не должен. Если у вас не так на 4.1 - пишите ещё раз, будем разбираться.

Сейчас просьба перейти на 4.1 и пока (до выкладывания последнего фикса на codeplex) - пользоваться CancelOrder, а не групповым снятием заявки.
Спасибо:

westtrd

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


Александр (ПАА) Перейти
Давайте попробуем. Суть в том что у меня есть много модулей, каждый из который торгует по некоему алгоритму, часто бывает так, что нужно отправить на биржу одновременно несколько заявок от разных модулей, чтобы сократить количество отправляемых заявок а так же исключить встречные заявки от модулей, я составляю одну - которая и отправляется на биржу через стратегию, но после исполнения или снятия этой объединенной заявки информацию по ней необходимо разобрать и вернуть каждому модулю сколько и как исполнилось по нему.

Вообще то это клиринговая логика, с распределением проторгованного объема по компонентам
Такое на западных рынках есть, и проблем тут достаточно.

Есть несколько основных сценариев:
1. пропорционально
2. FIFO
3. нечто производное

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

gazrvs_nur

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


Чтобы не плодить одинаковые темы, просьба помочь с простым вопросом по сделкам:
в тестовом примере SmaStrategy создал правило на появление новых сделок: this .WhenNewMyTrades() .Do(writecsv) .Apply(this);
в обработчике writecsv хочу получить данные по последней сделке: var trade = this.MyTrades. ???? ;
но не могу получить не одно из свойств MyTrades, хотя отладчике они все есть в ((StockSharp.BusinessEntities.MyTrade[])(this.MyTrades))

Есть другой способ?

Спасибо:

Alexander

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


gazrvs_nur Перейти
Чтобы не плодить одинаковые темы, просьба помочь с простым вопросом по сделкам:
в тестовом примере SmaStrategy создал правило на появление новых сделок: this .WhenNewMyTrades() .Do(writecsv) .Apply(this);
в обработчике writecsv хочу получить данные по последней сделке: var trade = this.MyTrades. ???? ;
но не могу получить не одно из свойств MyTrades, хотя отладчике они все есть в ((StockSharp.BusinessEntities.MyTrade[])(this.MyTrades))

Есть другой способ?




Код
this.WhenNewMyTrades().Do<IEnumerable<MyTrade>>(writecsv).Apply(this);

private void writecsv(IEnumerable<MyTrade> newMyTrades)
{
...
}


Таким образом в обработчик сразу передадутся новые сделки.
Спасибо:

gazrvs_nur

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


Компилятор ругается на строку
private void writecsv( IEnumerable<MyTrade> newMyTrades)

Ошибка 1 Вместе с аргументами-типами нельзя использовать не универсальный тип "System.Collections.IEnumerable" E:\WIN\Samples\Testing\SampleHistoryTestingParallel\SmaStrategy.cs 92 41 SampleHistoryTestingParallel
Спасибо:

Alexander

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


gazrvs_nur Перейти
Компилятор ругается на строку
private void writecsv( IEnumerable<MyTrade> newMyTrades)

Ошибка 1 Вместе с аргументами-типами нельзя использовать не универсальный тип "System.Collections.IEnumerable" E:\WIN\Samples\Testing\SampleHistoryTestingParallel\SmaStrategy.cs 92 41 SampleHistoryTestingParallel



Сейчас в 4.1 всё даже проще стало


Код

...
this.WhenNewMyTrades().Do(writecsv);
...

private void writecsv(IEnumerable<MyTrade> newMyTrades)
{
...
}
Спасибо:

gazrvs_nur

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


Александр,
я аналогично уже пробывал ..

На конструкцию: ".Do(writecsv);" компилятор выдает ошибку:
Ошибка 1 Наиболее подходящий перегруженный метод для "StockSharp.Algo.Strategies.StrategyRule<System.Collections.Generic.IEnumerable<StockSharp.BusinessEntities.MyTrade>>.Do(System.Action)" имеет несколько недопустимых аргументов
Ошибка 2 Аргумент "1": преобразование типа из "группа методов" в "System.Action" невозможно

А на "private void writecsv(IEnumerable<MyTrade> newMyTrades)" по прежднему:
Ошибка 3 Вместе с аргументами-типами нельзя использовать не универсальный тип "System.Collections.IEnumerable"

как бы вообще уйти от этого IEnumerable<MyTrade> в нормальный IEnumerable хотя бы.


Спасибо:

Alexander

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


gazrvs_nur Перейти
Александр,
я аналогично уже пробывал ..

На конструкцию: ".Do(writecsv);" компилятор выдает ошибку:
Ошибка 1 Наиболее подходящий перегруженный метод для "StockSharp.Algo.Strategies.StrategyRule<System.Collections.Generic.IEnumerable<StockSharp.BusinessEntities.MyTrade>>.Do(System.Action)" имеет несколько недопустимых аргументов
Ошибка 2 Аргумент "1": преобразование типа из "группа методов" в "System.Action" невозможно

А на "private void writecsv(IEnumerable<MyTrade> newMyTrades)" по прежднему:
Ошибка 3 Вместе с аргументами-типами нельзя использовать не универсальный тип "System.Collections.IEnumerable"

как бы вообще уйти от этого IEnumerable<MyTrade> в нормальный IEnumerable хотя бы.





У вас точно последняя версия 4.1?
Спасибо:

gazrvs_nur

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


у меня сборка stocksharp-16844 от 10.05.2012г.
сейчас скачаю последнюю и проверю
Спасибо:

gazrvs_nur

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


Проблема в stocksharp-17079 (папка dev) та же

private void writecsv(IEnumerable<MyTrade> newMyTrades)
Ошибка 3 Вместе с аргументами-типами нельзя использовать не универсальный тип "System.Collections.IEnumerable"

а не проще было бы сделать доступными свойства Strategy.MyTrades. ?
Спасибо:

Alexander

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


gazrvs_nur Перейти
Проблема в stocksharp-17079 (папка dev) та же

private void writecsv(IEnumerable<MyTrade> newMyTrades)
Ошибка 3 Вместе с аргументами-типами нельзя использовать не универсальный тип "System.Collections.IEnumerable"

а не проще было бы сделать доступными свойства Strategy.MyTrades. ?


Они все доступны.

У вас проблема в том, что не подключены либо библиотеки нужные, либо using.

Следующий код без проблем компилируется у меня:

Код
namespace Test
{
	using System.Collections.Generic;
	using StockSharp.Algo.Strategies;
	using StockSharp.BusinessEntities;

	public class MyStategy : Strategy
	{
		protected override void OnStarting()
		{
			base.OnStarting();

			this.WhenNewMyTrades().Do(writecsv);
		}

		void writecsv(IEnumerable<MyTrade> newMyTrades)
		{
		}
	}
}


Собираю под .Net Framework 4.0
Спасибо: gazrvs_nur

gazrvs_nur

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


Спасибо Александр,
вся проблема была в using System.Collections.Generic;
я использовал using System.Collections;
странно конечно .Generic должен входить в System.Collections по умолчанию, но видимо не обязан.

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

пока вытащить из IEnumerable<MyTrade> это данные неполучается.

добавить что то вроде this.MyTrades.Last() тоже нельзя.

в цикле foreach (IEnumerable<MyTrade> value in newMyTrades) получить какое либо значение(дату, время) "value." также не идет.
Спасибо:

gazrvs_nur

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


Может кому понадобится.
Извернулся в вышеуказанном случае следующим образом:
private void writecsv(IEnumerable<MyTrade> newMyTrades)
{
var Tradeneed = new List<MyTrade>(newMyTrades);
decimal ClosedVolumeneed = Tradeneed[0].ClosedVolume;
decimal Volumeneed = Tradeneed[0].Trade.Volume;
DateTime Timeneed = Tradeneed[0].Trade.Time;
string Securityneed = Tradeneed[0].Trade.Security.ToString();
decimal Priceneed = Tradeneed[0].Trade.Price;
string Directionneed = Tradeneed[0].Trade.OrderDirection.ToString();
long Idneed = Tradeneed[0].Trade.Id;
}
Спасибо:

Alexander

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


gazrvs_nur Перейти
вот только проблема была не в вызове процедуры с передаче туда MyTrades,
а в том, чтобы получить дату, время, цену и направление последней сделки из this.MyTrades.

пока вытащить из IEnumerable<MyTrade> это данные неполучается.

добавить что то вроде this.MyTrades.Last() тоже нельзя.

в цикле foreach (IEnumerable<MyTrade> value in newMyTrades) получить какое либо значение(дату, время) "value." также не идет.


К сожалению, лишь сейчас увидел это добавление к сообщению.
На будущее просьба писать новые сообщения, а не редактировать предыдущие :)
А то они через RSS не идут. Я уже вроде как прочитал, а потом оказывается что там половина нового была.

Так можно и без ответа остаться :)


Очень странно что не работает через MyTrades.Last()

MyTrades - это обычный IEnumerable<T>
Идём в MSDN, ищем метод Last у интерфейса.
Видим - необходимо объявить using System.Linq; и подключить reference System.Core.dll
Спасибо:
1 2  >

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

loading
clippy