public void AddCandle(int securityIndex, Candle candle)
			{
				if (candle == null)
					throw new ArgumentNullException(nameof(candle));

				if (Candles[securityIndex] != null)
				{
					if (_isSparseBuffer)
						return;
					
					throw new ArgumentException(LocalizedStrings.Str654Params.Put(candle.OpenTime), nameof(candle));
				}

				Candles[securityIndex] = candle;

				_counter--;

				if (_isSparseBuffer)
				{
					if (candle.OpenTime < OpenTime)
					{
						OpenTime = candle.OpenTime;
						OpenTime = Candles.Where(c => c != null).Min(c => c.OpenTime);
					}

					if (candle.CloseTime > CloseTime)
					{
						CloseTime = candle.CloseTime;
						CloseTime = Candles.Where(c => c != null).Max(c => c.CloseTime);
					}
				}
			}
示例#2
0
		/// <summary>
		/// To get the part value.
		/// </summary>
		/// <param name="current">The current candle.</param>
		/// <param name="prev">The previous candle.</param>
		/// <returns>Value.</returns>
		protected override decimal GetValue(Candle current, Candle prev)
		{
			if (current.LowPrice < prev.LowPrice && current.HighPrice - prev.HighPrice < prev.LowPrice - current.LowPrice)
				return prev.LowPrice - current.LowPrice;
			else
				return 0;
		}
			public CandleBuffer(DateTimeOffset openTime, DateTimeOffset closeTime, int maxCandleCount, bool isSparseBuffer)
			{
				OpenTime = openTime;
				CloseTime = closeTime;
				Candles = new Candle[maxCandleCount];
				_counter = maxCandleCount;
				_isSparseBuffer = isSparseBuffer;
			}
示例#4
0
		/// <summary>
		/// To get price components to select the maximal value.
		/// </summary>
		/// <param name="currentCandle">The current candle.</param>
		/// <param name="prevCandle">The previous candle.</param>
		/// <returns>Price components.</returns>
		protected virtual decimal[] GetPriceMovements(Candle currentCandle, Candle prevCandle)
		{
			return new[]
			{
				Math.Abs(currentCandle.HighPrice - currentCandle.LowPrice),
				Math.Abs(prevCandle.ClosePrice - currentCandle.HighPrice),
				Math.Abs(prevCandle.ClosePrice - currentCandle.LowPrice)
			};
		}
        protected void ProcessCandle(Candle candle)
        {
            if (Trade.GetPnL() <= -StopLossUnit)
            {
                OrderDirections direction = this.Trade.Order.Direction.Invert();
                decimal price = Security.LastTrade.Price;
                Order order = this.CreateOrder(direction, price, this.Trade.Order.Volume);

                RegisterOrder(order);
            }
        }
			public bool AddCandle(Candle candle)
			{
				if (candle == null)
					throw new ArgumentNullException(nameof(candle));

				if (!_byTime.SafeAdd(candle.OpenTime).TryAdd(candle))
					return false;

				_allCandles.AddLast(candle);
				_candleStat.Add(candle);

				_lastCandleTime = candle.OpenTime.UtcTicks;

				RecycleCandles();

				return true;
			}
示例#7
0
		/// <summary>
		/// To handle the input value.
		/// </summary>
		/// <param name="input">The input value.</param>
		/// <returns>The resulting value.</returns>
		protected override IIndicatorValue OnProcess(IIndicatorValue input)
		{
			var candle = input.GetValue<Candle>();

			if (_prevCandle != null)
			{
				if (input.IsFinal)
					IsFormed = true;

				var priceMovements = GetPriceMovements(candle, _prevCandle);

				if (input.IsFinal)
					_prevCandle = candle;

				return new DecimalIndicatorValue(this, priceMovements.Max());
			}

			if (input.IsFinal)
				_prevCandle = candle;

			return new DecimalIndicatorValue(this, candle.HighPrice - candle.LowPrice);
		}
示例#8
0
		private void ProcessCandle(Candle candle)
		{
			// если наша стратегия в процессе остановки
			if (ProcessState == ProcessStates.Stopping)
			{
				// отменяем активные заявки
				CancelActiveOrders();
				return;
			}

			// добавляем новую свечу
			LongSma.Process(candle);
			ShortSma.Process(candle);

			// вычисляем новое положение относительно друг друга
			var isShortLessThenLong = ShortSma.GetCurrentValue() < LongSma.GetCurrentValue();

			// если произошло пересечение
			if (_isShortLessThenLong != isShortLessThenLong)
			{
				// если короткая меньше чем длинная, то продажа, иначе, покупка.
				var direction = isShortLessThenLong ? Sides.Sell : Sides.Buy;

				// вычисляем размер для открытия или переворота позы
				var volume = Position == 0 ? Volume : Position.Abs() * 2;

				// регистрируем заявку (обычным способом - лимитированной заявкой)
				//RegisterOrder(this.CreateOrder(direction, (decimal)Security.GetCurrentPrice(direction), volume));

				// переворачиваем позицию через котирование
				var strategy = new MarketQuotingStrategy(direction, volume);
				ChildStrategies.Add(strategy);

				// запоминаем текущее положение относительно друг друга
				_isShortLessThenLong = isShortLessThenLong;
			}
		}
