← Zurück

Не могу справиться с 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

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

War dieses Thema hilfreich?

Thema teilen

Kommentare (38)

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

Foxbow
Foxbow Autor

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

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
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 скрипте не менял. Пробовал и на стандартном файле, идущем в примере, но результат такой же - пустая таблица. Что я делаю не правильно?