← 戻る

Не могу справиться с DdeCustomTable

Масса благодарностей за библиотеку!

Создал класс

[DdeCustomTable("Деривативы")]
	//[Ignore(FieldName = "IsDisposed")]
	public class DerivativesDDETable
	{
		[DdeCustomColumn("Бумага сокр.", Order = 0)]
		//[Identity]
		public string SecurityName { get; set; }

		[DdeCustomColumn("Код бумаги", Order = 1)]
		public string SecurityCode { get; set; }

		[DdeCustomColumn("До погашения", Order = 2)]
		public int TillExpiration { get; set; }

		[DdeCustomColumn("Шаг цены", Order = 3)]
		public double PriceStep { get; set; }

		[DdeCustomColumn("Ст. шага цены", Order = 4)]
		public double PriceStepPice { get; set; }

		[DdeCustomColumn("Страйк", Order = 5)]
		public double Strike { get; set; }

		[DdeCustomColumn("Баз. актив", Order = 6)]
		public string Asset { get; set; }

		[DdeCustomColumn("ГО покупателя", Order = 7)]
		public double BuyerMargin { get; set; }

		[DdeCustomColumn("ГО продавца", Order = 8)]
		public double SellerMargin { get; set; }

		[DdeCustomColumn("Дата исп.", Order = 9)]
		public DateTime FinalExpiration { get; set; }

		[DdeCustomColumn("Погашение", Order = 10)]
		public DateTime Expiration { get; set; }

		[DdeCustomColumn("Пред. оц", Order = 11)]
		public DateTime RC { get; set; }
	}

После

protected override void OnConnect()
		{
			ProcessCustomTables += (type, objects) =>
			{
				// нас интересует только CustomPortfolio
				if (type == typeof(DerivativesDDETable))
				{
					
				}
			};
			Terminal.StartDde("Деривативы");
			Terminal.StartDde(ListenedTables);

			base.OnConnect();
		}

на ProcessDataError приходит ArgumentOutOfRangeException

Деривативы Имя параметра: category

Что это значит? Пытался работать только с одной колонкой - то же самое. По форуму ничего не нашел =(

このトピックは参考になりましたか?

トピックを共有

コメント (38)

ログイン または アカウントを作成, コメントを残すにはログインまたは新規登録してください

Foxbow
Foxbow 著者

Спасибо, прошу прощения за невнимательность =)

a.dobryn
a.dobryn

Тоже есть вопрос. При создании описания портфеля имеют значения названия полей? Они должны быть такими же, как и в Quik? У меня так: Описание полей на QPile:

PARAMETER DATE;
PARAMETER_TITLE Дата;
PARAMETER_DESCRIPTION Дата сделки;
PARAMETER_TYPE STRING(32);
END
	
PARAMETER TIME;
PARAMETER_TITLE Время;
PARAMETER_DESCRIPTION Время;
PARAMETER_TYPE String(32);
END	

PARAMETER PRICE;
PARAMETER_TITLE Цена;
PARAMETER_DESCRIPTION Цена;
PARAMETER_TYPE Numeric(14,2);
END

PARAMETER seccode;
PARAMETER_TITLE Код;
PARAMETER_DESCRIPTION Код;
PARAMETER_TYPE String(32);
END	

описание полей на S#:

[DdeCustomColumn("Дата", Order = 0)]
public string Data { get; set; }

[DdeCustomColumn("Время", Order = 1)]
public string Time { get; set; }

[DdeCustomColumn("Цена", Order = 2)]
public double Price { get; set; }

[DdeCustomColumn("Код", Order = 3)]
public string Code { get; set; }

В итоге после показа портфеля в программе окно есть, но пустое. Соединение происходит нормально.

Mikhail Sukhov
Mikhail Sukhov

D_Alex: В итоге после показа портфеля в программе окно есть, но пустое. Соединение происходит нормально.

В начале QuikTrader.ProcessCustomTables вызывается? QuikTrader.ProcessDataError что-нибудь пишет?

a.dobryn
a.dobryn

Mikhail Sukhov: В начале QuikTrader.ProcessCustomTables вызывается? QuikTrader.ProcessDataError что-нибудь пишет?

ProcessCustomTables вызывается, как в примере

this.Trader.ProcessCustomTables += (type, objects) =>
{					
	if (type == typeof(CustomPortfolio))
		_portfolioWindow.Portfolios.AddRange(objects.Cast<CustomPortfolio>());
};

а как использовать ProcessDataError?

