Управление стаканом котировок
Atom Ответить
30.03.2010


Добрый день, Михаил! Как-то заметил, что стакан котировок отображается
не совсем правильно - цена почему-то не снижается сверху вниз по всей
глубине, а начинается с мимнимальной котировки и повышается сверху
вниз по "биду", а в месте где начинается "аск" "переворачивается и
снова начинается с самой маленькой котировки "аск" и так повышается до
самого низа. Думал отсортировать данные на этапе прихода данных:

this.Trader.ProcessWellKnownDdeData += (name, dict) =>
// узнаем, что пришедшие данные отвечают за стакан
if (name.Contains("stock"))
// первичная сортировка по цене
IEnumerable<Quote> _curquotes = (IEnumerable<Quote>)dict;
_curquotes = _curquotes.OrderBy(t => t.Price);
... и т.д.

но это ни к чему не привело. Подскажите, пожалуйста, как правильно
отсортировать данные?

Еще здесь был как-то уже вопрос про доступ к отдельным значениям
котировок в стакане, но объяснения я так и не нашел. Как же все-такии
это можно сделать (получить значение той или иной котировки в стакане
для анализа)?

Теги:


Спасибо:




82 Ответов
< 1 2 3 4  >
Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 13.04.2010
Ответить


А какой текст транзакции пр которой возникает ошибка?

Спасибо:

ddd888

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


Текст такой (интересно, есть способ как-то его скопировать, чтобы не
переписывать? :)):

"ACCOUNT=SPBFUT...;CLIENT_CODE=XXX;TYPE=L;TRANS_ID=3;CLASSCODE=SPBFUT;SECCDE=GZM0;ACTION=NEW_ORDER;OPERATION=B;QUANTITY=10;PRICE=17331;EXECUTION_CONITION=PUT_IN_QUEUE;"

дальше идут:

в [] [] (Int32 [],StringBuilder [])
в [] [] (String[], OrderStatus& [], Int32&[], Double& [], Strng& []) и
т.д. там где [] - на самом деле квадратики...

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

ddd888

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


Поскольку используется одна и та же функция NewOrder, то должно быть
дело где-то в составляющих Order order, который параметром в
RegisterOrder отправляется? Как же на самом деле формируется класс
Order?

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

ddd888

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


Пооблему удалось решить, послав в мой класс с методом ссылку на весь
экземпляр Security и затем использовав его в формировании заявки. :)
Ключевой момент - оказалось, что для формировании заявки только
Security.code и Security.class - не достаточно. Что же там еще
используется? Т.е. предыдущий вопрос все-таки остается - как
формируется класс Order? Какие свойства Security он использует и как?

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

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 13.04.2010
Ответить


А если посмотреть под Debug режимом в студии эти свойства?

Спасибо:

ddd888

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


Да, что хорошо в Ваших уклончивых ответах - они стимулируют процесс
познания. :)) Хоролшо бы еще разобраться как это сделать. :) До сих
пор это слово - Debug - меня очень сильно пугало своей темной
непостижимостью. Наверное, по нему где-то и проходит водораздел между
настоящими программистами и любителями. :)

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

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 13.04.2010
Ответить


Ставится точка останова - F9. Запускается программа из студии через
F5. Все, работаете в программе до тез пор, пока не сработает точка.
Далее, на переменной мышкой и в контекстном меню выбираете нужное
действие.

Спасибо:

ddd888

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


Спасибо, оказывается эта техника и называется Debug. :) Все оказалось
не так страшно. Я и раньше этим пользовался. Правда, почему-то на
точке останова программа не всегда останавливается. Или я что-то не
учитываю ...

Есть такой вопрос. Стал переходить на 1.8. Выглядит еще более
интересным и навороченным вариантом и поэтому не стал лениться и
теперь все новые коды перевожу из 1.7 в 1.8. Вручную, правда, всегда
есть риск что-то забыть. Существует ли какой-то алгоритм
автоматического внесения изменений?

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

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 14.04.2010
Ответить


Автоматическое внесение изменений - это VS 2008 + руки. Это не шутка.
Хотя все не так страшно. Я перевел свои разработки практически за день
+ день тестирование.

Не увидел Вашего поста про ссылка на Security. Можете выделить в
простое приложение и прислать если не будет работать. Как вариант,
взять SampleConsonle

Спасибо:

ddd888

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


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

// создаем заявку
var order = base.CreateOrder(OrderDirections.Buy,
this.Price, base.Volume);
// регистрируем ее (обычным способом
лимитированной заявкой)
base.Trader.RegisterOrder(order);
// добавляем зарегистрированную заявку в стратегию
base.AddOrder(order);

т.е. все почти как в Вашем примере. Проверяю затем позицию:

Console.WriteLine(base.PositionManager.Position.ToString() + " | "+
this.PositionManager.Position.ToString());

и в итоге даже после совершения сделки там стоит "0". Почему так
происходит? Как правильно отследить совершенную сделку?

Потом почему-то Strategy начинает самопроизвольно делать "отмену
ордеров", которых и так нет, что приводит к появлению непрекрающегося
потока сообщений об исключении от квика: "нельзя отменить заявку". Что
может подавать такие заявки, base.AddOrder(order);?

Если включить сюда try{}catch{}, то такие сообщения исчезают.

Нет ли возможности узнать подробнее "устройство" класса Strategy?

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

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 15.04.2010
Ответить


1. А точно код base.PositionManager.Position вызывается после
появления в программе сделки? если вызывать в NewMyTrades?
2. Strategy - это абстрактный класс, не имеющий торговой реализации.
Он ни регистрирует, ни снимает заявки. Думаю, работает какой-то другой
код. try-catch что оборачивали?

Спасибо:

ddd888

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


1. Код base.PositionManager.Position стоит в методе OnProcess(). Как я
понял этот метод исполняется всякий раз с установленным интервалом (у
меня 1 сек). Если он исполняется, то ведь и
base.PositionManager.Position должен при каждой итерации
воспроизводить то значение, которое у него устанавлено данным
экземпляром стратегии? Может, я неправильно понимаю смысл слов
"появления в программе сделки", но мое понимание, на основании
предложенных примеров, такое:
а) появление в программе сделки = запуск NewMyTrades,
а) после запуска своей стратегии OnStrategyPropertyChanged меняет
соответствующие свойства экземпляра стратегии, в т.ч. и свойства
PositionManager.Position, которое должно обновляться после совершения
сделки,
б) _manager.Register(_strategy); запускает менеджер (правда, пока
совсем не понимаю, что он конкретно делает, но я старался максимально
придерживаться предложенного примера, поэтому оставил его в коде).

2. try-catch обернул первоначально base.Trader.RegisterOrder(order);
и base.AddOrder(order); но сейчас понял, что отмену заявок скорее
вызывает этот метод:

base.Orders.Where(o => o.State ==
OrderStates.Active).ForEach(base.Trader.GuarantyCancelOrder);

но ведь после совершения сделки в рамках стратегии в квике
OrderStates.Active должен меняться соответственно? Т.е. если сделка
фактически совершилась, то ведь кол-во активных заявок в стратегии
должно каждый раз обнуляться? А получается, что это не так - в
"активе" остается накопленное кол-во ОТПРАВЛЕННЫХ заявок, а это, как я
понимаю, не то, для чего создаваось свойство OrderStates.

Мне кажется нужны более подробные объяснения работы класса, чтобы им
можно было безопасно пользоваться. Или, как вариант, может, проще
просто привести его код? :)

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

ddd888

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


В инстуркции для примера у Вас написано: "Для учета общей прибыли-
убытка (P&L) в торговом роботе необходимо использовать дочерние классы
от BasePnLManager". В случае со стратегией - все понятно из примера. А
как использовать другие дочерние классы? Например, как с помощью
SecurityPnLManager рассчитать прибыль-убыток для конкретного
инструмента?

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

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 20.04.2010
Ответить


var manager = new SecurityPnLManager(security, trader);
manager.PnLChanged += ...

Спасибо:

ddd888

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


Спасибо. Наверное, следовало догадаться. :)
В форуме где-то был аналогичный вопрос и как я понял, Ваши классы -
менеджеры считают позиции только внутри дня. Т.е. они используют
только внтуридневные данные "всех сделок" и "моих сделок"?

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

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 20.04.2010
Ответить


Да.

Спасибо:

ddd888

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


Не получается запустить StrategyPositionManager в окне QuotesWindow.
Сделал так:

в поле:

private QuikTrader _trader = MainWindow.Instance.Trader;

в конструкторе:

SecurityPositionManager _secmanager = new
SecurityPositionManager(this.Security, _trader);
this.SecPos.Content = _secmanager.Position.ToString();
_secmanager.PositionChanged += new
Action(_secmanager_PositionChanged);

обработчик:

void _secmanager_PositionChanged()
{
this.SecPos.Content = _secmanager.Position.ToString();

но при любом раскладе _secmanager.Position.ToString(); показывает 0.
StrategyPositionManager при этом работает нормально. Что сделано
неправильно?

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

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 20.04.2010
Ответить


this.Sync видели в примере? Я описал зачем это нужно в разделе
Пользовательский интерфейс (GUI)

Спасибо:

ddd888

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


Не ругайтесь, я не программист, а только учусь. :)
Пример читал, но видимо не совсем понял как работает this.Sync так
скать физически. Если цель его - обновление пользовательского окна,
то
тогда я добавляю его к обработчику и получаю:

void _secmanager_PositionChanged()
{
this.Sync(() =>
{
this.SecPos.Content = _secmanager.Position.ToString();
});
}
Делаю тестовый трейд, но позиция по-прежнему - 0... :(

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

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 21.04.2010
Ответить


А событие PositionChanged срабатывает?
GetMyTrades(_secmanager.Security) что возвращает (скажем, если
вызывать из ITrader.NewMyTrades)?

Спасибо:

ddd888

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


Похоже, что не вызывается почему-то. А GetMyTrades вызывает исключение
"в экземпляре объекта не задана ссылка на объект", хотя _secmanager
создается при открытии окна.

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

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 21.04.2010
Ответить


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

Спасибо:

ddd888

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


Смотрю. При остановке программы в месте подписки на событие экземпляр
_secmanager = null. Как это может быть, не те аргументы при создании
SecurityPositionManager? Может, не тот шлюз? У меня шлюз тот же, что и
в начале программы Sample, т.е. MainWindow.Instance.Trader.

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

ddd888

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


Заметил, что в топике по аналогичному вопросу http://groups.google.ru/

group/stocksharp/browse_thread/thread/7334ab4cd0ed9bd9) уже задавлся
этот вопрос. Но Ваш ответ там касался добавления заявки в стретагию
(Strategy.AddOrder.), а вопрос был про SecurityPnLManager. Тогда такой
вопрос - чем работа SecurityPnLManager отличается от
StrategyPnLManager? Как я понимаю в случае с SecurityPositionManager и
StrategyPositionManager ситуация аналогичная?

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

ddd888

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


Все перепроверил еще раз: при создании экземпляра
SecurityPositionManager его свойство Security остается = null, хотя в
параметрах идет явная ссылка на экземпляр типа Security. Может, баг в
конструкторе SecurityPositionManager?

Автор топика
Спасибо:
< 1 2 3 4  >

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

loading
clippy