public override object DeserializeProperty(XmlNode parent) { var sets = new List<MultyTimeframeIndexSettings>(); foreach (var child in parent.ChildNodes) { if (child is XmlElement == false) continue; var node = (XmlElement) child; if (node.Name != "chartSeries") continue; var set = new MultyTimeframeIndexSettings(); set.chartId = node.Attributes["chartId"].Value; set.FullyQualifiedSeriesDestName = node.Attributes["seriesDest"].Value; set.FullyQualifiedSeriesSrcName = node.Attributes["seriesSrc"].Value; set.TimeframeAndSymbol = node.Attributes["tfSmb"].Value; set.DiverType = (IndicatorDiver.DivergenceType) Enum.Parse(typeof(IndicatorDiver.DivergenceType), node.Attributes["diverType"].Value); set.maxPastExtremum = node.Attributes["maxPastExtr"].Value.ToInt(); set.periodExtremum = node.Attributes["periodExtremum"].Value.ToInt(); set.marginUpper = node.Attributes["marginUpper"].Value.ToDoubleUniform(); set.marginLower = node.Attributes["marginLower"].Value.ToDoubleUniform(); sets.Add(set); } return sets; }
public override object DeserializeProperty(XmlNode parent) { var sets = new List <MultyTimeframeIndexSettings>(); foreach (var child in parent.ChildNodes) { if (child is XmlElement == false) { continue; } var node = (XmlElement)child; if (node.Name != "chartSeries") { continue; } var set = new MultyTimeframeIndexSettings(); set.chartId = node.Attributes["chartId"].Value; set.FullyQualifiedSeriesDestName = node.Attributes["seriesDest"].Value; set.FullyQualifiedSeriesSrcName = node.Attributes["seriesSrc"].Value; set.TimeframeAndSymbol = node.Attributes["tfSmb"].Value; set.DiverType = (IndicatorDiver.DivergenceType) Enum.Parse(typeof(IndicatorDiver.DivergenceType), node.Attributes["diverType"].Value); set.maxPastExtremum = node.Attributes["maxPastExtr"].Value.ToInt(); set.periodExtremum = node.Attributes["periodExtremum"].Value.ToInt(); set.marginUpper = node.Attributes["marginUpper"].Value.ToDoubleUniform(); set.marginLower = node.Attributes["marginLower"].Value.ToDoubleUniform(); sets.Add(set); } return(sets); }
/// <summary> /// построить дивергенции /// </summary> private void BuildDivers(MultyTimeframeIndexSettings src, Dictionary <int, List <DiverMarker> > signs) { // получить диверы var divers = src.DiverType == IndicatorDiver.DivergenceType.Классические ? FindDivergencePointsClassic(src) : FindDivergencePointsQuasi(src); // добавить их в словарь foreach (var diver in divers) { // пересчитать индекс свечки var index = diver.end; if (src.seriesDest is StockSeries) { var time = ((StockSeries)src.seriesDest).GetCandleOpenTimeByIndex(index); index = owner.StockSeries.GetIndexByCandleOpen(time); } // создать для свечки список маркеров или добавить готовый var marker = new DiverMarker(src.InverseDivergency ? -diver.sign : diver.sign, src.TimeframeAndSymbol); List <DiverMarker> markers; signs.TryGetValue(index, out markers); if (markers == null) { markers = new List <DiverMarker> { marker }; signs.Add(index, markers); } else { markers.Add(marker); } } }
/// <summary> /// Принять изменения /// </summary> private void BtnOkClick(object sender, EventArgs e) { DialogResult = DialogResult.Cancel; if (cbChart.SelectedIndex < 0) return; var chart = (CandleChartControlTag)cbChart.Items[cbChart.SelectedIndex]; if (sets == null) sets = new MultyTimeframeIndexSettings(); sets.chartId = chart.chart.UniqueId; sets.InverseDivergency = cbInverse.Checked; sets.FullyQualifiedSeriesSrcName = cbSeriesSrc.Text; sets.FullyQualifiedSeriesDestName = cbSeriesDest.Text; sets.TimeframeAndSymbol = cbChart.Text; sets.DiverType = (IndicatorDiver.DivergenceType)cbDiverType.SelectedItem; sets.periodExtremum = tbPeriodExtremum.Text.ToInt(); sets.maxPastExtremum = tbMaxPastExtremum.Text.ToInt(); // интервал var parts = tbIntervalMargins.Text.Split(new[] {' ', ',', ';', (char) 9}, StringSplitOptions.RemoveEmptyEntries); if (parts.Length == 2) { sets.marginLower = (double)(parts[0].ToDecimalUniformSafe() ?? 0); sets.marginUpper = (double)(parts[1].ToDecimalUniformSafe() ?? 0); } DialogResult = DialogResult.OK; }
public SetupChartSeriesDlg(List<CandleChartControl> charts, MultyTimeframeIndexSettings sets) : this() { this.charts = charts; this.sets = sets; }
private List<DiverSpan> FindDivergencePointsQuasi(MultyTimeframeIndexSettings src) { var divers = new List<DiverSpan>(); var srcCount = src.seriesDest.DataCount; float? lastPeak = null; var peakPrice = 0f; var extremumSign = 0; var startIndex = 0; for (var i = 0; i < srcCount; i++) { var index = src.GetSourcePrice(i) ?? 0; var indexNext = i < srcCount ? (src.GetSourcePrice(i + 1) ?? 0) : index; // если находимся в зоне перекупленности / перепроданности, // если след. точка ниже (выше для перепроданности), // если текущая точка выше последнего максимума (ниже минимума...) var margUp = index >= src.marginUpper; var margDn = index <= src.marginLower; if ((margUp && indexNext < index && index > (lastPeak.HasValue ? lastPeak.Value : float.MinValue)) || (margDn && indexNext > index && index < (lastPeak.HasValue ? lastPeak.Value : float.MaxValue))) {// + или - экстремум peakPrice = src.GetDestPrice(i) ?? 0; extremumSign = margUp ? 1 : -1; startIndex = i; lastPeak = index; continue; } if (!margUp && margDn == false) {// конец отсчета экстремума extremumSign = 0; lastPeak = null; continue; } // отсчет экстремума - сравнить дельту цены и дельту индекса var deltaPrice = (src.GetDestPrice(i) ?? 0) - peakPrice; var deltaIndex = index - lastPeak; if (extremumSign > 0) if (deltaPrice > 0 && deltaIndex < 0) // медвежий дивер { divers.Add(new DiverSpan(startIndex, i, -1)); peakPrice = src.GetDestPrice(i) ?? 0; } if (extremumSign < 0) if (deltaPrice < 0 && deltaIndex > 0) // бычий дивер { divers.Add(new DiverSpan(startIndex, i, 1)); peakPrice = src.GetDestPrice(i) ?? 0; } } return divers; }
/// <summary> /// построить дивергенции /// </summary> private void BuildDivers(MultyTimeframeIndexSettings src, Dictionary<int, List<DiverMarker>> signs) { // получить диверы var divers = src.DiverType == IndicatorDiver.DivergenceType.Классические ? FindDivergencePointsClassic(src) : FindDivergencePointsQuasi(src); // добавить их в словарь foreach (var diver in divers) { // пересчитать индекс свечки var index = diver.end; if (src.seriesDest is StockSeries) { var time = ((StockSeries) src.seriesDest).GetCandleOpenTimeByIndex(index); index = owner.StockSeries.GetIndexByCandleOpen(time); } // создать для свечки список маркеров или добавить готовый var marker = new DiverMarker(src.InverseDivergency ? -diver.sign : diver.sign, src.TimeframeAndSymbol); List<DiverMarker> markers; signs.TryGetValue(index, out markers); if (markers == null) { markers = new List<DiverMarker> { marker }; signs.Add(index, markers); } else markers.Add(marker); } }
private static IEnumerable<DiverSpan> FindDivergencePointsClassic(MultyTimeframeIndexSettings src) { var diverPairs = new List<DiverSpan>(); var srcCount = src.seriesDest.DataCount; // найти экстремумы var extremums = new List<Point>(); // index - sign for (var i = src.periodExtremum; i < srcCount - src.periodExtremum - 1; i++) { bool isPeak = true, isLow = true; var price = src.GetDestPrice(i) ?? 0; for (var j = i - src.periodExtremum; j <= i + src.periodExtremum; j++) { if (j == i) continue; var priceNear = src.GetDestPrice(j); if (priceNear > price) isPeak = false; if (priceNear < price) isLow = false; if (!isPeak && isLow == false) break; } if (isPeak) extremums.Add(new Point(i, 1)); if (isLow) extremums.Add(new Point(i, -1)); } // от каждого экстремумы поиск вперед до M баров - поиск экстремума на интервале [i-N...i+1] foreach (var extr in extremums) { var signExtr = extr.Y; var indexExtr = extr.X; var priceExtr = src.GetDestPrice(indexExtr); for (var i = extr.X + 1; i <= (extr.X + src.maxPastExtremum); i++) { if (i >= (srcCount - 1)) break; // новый "экстремум" должен быть выше старого var price = src.GetDestPrice(i) ?? 0; if ((signExtr > 0 && price <= priceExtr) || (signExtr < 0 && price >= priceExtr)) continue; // за новым "экстремумом" должна следовать точка ниже (выше для минимума) var nextPrice = src.GetDestPrice(i + 1) ?? 0; if ((signExtr > 0 && price <= nextPrice) || (signExtr < 0 && price >= nextPrice)) continue; // сравнение с дельтой индекса // !! смещение индекса var srcPriceI = src.GetSourcePrice(i) ?? 0; var srcPriceEx = src.GetSourcePrice(indexExtr) ?? 0; var deltaIndex = Math.Sign(srcPriceI - srcPriceEx); if (signExtr == deltaIndex) continue; // экстремум найден priceExtr = price; diverPairs.Add(new DiverSpan(indexExtr, i, -signExtr)); } } return diverPairs; }
private List <DiverSpan> FindDivergencePointsQuasi(MultyTimeframeIndexSettings src) { var divers = new List <DiverSpan>(); var srcCount = src.seriesDest.DataCount; float?lastPeak = null; var peakPrice = 0f; var extremumSign = 0; var startIndex = 0; for (var i = 0; i < srcCount; i++) { var index = src.GetSourcePrice(i) ?? 0; var indexNext = i < srcCount ? (src.GetSourcePrice(i + 1) ?? 0) : index; // если находимся в зоне перекупленности / перепроданности, // если след. точка ниже (выше для перепроданности), // если текущая точка выше последнего максимума (ниже минимума...) var margUp = index >= src.marginUpper; var margDn = index <= src.marginLower; if ((margUp && indexNext < index && index > (lastPeak.HasValue ? lastPeak.Value : float.MinValue)) || (margDn && indexNext > index && index < (lastPeak.HasValue ? lastPeak.Value : float.MaxValue))) {// + или - экстремум peakPrice = src.GetDestPrice(i) ?? 0; extremumSign = margUp ? 1 : -1; startIndex = i; lastPeak = index; continue; } if (!margUp && margDn == false) {// конец отсчета экстремума extremumSign = 0; lastPeak = null; continue; } // отсчет экстремума - сравнить дельту цены и дельту индекса var deltaPrice = (src.GetDestPrice(i) ?? 0) - peakPrice; var deltaIndex = index - lastPeak; if (extremumSign > 0) { if (deltaPrice > 0 && deltaIndex < 0) // медвежий дивер { divers.Add(new DiverSpan(startIndex, i, -1)); peakPrice = src.GetDestPrice(i) ?? 0; } } if (extremumSign < 0) { if (deltaPrice < 0 && deltaIndex > 0) // бычий дивер { divers.Add(new DiverSpan(startIndex, i, 1)); peakPrice = src.GetDestPrice(i) ?? 0; } } } return(divers); }
private static IEnumerable <DiverSpan> FindDivergencePointsClassic(MultyTimeframeIndexSettings src) { var diverPairs = new List <DiverSpan>(); var srcCount = src.seriesDest.DataCount; // найти экстремумы var extremums = new List <Point>(); // index - sign for (var i = src.periodExtremum; i < srcCount - src.periodExtremum - 1; i++) { bool isPeak = true, isLow = true; var price = src.GetDestPrice(i) ?? 0; for (var j = i - src.periodExtremum; j <= i + src.periodExtremum; j++) { if (j == i) { continue; } var priceNear = src.GetDestPrice(j); if (priceNear > price) { isPeak = false; } if (priceNear < price) { isLow = false; } if (!isPeak && isLow == false) { break; } } if (isPeak) { extremums.Add(new Point(i, 1)); } if (isLow) { extremums.Add(new Point(i, -1)); } } // от каждого экстремумы поиск вперед до M баров - поиск экстремума на интервале [i-N...i+1] foreach (var extr in extremums) { var signExtr = extr.Y; var indexExtr = extr.X; var priceExtr = src.GetDestPrice(indexExtr); for (var i = extr.X + 1; i <= (extr.X + src.maxPastExtremum); i++) { if (i >= (srcCount - 1)) { break; } // новый "экстремум" должен быть выше старого var price = src.GetDestPrice(i) ?? 0; if ((signExtr > 0 && price <= priceExtr) || (signExtr < 0 && price >= priceExtr)) { continue; } // за новым "экстремумом" должна следовать точка ниже (выше для минимума) var nextPrice = src.GetDestPrice(i + 1) ?? 0; if ((signExtr > 0 && price <= nextPrice) || (signExtr < 0 && price >= nextPrice)) { continue; } // сравнение с дельтой индекса // !! смещение индекса var srcPriceI = src.GetSourcePrice(i) ?? 0; var srcPriceEx = src.GetSourcePrice(indexExtr) ?? 0; var deltaIndex = Math.Sign(srcPriceI - srcPriceEx); if (signExtr == deltaIndex) { continue; } // экстремум найден priceExtr = price; diverPairs.Add(new DiverSpan(indexExtr, i, -signExtr)); } } return(diverPairs); }