Помогите разобраться с TakeProfitStrategy...
Atom Ответить
23.11.2011


Сделал как в примерах...

Цитата:

private void OnNewMyTrades(IEnumerable<MyTrade> trades)
{
// фильтруем сделки, чтобы найти те, которые произошли для заявки MyOrder
trades = trades.Where(t => t.Order == MyOrder);
// если не найдена ни одна сделка для заявки MyOrder
if (trades.Count() == 0)
return;
// сама пакетная стратегия так же является параллельной, чтобы она не блокирована основной код робота
var Basket = new BasketStrategy(BasketStrategyFinishModes.All);
// для каждой сделки добавляем для защиты по пакетной стратегии
Basket.ChildStrategies.AddRange(trades.Select(CreateBasket).Cast<Strategy>());
base.ChildStrategies.Add(Basket);
}

BasketStrategy CreateBasket(MyTrade t)
{
var s = new BasketStrategy(BasketStrategyFinishModes.First);
// выставляет тейк-профит в 45 пунктов
var takeProfit = new TakeProfitStrategy(t, 45);
s.ChildStrategies.Add(takeProfit);
return s;
}

Лог такой:

Цитата:

16:33:51.023 | | OS | Стратегия запущена.
16:34:41.639 | | OS | Новая Buy сделка 458108237 по цене 140960 на 1 заявки 59619294.
16:34:41.665 | | BS | Стратегия запущена.
16:34:41.666 | | BS | Стратегия запущена.
16:34:41.666 | | TPS | Стратегия запущена.
16:35:48.452 | | TPS | Регистрация новой заявки на Sell с ценой 141005 и объемом 1.
16:35:48.455 | | TPS | Заявка 59619295 на Sell отправлена с ценой 141005 объемом 1.
16:35:48.489 | Warning | TPS | Заявка 59619295 не имеет состояния.
16:35:51.464 | | OS | Новая Sell сделка 458109666 по цене 141005 на 1 заявки 59619295.
16:35:51.465 | | TPS | Позиция изменилась на -1.
16:35:51.465 | | TPS | Заканчиваем котирование с неисполненным объемом равный 0.
16:35:51.465 | | BS | Новая Sell сделка 458109666 по цене 141005 на 1 заявки 59619295.
16:35:51.465 | | BS | Новая Sell сделка 458109666 по цене 141005 на 1 заявки 59619295.
16:35:51.465 | | TPS | Новая Sell сделка 458109666 по цене 141005 на 1 заявки 59619295.
16:35:51.466 | | BS | Стратегия останавливается.
16:35:51.467 | | TPS | Заканчиваем котирование с неисполненным объемом равный 0.
16:35:51.467 | | TPS | Заканчиваем котирование с неисполненным объемом равный 0.
16:35:51.469 | | BS | Стратегия останавливается.
16:35:51.470 | | TPS | Стратегия останавливается.
16:35:51.470 | | TPS | Заканчиваем котирование с неисполненным объемом равный 0.
16:35:51.473 | | BS | Стратегия остановлена.



Никак не разберусь, что делает TPS целую минуту от момента запуска до регистрации заявки. Сколько пробовал запускать - наименьший интервал был 6 секунд.

Теги:


Спасибо:




37 Ответов
1 2  >
esper

Фотография
Программист
Дата: 23.11.2011
Ответить


Ждет, пока выполнится условие, что цена вырастет/упадет на заданное значение
Спасибо: profts

profts

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


Невнимательно документацию прочитал )
для HFT стратегии такое явно не подходит )

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

как по событию NewMyTrades определить чем является данная сделка - исполненной покупкой или тэйком? можно ли в комментарии к заявке добавлять buy или Take, к примеру...
Автор топика
Спасибо:

esper

Фотография
Программист
Дата: 23.11.2011
Ответить


У MyTrade есть поле Order, это заявка по которой пришли сделки, при создании заявко можно где-то запоминать их, а потом проверять
Спасибо:

profts

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


Что-то вроде этого?:


Цитата:

MyBuy = this.CreateOrder();
this.RegisterOrder(MyBuy);
MyTake = this.CreateOrder();
this.RegisterOrder(MyTake);
...

private void OnNewMyTrades(IEnumerable<MyTrade> trades)
{
trades = trades.Where(t => t.Order == MyBuy);
if (trades.Count() == 1)
{
//прошла покупка
}
else
{
trades = trades.Where(t => t.Order == MyTake);
if (trades.Count() == 1)
{
// исполнился тэйк
}
}
}


По-моему можно как-то более красиво сделать )))
Автор топика
Спасибо:

frontman

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


Ну например у каждой заявки есть правило order.NewTrades() и if тогда нафик не нужен.
И странное какое то у вас условие... А что если например MyBuy сделка была на 2 лота и они прошли в разных сделках?
Тогда у вас условие не выполниться явно...
Спасибо:

profts

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


Цитата:

А что если например MyBuy сделка была на 2 лота и они прошли в разных сделках?

Можно изменить на: if (trades.Count() > 0) , но в любом случае order.NewTrades() более удобно использовать.
Спасибо!
Автор топика
Спасибо:

profts

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


Сделал подобным образом:

Цитата:

if (position == 0)
{

if (условие на сделку)
{
position = 1;
order_buy1 = this.CreateOrder(OrderDirections.Buy, base.Security.GetMarketPrice(OrderDirections.Buy), 1);
this.RegisterOrder(order_buy1);
};
};
if (position == 1)
{
this
.When(order_buy1.NewTrades())
.Do(Takeprofit1);
}


private void Takeprofit1()
{
order_takeprofit1 = this.CreateOrder(OrderDirections.Sell, order_buy1.Price + 45, 1);
this.RegisterOrder(order_takeprofit1);
position = 2;
}


получаю следующий лог:

Цитата:

13:09:44.264 | | OS | Новая Buy сделка 458811146 по цене 140605 на 1 заявки 47354464.
13:09:44.592 | Error | OS | Заявка 47354476 не была принята по причине StockSharp.Quik.ApiException: Код ошибки Failed Сообщение Ошибка создания заявки. [FORTS] "Нехватка средств по лимитам клиента."..
13:09:44.592 | Error | OS | Заявка 47354475 не была принята по причине StockSharp.Quik.ApiException: Код ошибки Failed Сообщение Ошибка создания заявки. [FORTS] "Нехватка средств по лимитам клиента."..
13:09:44.592 | Error | OS | Заявка 47354477 не была принята по причине StockSharp.Quik.ApiException: Код ошибки Failed Сообщение Ошибка создания заявки. [FORTS] "Нехватка средств по лимитам клиента."..
13:09:44.592 | Error | OS | Заявка 47354478 не была принята по причине StockSharp.Quik.ApiException: Код ошибки Failed Сообщение Ошибка создания заявки. [FORTS] "Нехватка средств по лимитам клиента."..
13:09:44.593 | Error | OS | Заявка 47354479 не была принята по причине StockSharp.Quik.ApiException: Код ошибки Failed Сообщение Ошибка создания заявки. [FORTS] "Нехватка средств по лимитам клиента."..
13:09:44.593 | Error | OS | Заявка 47354480 не была принята по причине StockSharp.Quik.ApiException: Код ошибки Failed Сообщение Ошибка создания заявки. [FORTS] "Нехватка средств по лимитам клиента."..
13:09:44.643 | Error | OS | Заявка 47354481 не была принята по причине StockSharp.Quik.ApiException: Код ошибки Failed Сообщение Ошибка создания заявки. [FORTS] "Нехватка средств по лимитам клиента."..
13:09:44.643 | Error | OS | Заявка 47354483 не была принята по причине StockSharp.Quik.ApiException: Код ошибки Failed Сообщение Ошибка создания заявки. [FORTS] "Нехватка средств по лимитам клиента."..
13:09:44.805 | Error | OS | Заявка 47354482 не была принята по причине StockSharp.Quik.ApiException: Код ошибки Failed Сообщение Ошибка создания заявки. [FORTS] "Нехватка средств по лимитам клиента."..
13:09:44.805 | Error | OS | Заявка 47354484 не была принята по причине StockSharp.Quik.ApiException: Код ошибки Failed Сообщение Ошибка создания заявки. [FORTS] "Нехватка средств по лимитам клиента."..
13:09:44.805 | Error | OS | Заявка 47354485 не была принята по причине StockSharp.Quik.ApiException: Код ошибки Failed Сообщение Ошибка создания заявки. [FORTS] "Нехватка средств по лимитам клиента."..
13:09:44.805 | Error | OS | Заявка 47354486 не была принята по причине StockSharp.Quik.ApiException: Код ошибки Failed Сообщение Ошибка создания заявки. [FORTS] "Нехватка средств по лимитам клиента."..
13:09:47.748 | | OS | Стратегия останавливается.
13:09:47.753 | | OS | Стратегия остановлена.
13:09:52.752 | | OS | Новая Sell сделка 458811274 по цене 140650 на 1 заявки 47354465.
13:09:52.754 | | OS | Новая Sell сделка 458811275 по цене 140650 на 1 заявки 47354466.
13:09:52.755 | | OS | Новая Sell сделка 458811276 по цене 140650 на 1 заявки 47354467.
13:09:52.755 | | OS | Новая Sell сделка 458811277 по цене 140650 на 1 заявки 47354468.
13:09:52.755 | | OS | Новая Sell сделка 458811278 по цене 140650 на 1 заявки 47354470.
13:09:52.756 | | OS | Новая Sell сделка 458811279 по цене 140650 на 1 заявки 47354471.
13:09:52.756 | | OS | Новая Sell сделка 458811280 по цене 140650 на 1 заявки 47354473.
13:09:52.756 | | OS | Новая Sell сделка 458811281 по цене 140650 на 1 заявки 47354474.