示例#9
0
		private void ProcessCandle(Candle candle)
		{
			// strategy are stopping
			if (ProcessState == ProcessStates.Stopping)
			{
				CancelActiveOrders();
				return;
			}

			// process new candle
			LongSma.Process(candle);
			ShortSma.Process(candle);

			// calc new values for short and long
			var isShortLessThenLong = ShortSma.GetCurrentValue() < LongSma.GetCurrentValue();

			// crossing happened
			if (_isShortLessThenLong != isShortLessThenLong)
			{
				// if short less than long, the sale, otherwise buy
				var direction = isShortLessThenLong ? Sides.Sell : Sides.Buy;

				// calc size for open position or revert
				var volume = Position == 0 ? Volume : Position.Abs() * 2;

				// register order (limit order)
				RegisterOrder(this.CreateOrder(direction, (decimal)(Security.GetCurrentPrice(this, direction) ?? 0), volume));

				// or revert position via market quoting
				//var strategy = new MarketQuotingStrategy(direction, volume);
				//ChildStrategies.Add(strategy);

				// store current values for short and long
				_isShortLessThenLong = isShortLessThenLong;
			}
		}
示例#10
0
		private void DrawCandle(CandleSeries series, Candle candle)
		{
			var wnd = _chartWindows.TryGetValue(series);

			if (wnd != null)
				wnd.Chart.Draw((ChartCandleElement)wnd.Chart.Areas[0].Elements[0], candle);
		}
示例#11
0
        public IEnumerable <Candle> ProcessCandle(Candle candle)
        {
            return(GetFormedBuffers(candle)
                   .Select(buffer =>
            {
                var indexCandle = candle.GetType().CreateInstance <Candle>();

                indexCandle.Security = _security;
                indexCandle.Arg = CloneArg(candle.Arg, _security);
                indexCandle.OpenTime = buffer.OpenTime;
                indexCandle.CloseTime = buffer.CloseTime;

                try
                {
                    indexCandle.OpenPrice = Calculate(buffer, true, c => c.OpenPrice);
                    indexCandle.ClosePrice = Calculate(buffer, true, c => c.ClosePrice);
                    indexCandle.HighPrice = Calculate(buffer, true, c => c.HighPrice);
                    indexCandle.LowPrice = Calculate(buffer, true, c => c.LowPrice);

                    if (_security.CalculateExtended)
                    {
                        indexCandle.TotalVolume = Calculate(buffer, false, c => c.TotalVolume);

                        indexCandle.TotalPrice = Calculate(buffer, true, c => c.TotalPrice);
                        indexCandle.OpenVolume = Calculate(buffer, false, c => c.OpenVolume ?? 0);
                        indexCandle.CloseVolume = Calculate(buffer, false, c => c.CloseVolume ?? 0);
                        indexCandle.HighVolume = Calculate(buffer, false, c => c.HighVolume ?? 0);
                        indexCandle.LowVolume = Calculate(buffer, false, c => c.LowVolume ?? 0);
                    }
                }
                catch (ArithmeticException ex)
                {
                    if (!_security.IgnoreErrors)
                    {
                        throw;
                    }

                    ex.LogError();
                    return null;
                }

                // если некоторые свечи имеют неполные данные, то и индекс будет таким же неполным
                if (indexCandle.OpenPrice == 0 || indexCandle.HighPrice == 0 || indexCandle.LowPrice == 0 || indexCandle.ClosePrice == 0)
                {
                    var nonZeroPrice = indexCandle.OpenPrice;

                    if (nonZeroPrice == 0)
                    {
                        nonZeroPrice = indexCandle.HighPrice;
                    }

                    if (nonZeroPrice == 0)
                    {
                        nonZeroPrice = indexCandle.LowPrice;
                    }

                    if (nonZeroPrice == 0)
                    {
                        nonZeroPrice = indexCandle.LowPrice;
                    }

                    if (nonZeroPrice != 0)
                    {
                        if (indexCandle.OpenPrice == 0)
                        {
                            indexCandle.OpenPrice = nonZeroPrice;
                        }

                        if (indexCandle.HighPrice == 0)
                        {
                            indexCandle.HighPrice = nonZeroPrice;
                        }

                        if (indexCandle.LowPrice == 0)
                        {
                            indexCandle.LowPrice = nonZeroPrice;
                        }

                        if (indexCandle.ClosePrice == 0)
                        {
                            indexCandle.ClosePrice = nonZeroPrice;
                        }
                    }
                }

                if (indexCandle.HighPrice < indexCandle.LowPrice)
                {
                    var high = indexCandle.HighPrice;

                    indexCandle.HighPrice = indexCandle.LowPrice;
                    indexCandle.LowPrice = high;
                }

                if (indexCandle.OpenPrice > indexCandle.HighPrice)
                {
                    indexCandle.HighPrice = indexCandle.OpenPrice;
                }
                else if (indexCandle.OpenPrice < indexCandle.LowPrice)
                {
                    indexCandle.LowPrice = indexCandle.OpenPrice;
                }

                if (indexCandle.ClosePrice > indexCandle.HighPrice)
                {
                    indexCandle.HighPrice = indexCandle.ClosePrice;
                }
                else if (indexCandle.ClosePrice < indexCandle.LowPrice)
                {
                    indexCandle.LowPrice = indexCandle.ClosePrice;
                }

                indexCandle.State = CandleStates.Finished;

                return indexCandle;
            })
                   .Where(c => c != null));
        }