Mikhail Sukhov
Mikhail Sukhov

D_Alex:

Mikhail Sukhov: В начале QuikTrader.ProcessCustomTables вызывается? QuikTrader.ProcessDataError что-нибудь пишет?

ProcessCustomTables вызывается, как в примере

this.Trader.ProcessCustomTables += (type, objects) => { if (type == typeof(CustomPortfolio)) _portfolioWindow.Portfolios.AddRange(objects.Cast()); };

> 
> а как использовать ProcessDataError?

Прочитайте как использовать события в C# и для чего они нужны. После этого станет значительно понятнее как используется ProcessCustomTables и что такое +=
a.dobryn
a.dobryn

С событиями вроде разобралась, что такое += поняла, как подписываться на ошибки тоже. Только где именно надо использовать ProcessDataError? есть еще ConnectionError. Какие именно функции надо проверять и где?

Mikhail Sukhov
Mikhail Sukhov

D_Alex: С событиями вроде разобралась, что такое += поняла, как подписываться на ошибки тоже. Только где именно надо использовать ProcessDataError? есть еще ConnectionError. Какие именно функции надо проверять и где?

Это не функции, а обработчики событий.

Подпишитесь на событие ITrader.ProcessDataError, и, если в его обработчик что-нибудь придет, сохраните ошибку (или просто запустите под Debug и поставьте точку останова).

ConnectionError - это другое событие, связанное с ошибкой соединения. Вы подключиться смогли к Квик?

a.dobryn
a.dobryn

Да, обработчики, я не совсем правильно сформулировала вопрос =) нужно подписаться на это событие, но где? В какой момент? К квику подключилась. Есть функция Connect_Click, но, раз подключение успешно выполняется, но надо это делать не там? Хотя работа с портфелем вроде осуществляется там, до старта DDE


private void Connect_Click(object sender, RoutedEventArgs e)
		{
			if (!_isConnected)
			{
                if (this.Path.Text.IsEmpty())
					MessageBox.Show(this, "Путь к Quik не выбран");
				else
				{
					if (this.Trader == null)
					{
						// создаем шлюз
						this.Trader = new QuikTrader(this.Path.Text);

						// возводим флаг, что соединение установлено
						_isConnected = true;

						// подписываемся на событие ошибки соединения
						this.Trader.ConnectionError += error => this.GuiAsync(() => MessageBox.Show(this, error.ToString()));       

						// добавляем тип CustomPortfolio для преобразования строчки из таблица в Портфель в объект CustomPortfolio
						this.Trader.AddCustomTableMapping(typeof(CustomPortfolio));

						this.Trader.ProcessCustomTables += (type, objects) => 
						{
							// нас интересует только CustomPortfolio
							if (type == typeof(CustomPortfolio))
								_portfolioWindow.Portfolios.AddRange(objects.Cast<CustomPortfolio>());
						};

						this.Trader.Connected += () => this.GuiAsync(() =>
						{
							this.ShowPortfolio.IsEnabled = true;
							this.ExportDde.IsEnabled = true;

							_isConnected = true;
							this.ConnectBtn.Content = "Отключиться";
						});

						this.Trader.Disconnected += () => this.GuiAsync(() =>
						{
							_isConnected = false;
							this.ConnectBtn.Content = "Подключиться";
						});
					}
           
					this.Trader.Connect();
				}
			}
			else
				this.Trader.Disconnect();
		}

Извиняюсь за столь глупые вопросы, пытаюсь понять все с наскока :-[

MCTuTeJ|19951995
MCTuTeJ|19951995

Попробуйте там же где Вы на все остальные подписываетесь.

a.dobryn
a.dobryn

MCTuTeJ|19951995: Попробуйте там же где Вы на все остальные подписываетесь. спасибо, так и сделала =)

в итоге получилось это:

Message "Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index"

