← Zurück

не понятен механизм работы метода AddRange

здравствуйте. Пытаюсь реализовать такую стратегию, в которой, цена следующей заявки зависит от цены предидущей. Для этого подпислся на событие получения новых моих сделок, сохраняю их в коллекцию, и получаю цену последней сделки. Регистрирую заявку, жду когда придет сделка, извлекаю последную сдлку и беру цену.


MainWindow.Instance.Trader.RegisterOrder(order);
waitHandle.WaitOne();
						if (_backgroundWorker.CancellationPending){return;}
						_backgroundWorker.ReportProgress(4, order); 						                                curLotBuyNow += Trades[Trades.Count-1].Order.Volume;
						MessageBox.Show("Id= "+Trades[Trades.Count-1].Order.Id.ToString()+" curLotBuyNow= " + curLotBuyNow.ToString());
						waitHandle.Reset();
						
						price = Math.Min(_priceOfOrder, Trades[Trades.Count-1].Trade.Price);

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


MainWindow.Instance.Trader.NewMyTrades += trades =>this.GuiAsync(() =>
			                                                                 {
			                                                                 	lock(this)
			                                                                 	{
			                                                                 		trades = from n in trades
			                                                                 			where (n.Trade.Security == _security) && (n.Order.ExtensionInfo == "S#")
			                                                                 			select n;
			                                                                 		int startSize = Trades.Count;
			                                                                 		MessageBox.Show("startSize= "+startSize.ToString());
			                                                                 		this.Trades.AddRange(trades);
			                                                                 		while(startSize == Trades.Count){
			                                                                 		}
			                                                                 		MessageBox.Show("Count= "+Trades.Count.ToString());
			                                                                 		//Если по другому инструменту?
			                                                                 		if((Orders.Count != 0) && Orders[Orders.Count-1].IsMatched()){
			                                                                 			this.Orders.RemoveAt(Orders.Count-1);
			                                                                 			waitHandle.Set();
			                                                                 		}
			                                                                 	}
			                                                                 });

Но этого не происходит. Часто этот код curLotBuyNow += Trades[Trades.Count-1].Order.Volume; извлает предпоследнуюю сделку. Я пытался и цикл ожидания использовать(while(startSize == Trades.Count)) и lock, но ничего не помогает. Помогите, пожалуйста, разобратся.

War dieses Thema hilfreich?

Thema teilen

Kommentare (8)

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

Alexander
Alexander

Про метод AddRange есть на MSDN

Совсем не понятно зачем строить такую логику - использовать внутри стратегии обращение к MainWindow.Instance.Trader к примеру. Для чего нужны эти блокировки (waitHandle.WaitOne();...)? Зачем удалять \ добавлять в коллекции?

Или же это делается не внутри стратегии (класса Strategy)? Как тогда задеклорированы Trades и Orders? В любом случае отвечая на вопрос в заголовке - см. MSDN, там есть описание данного метода

vader
vader Autor

MainWindow.Instance.Trader.RegisterOrder(order); я использую для регистрации заявки.

Для чего нужны эти блокировки (waitHandle.WaitOne();...)? Для того. чтобы знать, что заявки исполнена. Блокировка снимается, когда происходит событие получения новой сделки. Добавление в коллекцию - для того, чтобы отображать собственные заявки. Удаляю я не активные заявки.

Это делается не внутри класса Strategy. public ObservableCollection<MyTrade> Trades { get; private set; } public ObservableCollection<Order> Orders { get; private set; }

По поводу главного вопроса. Я в цикле сталю заявки, и жду их исполнения, чтобы ставить следующие, опираясь на зену исполнения последней сделки. Как мне узнать о том, что заявки исполнена? Раньше я проверял так - Orders[Orders.Count-1].IsMatched() Но, видимо, если часть заявки исполняется сразу, то коллекция не успевает обновится и робот, думает, что заявка исполнена, т.к. он видит прошлую, которая уже исполнена. Я предролагаю, что анонимных метод синхронизированый, но видимо, это не так, иначе бы все заявки и сделки попадлибы в свои коллекции, а потом происходили бы дальнейшие действия.

Alexander
Alexander

У вас логика работы некорректная.

Зачем использовать Trader у MainWindow.Instance ? Ведь он есть у Strategy

Блокировки не нужны, пользуйтесь событиями и When\Do. Коллекции вообще не нужны. Все сделки есть в Strategy.MyTrades, заявки - Strategy.Orders Эти коллекции - синхронизированные (SynchronizedList и SynchronizedSet соответственно).

А вы объявляете свою коллекцию как ObservableCollection и удивляетесь что она не синхронизирована :)

А так - надо пользоваться When(order.Matched()).Do(blablabla); When(order.NewTrades()).Do(blablabla);

vader
vader Autor

Alexander: У вас логика работы некорректная.

Зачем использовать Trader у MainWindow.Instance ? Ведь он есть у Strategy

Блокировки не нужны, пользуйтесь событиями и When\Do. Коллекции вообще не нужны. Все сделки есть в Strategy.MyTrades, заявки - Strategy.Orders Эти коллекции - синхронизированные (SynchronizedList и SynchronizedSet соответственно).

А вы объявляете свою коллекцию как ObservableCollection и удивляетесь что она не синхронизирована :)

А так - надо пользоваться When(order.Matched()).Do(blablabla); When(order.NewTrades()).Do(blablabla); Alexander? не моглы бы вы прояснить, как правильно использовать коллекции заявок и сделок. я хочу вычтавлять заявки последовательно, онда за другой. Есть условие для высталения завок и дополнительное условие ,заключающееся в том, что пока одна заявка не исполнится, следующая не выставляается. Но списки сделок и заявок не успевают обновится. Допустим в этом методе дожен расчитыватся обший объем купленных лотов ,но из-за того ,что список сделок не успевает дополнится, часто объем считается не верно. К примеру, прошли две сделки объемом 1 и 7, купленный объем посчитается как 2.


private bool RecalculateVolume()
	{		if(this.MyTrades.Count > 0){
			_curLotBuySellNow += this.MyTrades[this.MyTrades.Count-1].Trade.Volume;
			//MessageBox.Show(_curLotBuySellNow.ToString() + " Volume= " + this.Volume.ToString());
			if (_curLotBuySellNow >= this.Volume){
				this.Stop();
				return false;
			}
		}
		return true;
	}

можно ли как-то заставить все стратегию выполнятся в одном потоке? Атрибут [Synchronization] не помогает.

vader
vader Autor

Ориентируюся на ваши посты, я понял, что надо писать через стратегии. я видел у вас пример позиционной стратегии(итерационной). Есть ли у вас пример использование и работы с событийной стратегии?( как у вас есть пример SampleSMA)? А то тяжеловато разобратся.

esper
esper

vader: Ориентируюся на ваши посты, я понял, что надо писать через стратегии. я видел у вас пример позиционной стратегии(итерационной). Есть ли у вас пример использование и работы с событийной стратегии?( как у вас есть пример SampleSMA)? А то тяжеловато разобратся.

В документации есть пример

vader
vader Autor

esper, да я это видел, но я прошу пример не только стратегии но и её комплексного использования в роботе. чтобы было понятно, как с ней работать.

Alexander
Alexander

vader: esper, да я это видел, но я прошу пример не только стратегии но и её комплексного использования в роботе. чтобы было понятно, как с ней работать.

см. SampleSMA. Работа с событийной стратегией ничем не отличается.