示例#12
0
 /// <summary>
 /// Whether the candle is hammer.
 /// </summary>
 /// <param name="candle">The candle which should match the pattern.</param>
 /// <returns><see langword="true" /> if it is matched, <see langword="false" /> if not.</returns>
 public static bool IsHammer(this Candle candle)
 {
     return(!candle.IsMarubozu() && (candle.GetBottomShadow() == 0 || candle.GetTopShadow() == 0));
 }
		/// <summary>
		/// To add a candle for the series.
		/// </summary>
		/// <param name="series">Candles series.</param>
		/// <param name="candle">Candle.</param>
		/// <returns><see langword="true" /> if the candle is not added previously, otherwise, <see langword="false" />.</returns>
		public bool AddCandle(CandleSeries series, Candle candle)
		{
			var info = GetInfo(series);

			if (info == null)
				throw new InvalidOperationException(LocalizedStrings.Str648Params.Put(series));

			return info.AddCandle(candle);
		}
示例#14
0
				public void AddCandle(Candle candle)
				{
					if (_firstTime == null)
						_firstTime = candle.OpenTime;

					lock (_candles.SyncRoot)
					{
						if ((candle.OpenTime.Date - _firstTime.Value.Date).TotalDays >= 3)
						{
							_firstTime = candle.OpenTime;
							FlushCandles(_candles.CopyAndClear());
						}

						_candles.Add(candle);
					}
				}
示例#15
0
		private IIndicatorValue CreateIndicatorValue(ChartIndicatorElement element, Candle candle)
		{
			var indicator = _indicators.TryGetValue(element);

			if (indicator == null)
				throw new InvalidOperationException(LocalizedStrings.IndicatorNotFound.Put(element));

			return indicator.Process(candle);
		}
示例#16
0
		public IEnumerable<Candle> ProcessCandle(Candle candle)
		{
			return GetFormedBuffers(candle)
				.Select(buffer =>
				{
					var openPrice = TryCalculate(buffer, c => c.OpenPrice);

					if (openPrice == null)
						return null;

					var indexCandle = candle.GetType().CreateInstance<Candle>();

					indexCandle.Security = _security;
					indexCandle.Arg = CloneArg(candle.Arg, _security);
					indexCandle.OpenTime = buffer.OpenTime;
					indexCandle.CloseTime = buffer.CloseTime;

					indexCandle.TotalVolume = Calculate(buffer, c => c.TotalVolume);
					indexCandle.TotalPrice = Calculate(buffer, c => c.TotalPrice);
					indexCandle.OpenPrice = (decimal)openPrice;
					indexCandle.OpenVolume = Calculate(buffer, c => c.OpenVolume ?? 0);
					indexCandle.ClosePrice = Calculate(buffer, c => c.ClosePrice);
					indexCandle.CloseVolume = Calculate(buffer, c => c.CloseVolume ?? 0);
					indexCandle.HighPrice = Calculate(buffer, c => c.HighPrice);
					indexCandle.HighVolume = Calculate(buffer, c => c.HighVolume ?? 0);
					indexCandle.LowPrice = Calculate(buffer, c => c.LowPrice);
					indexCandle.LowVolume = Calculate(buffer, c => c.LowVolume ?? 0);

					// если некоторые свечи имеют неполные данные, то и индекс будет таким же неполным
					if (indexCandle.OpenPrice == 0 || indexCandle.HighPrice == 0 || indexCandle.LowPrice == 0 || indexCandle.ClosePrice == 0)
					{
						var nonZeroPrice = indexCandle.OpenPrice;

						if (nonZeroPrice == 0)
							nonZeroPrice = indexCandle.HighPrice;

						if (nonZeroPrice == 0)
							nonZeroPrice = indexCandle.LowPrice;

						if (nonZeroPrice == 0)
							nonZeroPrice = indexCandle.LowPrice;

						if (nonZeroPrice != 0)
						{
							if (indexCandle.OpenPrice == 0)
								indexCandle.OpenPrice = nonZeroPrice;

							if (indexCandle.HighPrice == 0)
								indexCandle.HighPrice = nonZeroPrice;

							if (indexCandle.LowPrice == 0)
								indexCandle.LowPrice = nonZeroPrice;

							if (indexCandle.ClosePrice == 0)
								indexCandle.ClosePrice = nonZeroPrice;
						}
					}

					if (indexCandle.HighPrice < indexCandle.LowPrice)
					{
						var high = indexCandle.HighPrice;

						indexCandle.HighPrice = indexCandle.LowPrice;
						indexCandle.LowPrice = high;
					}

					if (indexCandle.OpenPrice > indexCandle.HighPrice)
						indexCandle.HighPrice = indexCandle.OpenPrice;
					else if (indexCandle.OpenPrice < indexCandle.LowPrice)
						indexCandle.LowPrice = indexCandle.OpenPrice;

					if (indexCandle.ClosePrice > indexCandle.HighPrice)
						indexCandle.HighPrice = indexCandle.ClosePrice;
					else if (indexCandle.ClosePrice < indexCandle.LowPrice)
						indexCandle.LowPrice = indexCandle.ClosePrice;

					indexCandle.State = CandleStates.Finished;

					return indexCandle;
				})
				.Where(c => c != null);
		}
