//private decimal? TryCalculate(CandleBuffer buffer, Func<Candle, decimal> getPart) //{ // return _security.Calculate(buffer.Candles.ToDictionary(c => _securityToSecurity[c.Security], getPart)); //} private decimal Calculate(CandleBuffer buffer, Func <Candle, decimal> getPart) { return(_security.Calculate(buffer.Candles.Select(getPart).ToArray())); //var calculate = TryCalculate(buffer, getPart); //if (calculate == null) // throw new InvalidOperationException(LocalizedStrings.Str657); //return (decimal)calculate; }
private decimal Calculate(CandleBuffer buffer, Func <Candle, decimal> getPart) { var calculate = TryCalculate(buffer, getPart); if (calculate == null) { throw new InvalidOperationException(LocalizedStrings.Str657); } return((decimal)calculate); }
private decimal Calculate(CandleBuffer buffer, bool isPrice, Func <Candle, decimal> getPart) { var values = buffer.Candles.Select(getPart).ToArray(); try { return(_security.Calculate(values, isPrice)); } catch (ArithmeticException excp) { throw new ArithmeticException(LocalizedStrings.BuildIndexError.Put(_security, _security.InnerSecurityIds.Zip(values, (s, v) => "{0}: {1}".Put(s, v)).Join(", ")), excp); } }
private decimal Calculate(CandleBuffer buffer, Func <Candle, decimal> getPart) { var values = buffer.Candles.Select(getPart).ToArray(); try { return(_security.Calculate(values)); } catch (ArithmeticException excp) { throw new ArithmeticException("Build index candle {0} for {1} error.".Put(_security, _security.InnerSecurities.Zip(values, (s, v) => "{0}: {1}".Put(s, v)).Join(", ")), excp); } }
public void Fill(CandleBuffer prevBuffer) { if (prevBuffer == null) throw new ArgumentNullException(nameof(prevBuffer)); for (var i = 0; i < Candles.Length; i++) { if (Candles[i] == null && prevBuffer.Candles[i] != null) { Candles[i] = CreateFilledCandle(prevBuffer.Candles[i]); _counter--; } //if (Candles[i] == null) // throw new ArgumentException("Предыдущий буфер так же не содержит свечи.", "prevBuffer"); } }
public void Fill(CandleBuffer prevBuffer) { if (prevBuffer == null) { throw new ArgumentNullException(nameof(prevBuffer)); } for (var i = 0; i < Candles.Length; i++) { if (Candles[i] == null && prevBuffer.Candles[i] != null) { Candles[i] = CreateFilledCandle(prevBuffer.Candles[i]); _counter--; } //if (Candles[i] == null) // throw new ArgumentException("Предыдущий буфер так же не содержит свечи.", "prevBuffer"); } }
private decimal?TryCalculate(CandleBuffer buffer, Func <Candle, decimal> getPart) { return(_security.Calculate(buffer.Candles.ToDictionary(c => _securityToSecurity[c.Security], getPart))); }
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); }
public void Reset() { _lastProcessBuffer = null; _buffers.Clear(); }
private decimal Calculate(CandleBuffer buffer, Func<Candle, decimal> getPart) { var calculate = TryCalculate(buffer, getPart); if (calculate == null) throw new InvalidOperationException(LocalizedStrings.Str657); return (decimal)calculate; }
private decimal? TryCalculate(CandleBuffer buffer, Func<Candle, decimal> getPart) { return _security.Calculate(buffer.Candles.ToDictionary(c => _securityToSecurity[c.Security], getPart)); }
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 int updateCurrentInfoGrid() { int result = 0; try { this.CurrentInfoGrid.Rows.Clear(); if (m_boxer == null) { result = 1; return(result); } CandleBuffer candleBuf = m_boxer.getCandleBuffer(); if (candleBuf == null) { result = 1; return(result); } Candlestick curCandle = candleBuf.getLastCandle(); if (curCandle == null) { result = 1; return(result); } Position pos = m_boxer.getPosition(); if (pos == null) { result = 1; return(result); } { // ポジション int idx = this.CurrentInfoGrid.Rows.Add(); this.CurrentInfoGrid.Rows[idx].Cells[0].Value = "POS"; this.CurrentInfoGrid.Rows[idx].Cells[1].Value = m_boxer.getPositionName(); } { // Entry値 int idx = this.CurrentInfoGrid.Rows.Add(); this.CurrentInfoGrid.Rows[idx].Cells[0].Value = "ENTRY"; this.CurrentInfoGrid.Rows[idx].Cells[1].Value = string.Format("{0:0}", m_boxer.getEntryPrice()); } { // 利益 int idx = this.CurrentInfoGrid.Rows.Add(); this.CurrentInfoGrid.Rows[idx].Cells[0].Value = "PROFIT_SUM"; this.CurrentInfoGrid.Rows[idx].Cells[1].Value = string.Format("{0:0}", m_boxer.m_profitSum); } { // 終値(現在値) int idx = this.CurrentInfoGrid.Rows.Add(); this.CurrentInfoGrid.Rows[idx].Cells[0].Value = "LAST"; this.CurrentInfoGrid.Rows[idx].Cells[1].Value = string.Format("{0:0}", curCandle.last); } //{ // // EMA // int idx = this.CurrentInfoGrid.Rows.Add(); // this.CurrentInfoGrid.Rows[idx].Cells[0].Value = "EMA"; // this.CurrentInfoGrid.Rows[idx].Cells[1].Value = string.Format("{0:0}", curCandle.ema); //} //{ // // BOLL_H // int idx = this.CurrentInfoGrid.Rows.Add(); // this.CurrentInfoGrid.Rows[idx].Cells[0].Value = "BOLL_H"; // this.CurrentInfoGrid.Rows[idx].Cells[1].Value = string.Format("{0:0}", curCandle.boll_high); //} //{ // // BOLL_L // int idx = this.CurrentInfoGrid.Rows.Add(); // this.CurrentInfoGrid.Rows[idx].Cells[0].Value = "BOLL_L"; // this.CurrentInfoGrid.Rows[idx].Cells[1].Value = string.Format("{0:0}", curCandle.boll_low); //} { // LASTとEMAとの差 int idx = this.CurrentInfoGrid.Rows.Add(); this.CurrentInfoGrid.Rows[idx].Cells[0].Value = "EMA_DIFF"; this.CurrentInfoGrid.Rows[idx].Cells[1].Value = string.Format("{0:0}", curCandle.last - curCandle.ema); } { // EMAの角度 int idx = this.CurrentInfoGrid.Rows.Add(); this.CurrentInfoGrid.Rows[idx].Cells[0].Value = "EMA_ANGLE"; this.CurrentInfoGrid.Rows[idx].Cells[1].Value = string.Format("{0:0.0}", curCandle.ema_angle); } { int idx = this.CurrentInfoGrid.Rows.Add(); this.CurrentInfoGrid.Rows[idx].Cells[0].Value = "CUR_BB"; if (curCandle == null) { this.CurrentInfoGrid.Rows[idx].Cells[1].Value = "NONE"; } else { if (curCandle.isTouchBollHighLow()) { this.CurrentInfoGrid.Rows[idx].Cells[1].Value = "TOUCH"; } else { this.CurrentInfoGrid.Rows[idx].Cells[1].Value = "NONE"; } } } { int idx = this.CurrentInfoGrid.Rows.Add(); this.CurrentInfoGrid.Rows[idx].Cells[0].Value = "PREV_BB"; int curIndex = candleBuf.getCandleCount() - 1; Candlestick prevCandle = candleBuf.getCandle(curIndex - 1); Candlestick pastCandle = candleBuf.getCandle(curIndex - 2); if (prevCandle == null && pastCandle == null) { this.CurrentInfoGrid.Rows[idx].Cells[1].Value = "NONE"; } else { if (prevCandle.isTouchBollHighLow()) { this.CurrentInfoGrid.Rows[idx].Cells[1].Value = "PREV_TOUCH"; } else if (pastCandle.isTouchBollHighLow()) { this.CurrentInfoGrid.Rows[idx].Cells[1].Value = "PAST_TOUCH"; } else { this.CurrentInfoGrid.Rows[idx].Cells[1].Value = "NONE"; } } } { int idx = this.CurrentInfoGrid.Rows.Add(); this.CurrentInfoGrid.Rows[idx].Cells[0].Value = "PRE_LONG_LV"; this.CurrentInfoGrid.Rows[idx].Cells[1].Value = m_boxer.m_preLongBollLv; } { int idx = this.CurrentInfoGrid.Rows.Add(); this.CurrentInfoGrid.Rows[idx].Cells[0].Value = "CUR_LONG_LV"; this.CurrentInfoGrid.Rows[idx].Cells[1].Value = m_boxer.m_curLongBollLv; } { int idx = this.CurrentInfoGrid.Rows.Add(); this.CurrentInfoGrid.Rows[idx].Cells[0].Value = "PRE_SHORT_LV"; this.CurrentInfoGrid.Rows[idx].Cells[1].Value = m_boxer.m_preShortBollLv; } { int idx = this.CurrentInfoGrid.Rows.Add(); this.CurrentInfoGrid.Rows[idx].Cells[0].Value = "CUR_SHORT_LV"; this.CurrentInfoGrid.Rows[idx].Cells[1].Value = m_boxer.m_curShortBollLv; } { double vola = curCandle.getVolatility(); int idx = this.CurrentInfoGrid.Rows.Add(); this.CurrentInfoGrid.Rows[idx].Cells[0].Value = "VOLA"; this.CurrentInfoGrid.Rows[idx].Cells[1].Value = string.Format("{0:0}", vola); } { int idx = this.CurrentInfoGrid.Rows.Add(); this.CurrentInfoGrid.Rows[idx].Cells[0].Value = "VOLA_MA"; this.CurrentInfoGrid.Rows[idx].Cells[1].Value = string.Format("{0:0}", curCandle.vola_ma); } { double vola_rate = curCandle.getVolatilityRate(); int idx = this.CurrentInfoGrid.Rows.Add(); this.CurrentInfoGrid.Rows[idx].Cells[0].Value = "VOLA_RATE"; this.CurrentInfoGrid.Rows[idx].Cells[1].Value = string.Format("{0:0}%", vola_rate); } } catch (Exception ex) { Console.WriteLine(ex); result = -1; } finally { } return(result); }
private int updateIndicatorChart() { int result = 0; try { m_series_indi.Points.Clear(); if (m_boxer == null) { result = 1; return(result); } CandleBuffer candleBuf = m_boxer.getCandleBuffer(); if (candleBuf == null) { result = 1; return(result); } if (!candleBuf.isFullBuffer()) { result = 1; return(result); } int candle_full_cnt = candleBuf.getCandleCount(); if (candle_full_cnt <= 0) { result = -1; return(result); } int beg_idx = 0; if (candle_full_cnt >= 100) { beg_idx = candle_full_cnt - 100; } int candle_cnt = 0; double y_min = 0.0; double y_max = 0.0; //foreach (Candlestick candle in candleBuf.getCandleList()) for (int i = beg_idx; i < candle_full_cnt; i++) { Candlestick candle = candleBuf.getCandle(i); if (candle == null) { continue; } double value = Math.Floor(candle.ma_top_increase_rate); DataPoint dp_value = new DataPoint(candle_cnt, value); m_series_indi.Points.Add(dp_value); // 表示範囲を算出 if (candle_cnt == 0) { y_max = value; y_min = 0.0; } else { if (y_max < value) { y_max = value; } if (y_min > value) { y_min = value; } } candle_cnt++; } m_series_indi.ChartArea = "IndicatorChart"; m_indicatorArea.AxisY.Minimum = Math.Floor(y_min); m_indicatorArea.AxisY.Maximum = Math.Floor(y_max); this.chart1.Series.Add(m_series_indi); } catch (Exception ex) { Console.WriteLine(ex); result = -1; } finally { } return(result); }
private int updateCandleChart() { int result = 0; try { m_series_ltp.Points.Clear(); m_series_ema.Points.Clear(); m_series_ema_sub.Points.Clear(); m_series_bollHigh.Points.Clear(); m_series_bollLow.Points.Clear(); m_series_bollHigh_top.Points.Clear(); m_series_bollLow_top.Points.Clear(); m_series_min.Points.Clear(); m_series_max.Points.Clear(); m_series_body_min.Points.Clear(); m_series_body_max.Points.Clear(); m_series_entry.Points.Clear(); if (m_boxer == null) { result = 1; return(result); } CandleBuffer candleBuf = m_boxer.getCandleBuffer(); if (candleBuf == null) { result = 1; return(result); } Candlestick curCandle = candleBuf.getLastCandle(); if (curCandle == null) { result = 1; return(result); } double range_min = curCandle.range_min; double range_max = curCandle.range_max; double body_min = curCandle.body_min; double body_max = curCandle.body_max; double entry_price = m_boxer.getEntryPrice(); if (!candleBuf.isFullBuffer()) { result = 1; return(result); } int candle_full_cnt = candleBuf.getCandleCount(); if (candle_full_cnt <= 0) { result = -1; return(result); } int beg_idx = 0; if (candle_full_cnt >= 100) { beg_idx = candle_full_cnt - 100; } int candle_cnt = 0; double y_min = 0.0; double y_max = 0.0; //foreach (Candlestick candle in candleBuf.getCandleList()) for (int i = beg_idx; i < candle_full_cnt; i++) { Candlestick candle = candleBuf.getCandle(i); if (candle == null) { continue; } // High Low Open Closeの順番で配列を作成 double[] values = new double[4] { Math.Round(candle.high, 0), Math.Round(candle.low, 0), Math.Round(candle.open, 0), Math.Round(candle.last, 0) }; // 日付、四本値の配列からDataPointのインスタンスを作成 DataPoint dp = new DataPoint(candle_cnt, values); m_series_ltp.Points.Add(dp); DataPoint dp_ema = new DataPoint(candle_cnt, Math.Round(candle.ema, 0)); m_series_ema.Points.Add(dp_ema); DataPoint dp_ema_sub = new DataPoint(candle_cnt, Math.Round(candle.ema_sub, 0)); m_series_ema_sub.Points.Add(dp_ema_sub); DataPoint dp_bollHigh = new DataPoint(candle_cnt, Math.Round(candle.boll_high, 0)); m_series_bollHigh.Points.Add(dp_bollHigh); DataPoint dp_bollLow = new DataPoint(candle_cnt, Math.Round(candle.boll_low, 0)); m_series_bollLow.Points.Add(dp_bollLow); DataPoint dp_bollHigh_top = new DataPoint(candle_cnt, Math.Round(candle.boll_high_top, 0)); m_series_bollHigh_top.Points.Add(dp_bollHigh_top); DataPoint dp_bollLow_top = new DataPoint(candle_cnt, Math.Round(candle.boll_low_top, 0)); m_series_bollLow_top.Points.Add(dp_bollLow_top); DataPoint dp_min = new DataPoint(candle_cnt, Math.Round(range_min, 0)); m_series_min.Points.Add(dp_min); DataPoint dp_max = new DataPoint(candle_cnt, Math.Round(range_max, 0)); m_series_max.Points.Add(dp_max); DataPoint dp_body_min = new DataPoint(candle_cnt, Math.Round(body_min, 0)); m_series_body_min.Points.Add(dp_body_min); DataPoint dp_body_max = new DataPoint(candle_cnt, Math.Round(body_max, 0)); m_series_body_max.Points.Add(dp_body_max); if (entry_price > double.Epsilon) { DataPoint dp_entry = new DataPoint(candle_cnt, Math.Round(entry_price, 0)); m_series_entry.Points.Add(dp_entry); } double elem_max = candle.boll_high; double elem_min = candle.boll_low; if (candle.high > candle.boll_high) { elem_max = candle.high; } if (candle.low < candle.boll_low) { elem_min = candle.low; } if (candle.boll_high_top > elem_max) { elem_max = candle.boll_high_top; } if (candle.boll_low_top < elem_min) { elem_min = candle.boll_low_top; } // 表示範囲を算出 if (candle_cnt == 0) { y_max = elem_max; y_min = elem_min; } else { if (y_max < elem_max) { y_max = elem_max; } if (y_min > elem_min) { y_min = elem_min; } } candle_cnt++; } m_area.AxisY.Minimum = Math.Round(Math.Floor((y_min - 1000) / 1000) * 1000); m_area.AxisY.Maximum = Math.Round(Math.Ceiling((y_max + 1000) / 1000) * 1000); this.chart1.Series.Add(m_series_ltp); this.chart1.Series.Add(m_series_ema); this.chart1.Series.Add(m_series_ema_sub); this.chart1.Series.Add(m_series_bollHigh); this.chart1.Series.Add(m_series_bollLow); this.chart1.Series.Add(m_series_bollHigh_top); this.chart1.Series.Add(m_series_bollLow_top); this.chart1.Series.Add(m_series_min); this.chart1.Series.Add(m_series_max); this.chart1.Series.Add(m_series_body_min); this.chart1.Series.Add(m_series_body_max); if (entry_price > double.Epsilon) { this.chart1.Series.Add(m_series_entry); } // Console.WriteLine("update Chart. y_min={0} y_max={1}", y_min, y_max); } catch (Exception ex) { Console.WriteLine(ex); result = -1; } finally { } return(result); }