Собственно сабж
Индикатор без визуализации так как не вызывает события перерисовки графика индикатора при изменении крайней точки, а так же в силу работы OsEngine с данными типа decimal которые не имеют не числовых значений. Индикатор в результируещем временном ряде содержит верные значения точек экстремумов, что позволяет использовать его значения в роботах так, как бы это был полноценный зигзаг с визуализацией.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Drawing;
using OsEngine.Entity;
using OsEngine.Indicators;
namespace CustomIndicators.Scripts
{
public class ZigZag : Aindicator
{
private IndicatorParameterInt _period;
private IndicatorDataSeries _series;
public override void OnStateChange(IndicatorState state)
{
_period = CreateParameterInt("Length", 14);
_series = CreateSeries("ZigZag", Color.DarkRed, IndicatorChartPaintType.Line, true);
}
private decimal currentZigZagHigh = 0;
private decimal currentZigZagLow = 0;
private int lastSwingIndex = -1;
private decimal lastSwingPrice = 0;
private int trendDir = 0;
private int CurrentBar;
private decimal GetExtremum(List<Candle> candles, int period, string points)
{
List<decimal> values = new List<decimal>();
for (int i = candles.Count - 1; i >= candles.Count - period; i--)
values.Add(candles[i].GetPoint(points));
if(points == "High")
return values.Max();
if (points == "Low")
return values.Min();
return 0;
}
public override void OnProcess(List<Candle> candles, int index)
{
CurrentBar = candles.Count;
if (CurrentBar < _period.ValueInt * 2)
return;
decimal High = candles[index].High;
decimal Low = candles[index].Low;
if (lastSwingPrice == 0)
lastSwingPrice = Low + (High - Low) / 2;
bool isSwingHigh = High == GetExtremum(candles, _period.ValueInt, "High");
bool isSwingLow = Low == GetExtremum(candles, _period.ValueInt, "Low");
decimal saveValue = 0;
bool addHigh = false;
bool addLow = false;
bool updateHigh = false;
bool updateLow = false;
if (!isSwingHigh && !isSwingLow)
{
return;
}
if (trendDir == 1 && isSwingHigh && High >= lastSwingPrice)
{
saveValue = High;
updateHigh = true;
}
else if (trendDir == -1 && isSwingLow && Low <= lastSwingPrice)
{
saveValue = Low;
updateLow = true;
}
else if (trendDir <= 0 && isSwingHigh)
{
saveValue = High;
addHigh = true;
trendDir = 1;
}
else if (trendDir >= 0 && isSwingLow)
{
saveValue = Low;
addLow = true;
trendDir = -1;
}
if (addHigh || addLow || updateHigh || updateLow)
{
if (updateHigh && lastSwingIndex >= 0)
_series.Values[lastSwingIndex] = 0; // тут в оригинале double.NaN
else if (updateLow && lastSwingIndex >= 0)
_series.Values[lastSwingIndex] = 0; // тут в оригинале double.NaN
if (addHigh || updateHigh)
{
currentZigZagHigh = saveValue;
_series.Values[index] = currentZigZagHigh;
}
else if (addLow || updateLow)
{
currentZigZagLow = saveValue;
_series.Values[index] = currentZigZagLow;
}
lastSwingIndex = CurrentBar - 1;
lastSwingPrice = saveValue;
}
}
}
}
Данный индикатор хорошо показал себя в совокупности с ML для прогнозирования акций и фьючей.
Работать со значениями индикатора из робота можно с помощью этого псевдокода получая значения в точках экстремумов и количество бар до исколого по счету экстремума, где indexFromEnd номер искомого экстремума с конца начиная с нуля.
//---------------------------------------------------------------
//---ПОЛУЧАЕМ НОМЕР СВЕЧИ ЭКСТРЕМУМА-----------------------------
//---------------------------------------------------------------
decimal GetZigZagCount(List<Candle> candles, int indexFromEnd)
{
for (var i = candles.Count - 1; i >= 0; i--)
{
if (zigZag.Result[i] != 0)
{
if (indexFromEnd == 0)
return i;
indexFromEnd--;
}
}
return 0;
}
//---------------------------------------------------------------
//---ПОЛУЧАЕМ ЗНАЧЕНИЯ ЦЕНЫ В ТОЧКАХ ЭКСТРЕМУМА------------------
//---------------------------------------------------------------
decimal GetZigZagValue(List<Candle> candles, int indexFromEnd)
{
for (var i = candles.Count - 1; i >= 0; i--)
{
if (zigZag.Result[i] != 0)
{
if (indexFromEnd == 0)
return zigZag.Result[i];
indexFromEnd--;
}
}
return 0;
}
Цитата: karuzzo
Индикатор без визуализации так как не вызывает события перерисовки графика индикатора при изменении крайней точки, а так же в силу работы OsEngine с данными типа decimal которые не имеют не числовых значений. Индикатор в результируещем временном ряде содержит верные значения точек экстремумов, что позволяет использовать его значения в роботах так, как бы это был полноценный зигзаг с визуализацией.
Данный индикатор хорошо показал себя в совокупности с ML для прогнозирования акций и фьючей.
Работать со значениями индикатора из робота можно с помощью этого псевдокода получая значения в точках экстремумов и количество бар до исколого по счету экстремума, где indexFromEnd номер искомого экстремума с конца начиная с нуля.
Запушил на Гит. Спасибо.
Добавил свойство CanReBuildHistoricalValues в серии данных. Чтобы чарт перерисовывал такие серии принудительно целиком по обновлению свечи. И серию для прорисовки тоже добавил
Цитата: Алексей Ван
Цитата: karuzzo
Индикатор без визуализации так как не вызывает события перерисовки графика индикатора при изменении крайней точки, а так же в силу работы OsEngine с данными типа decimal которые не имеют не числовых значений. Индикатор в результируещем временном ряде содержит верные значения точек экстремумов, что позволяет использовать его значения в роботах так, как бы это был полноценный зигзаг с визуализацией.
Данный индикатор хорошо показал себя в совокупности с ML для прогнозирования акций и фьючей.
Работать со значениями индикатора из робота можно с помощью этого псевдокода получая значения в точках экстремумов и количество бар до исколого по счету экстремума, где indexFromEnd номер искомого экстремума с конца начиная с нуля.
Запушил на Гит. Спасибо.
Добавил свойство CanReBuildHistoricalValues в серии данных. Чтобы чарт перерисовывал такие серии принудительно целиком по обновлению свечи. И серию для прорисовки тоже добавил
Круто!
ООО «ВАН ТЕХНОЛОГИИ»т: +7 953 769 56 45
* Торговля на финансовых рынках связана с риском, который лежит на Вас.
* Ничто из написанного на сайте o-s-a.net не является рекомендацией.
* Если Вы этого не понимаете, не читайте этот сайт, ничего не покупайте.