示例#17
0
			private Candle CreateFilledCandle(Candle candle)
			{
				if (candle == null)
					throw new ArgumentNullException(nameof(candle));

				var filledCandle = candle.GetType().CreateInstance<Candle>();

				//filledCandle.Series = candle.Series;
				filledCandle.Security = candle.Security;
				filledCandle.Arg = CloneArg(candle.Arg, candle.Security);
				filledCandle.OpenTime = candle.OpenTime;
				filledCandle.CloseTime = candle.CloseTime;

				//filledCandle.TotalVolume = candle.TotalVolume;
				//filledCandle.TotalPrice = candle.TotalPrice;
				filledCandle.OpenPrice = candle.ClosePrice;
				//filledCandle.OpenVolume = candle.CloseVolume;
				filledCandle.ClosePrice = candle.ClosePrice;
				//filledCandle.CloseVolume = candle.CloseVolume;
				filledCandle.HighPrice = candle.ClosePrice;
				//filledCandle.HighVolume = candle.CloseVolume;
				filledCandle.LowPrice = candle.ClosePrice;
				//filledCandle.LowVolume = candle.CloseVolume;

				filledCandle.State = CandleStates.Finished;

				return filledCandle;
			}
 protected void OnCandleProcessed(Candle candle)
 {
     if (CandleProcessed != null)
     {
         CandleProcessed(candle);
     }
 }
示例#19
0
        private IEnumerable <CandleBuffer> GetFormedBuffers(Candle candle)
        {
            var buffers = new List <CandleBuffer>();

            lock (_buffers.SyncRoot)
            {
                var buffer = _buffers.SafeAdd(candle.OpenTime, key => new CandleBuffer(_candleType, candle.OpenTime, candle.CloseTime, _bufferSize, false));
                buffer.AddCandle(_securityIndecies[candle.Security], candle);

                if (!buffer.IsFilled)
                {
                    return(Enumerable.Empty <CandleBuffer>());

                    // mika
                    // заполняем "размазанные" буфера, чтобы определить, что первее наступит,
                    // заполнится ли полностью одна из свечек,
                    // или мы сможем достроить спред из "размазанных" буферов

                    // TODO пока убрал, нужно больше тестов
                    if (_sparseBuffer1 == null)
                    {
                        _sparseBuffer1 = new CandleBuffer(_candleType, candle.OpenTime, candle.CloseTime, _bufferSize, true);
                    }

                    if (!_sparseBuffer1.IsFilled)
                    {
                        _sparseBuffer1.AddCandle(_securityIndecies[candle.Security], candle);
                    }
                    else
                    {
                        if (_sparseBuffer2 == null)
                        {
                            _sparseBuffer2 = new CandleBuffer(_candleType, candle.OpenTime, candle.CloseTime, _bufferSize, true);
                        }

                        _sparseBuffer2.AddCandle(_securityIndecies[candle.Security], candle);

                        // если первая свеча будет построена по размазанному буферу, то разница между временем эти буферов
                        // должна гарантировать, что между ними
                        //if (_lastProcessBuffer == null && _sparseBuffer2.IsFilled && (_sparseBuffer1.CloseTime > _sparseBuffer2.OpenTime))
                        //	return Enumerable.Empty<CandleBuffer>();
                    }

                    if (_sparseBuffer2 == null || !_sparseBuffer2.IsFilled)
                    {
                        return(Enumerable.Empty <CandleBuffer>());
                    }
                }

                // mika
                // далее идет обработка 4-рех ситуаций
                //
                // 1. первая свеча оказалась заполненой полностью, и мы просто удаляем начальные буфера
                // так как они уже никогда не заполняться.
                //
                // 2. первая свеча оказалось размазанной, тогда так же удаляем хвосты, но при этом формируем
                // из одной размазанной свечи N (= равное кол-ву инструментов) дозаполненных.
                //
                // 3. появилась заполненная полностью свеча, и тогда дозаполняем промежутки с _lastProcessBuffer
                //
                // 4. появилась размазанная свеча, и тогда дозаполняем промежутки с _lastProcessBuffer + формируем
                // из одной размазанной свечи N (= равное кол-ву инструментов) дозаполненных.

                var firstTimeBuffer = _lastProcessBuffer == null;

                // последней буфер, до которого (включительно) можно сформировать спред по текущим данным
                var lastBuffer = buffer.IsFilled ? buffer : _buffers[_sparseBuffer2.OpenTime];

                var deleteKeys = new List <DateTimeOffset>();

                foreach (var time in _buffers.CachedKeys)
                {
                    if (time >= lastBuffer.OpenTime)
                    {
                        break;
                    }

                    var curr = _buffers[time];

                    if (firstTimeBuffer)
                    {
                        if (!buffer.IsFilled)
                        {
                            if (_lastProcessBuffer == null)
                            {
                                _lastProcessBuffer = curr;
                            }
                            else
                            {
                                _lastProcessBuffer.Fill(curr);
                                _lastProcessBuffer = curr;
                            }
                        }
                    }
                    else
                    {
                        curr.Fill(_lastProcessBuffer);

                        if (!curr.IsFilled)
                        {
                            throw new InvalidOperationException(LocalizedStrings.Str655);
                        }

                        _lastProcessBuffer = curr;
                        buffers.Add(curr);
                    }

                    deleteKeys.Add(time);
                }

                if (!buffer.IsFilled)
                {
                    lastBuffer.Fill(_lastProcessBuffer);
                }

                if (!lastBuffer.IsFilled)
                {
                    throw new InvalidOperationException(LocalizedStrings.Str656);
                }

                deleteKeys.Add(lastBuffer.OpenTime);

                _lastProcessBuffer = lastBuffer;
                buffers.Add(lastBuffer);

                _sparseBuffer1 = _sparseBuffer2;
                _sparseBuffer2 = null;

                deleteKeys.ForEach(k => _buffers.Remove(k));
            }

            return(buffers);
        }