текст целиком (не вытащить во время дебага, у error'а столько всего внутри)

все равно не понимаю - мы подписываемся на событие ProcessDataError в функции коннекта к quik'у, а ошибка вылезает при начале DDE, как оно так?

a.dobryn
a.dobryn

Хм, переделала это дело под другую таблицу, и оно внезапно заработало, без нареканий.

Mikhail Sukhov
Mikhail Sukhov

D_Alex: Хм, переделала это дело под другую таблицу, и оно внезапно заработало, без нареканий.

Я посмотрел причину такой ошибки. Она может быть только в том случае, если у колонки индекс больше допустимого. Например, пришло меньше полей по ДДЕ.

a.dobryn
a.dobryn

Mikhail Sukhov: Я посмотрел причину такой ошибки. Она может быть только в том случае, если у колонки индекс больше допустимого. Например, пришло меньше полей по ДДЕ. скорее всего, наверное, неправильно описала саму структуру портфеля.

Mikhail Sukhov:

D_Alex: Только данные не обновляются после обновления таблицы в quick - где нужно проверить? Посмотрите соседний топик. Я думаю такая же ситуация.

Посмотрела - там немного другая ситуация, уже полученные данные не меняются, должны добавляться новые.

upd:

Оказалось, не описан NotifyPropertyChanged (да уж, а еще жду от программы чего-то)

Делаю, как в примере

   private PropertyChangedEventHandler _propertyChanged;

        event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged
        {
            add { _propertyChanged += value; }
            remove { _propertyChanged -= value; }
        }
        private void NotifyPropertyChanged(string info)
        {
            if (_propertyChanged != null)
                _propertyChanged(this, new PropertyChangedEventArgs(info));
        }

Вылезает такая штука:

'TFromQuik.CustomPortfolio.INotifyPropertyChanged.PropertyChanged': containing type does not implement interface 'System.ComponentModel.INotifyPropertyChanged'
a.dobryn
a.dobryn

Только данные не обновляются после обновления таблицы в quick - где нужно проверить?

Mikhail Sukhov
Mikhail Sukhov

D_Alex: Только данные не обновляются после обновления таблицы в quick - где нужно проверить?

Посмотрите соседний топик. Я думаю такая же ситуация.

MCTuTeJ|19951995
MCTuTeJ|19951995

Сталкивался с такой штукой - класс нужно отнаследовать от INotifyPropertyChanged

a.dobryn
a.dobryn

Сделала =) Закомпилилось, работает. Вроде обновляется (у меня сейчас одна колонка с данными, ползунок ползет), но данные те же самые! Ничего не понимаю.

код в итоге такой

public class CustomPortfolio : INotifyPropertyChanged
{
        [DdeCustomColumn("Цена", Order = 0)]
        public double Price { get; set; }

        private PropertyChangedEventHandler _propertyChanged;

        event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged
        {
            add { _propertyChanged += value; }
            remove { _propertyChanged -= value; }
        }
        private void NotifyPropertyChanged(string info)
        {
            if (_propertyChanged != null)
                _propertyChanged(this, new PropertyChangedEventArgs(info));
        }
}

Причем при каждом запуске ощущение такое, что данные одни и те же, хотя в квике они давно поменялись.

MCTuTeJ|19951995
MCTuTeJ|19951995

Какой ползунок ? А где проверяете обновление данных ? Если в ProcessCustomTables то оно не приходит при изменении существующих данных.

a.dobryn
a.dobryn

MCTuTeJ|19951995: Какой ползунок ? А где проверяете обновление данных ? Если в ProcessCustomTables то оно не приходит при изменении существующих данных. Ползунок на самой форме с данными =) там и проверяю. Существующие данные не меняются, появляются новые.

MCTuTeJ|19951995
MCTuTeJ|19951995

Михаил, а Вы не подскажете нормальный источник где можно про технологию DDE почитать ?

MCTuTeJ|19951995
MCTuTeJ|19951995

Как Вы определяете что не меняются данные ? А NotifyPropertyChanged вызывается ? Где храните полученные данные ?

a.dobryn
a.dobryn

MCTuTeJ|19951995: Как Вы определяете что не меняются данные ? А NotifyPropertyChanged вызывается ? Где храните полученные данные ? смотрю на них =) они те же самые. Сделала даже скрин, сверила. ой, кстати, да. А где вызывать NotifyPropertyChanged? Храню вроде бы в this.Portfolios

Mikhail Sukhov
Mikhail Sukhov

D_Alex:

MCTuTeJ|19951995: Как Вы определяете что не меняются данные ? А NotifyPropertyChanged вызывается ? Где храните полученные данные ? смотрю на них =) они те же самые. Сделала даже скрин, сверила. ой, кстати, да. А где вызывать NotifyPropertyChanged? Храню вроде бы в this.Portfolios

http://stocksharp.com/doc/help/html/7d73f7bf-ae8b-4d76-9895-cffb6342203f.htm Посмотрите, как нужно использовать INotifyPropertyChanged. Лучше даже откройте соответствующий пример http://stocksharp.com/doc/help/html/4efd0545-a100-44ed-bdf5-4588e5665199.htm SampleDdeCustomTable.

