Не получается получить BestAsk и BestBid цены
Atom Ответить
24.02.2015


Написал небольшую программу, которая коннектится к Quik, подгружает мои портфели и два необходимых мне инструмента: VTBR и SBER, а так же позволяет купить/продать данные бумаги по рынку.

Все было хорошо, пока мне не понадобились BestAsk.Price и BestBid.Price. Причем чтобы я не делал: пытался присвоить цену переменной или купить/продать по бестбид/аск цене - получаю ошибку:

Error

Вот мой код, что я делаю не так?

Код
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Net;
using System.Security;

using MoreLinq;

using Ecng.Common;
using Ecng.Collections;
using Ecng.ComponentModel;
using Ecng.Serialization;
using Ecng.Xaml;

using StockSharp.Quik;
using StockSharp.Algo;
using StockSharp.BusinessEntities;
using StockSharp.Fix;
using StockSharp.Logging;
using StockSharp.Messages;
using StockSharp.Quik.Lua;


namespace Robot
{    
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        
        private static Security _sber;
        private static Security _vtbr;                
        private QuikTrader CommonRobot1;
        
        private void Connect_Click(object sender, RoutedEventArgs e)
        {
            CommonRobot1 = new QuikTrader
            {
                LuaFixServerAddress = "127.0.0.1:5001".To<EndPoint>(),
                LuaLogin = "quik",
                LuaPassword = "quik".To<SecureString>()
            };            

            CommonRobot1.NewPortfolios += portfolios => this.GuiAsync(() =>
                {
                    portf.ItemsSource = CommonRobot1.Portfolios;                    
                });
            
            CommonRobot1.NewSecurities += securities => this.GuiAsync(() =>
            {                
                _sber = securities.FirstOrDefault(s => s.Id == "SBER@TQBR");
                _vtbr = securities.FirstOrDefault(s => s.Id == "VTBR@TQBR");                
                financial.Items.Add(_sber);
                financial.Items.Add(_vtbr);                
            });

            CommonRobot1.Connected += () =>
            {
                CommonRobot1.StartExport();
            };

            CommonRobot1.Connect();
        }

        private void Buy_Click(object sender, RoutedEventArgs e)
        {
            int vol;

            if (String.IsNullOrEmpty(volume.Text))
                vol = 1;
            else
                vol = int.Parse(volume.Text);

            var order = new Order
            {
                Portfolio = (Portfolio)portf.SelectedItem,
                Security = _vtbr, //(Security)financial.SelectedItem,
                Volume = vol,
                Price = _vtbr.BestBid.Price,
                //Type = OrderTypes.Market,
                Direction = Sides.Buy,
            };

            CommonRobot1.RegisterOrder(order);
        }

        private void Sell_Click(object sender, RoutedEventArgs e)
        {
            int vol;

            if (String.IsNullOrEmpty(volume.Text))
                vol = 1;
            else
                vol = int.Parse(volume.Text);

            var order = new Order
            {
                Portfolio = (Portfolio)portf.SelectedItem,
                Security = (Security)financial.SelectedItem,
                Volume = vol,
                Type = OrderTypes.Market,
                Direction = Sides.Sell,
            };

            CommonRobot1.RegisterOrder(order);
        }        
    }
}

Теги:


Спасибо:




13 Ответов
RomSunZ

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


Примеры смотрите. Ваши инструменты не подписаны на рыночные данные.
Спасибо:

Zabik

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


RomSunZ Перейти
Примеры смотрите. Ваши инструменты не подписаны на рыночные данные.


Примеры я смотрю, правда верить им или нет - не знаю. они все-равно не работают. В одних примерах никто на рыночные данные не подписывается, в других подписываются, но и там и там используют BestBid/Ask Confused

Пробовал я уже много чего, вот например так:

Код
CommonRobot1.NewSecurities += securities => this.GuiAsync(() =>
            {
                _sber = securities.FirstOrDefault(s => s.Id == "SBER@TQBR");
                _vtbr = securities.FirstOrDefault(s => s.Id == "VTBR@TQBR");
                financial.Items.Add(_sber);
                financial.Items.Add(_vtbr);
                if (_sber != null)
                {
                    CommonRobot1.RegisterMarketDepth(_sber);
                    CommonRobot1.RegisterSecurity(_sber);
                    var pri = _sber.BestAsk.Price;
                }
                if (_vtbr != null)
                {
                    CommonRobot1.RegisterSecurity(_vtbr);
                }
            });


С той же ошибкой во время выполнения выделяет строчку var pri = _sber.BestAsk.Price;

Читаю букварь: "RegisterSecurity - метод. Начать получать новую информацию (например, LastTrade или BestBid) по инструменту."

Подскажите по крайней мере причину ошибки. Я так понимаю, что в моем случае BestAsk так и остается равным null, поэтому и ошибка выскакивает? Пробовал так же подписываться и на обновления стакана, присваивал переменной значение внутри него - та же ошибка Crying .

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

Zabik

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


Ну да, так и есть, написал следующее:

Код
CommonRobot1.NewSecurities += securities => this.GuiAsync(() =>
            {
                _sber = securities.FirstOrDefault(s => s.Id == "SBER@TQBR");
                _vtbr = securities.FirstOrDefault(s => s.Id == "VTBR@TQBR");
                financial.Items.Add(_sber);
                financial.Items.Add(_vtbr);
                if (_sber != null)
                {
                    CommonRobot1.RegisterMarketDepth(_sber);
                    CommonRobot1.RegisterSecurity(_sber);
                    if (_sber.LastTrade != null)
                    {
                        var pri = _sber.LastTrade.Price;
                        info2.Content = pri.ToString();
                    }

                }
                if (_vtbr != null)
                {
                    CommonRobot1.RegisterSecurity(_vtbr);
                }
            });