示例#20
0
		private IEnumerable<CandleBuffer> GetFormedBuffers(Candle candle)
		{
			var buffers = new List<CandleBuffer>();

			lock (_buffers.SyncRoot)
			{
				var buffer = _buffers.SafeAdd(candle.OpenTime, key => new CandleBuffer(candle.OpenTime, candle.CloseTime, _bufferSize, false));
				buffer.AddCandle(_securityIndecies[candle.Security], candle);

				if (!buffer.IsFilled)
				{
					return Enumerable.Empty<CandleBuffer>();

					// mika
					// заполняем "размазанные" буфера, чтобы определить, что первее наступит,
					// заполнится ли полностью одна из свечек,
					// или мы сможем достроить спред из "размазанных" буферов

					// TODO пока убрал, нужно больше тестов
					if (_sparseBuffer1 == null)
						_sparseBuffer1 = new CandleBuffer(candle.OpenTime, candle.CloseTime, _bufferSize, true);

					if (!_sparseBuffer1.IsFilled)
						_sparseBuffer1.AddCandle(_securityIndecies[candle.Security], candle);
					else
					{
						if (_sparseBuffer2 == null)
							_sparseBuffer2 = new CandleBuffer(candle.OpenTime, candle.CloseTime, _bufferSize, true);

						_sparseBuffer2.AddCandle(_securityIndecies[candle.Security], candle);

						// если первая свеча будет построена по размазанному буферу, то разница между временем эти буферов
						// должна гарантировать, что между ними 
						//if (_lastProcessBuffer == null && _sparseBuffer2.IsFilled && (_sparseBuffer1.CloseTime > _sparseBuffer2.OpenTime))
						//	return Enumerable.Empty<CandleBuffer>();
					}

					if (_sparseBuffer2 == null || !_sparseBuffer2.IsFilled)
						return Enumerable.Empty<CandleBuffer>();
				}

				// mika
				// далее идет обработка 4-рех ситуаций
				//
 				// 1. первая свеча оказалась заполненой полностью, и мы просто удаляем начальные буфера
				// так как они уже никогда не заполняться.
				//
				// 2. первая свеча оказалось размазанной, тогда так же удаляем хвосты, но при этом формируем
				// из одной размазанной свечи N (= равное кол-ву инструментов) дозаполненных.
				//
				// 3. появилась заполненная полностью свеча, и тогда дозаполняем промежутки с _lastProcessBuffer
				//
				// 4. появилась размазанная свеча, и тогда дозаполняем промежутки с _lastProcessBuffer + формируем
				// из одной размазанной свечи N (= равное кол-ву инструментов) дозаполненных.

				var firstTimeBuffer = _lastProcessBuffer == null;

				// последней буфер, до которого (включительно) можно сформировать спред по текущим данным
				var lastBuffer = buffer.IsFilled ? buffer : _buffers[_sparseBuffer2.OpenTime];

				var deleteKeys = new List<DateTimeOffset>();

				foreach (var time in _buffers.CachedKeys)
				{
					if (time >= lastBuffer.OpenTime)
						break;

					var curr = _buffers[time];

					if (firstTimeBuffer)
					{
						if (!buffer.IsFilled)
						{
							if (_lastProcessBuffer == null)
								_lastProcessBuffer = curr;
							else
							{
								_lastProcessBuffer.Fill(curr);
								_lastProcessBuffer = curr;
							}
						}
					}
					else
					{
						curr.Fill(_lastProcessBuffer);

						if (!curr.IsFilled)
							throw new InvalidOperationException(LocalizedStrings.Str655);

						_lastProcessBuffer = curr;
						buffers.Add(curr);
					}

					deleteKeys.Add(time);
				}

				if (!buffer.IsFilled)
					lastBuffer.Fill(_lastProcessBuffer);

				if (!lastBuffer.IsFilled)
					throw new InvalidOperationException(LocalizedStrings.Str656);

				deleteKeys.Add(lastBuffer.OpenTime);

				_lastProcessBuffer = lastBuffer;
				buffers.Add(lastBuffer);

				_sparseBuffer1 = _sparseBuffer2;
				_sparseBuffer2 = null;

				deleteKeys.ForEach(k => _buffers.Remove(k));
			}

			return buffers;
		}