Почему событие .When(order_buy1.NewTrades()) возникает несколько раз?
Изменил на .When(order_buy1.Matched()) - то же самое... просто начинают выставляться тейкпрофиты без остановок.
Автор топика
Спасибо:

frontman

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


Ну судя по логам у вас события срабатывают для разных заявок
13:09:52.752 | | OS | Новая Sell сделка 458811274 по цене 140650 на 1 заявки 47354465.
13:09:52.754 | | OS | Новая Sell сделка 458811275 по цене 140650 на 1 заявки 47354466.
13:09:52.755 | | OS | Новая Sell сделка 458811276 по цене 140650 на 1 заявки 47354467.
13:09:52.755 | | OS | Новая Sell сделка 458811277 по цене 140650 на 1 заявки 47354468.
13:09:52.755 | | OS | Новая Sell сделка 458811278 по цене 140650 на 1 заявки 47354470.
13:09:52.756 | | OS | Новая Sell сделка 458811279 по цене 140650 на 1 заявки 47354471.
13:09:52.756 | | OS | Новая Sell сделка 458811280 по цене 140650 на 1 заявки 47354473.
13:09:52.756 | | OS | Новая Sell сделка 458811281 по цене 140650 на 1 заявки 47354474.
Спасибо:

frontman

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


Сколько контрактов у вас в первоначальной заявке?
Спасибо:

profts

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


Да объем везде 1 контракт... Да и на покупку выставляется только одна заявка order_buy1...

Может причина в том, что условия if внутри метода raschet, который вызывается по событию:

Цитата:

protected override void OnStarting()
{
this
.When(base.Security.Changed())
.Do(raschet);
base.OnStarting();
}
Автор топика
Спасибо:

frontman

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


Ну могу вам сказать что это правило я сам лично использую и оно 100% верно. Ищите ошибку в логике программы самой.
Спасибо:

profts

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


Ну собственно вот вся логика:

Цитата:




protected override void OnStarting()
{
this
.When(base.Security.Changed())
.Do(raschet);
base.OnStarting();
}

private void raschet()
{
...
//расчет условия на сделку
...
if (position == 0)
{
if (условие на сделку)
{
position = 1;
order_buy1 = this.CreateOrder(OrderDirections.Buy, base.Security.GetMarketPrice(OrderDirections.Buy), 1);
this.RegisterOrder(order_buy1);
};
};

if (position == 1)
{
this
.When(order_buy1.NewTrades())
.Do(Takeprofit1);
}
}

private void Takeprofit1()
{
order_takeprofit1 = this.CreateOrder(OrderDirections.Sell, order_buy1.Price + 45, 1);
this.RegisterOrder(order_takeprofit1);
position = 2;
}


Автор топика
Спасибо:

frontman

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


Давай те вы так сделаете : В методе OnStarting()
Оставите только
this.AddInfoLog("Создаю");
order_buy1 = this.CreateOrder(OrderDirections.Buy, base.Security.GetMarketPrice(OrderDirections.Buy), 1);
this
.When(order_buy1.NewTrades())
.Do(() => this.AddInfoLog("Новая сделка"));
this.AddInfoLog("Регистрирую");
this.RegisterOrder(order_buy1);

И выложите здесь полученные в результате логи.
Спасибо:

profts

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


Сделал...


Цитата:

15:27:53.484 | | OS | Стратегия запущена.
15:27:53.493 | | OS | Создаю
15:27:53.501 | | OS | Регистрирую
15:27:54.061 | | OS | Новая Buy сделка 459004723 по цене 140345 на 1 заявки 55665883.
15:27:54.074 | | OS | Новая сделка
Автор топика
Спасибо:

profts

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


А вообще может быть, что событие
.When(base.Security.Changed())
.Do(raschet);

возникает очень часто и вызывается одновременно в нескольких потоках и из разных потоков выставляется тэйк?
Автор топика
Спасибо:

profts

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


и еще добавил логи след. образом:

Цитата:

if (position == 0)
{
if (условие на сделку)
{
position = 1;
order_buy1 = this.CreateOrder(OrderDirections.Buy, base.Security.GetMarketPrice(OrderDirections.Buy), 1);
this.RegisterOrder(order_buy1);
};
};

if (position == 1)
{
this.AddInfoLog("pos = 1");
this
.When(order_buy1.NewTrades())
.Do(Takeprofit1);
}
}

