Получение стакана Фортс.
Atom
10.02.2012
wkj


Продолжаю ковырять SampleConsole, и столкнулся я вот с этим "Если код и класс инструмента содержат символ @, то рекомендуется поменять разделитель на другой символ через свойство SecurityIdGenerator....Delimiter у BaseTrader....SecurityIdGenerator. " , а как сие применить примера нема.В общем нужно получить стакан srh2@rts в sampleconsole.Может кто кусок кода кинет по теме?


Теги:


Спасибо:


< 1 2 3  >
wkj

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


В таблице "Инструменты" фьючерс SRH2 есть. Приложу листинг может пропустил что.Кстати как код выкладывать цивилизовано? namespace SampleConsole { using System; using System.Linq; using System.Threading;

using Ecng.Common;

using StockSharp.BusinessEntities;
using StockSharp.Quik;
using StockSharp.Algo;

class Program
{
	private static Security _srh2;
	private static Portfolio _portfolio;
	private static MarketDepth _depth;

	static void Main()
	{
		try
		{
			// для теста выбираем бумагу Лукойл
			const string secCode = "SRH2";

			var quikPath = QuikTerminal.GetDefaultPath();

			if (quikPath.IsEmpty())
			{
				Console.WriteLine("Не найден ни один запущенный Quik");
				return;
			}

			Console.WriteLine("Запущенный Quik найден по пути " + quikPath);

			Console.Write("Введите код клиента, через который будет выставлена заявка: ");
			var account = Console.ReadLine();

			using (var waitHandle = new AutoResetEvent(false))
			{
				// создаем шлюз к Quik-у
				using (var trader = new QuikTrader(quikPath))
				{
					// необходимо раскомментировать, если идет работа с РТС Стандарт
					//trader.FormatTransaction += builder => builder.RemoveInstruction(TransactionBuilder.ExecutionCondition);

					// подписываемся на событие успешного подключения
					// все действия необходимо производить только после подключения
					trader.Connected += () =>
					{
						Console.WriteLine("Подключение было произведено успешно.");

						// извещаем об успешном соединени
						waitHandle.Set();
					};

					Console.WriteLine("Производим подключение...");

					trader.Connect();

					// дожидаемся события об успешном соединении
					waitHandle.WaitOne();

					trader.NewPortfolios += portfolios =>
					{
						if (_portfolio == null)
						{
							// находим Лукойл и присваиваем ее переменной lkoh
							_portfolio = portfolios.FirstOrDefault(p => p.Name == account);

							if (_portfolio != null)
							{
								Console.WriteLine("Портфель {0} появился.", account);

								// если инструмент и стакан уже появились,
								// то извещаем об этом основной поток для выставления заявки
								if (_srh2 != null && _depth != null)
									waitHandle.Set();
							}
						}
					};

					// подписываемся на событие появление инструментов
					trader.NewSecurities += securities =>
					{
                        if (_srh2 == null)
						{
							// находим Лукойл и присваиваем ее переменной lkoh
                            _srh2 = securities.FirstOrDefault(sec => sec.Code == secCode);

                            if (_srh2 != null)
							{
								Console.WriteLine("Инструмент SRH2 появился.");

								// запускаем экспорт стакана
                                trader.RegisterQuotes(_srh2);

								if (_portfolio != null && _depth != null)
									waitHandle.Set();
							}
						}
					};

					// подписываемся на событие появления моих новых сделок
					trader.NewMyTrades += myTrades =>
					{
						foreach (var myTrade in myTrades)
						{
							var trade = myTrade.Trade;
							Console.WriteLine("Сделка {0} по цене {1} по бумаге {2} по объему {3} в {4}.", trade.Id, trade.Price, trade.Security.Code, trade.Volume, trade.Time);
						}
					};

					// подписываемся на событие обновления стакана
					trader.QuotesChanged += depths =>
					{
                        if (_depth == null && _srh2 != null)
						{
                            _depth = depths.FirstOrDefault(d => d.Security == _srh2);

							if (_depth != null)
							{
								Console.WriteLine("Стакан SRH2 появился.");

								// если портфель и инструмент уже появился, то извещаем об этом основной поток для выставления заявки
                                if (_portfolio != null && _srh2 != null)
									waitHandle.Set();
							}
						}
					};

					Console.WriteLine("Дожидаемся появления в программе инструмента Лукойл и портфеля {0}...".Put(account));

					// запускаем экспорт по DDE
					trader.StartExport(trader.SecuritiesTable, trader.MyTradesTable, trader.EquityPositionsTable,
					                   trader.EquityPortfoliosTable, trader.OrdersTable);

					// дожидаемся появления портфеля и инструмента
					waitHandle.WaitOne();

					// 0.1% от изменения цены
					const decimal delta = 0.001m;

					// запоминаем первоначальное значение середины спреда
                    var firstMid = _srh2.BestPair.SpreadPrice / 2;
                    if (_srh2.BestBid == null)
						throw new Exception("Нет лучшего бида для котировки.");

                    Console.WriteLine("Первоначальное значение середины спреда {0:0.##}", _srh2.BestBid.Price + firstMid);

					while (true)
					{
                        var mid = _srh2.BestPair.SpreadPrice / 2;

						// если спред вышел за пределы нашего диапазона
						if	(
								((firstMid + firstMid * delta) <= mid) ||
								((firstMid - firstMid * delta) >= mid)
							)
						{
							var order = new Order
							{
								Portfolio = _portfolio,
                                Price = _srh2.ShrinkPrice(_srh2.BestBid.Price + mid),
                                Security = _srh2,
								Volume = 1,
								Direction = OrderDirections.Buy,
							};
							trader.RegisterOrder(order);
							Console.WriteLine("Заявка {0} зарегистрирована.", order.Id);
							break;
						}
						else
                            Console.WriteLine("Текущее значение середины спреда {0:0.##}", _srh2.BestBid.Price + mid);

						// ждем 1 секунду
						Thread.Sleep(1000);
					}

					// останавливаем экспорт по DDE
					trader.StopExport(trader.SecuritiesTable, trader.MyTradesTable, trader.EquityPositionsTable,
					                  trader.EquityPortfoliosTable, trader.OrdersTable);
				}
			}
		}
		catch (Exception ex)
		{
			Console.WriteLine(ex);
		}
	}
}

}