示例#21
0
		private void Process(Candle candle)
		{
			//this.AddInfoLog("Свеча {0}: {1};{2};{3};{4}; объем {5}", candle.OpenTime, candle.OpenPrice, candle.HighPrice, candle.LowPrice, candle.ClosePrice, candle.TotalVolume);

			var isShortWasFormed = _shortSma.IsFormed;
			var isLongWasFormed = _longSma.IsFormed;

			var currentShort = _shortSma.Process(candle);
			var currentLong = _longSma.Process(candle);

			if (candle.State == CandleStates.Finished && isShortWasFormed && isLongWasFormed
				&& _longSma.Length > 1 && _shortSma.Length > 1 && candle.OpenTime > StartedTime)
			{
				Order order = null;

				var prevShort = _shortSma.GetValue(1);
				var prevLong = _longSma.GetValue(1);

				if (prevShort < prevLong && currentShort.GetValue<decimal>() > currentLong.GetValue<decimal>() && Position <= 0)
				{
					this.AddInfoLog(LocalizedStrings.Str3297);
					order = this.BuyAtMarket(Position == 0 ? Volume : Position.Abs() * 2);
				}
				else if (prevShort > prevLong && currentShort.GetValue<decimal>() < currentLong.GetValue<decimal>() && Position >= 0)
				{
					this.AddInfoLog(LocalizedStrings.Str3298);
					order = this.SellAtMarket(Position == 0 ? Volume : Position.Abs() * 2);
				}

				if (order != null)
					RegisterOrder(order);
			}

			new ChartDrawCommand(candle.OpenTime, new Dictionary<IChartElement, object>
			{
				{ _area.Elements[0], candle },
				{ _area.Elements[1], currentLong },
				{ _area.Elements[2], currentShort },
			}).Process(this);
		}
示例#22
0
		protected virtual void ProcessCandle(Candle candle)
		{
			if (Orders.Any(o => o.State == OrderStates.Active || o.State == OrderStates.Pending || o.State == OrderStates.None))
			{
				//Logger.DebugFormat("Blocks Orders because: State");
				return;
			}

			var timeout = TimeSpan.FromMilliseconds(_strategyConfiguration.CandleTimeFrame.TotalMilliseconds*6);
			if (Orders.Any(o => o.Time.Add(timeout) > CurrentTime))
			{
				//Logger.DebugFormat("Blocks Orders because: Last Order Time");
				return;
			}

			TimeFrameCandle lastCandle = _series.GetCandle<TimeFrameCandle>(1);
			if (lastCandle == null)
			{
				//Logger.DebugFormat("Can't get last candle yet.");
				return;
			}

			// hack to avoid analyzing obsolete candles
			if (candle.ClosePrice == lastCandle.ClosePrice
				|| candle.CloseTime.Add(_strategyConfiguration.CandleTimeFrame) < CurrentTime)
			{
				return;
			}

			Sides direction;
			decimal targetPrice;
			bool isOrderAllowed = false;

			if (candle.ClosePrice > lastCandle.ClosePrice)
			{
				direction = Sides.Buy;
				targetPrice = candle.ClosePrice + _strategyConfiguration.TakeProfitLevel;

				if (lastCandle.HighPrice > targetPrice)
				{
					isOrderAllowed = true;
				}
			}
            else
            {
	            direction = Sides.Sell;
				targetPrice = candle.ClosePrice - _strategyConfiguration.TakeProfitLevel;

				if (lastCandle.LowPrice < targetPrice)
				{
					isOrderAllowed = true;
				}
			}

			if (!isOrderAllowed)
			{
				return;
			}
			
			var newOrder = direction == Sides.Buy
				? this.BuyAtLimit(candle.ClosePrice)
				: this.SellAtLimit(candle.ClosePrice);

			Logger.WarnFormat("New Order: {0}", newOrder);

			newOrder
				.WhenNewTrades()
				.Do(OnNewOrderTrades)
				.Apply(this);

			RegisterOrder(newOrder);
		}
		private void ProcessIndexSourceElements(Candle candle)
		{
			var element = _sourceElements.TryGetValue(candle.Series.Security);

			if (element == null)
				return;

			_bufferedChart.Draw(candle.OpenTime, new Dictionary<IChartElement, object>
			{
				{ element, CreateIndicatorValue(element, candle) }
			});
		}
        protected void ProcessCandle(Candle candle)
        {
            if (candle == null || candle.State != CandleStates.Finished)
            {
                return;
            }

            LongMA.Process(candle);
            ShortMA.Process(candle);
            FilterMA.Process(candle);

            if (candle.CloseTime > this._strategyStartTime
                && LongMA.IsFormed
                && ShortMA.IsFormed
                && FilterMA.IsFormed)
            {
                this.AnalyseAndTrade();
            }

            this.OnCandleProcessed(candle);
        }
