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

Вот мой код, что я делаю не так?
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);
}
}
}
コメント (14)
ログイン または アカウントを作成, コメントを残すにはログインまたは新規登録してください
Примеры смотрите. Ваши инструменты не подписаны на рыночные данные.
Примеры я смотрю, правда верить им или нет - не знаю. они все-равно не работают. В одних примерах никто на рыночные данные не подписывается, в других подписываются, но и там и там используют BestBid/Ask 🤨
Пробовал я уже много чего, вот например так:
С той же ошибкой во время выполнения выделяет строчку var pri = _sber.BestAsk.Price;
Читаю букварь: "RegisterSecurity - метод. Начать получать новую информацию (например, LastTrade или BestBid) по инструменту."
Подскажите по крайней мере причину ошибки. Я так понимаю, что в моем случае BestAsk так и остается равным null, поэтому и ошибка выскакивает? Пробовал так же подписываться и на обновления стакана, присваивал переменной значение внутри него - та же ошибка 😭 .
Самое обидно, что это последнее что мне нужно от библиотеки StockSharp, остальное реализуется без нее.
Ну да, так и есть, написал следующее:
Теперь ошибки нет, но и цен нет, значит _sber.LastTrade так и остается равным null 😂 . Plz help!
подпишитесь на ```csharp CommonRobot1.SecuritiesChanged+= securities =>
Запустите пример quik sample и если там все работает (получение последней сделки и лучшие цены), посмотрите код и перенесите его в свой робот.
Так, ну вот уже что-то 😀 , спасибо! По дефолту подкачивается всего 5 параметров по инструменту, а вот после нажатия кнопки level1 по выбранному инструменту подкачиваются и остальные параметры и стакан. Конечно при разборе этого примера я не обращал внимания на эту кнопку, щас посмотрю что там спрятано 😎
Так, ну нового там ничего нет. Все как и у меня:
В общем поковырялся, вроде заработало, но пока в основном возвращает нули, может потому что биржа уже не работает - завтра посмотрим. А вообще так до конца и не понятно, почему ошибка вылазит именно на BestBid.Price а на просто BestBid нет?
Короче, пока надо понять подгружает ли он мне реальные данные или просто по дефолту, но это завтра.
CommonRobot1.RegisterSecurity(_usd); CommonRobot1.RegisterTrades(_usd);
Поковырявшись понял что так и есть. Но вот почему не могу понять. 😊
От безисходности перепахал под себя пример Sample. Все работает, все цены, объемы и т.п. в таблицу SecurityPicker идут, но видимо с помощью какого-то волшебства, т.к. тут же рядом с этой таблицей пытаюсь вбить в текстбокс _sber.LastTrade.Price и опять эта ошибка, и потому что LastTrade == null. Но как он может быть пустым если в таблицу рядом вот они идут значения по последним сделкам я не понимаю. 🤬
Подскажите, может есть какая-то возможность взглянуть на код этой волшебной таблицы SecurityPicker?
https://github.com/stocksharp/stocksharp/blob/master/Xaml/SecurityPicker.xaml.cs
Ну что же, получилось с горем пополам, и то через одно место:
Т.е. цепляю дынные из самой таблицы (как они там появляются для меня остается загадкой). Осталось теперь понять куда запихать этот код, чтобы данные приходили в реальном времени, а не только на момент нажатия _result.
Все, всем спасибо!
Не знаю как, но работает правильно. Так что даже разбираться не буду 😂
🤨