Спасибо:

vader

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


"Кстати как код выкладывать цивилизовано?" Нажать кнопку - ответить, там сверху есть кнопки, онда из них - подсветка кода. Нажать её и выбрать нужный код. Появятся открывающий и закрывающий теги, ввести туда код.

После того, как вы стака отредактировали ,вы нажимаете кнопку "Начать вывод" ?

Спасибо:

Moadip

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


Попробовал скопипастить ваш код и запустить. В итоге работа программы остановилась на "стакан SRH2 появился". Запускаю оригинальный пример просто с изменением инструмента. То же самое.[blink]

Ставлю бряк на вход в обработчик события NewPortfolios и наблюдаю следующуюю картину.

Событие сработало, нашелся портфель ММВБ. Но после этого, событие больше не срабатывало. Хотя должно было, и должен был найден портфель FORTS

Проблема оказалась в следующем. Есть вот такие куски кода


trader.StartExport(trader.SecuritiesTable, trader.MyTradesTable, trader.EquityPositionsTable,
		  trader.EquityPortfoliosTable, trader.OrdersTable);

...

trader.StopExport(trader.SecuritiesTable, trader.MyTradesTable, trader.EquityPositionsTable,
		  trader.EquityPortfoliosTable, trader.OrdersTable);

Так вот в оригинальном примере по dde выводятся таблицы "портфель по бумагам" и "позиции по бумагам" - trader.EquityPositionsTable, trader.EquityPortfoliosTable

Чтобы работать с фьючерсами, надо добавить еще две таблицы trader.DerivativePositionsTable и trader.DerivativePortfoliosTable


trader.StartExport(trader.SecuritiesTable, trader.MyTradesTable, trader.EquityPositionsTable,
		  trader.EquityPortfoliosTable, trader.OrdersTable, trader.DerivativePositionsTable, trader.DerivativePortfoliosTable);

...

trader.StopExport(trader.SecuritiesTable, trader.MyTradesTable, trader.EquityPositionsTable,
		  trader.EquityPortfoliosTable, trader.OrdersTable, trader.DerivativePositionsTable, trader.DerivativePortfoliosTable);

Или сделать проще


trader.StartExport();

...

trader.StopExport();

И все будет работать.

Самое интересное почему у меня тогда вчера правильно работал этот пример, ведь я ничего не менял кроме инструмента?

Начинаю разбираться. Удаляю таблицы по деривативам, запускаю, пример отрабатывает как надо.[blink] Ставлю опять бряк на вход в обработчик события NewPortfolios. Смотрю, находится портфель по FORTS. Смотрю в квике запущен ли экспорт по таблицам деривативов - нет, не запущен.[confused]

Оказывается. Даже если не запущен экспорт dde по таблицам деривативов, то если есть хоть одна заявка в таблице "Заявки", то номер счета будет браться оттуда.

Это фича или баг?

Проверил следующим образом, удалил таблицу заявок из экспорта - trader.OrdersTable. Запустил и программа не отработала как надо. Поэтому у меня вчера пример отработал без проблем, т.к. были сделки по FORTS.

Спасибо: wkj Yury Smykalov

Alexander

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


Это не фича и не баг. Это то как работает QuikTrader - строит информацию по той таблице, которая пришла первой.

Спасибо:

Moadip

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


Ок. Понятно.

Спасибо:

wkj

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


И снова здравствуйте [woot] ! Спасибо vader и Moadip за внимание к проблеме.Я опять с плохими новостями. Если использовать trader.StartExport(); trader.StopExport(); то упираюсь в "Портфель ХХХ появился" а после закрытия консоли квик выдает - DDE сервер 'STOCKSHARP'. Документ 'все сделки[]'. Таблица 'Все сделки'. Ошибка при передаче таблицы,вывод приостановлен. Неверные параметры. И еще 'Переполнена очередь сообщений', и еще что-то про переполнение сервера что я не смог воспроизвести и записать. А при использовании старт экспорта с перечислением таблиц, также упираюсь в "Портфель ХХХ появился" но после закрытия консоли квик ошибок не выдает. Verifier говорит все хорошо. На всякий случай оставил в таблице всех сделок только сбер. Кто что думает?

Спасибо:

Moadip

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


Оригинальный пример SampleConsole как работает? Нормально или нет?

Спасибо:

wkj

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


Moadip: Оригинальный пример SampleConsole как работает? Нормально или нет? У меня только Фортс включен.

Спасибо:

Moadip

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


Для всех экспериментов лучше поставить демо квик. На боевом как то неохото тренироваться в отладке кода.

Спасибо:

wkj

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


Moadip: Для всех экспериментов лучше поставить демо квик. На боевом как то неохото тренироваться в отладке кода. Мне особо рисковать там нечем, отношусь как к демо [biggrin] .

Спасибо:
< 1 2 3  >

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

loading
clippy