示例#25
0
		public void ProcessCandles(Candle candle)
		{
			Chart.Draw(_candleElement, candle);
		}
		private void ProcessCandle(CandleSeries series, Candle candle)
		{
			// возможно была задержка в получении данных и обработаны еще не все данные
			if (!_isStarted)
				this.GuiAsync(() => IsStarted = true);

			_timer.Activate();

			_candlesCount++;

			// ограничиваем кол-во передаваемых свечек, чтобы не фризился интерфейс
			if (_candlesCount % 100 == 0)
				System.Threading.Thread.Sleep(200);

			var candleSeries = (CandleSeries)_bufferedChart.GetSource(_candleElement);

			if (series == candleSeries)
			{
				var values = new Dictionary<IChartElement, object>();

				lock (_syncRoot)
				{
					foreach (var element in _bufferedChart.Elements.Where(e => _bufferedChart.GetSource(e) == series))
					{
						if (_skipElements.Contains(element))
							continue;

						element.DoIf<IChartElement, ChartCandleElement>(e => values.Add(e, candle));
						element.DoIf<IChartElement, ChartIndicatorElement>(e => values.Add(e, CreateIndicatorValue(e, candle)));
					}
				}

				_bufferedChart.Draw(candle.OpenTime, values);

				if (series.Security is ContinuousSecurity)
				{
					// для непрерывных инструментов всегда приходят данные по одной серии
					// но инструмент у свечки будет равен текущему инструменту
					ProcessContinuousSourceElements(candle);
				}
			}
			else
			{
				// для индексов будут приходить отдельные свечки для каждого инструмента
				ProcessIndexSourceElements(candle);
			}
		}
示例#27
0
        private static void GetCandles(CandleSeries series, Candle candle)
        {
            if (candle.State == CandleStates.Finished)
            {
                LisfStreamWriters[series.ToString()].WriteLine(candle.OpenTime.Date.ToString("d") + " " + candle.OpenTime.DateTime.ToString("T") +
                                       " " + candle.OpenPrice.ToString()+ " "+ candle.HighPrice.ToString() +" "+
                                       candle.LowPrice.ToString() +" "+candle.ClosePrice.ToString() +" "+candle.TotalVolume.ToString());

                Console.Write(".");
            }
        }
		private void ProcessContinuousSourceElements(Candle candle)
		{
			var values = _sourceElements
				.Select(sourceElement => sourceElement.Value)
				.ToDictionary<ChartIndicatorElement, IChartElement, object>(e => e, e => CreateIndicatorValue(e, candle));

			_bufferedChart.Draw(candle.OpenTime, values);
		}
		private void OnProcessCandle(Candle candle)
		{
			if (candle.State == CandleStates.Finished)
				NewCandle(candle);
		}
示例#30
0
		private void Process(Candle candle)
		{
			var values = new Dictionary<IChartElement, object>();

			lock (_syncRoot)
			{
				this.AddInfoLog("{0}: {1}", candle.OpenTime, candle.State);

				var elements = _elementsBySeries[candle.Series]
					.OfType<ChartIndicatorElement>();

				var candleElement = _elementsBySeries[candle.Series]
					.OfType<ChartCandleElement>()
					.FirstOrDefault();

				if (candle.State == CandleStates.Finished)
					this.AddInfoLog(LocalizedStrings.Str3634Params, candle.OpenTime, candle.OpenPrice, candle.HighPrice, candle.LowPrice, candle.ClosePrice, candle.TotalVolume, candle.Security.Id);

				if (candleElement != null)
					values.Add(candleElement, candle);

				foreach (var element in elements)
				{
					var info = _elementsInfo[element];

					if (candle.OpenTime < info.First)
						continue;

					info.First = candle.OpenTime;
					values.Add(element, CreateIndicatorValue(element, candle));
				}
			}

			if (values.Count > 0)
				new ChartDrawCommand(candle.OpenTime, values).Process(this);
		}