MCTuTeJ|19951995
MCTuTeJ|19951995

я ничего не понимаю .... Привязку данных делаете ? this.Portfolios это что ? Какой компонент используете для вывода данных ?

a.dobryn
a.dobryn

Привязку делаю, данные выводятся в GridView.

MCTuTeJ|19951995
MCTuTeJ|19951995

А коллекция в который Вы храните данные поддерживает выдачу уведомления при получении и удалении элементов или при обновлении коллекции ? Попробуйте использовать ObservableCollection... А Вы пишете приложение WindowsForms или WPF ?

a.dobryn
a.dobryn
a.dobryn

WPF Это приложение взято из примеров Stock#, я до конца в нем не разобралась еще =) уведомление вроде есть, CollectionChanged это то? тип вроде ThreadSaveObservableCollection http://stocksharp.com/doc/help/html/AllMembers_T_Ecng_Trading_BusinessEntities_Portfolio.htm

MCTuTeJ|19951995
MCTuTeJ|19951995

А код не можете выложить ?

a.dobryn
a.dobryn

сделала вместо


DdeCustomColumn("Цена", Order = 0)]
public double Price { get; set; }

вот так


        private double _price;

        [DdeCustomColumn("Цена", Order = 0)]
        public double Price
        {
            get { return _price; }
            set
            {
                _price = value;
                NotifyPropertyChanged("Price");
            }
        }

Все равно все также, данные добавляются, но все те же, а не новые.

Mikhail Sukhov
Mikhail Sukhov

D_Alex: Все равно все также, данные добавляются, но все те же, а не новые.

Если помечено атрибутом IdentityAttr, то данные обновляются, а не добавляются.

a.dobryn
a.dobryn

Вроде нет такого у меня. Сейчас, например, цена в квике уже 173к и больше, а в моей таблице она все в пределах 171-172к, и причем все время добавляется. Такое ощущение, что какие были получены данные в первый раз, все добавляются туда.

Mikhail Sukhov
Mikhail Sukhov

D_Alex: Вроде нет такого у меня. Сейчас, например, цена в квике уже 173к и больше, а в моей таблице она все в пределах 171-172к, и причем все время добавляется. Такое ощущение, что какие были получены данные в первый раз, все добавляются туда.

Если это Ваш код http://codepaste.ru/4744/, то есть. Причем добавлен зачем-то на цену.

a.dobryn
a.dobryn

Mikhail Sukhov:

D_Alex: Вроде нет такого у меня. Сейчас, например, цена в квике уже 173к и больше, а в моей таблице она все в пределах 171-172к, и причем все время добавляется. Такое ощущение, что какие были получены данные в первый раз, все добавляются туда.

Если это Ваш код http://codepaste.ru/4744/, то есть. Причем добавлен зачем-то на цену.

Мой, но я это убрала уже, еще до добавления NotifyPropertyChanged. Сейчас точно нет =)

Mikhail Sukhov
Mikhail Sukhov

D_Alex:

Mikhail Sukhov:

D_Alex: Вроде нет такого у меня. Сейчас, например, цена в квике уже 173к и больше, а в моей таблице она все в пределах 171-172к, и причем все время добавляется. Такое ощущение, что какие были получены данные в первый раз, все добавляются туда.

Если это Ваш код http://codepaste.ru/4744/, то есть. Причем добавлен зачем-то на цену.

Мой, но я это убрала уже, еще до добавления NotifyPropertyChanged. Сейчас точно нет =)

Ок, тогда если только это поменялось, то поведение Вашей программы должно быть: каждое обновление или добавление в Квике трактуется как добавление новой записи у Вас. У Вас не так?

a.dobryn
a.dobryn

Мистика, еще раз просмотрела код, перекомпилила, теперь все работает как надо =) спасибо за помощь =)

neighbour
neighbour

Добрый день!

Вот у меня тоже проблема с выводом исторических свечек. Только у меня проблема еще раньше: я загружаю портфель qpile, добавляю таблицу на этот портфель, а она пустая. Пытаюсь просмотреть историю Сбербанка,последние 50 часовых свечек. <mark>secClass = "EQBR" secCode = "SBER03" timeFrame = 60 candleMaxCount = 50</mark>Остальные данные в qpile скрипте не менял. Пробовал и на стандартном файле, идущем в примере, но результат такой же - пустая таблица. Что я делаю не правильно?