Теперь ошибки нет, но и цен нет, значит _sber.LastTrade так и остается равным null Laugh . Plz help!
Автор топика
Спасибо:

Иван З.

Фотография
Курсы Автор статей Благотворитель
Дата: 25.02.2015
Ответить


подпишитесь на
Код
CommonRobot1.SecuritiesChanged+= securities =>

и там поищите, может поможет.
Спасибо:

Zabik

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


Иван З. Перейти
подпишитесь на
Код
CommonRobot1.SecuritiesChanged+= securities =>

и там поищите, может поможет.


Не помогло Blushing Заметил, что ошибка отсутствует, если просить не BestBid.Price, а например _sber.Volume, но выдает все-равно 0
Автор топика
Спасибо:

RomSunZ

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


Запустите пример quik sample и если там все работает (получение последней сделки и лучшие цены), посмотрите код и перенесите его в свой робот.
Спасибо: Zabik

Zabik

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


RomSunZ Перейти
Запустите пример quik sample и если там все работает (получение последней сделки и лучшие цены), посмотрите код и перенесите его в свой робот.


Так, ну вот уже что-то BigGrin , спасибо! По дефолту подкачивается всего 5 параметров по инструменту, а вот после нажатия кнопки level1 по выбранному инструменту подкачиваются и остальные параметры и стакан. Конечно при разборе этого примера я не обращал внимания на эту кнопку, щас посмотрю что там спрятано Cool
Автор топика
Спасибо:

Zabik

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


Так, ну нового там ничего нет. Все как и у меня:

Код
CommonRobot1.RegisterSecurity(_usd);
                    CommonRobot1.RegisterTrades(_usd);


В общем поковырялся, вроде заработало, но пока в основном возвращает нули, может потому что биржа уже не работает - завтра посмотрим. А вообще так до конца и не понятно, почему ошибка вылазит именно на BestBid.Price а на просто BestBid нет?

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

RomSunZ

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


Zabik Перейти
Так, ну нового там ничего нет. Все как и у меня:

Код
CommonRobot1.RegisterSecurity(_usd);
                    CommonRobot1.RegisterTrades(_usd);


В общем поковырялся, вроде заработало, но пока в основном возвращает нули, может потому что биржа уже не работает - завтра посмотрим. А вообще так до конца и не понятно, почему ошибка вылазит именно на BestBid.Price а на просто BestBid нет?

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


Потому что у Вас BestBid==null
Спасибо:

Zabik

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


RomSunZ Перейти

Потому что у Вас BestBid==null


Поковырявшись понял что так и есть. Но вот почему не могу понять. Blushing

От безисходности перепахал под себя пример Sample. Все работает, все цены, объемы и т.п. в таблицу SecurityPicker идут, но видимо с помощью какого-то волшебства, т.к. тут же рядом с этой таблицей пытаюсь вбить в текстбокс _sber.LastTrade.Price и опять эта ошибка, и потому что LastTrade == null. Но как он может быть пустым если в таблицу рядом вот они идут значения по последним сделкам я не понимаю. Cursing

Подскажите, может есть какая-то возможность взглянуть на код этой волшебной таблицы SecurityPicker?
Автор топика
Спасибо:

Иван З.

Фотография
Курсы Автор статей Благотворитель
Дата: 02.03.2015
Ответить


Спасибо: Zabik

Zabik

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


Ну что же, получилось с горем пополам, и то через одно место:

Код
private void _result_Click(object sender, RoutedEventArgs e)
        {
            var security_sber = SecurityPicker.Securities.FirstOrDefault(s => s.Id == "SBER@TQBR");
            _lasttrade_sber.Text = security_sber.LastTrade.Price.ToString();
            var security_vtbr = SecurityPicker.Securities.FirstOrDefault(s => s.Id == "VTBR@TQBR");
            _lasttrade_vtbr.Text = security_vtbr.LastTrade.Price.ToString();
        }


Т.е. цепляю дынные из самой таблицы (как они там появляются для меня остается загадкой). Осталось теперь понять куда запихать этот код, чтобы данные приходили в реальном времени, а не только на момент нажатия _result.
Автор топика
Спасибо:

Zabik

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


Все, всем спасибо!

Код

private void _result_Click(object sender, RoutedEventArgs e)
        {
            var trader = MainWindow.Instance.Trader;
            trader.MarketDepthsChanged += depths => this.GuiAsync(() =>
            {
                depths.ForEach(d =>
                {
                    var security_sber = SecurityPicker.Securities.FirstOrDefault(s => s.Id == "SBER@TQBR");
                    _lasttrade_sber.Text = security_sber.LastTrade.Price.ToString();
                    var security_vtbr = SecurityPicker.Securities.FirstOrDefault(s => s.Id == "VTBR@TQBR");
                    _lasttrade_vtbr.Text = security_vtbr.LastTrade.Price.ToString();
                });
            });
            
        }


Не знаю как, но работает правильно. Так что даже разбираться не буду Laugh
Автор топика
Спасибо:


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

loading
clippy