示例#31
0
        public IEnumerable <Candle> ProcessCandle(Candle candle)
        {
            return(GetFormedBuffers(candle)
                   .Select(buffer =>
            {
                //var openPrice = Calculate(buffer, c => c.OpenPrice);

                //if (openPrice == null)
                //	return null;

                var indexCandle = candle.GetType().CreateInstance <Candle>();

                indexCandle.Security = _security;
                indexCandle.Arg = CloneArg(candle.Arg, _security);
                indexCandle.OpenTime = buffer.OpenTime;
                indexCandle.CloseTime = buffer.CloseTime;

                indexCandle.TotalVolume = Calculate(buffer, c => c.TotalVolume);
                indexCandle.TotalPrice = Calculate(buffer, c => c.TotalPrice);
                indexCandle.OpenPrice = Calculate(buffer, c => c.OpenPrice);
                indexCandle.OpenVolume = Calculate(buffer, c => c.OpenVolume ?? 0);
                indexCandle.ClosePrice = Calculate(buffer, c => c.ClosePrice);
                indexCandle.CloseVolume = Calculate(buffer, c => c.CloseVolume ?? 0);
                indexCandle.HighPrice = Calculate(buffer, c => c.HighPrice);
                indexCandle.HighVolume = Calculate(buffer, c => c.HighVolume ?? 0);
                indexCandle.LowPrice = Calculate(buffer, c => c.LowPrice);
                indexCandle.LowVolume = Calculate(buffer, c => c.LowVolume ?? 0);

                // если некоторые свечи имеют неполные данные, то и индекс будет таким же неполным
                if (indexCandle.OpenPrice == 0 || indexCandle.HighPrice == 0 || indexCandle.LowPrice == 0 || indexCandle.ClosePrice == 0)
                {
                    var nonZeroPrice = indexCandle.OpenPrice;

                    if (nonZeroPrice == 0)
                    {
                        nonZeroPrice = indexCandle.HighPrice;
                    }

                    if (nonZeroPrice == 0)
                    {
                        nonZeroPrice = indexCandle.LowPrice;
                    }

                    if (nonZeroPrice == 0)
                    {
                        nonZeroPrice = indexCandle.LowPrice;
                    }

                    if (nonZeroPrice != 0)
                    {
                        if (indexCandle.OpenPrice == 0)
                        {
                            indexCandle.OpenPrice = nonZeroPrice;
                        }

                        if (indexCandle.HighPrice == 0)
                        {
                            indexCandle.HighPrice = nonZeroPrice;
                        }

                        if (indexCandle.LowPrice == 0)
                        {
                            indexCandle.LowPrice = nonZeroPrice;
                        }

                        if (indexCandle.ClosePrice == 0)
                        {
                            indexCandle.ClosePrice = nonZeroPrice;
                        }
                    }
                }

                if (indexCandle.HighPrice < indexCandle.LowPrice)
                {
                    var high = indexCandle.HighPrice;

                    indexCandle.HighPrice = indexCandle.LowPrice;
                    indexCandle.LowPrice = high;
                }

                if (indexCandle.OpenPrice > indexCandle.HighPrice)
                {
                    indexCandle.HighPrice = indexCandle.OpenPrice;
                }
                else if (indexCandle.OpenPrice < indexCandle.LowPrice)
                {
                    indexCandle.LowPrice = indexCandle.OpenPrice;
                }

                if (indexCandle.ClosePrice > indexCandle.HighPrice)
                {
                    indexCandle.HighPrice = indexCandle.ClosePrice;
                }
                else if (indexCandle.ClosePrice < indexCandle.LowPrice)
                {
                    indexCandle.LowPrice = indexCandle.ClosePrice;
                }

                indexCandle.State = CandleStates.Finished;

                return indexCandle;
            })
                   .Where(c => c != null));
        }
示例#32
0
			private void OnProcessing(CandleSeries series, Candle candle)
			{
				if (candle.State != CandleStates.Finished)
					return;

				//if (candle.TotalVolume == 0)
				//	throw new Exception();

				_candles.SafeAdd(series, key => new StorageSeriesInfo(key)).AddCandle(candle);
			}
示例#33
0
		private void ProcessCandle(Candle candle)
		{
			var longValue = candle.State == CandleStates.Finished ? _strategy.LongSma.Process(candle) : null;
			var shortValue = candle.State == CandleStates.Finished ? _strategy.ShortSma.Process(candle) : null;

			_chart.Draw(candle.OpenTime, new Dictionary<IChartElement, object>
			{
				{ _candlesElem, candle },
				{ _longMaElem, longValue },
				{ _shortMaElem, shortValue },
			});
		}
示例#34
0
		private void CandleManagerProcessing(CandleSeries series, Candle candle)
		{
			if (series == this)
				ProcessCandle.SafeInvoke(candle);
		}
示例#35
0
 /// <summary>
 /// Whether the candle is neutral to trades.
 /// </summary>
 /// <param name="candle">The candle for which you need to calculate whether it is neutral.</param>
 /// <returns><see langword="true" /> if the candle is neutral, <see langword="false" /> if it is not neutral.</returns>
 /// <remarks>
 /// The neutrality is defined as a situation when during the candle neither buyers nor sellers have not created a trend.
 /// </remarks>
 public static bool IsSpinningTop(this Candle candle)
 {
     return(!candle.IsMarubozu() && (candle.GetBottomShadow() == candle.GetTopShadow()));
 }