private void Takeprofit1()
{
this.AddInfoLog("создается тэйк");
order_takeprofit1 = this.CreateOrder(OrderDirections.Sell, order_buy1.Price + 45, 1);
this.RegisterOrder(order_takeprofit1);
position = 2;
this.AddInfoLog("pos=2");
}


В итоге получаю следующий лог:

Цитата:

15:36:36.917 | | OS | Стратегия запущена.
15:37:05.590 | | OS | pos = 1
15:37:05.917 | | OS | pos = 1
15:37:06.686 | | OS | pos = 1
15:37:06.794 | | OS | pos = 1
15:37:07.224 | | OS | pos = 1
15:37:08.215 | | OS | pos = 1
15:37:08.242 | | OS | Новая Buy сделка 459012183 по цене 140190 на 1 заявки 56189139.
15:37:08.254 | | OS | pos = 1
15:37:08.255 | | OS | создается тэйк
15:37:08.255 | | OS | pos=2
15:37:08.255 | | OS | создается тэйк
15:37:08.255 | | OS | pos=2
15:37:08.255 | | OS | создается тэйк
15:37:08.256 | | OS | pos=2
15:37:08.256 | | OS | создается тэйк
15:37:08.256 | | OS | pos=2
15:37:08.256 | | OS | создается тэйк
15:37:08.256 | | OS | pos=2
15:37:08.256 | | OS | создается тэйк
15:37:08.256 | | OS | pos=2
15:37:10.644 | | OS | Новая Sell сделка 459012259 по цене 140235 на 1 заявки 56189140.
15:37:10.645 | | OS | Новая Sell сделка 459012260 по цене 140235 на 1 заявки 56189141.
15:37:10.645 | | OS | Новая Sell сделка 459012261 по цене 140235 на 1 заявки 56189142.
15:37:10.645 | | OS | Новая Sell сделка 459012262 по цене 140235 на 1 заявки 56189143.
15:37:10.878 | | OS | Новая Sell сделка 459012268 по цене 140235 на 1 заявки 56189144.
15:37:10.878 | | OS | Новая Sell сделка 459012269 по цене 140235 на 1 заявки 56189145.

Автор топика
Спасибо:

kenota

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


profts: Ваш метод raschet() откуда вызывается? :)
Спасибо:

profts

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


Цитата:

Ваш метод raschet() откуда вызывается? :)


protected override void OnStarting()
{
this
.When(base.Security.Changed())
.Do(raschet);
base.OnStarting();
}
Автор топика
Спасибо:

kenota

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


Может быть в этом проблема, два потока могут одновременно зайти и оба прочитать что position = 0 и поставить ордер.

Что же касается вызовов метода NewTrades несколько раз, попробуйте вместо него использовать событие ордера Matched. Т.е. this.When(order_buy1.Matched()).Do(TakeProfit1);
Спасибо:

frontman

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


profts Перейти
Сделал...


Цитата:

15:27:53.484 | | OS | Стратегия запущена.
15:27:53.493 | | OS | Создаю
15:27:53.501 | | OS | Регистрирую
15:27:54.061 | | OS | Новая Buy сделка 459004723 по цене 140345 на 1 заявки 55665883.
15:27:54.074 | | OS | Новая сделка

Это говорит о том что событие не генерируются несколько раз...
Спасибо:

profts

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


Цитата:

Может быть в этом проблема, два потока могут одновременно зайти и оба прочитать что position = 0 и поставить ордер.

Цитата:

Это говорит о том что событие не генерируются несколько раз...


Видимо так и есть... NewTrades генерируется один раз, но одновременно в разных потоках. )

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

Тогда встает вопрос как это можно обойти, если расчет у меня происходит с частотой появления новых сделок и на основе него появляется условие на совершение сделки. Мне казалось, что .When(base.Security.Changed()) .Do(raschet); выполняется следующий раз только после того, как заканчивается предыдущий расчет, а не одновременно в нескольких потоках.
Автор топика
Спасибо:

frontman

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


В смысле одновременно в разных потоках?
Оно генерируется столько раз сколько вы на него подписались.
Если я напишу вот так

his
.When(order_buy1.NewTrades())
.Do(Takeprofit1);
his
.When(order_buy1.NewTrades())
.Do(Takeprofit1);

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

kenota

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


Внутри метода raschet делайте все в блоке блокировки, например lock(this)
Спасибо:

frontman

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


base.Security.Changed() - вообще какое то странное правило.
Вам что нужно ловить новые сделки по инструменту?Тогда исп Security.SecurityNewTrades()
Спасибо:

frontman

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


kenota Перейти
Внутри метода raschet делайте все в блоке блокировки, например lock(this)

Почитайте MSDN по поводу этого оператора.
lock(this) - вообще не самый хороший вариант.
Спасибо:
1 2  >

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

loading
clippy