Выводится в логи следующая ошибка (правильно я понял, что логируется только то, что описывается через AddLog()) :
IS_01:00:10 10:12:00.1564059 Стратегия запущена.
IS_01:00:10 16:00:01.3877441 Регистрация заявки - цена 193245, направление Buy, объем 5
IS_01:00:10 16:00:02.9208318 Прошла сделка по цене 192375, объём 5, направление Buy.
IS_01:00:10 16:00:02.9618341 Регистрация стоп-лосс по цене 190550
IS_01:00:10 16:00:02.9618341 Регистрация тейк-профит по цене 192640
BS 16:00:02.9628342 Стратегия запущена.
BS 16:00:02.9628342 Стратегия запущена.
TPS 16:00:02.9628342 Стратегия запущена.
SLS 16:00:02.9628342 Стратегия запущена.
TPS 18:45:25.8543911 [h]System.ArgumentException: Коллекция котировок пуста.
Имя параметра: quotes
в Ecng.Trading.Algo.TraderHelper.GetFilteredQuotes(IEnumerable`1 quotes, Order currentOrder)
в Ecng.Trading.Algo.TraderHelper.GetFilteredQuotes(MarketDepth depth, OrderDirections orderDirection, Order currentOrder)
в Ecng.Trading.Algo.TraderHelper.GetFilteredQuotes(Security security, OrderDirections orderDirection, Order currentOrder)
в Ecng.Trading.Algo.Strategies.ProtectiveStrategy.GetNewPrice()
в Ecng.Trading.Algo.Strategies.TakeProfitStrategy.CanRegister()
в Ecng.Trading.Algo.Strategies.QuotingStrategy.OnProcess()
в Ecng.Trading.Algo.Strategies.Strategy.#=qnMN_PMdUfHysEK$_tfQ8grn_QTjzOIMGPiv$tYCH2Bw=.#=q3rD2zIrUx4ViUbhRH66B2w==()[/h]
TPS 18:45:25.8543911 Стратегия останавливается.
SLS 18:45:25.8543911 System.ArgumentException: Коллекция котировок пуста.
Имя параметра: quotes
в Ecng.Trading.Algo.TraderHelper.GetFilteredQuotes(IEnumerable`1 quotes, Order currentOrder)
в Ecng.Trading.Algo.TraderHelper.GetFilteredQuotes(MarketDepth depth, OrderDirections orderDirection, Order currentOrder)
в Ecng.Trading.Algo.TraderHelper.GetFilteredQuotes(Security security, OrderDirections orderDirection, Order currentOrder)
в Ecng.Trading.Algo.Strategies.ProtectiveStrategy.GetNewPrice()
в Ecng.Trading.Algo.Strategies.StopLossStrategy.CanRegister()
в Ecng.Trading.Algo.Strategies.QuotingStrategy.OnProcess()
в Ecng.Trading.Algo.Strategies.Strategy.#=qnMN_PMdUfHysEK$_tfQ8grn_QTjzOIMGPiv$tYCH2Bw=.#=q3rD2zIrUx4ViUbhRH66B2w==()
SLS 18:45:25.8543911 Стратегия останавливается.
TPS 18:45:26.8554483 Котирование закончилось.
TPS 18:45:26.8564484 Стратегия остановлена.
SLS 18:45:26.8574485 Котирование закончилось.
SLS 18:45:26.8574485 Стратегия остановлена.
BS 18:45:26.8794497 Стратегия останавливается.
BS 18:45:27.8795069 Стратегия остановлена.
BS 18:45:27.8795069 Стратегия останавливается.
BS 18:45:28.8795641 Стратегия остановлена.
Стратегии регистрирую как в примере:
private void OnNewMyTrades(IEnumerable<MyTrade> trades)
{
foreach (var trade in trades)
{
AddLog(StrategyErrorStates.None, "Прошла сделка по цене {0}, объём {1}, направление {2}.",
trade.Trade.Price, trade.Trade.Volume, trade.Order.Direction);
}
// фильтруем сделки, чтобы найти те, которые произошли для заявки TargetOrder// сделать проверку не на последнюю заявку а на все заявки которые
trades = trades.Where(t => t.Order == TargetOrder);
// если не найдена ни одна сделка для заявки TargetOrder
if (trades.Count() == 0)
return;
// сама пакетная стратегия так же является параллельной, чтобы она не блокирована основной код робота
var batch = new BatchStrategy(BatchFinishModes.All) { IsParallel = true };
// для каждой сделки добавляем для защиты по пакетной стратегии
batch.ChildStrategies.AddRange(trades.Select(t =>
{
var s = new BatchStrategy(BatchFinishModes.First) { IsParallel = true };
// выставляет тейк-профит в N пунктов
var takeProfit = new TakeProfitStrategy(t,new Unit((decimal)Fractal.Up) + _takeDelta.Pips(Security));
// выставляет стоп-лосс в M пунктов
var stopLoss = new StopLossStrategy(t, new Unit((decimal)Fractal.Down) - _stopDelta.Pips(Security));
takeProfit.PriceDelta=stopLoss.PriceDelta = _priceDelta;
// делаем стратегии параллельными, чтобы они не блокировали работу контролирующей BatchStrategy
takeProfit.IsParallel = stopLoss.IsParallel = true;
s.ChildStrategies.Add(takeProfit);
s.ChildStrategies.Add(stopLoss);
AddLog(StrategyErrorStates.None, "Регистрация стоп-лосс по цене {0}", stopLoss.ProtectiveDelta);
AddLog(StrategyErrorStates.None, "Регистрация тейк-профит по цене {0}", takeProfit.ProtectiveDelta);
return s;
}).Cast<Strategy>());
if (batch.ChildStrategies.Count > 0)
{
base.ChildStrategies.Add(batch);
}
TargetOrder = null;
}
Заявки выставляю лимитированные через base.RegisterOrder(order).Процесс получения стакана происходит - _trader.RegisterQuotes(_strategy.Security). Что я неправильно делаю? Спасибо
Комментарии (64)
Вход или Создать аккаунт, Войдите или зарегистрируйтесь, чтобы оставить комментарий
Перед запуском стратегии проверьте стакан.
Да я проверил, экспорт происходит
Заявка зарегистрированная через котирование исполняется,
А добавление стратегии и регистрация заявки через базовый класс не влияет на получение информации со стакана?
if (_strategy.ProcessState == StrategyProcessStates.Stopped) { // запускаем процесс получения стакана, необходимый для работы алгоритма котирования _trader.RegisterQuotes(_strategy.Security); _strategy.Start(); this.Start.Content = "Стоп"; }
if (_strategy.ProcessState == StrategyProcessStates.Stopped) { // запускаем процесс получения стакана, необходимый для работы алгоритма котирования _trader.RegisterQuotes(_strategy.Security); _strategy.Start(); this.Start.Content = "Стоп"; }
Помогите, пожалуйста, разобраться 🤔 Наверника ж кто-то сталкивался с такой же проблемой, код из примера...
А в чем проблема?
Как сделать, чтобы стакан заполнялся и защитные стратегии отрабатывали и не выдавали ошибку, которую я описал выше. Я сделал проверку при запуске экспорта стакана, но чего-то я не уверен, что правильно. Проверку нужно делать в событии QuotesChanged? И что нужно сделать, если не пришел стакан, чтобы выполнились защитные стратегии?😊
Запустите и проверьте.
Это как?
Если нет стакана, то какой смысл защищать (нет ни продавцов, ни покупателей)? Вы на неликвиде работаете?
Проверка проходит, а ситуацию, чтобы сработал стоп еще не отлавил.
Это мои предположения ничем не подкрепленные🙂
Я запускаю стратегию для Rim1. И еще повторюсь, что когда заявку выставляю через котирование, она исполняется, значит стакан грузится, как я понял. Но я выставляю лимитировано, заявка исполняется, а защитные стратегии выдают ошибку, что коллекция котировок пуста... Информация по стакану с одного места берется?
Стакан не успевает прийти.
А как сделать, чтобы успевал или хотя бы отрабатывали с задержкой защитные стратегии?
Запускать стакан раньше стратегий.
Михаил, запускаю стакан сразу после того как экспорт дде закончен и определен инструмент
А стратегию уже потом при нажатии на кнопку. Но все равно та же ошибка вознкикает :(
Пробовал также ставить задержку, но та же ошибка...
Проверьте, событие ITrader.QuotesChanged передается стакан для RIM1.
Да, в коллекции MarketDepth есть один стакан для инструмента RIM1.
А эти записи идентичны?
_trader - это RealTimeTestTrader.
_trader.QuotesChanged += Trader_QuotesChanged; _trader.Trader.QuotesChanged += Trader_QuotesChangedReal;
_trader.QuotesChanged += Trader_QuotesChanged; _trader.Trader.QuotesChanged += Trader_QuotesChangedReal;
Она не меняет ничего. Просто она мне покажет, что вы там такого понаписали и почему не работает.🙂
И не говорите, написал теперь вот покоя людям не даю 🙂 Ну тогда получается, что ситуация останется той же... А сообщение я вывел так
Так регистрацию стакана нужно делать до запуска стратегии, а насколько до по времени? И принципиально ли место регистрации стакана, если я зарегистрирую ее в Running? Я уже думаю может причина не в том что стакан не приходит, а в самих защитных стратегиях. Может ли повлиять то, что я не снимаю стратегию, после того как сделка совершится по сигналу?
Михаил, я кажется понял, почему происходит эта ошибка:
TPS <mark>14:11:52</mark>.7958984 System.ArgumentException: Коллекция котировок пуста. Имя параметра: quotes....
TPS <mark>18:45:26</mark>.1187618 System.ArgumentException: Коллекция котировок пуста. Имя параметра: quotes...
Стратегии продолжают работать во время клиринга, собственно, когда стакан пуст. Но тогда вопрос, как сделать, чтобы защитные стратегии не работали в это время? Для базовой стратегии условие на время работы выставлено в OnProcess()
Хелп ми плиз
Есть стратегия на S#, которая работает только при наличие стакана. Стакан отсутствует. Но торговать все равно хотите. Вывод, или вам нужна другая стратегия, или доводите до ума эта. OnProcess правильно переопределили. Видимо нужно что-то еще.
Спасибо, я так и сделал, тестирую
А как задать время работы защитных стратегий в версии 3.2.5? До этого я переопределял OnProcess и там указывал.
Через When \ Do в When - указывайте время когда не хотите чтобы ваша стратегия работала
А как через MarketTimeChanged можно? Мой вариант не работает, потому что коллекция ChildStrategies изменяется во время проверки
_trader.MarketTimeChanged += () => this.GuiAsync(() => { if (_strategy != null) { if (_strategy.ChildStrategies.Count != 0) if (_security.Exchange.IsTradeTime(_trader.MarketTime) == false) { foreach (var s in this._strategy.ChildStrategies.Where(s => s.ProcessState == StrategyProcessStates.Runned)) s.Stop(); } else foreach (var s in this._strategy.ChildStrategies.Where(s => s.ProcessState == StrategyProcessStates.Stopped)) s.Start(); } });
Возникает ошибка при логировании
for (int i = 0; i < base.ChildStrategies.Count; i++) { [h]AddLog(StrategyErrorStates.None, "Удаление стратегии {0}", base.ChildStrategies[i].Name);[/h] base.ChildStrategies.RemoveAt(i); }
Возникает ошибка при логировании
for (int i = 0; i < base.ChildStrategies.Count; i++) { [h]AddLog(StrategyErrorStates.None, "Удаление стратегии {0}", base.ChildStrategies[i].Name);[/h] base.ChildStrategies.RemoveAt(i); }
А судя по стэктрэйсу - ошибка вовсе не при логировании: Цитата: в Ecng.Collections.SynchronizedSet
1.System.Collections.Generic.IList<T>.get_Item(Int32 index) в Ecng.Collections.BaseCollection1.get_Item(Int32 index) в SampleSma.SmaStrategy.OnNewMyTrades(IEnumerable`1 trades) в D:\StockSharp_3.2.7_Sources\SmaStrategy.cs:строка 217судя по всему - это что-то ваше, внутреннее. в исходниках в SmaStrategy.cs заметно меньше строчек :)
Да, пример переделанный, Александр, вы прям Шерлок Хомс :) я добавил в OnNewMyTrades обработку защитных стратегий. Так, а в чем ошибка, я тогда не понимаю...
Как я выяснил сейчас, ошибка возникает и в строке ```csharp AddLog(StrategyErrorStates.None, "Удаление стратегии {0}", base.ChildStrategies[i].Name);
Метод есть, но он не поддерживается... При чем я помню, что в какой-то версии S# этот код работал...
что у вас на 217 строчке файла?
В 3.2.9 ошибка осталась?
А уже есть 3.2.9? На боксе и на кодплех не вижу...
Скоро будет 😎 Поспешил я.
Ошибка осталась.
Да, нет доступа по [] и GetItem не поддерживается. А сильно надо?
Собственно задача в том, чтобы защитные стратегии выставленные при покупке удалить после сделки продажи на основе сигнала. Может как-то это можно сделать по другому?
Так они автоматом удаляются :)
Ситуация. Сигнал на покупку. Покупка. Создание защитной стратегии. Сигнал на продажу (защитная стратегия не начала свою работу). Продажа. В такой ситуации защитная стратегия автоматически удаляется?
А еще я получил такой лог, но может он уже не актуальный (в.3.2.7). Тут защитная стратегия продолжает свою работу несколько раз.
Так защитная стратегия автоматически удаляется после сделки на продажу, даже если не сработала?
Защитная стратегия (пара СЛ + ТП) удаляется тогда, когда одна из них закончила свою работу (выставила заявку и по ней была совершена сделка).
Ну значит я все правильно понял. Так а ак тогда удалить стратегию если она не закончила свою работу?
Остановить ее через метод Stop.
Ну она же в коллекции останется?
У меня идет проверка для защитных стратегий, чтобы они в не торговое время отключались, а в торговое включались. Получается включатся все стратегии в коллекции, когда нужны только последние.
Запомните какие стратегии надо включать, какие - нет. Зачем отключать стратегии в не торговое время?
Ну как я понял защитные стратегии продолжают работать во время клиринга, собственно, когда стакан пуст. И возникает ошибка, о чем я писал выше.
Защитные стратегии могут работать без использования стакана?
Исправил, такой ошибки больше не будет. Спасибо за фидбэк
Пожалуйста 🙂 Так, а как мне быть с проверкой? Что конкретно вы исправили?
Не будет эксепшена во время клиринга на тему пустой коллекции. Вам же ничего не надо делать, никаких проверок.
Получаю такой лог
Я останавливаю защитную стратегию через метод Stop(), а она все равно продолжает выставлять заявку... Почему?
Получаю такой лог
Я останавливаю защитную стратегию через метод Stop(), а она все равно продолжает выставлять заявку... Почему?
А что за Стратегия-1? Покажите где и как останавливаете. Какая версия S#?
Версия 3.2.10
Публиковал код и видимо случайно удалил собственно строчку - base.ChildStrategies.Stop();
Распечатайте ProcessState до и после этой строчки.
Чего то, так и не получилось отловить это место. Но вот при отработке тейк-профита один раз, он потом отрабатывает еще раз. Может я что-то не так делаю(
Вот лог:
А вот код:
Какая версия? Если не 4.0.0 - попробуйте её.
Попробовал 4.0.0
Получил такой лог:
Не понятно происхождение ошибки связанной с кросс-заявкой, на момент выставления заявки 12:40:02.118 никаких других заявок не было в квике, почему так происходит?
Вторая ошибка возникла в этом участке кода:
Получается ошибка возникла либо в ChildStrategies.ProcessState, либо base.ChildStrategies.Stop();
Собственно может из-за того, что вы писали "Да, нет доступа по [] и GetItem не поддерживается..."
Да, доступ по [] не поддерживается, уже обсуждалось.
По поводу кросс-заявок - поискал в гугле, наткнулся на наш же топик ну и как обычно на форуме квика. в общем проблема не со стороны S#.
Я читал на форуме, но там реально ставится вопрос, когда есть заявка и выставляется еще одна. А у меня не было никаких противоположных, вообще никаких не было. Ну раз разработчики говорят что проблема не со стороны S#, значит тому и быть 🙂
А вот про защитные стратегии запутался.
Мне нужно было их удалять или останавливать. Выяснилось, что удалить не получится, нужно использовать метод Stop(). Я его использовал, но защитная стратегии создавала две заявки на продажу. Вы посоветовали:
Alexander;10250 написал: Евгений;10248 написал: Публиковал код и видимо случайно удалил собственно строчку - base.ChildStrategies.Stop(); Распечатайте ProcessState до и после этой строчки.
Я пытаюсь распечатать, но возникает ошибка System.NotSupportedException: Указанный метод не поддерживается.
А как тогда проверить, остановились ли стратегии?
по поводу кроссзаявок может проблема быть на стороне брокера. у некоторых реализован механизм исполнения кросссделок между субсчетами, у некоторых нет(в основном у мелких)
У того же Открытия 100% запрещены кросс-сделки по разным субсчетам. Сам с этим сталкивался пару раз. Лучше этот вопрос уточнить непосредственно у брокера - почему не прошла сделка.
Это демо-счет, но думаю есть смысл все-равно спросить.
Так, а как все-таки проверить останавливается стратегия или нет?