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); } } }
/// <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; }
/// <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; }
/// <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); }
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; } }
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; } }
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); }
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)); }
/// <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); }
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); } }
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); }
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); }
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); } }
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); }
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; }
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); }
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); }
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); } }
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); }
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); }
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)); }
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); }
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 }, }); }
private void CandleManagerProcessing(CandleSeries series, Candle candle) { if (series == this) ProcessCandle.SafeInvoke(candle); }
/// <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())); }