← Zurück

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

Написал небольшую программу, которая коннектится к 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);
        }        
    }
}

War dieses Thema hilfreich?

Thema teilen

Kommentare (14)

Anmelden oder Konto erstellen, Melden Sie sich an oder registrieren Sie sich, um einen Kommentar zu hinterlassen

RomSunZ
RomSunZ

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

Zabik
Zabik Autor

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

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

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

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, поэтому и ошибка выскакивает? Пробовал так же подписываться и на обновления стакана, присваивал переменной значение внутри него - та же ошибка 😭 .

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

Zabik
Zabik Autor

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

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 😂 . Plz help!

Иван З.
Иван З.

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

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

Иван З.: подпишитесь на ```csharp CommonRobot1.SecuritiesChanged+= securities =>

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

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

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

Zabik
Zabik
Zabik Autor

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

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

Zabik
Zabik Autor

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

CommonRobot1.RegisterSecurity(_usd);
                    CommonRobot1.RegisterTrades(_usd);

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

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

RomSunZ
RomSunZ

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

CommonRobot1.RegisterSecurity(_usd); CommonRobot1.RegisterTrades(_usd);

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

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

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

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

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

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

Zabik
Zabik Autor

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

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
Zabik Autor

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


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();
                });
            });
            
        }

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

Renat
Renat

🤨