Пользовательские индикаторы > ФИЛЬТР КАЛМАНА!

Дополнительные индикаторы от пользователей Альфа-Директ 4. Готовые решения от пользователей.
ensh
Сообщения: 229
Зарегистрирован: 28 июн 2017, 13:56
Благодарил (а): 4 раза
Поблагодарили: 41 раз

Re: ФИЛЬТР КАЛМАНА!

Непрочитанное сообщение ensh » 25 ноя 2024, 22:13

Класс AdsInput следующее определение

Код: Выделить всё

// TA.Script.XSeries
using System;
using System.Collections.Generic;
using System.Drawing;
using AD.Common.DataStructures;
using TA.Script;

public class XSeries
{
   public string Name;

   public DrawAs Style;

   public Color Color;

   public LineStyles LineStyle;

   public int LineWidth = 1;

   public SortedList<long, double> Points;

   public AxesKindList _PriceStudy;

   private bool _NewArea = true;

   private int _AxisSize = 100;

   private ScriptedCode _Owner;

   public double LastValue;

   public const int DefaultAlpha = 50;

   public const int DefaultAlphaFigure = 100;

   public bool Visible { get; set; }

   public bool PriceStudy => GetPriceStudy();

   public bool ZeroBased { get; set; }

   public bool NeedToCorrect { get; set; }

   public bool NewArea
   {
      get
      {
         return _NewArea;
      }
      set
      {
         _NewArea = value;
      }
   }

   public int AxisSize
   {
      get
      {
         return _AxisSize;
      }
      set
      {
         if (value >= 10 && value <= 100)
         {
            _AxisSize = value;
            return;
         }
         throw new ArgumentOutOfRangeException("AxisSize", "Parameter should be in the range [10, 100]!");
      }
   }

   public ScriptedCode Owner
   {
      get
      {
         return _Owner;
      }
      set
      {
         SetOwner(value);
      }
   }

   public double this[int index]
   {
      get
      {
         return GetValue(index);
      }
      set
      {
         SetValue(index, value);
      }
   }

   public double this[AdsFuncParameter index]
   {
      get
      {
         return GetValue((int)(double)index);
      }
      set
      {
         SetValue((int)(double)index, value);
      }
   }

   private bool GetPriceStudy()
   {
      if (Owner is ScriptedIndicator)
      {
         if (_PriceStudy != 0)
         {
            return _PriceStudy == AxesKindList.Parent;
         }
         return (Owner as ScriptedIndicator).PriceStudy;
      }
      return _PriceStudy == AxesKindList.Parent;
   }

   private void SetOwner(ScriptedCode value)
   {
      _Owner = value;
   }

   public XSeries()
   {
      Init();
   }

   public void Init()
   {
      Points = new SortedList<long, double>();
   }

   public static implicit operator double(XSeries value)
   {
      return value[0];
   }

   public static implicit operator XSeries(double value)
   {
      return new XSeries
      {
         LastValue = value
      };
   }

   public static implicit operator XSeries(AdsInputStream value)
   {
      return new XSeries
      {
         LastValue = value[0]
      };
   }

   public static implicit operator XSeries(AdsFuncParameter value)
   {
      return new XSeries
      {
         LastValue = value
      };
   }

   private void SetValue(int index, double value)
   {
      if (Owner.TryGetTime(index, out var time))
      {
         long key = DataPoint.SecondsFromDateTime(time);
         if (Points.ContainsKey(key))
         {
            Points[key] = value;
         }
         else
         {
            Points.Add(key, value);
         }
      }
   }

   private double GetValue(int index)
   {
      double value = double.NaN;
      if (Owner.TryGetTime(index, out var time))
      {
         long key = DataPoint.SecondsFromDateTime(time);
         Points.TryGetValue(key, out value);
      }
      return value;
   }

   private double GetValueByTime(long time)
   {
      return Points[time];
   }

   private void SetValueByTime(long time, double value)
   {
      if (Points.ContainsKey(time))
      {
         Points[time] = value;
      }
      else
      {
         Points.Add(time, value);
      }
   }

   public void Clear()
   {
      if (Points != null)
      {
         Points.Clear();
      }
   }

   public string Prepare4Compiler()
   {
      return "XSeries __" + Name + " = new XSeries() {" + $" Name = \"{Name}\", Style = DrawAs.{Style.ToString()}, Color = Color.{Color.ToKnownColor().ToString()}, Visible = {Visible.ToString().ToLower()} " + "};\npublic XSeries " + Name + "\n{ get { return __" + Name + "; } set { " + $"SetSeries(__{Name}, value);" + "}}";
   }

   public void Hide()
   {
      Owner.CustomDrawPoint(this, DrawPointAs.Hidden);
   }

   public void DrawLine(Color color, LineStyles style, int width)
   {
      Owner.CustomDrawPoint(this, DrawPointAs.Line, color, style, width, true);
   }

   public void DrawLine()
   {
      DrawLine(Color.Empty, LineStyle, LineWidth);
   }

   public void DrawDash(Color color, LineStyles style, int width, int delta = 0)
   {
      Owner.CustomDrawPoint(this, DrawPointAs.HorizontalLine, color, style, width, delta, true);
   }

   public void DrawDash(int delta = 0)
   {
      DrawDash(Color.Empty, LineStyle, LineWidth, delta);
   }

   public void DrawVertical(XSeries series)
   {
      Owner.CustomDrawPoint(this, DrawPointAs.VerticalLine, Color.Empty, LineStyle, LineWidth, (series != null) ? series.Name : string.Empty, true);
   }

   public void DrawVertical(XSeries series, Color color, LineStyles style = LineStyles.Solid, int width = 1)
   {
      Owner.CustomDrawPoint(this, DrawPointAs.VerticalLine, color, style, width, (series != null) ? series.Name : string.Empty, true);
   }

   public void DrawVertical(Color color, LineStyles style, int width)
   {
      DrawVertical(null, color, style, width);
   }

   public void DrawVertical()
   {
      DrawVertical(Color.Empty, LineStyle, LineWidth);
   }

   public void DrawFigure(PointFigure figure, Color color, LineStyles style, int width, Color fill, int alpha = 100)
   {
      Owner.CustomDrawPoint(this, DrawPointAs.Point, figure, true, color, style, width, fill, alpha);
   }

   public void DrawCircle(Color color, LineStyles style, int width, Color fill, int alpha = 100)
   {
      DrawFigure(PointFigure.Circle, color, style, width, fill, alpha);
   }

   public void DrawCircle()
   {
      DrawCircle(Color.Empty, LineStyles.Solid, 1, Color.Empty);
   }

   public void DrawSquare(Color color, LineStyles style, int width, Color fill, int alpha = 100)
   {
      DrawFigure(PointFigure.Square, color, style, width, fill, alpha);
   }

   public void DrawSquare()
   {
      DrawSquare(Color.Empty, LineStyles.Solid, 1, Color.Empty);
   }

   public void DrawArrowUp(Color color, LineStyles style, int width, Color fill, int alpha = 100)
   {
      DrawFigure(PointFigure.Up, color, style, width, fill, alpha);
   }

   public void DrawArrowUp()
   {
      DrawArrowUp(Color.Empty, LineStyles.Solid, 1, Color.Empty);
   }

   public void DrawArrowDown(Color color, LineStyles style, int width, Color fill, int alpha = 100)
   {
      DrawFigure(PointFigure.Down, color, style, width, fill, alpha);
   }

   public void DrawArrowDown()
   {
      DrawArrowDown(Color.Empty, LineStyles.Solid, 1, Color.Empty);
   }

   public void DrawArrowLeft(Color color, LineStyles style, int width, Color fill, int alpha = 100)
   {
      DrawFigure(PointFigure.Left, color, style, width, fill, alpha);
   }

   public void DrawArrowLeft()
   {
      DrawArrowLeft(Color.Empty, LineStyles.Solid, 1, Color.Empty);
   }

   public void DrawArrowRight(Color color, LineStyles style, int width, Color fill, int alpha = 100)
   {
      DrawFigure(PointFigure.Right, color, style, width, fill, alpha);
   }

   public void DrawArrowRight()
   {
      DrawArrowRight(Color.Empty, LineStyles.Solid, 1, Color.Empty);
   }

   public void DrawHistogram(XSeries series, Color color, LineStyles style, int width, Color fill, int alpha = 50)
   {
      Owner.CustomDrawPoint(this, DrawPointAs.Histogram, color, style, width, true, fill, alpha, (series != null) ? series.Name : string.Empty);
   }

   public void DrawHistogram(Color color, LineStyles style, int width, Color fill, int alpha = 50)
   {
      Owner.CustomDrawPoint(this, DrawPointAs.Histogram, color, style, width, true, fill, alpha, string.Empty);
   }

   public void DrawHistogram(Color color, int alpha = 50)
   {
      DrawHistogram(null, color, LineStyles.Solid, 1, color, alpha);
   }

   public void DrawHistogram(Color color, Color fill, int alpha = 50)
   {
      DrawHistogram(null, color, LineStyles.Solid, 1, fill, alpha);
   }

   public void DrawHistogram(XSeries series, Color fill, int alpha = 50)
   {
      DrawHistogram(series, Color.Empty, LineStyles.Solid, 1, fill, alpha);
   }

   public void DrawHistogram(XSeries series)
   {
      DrawHistogram(series, Color.Empty, LineStyles.Solid, 1, Color.Empty);
   }

   public void DrawHistogram()
   {
      DrawHistogram(Color.Empty, LineStyles.Solid, 1, Color.Empty);
   }

   public void DrawArea(Color color, LineStyles style, int width, Color fill, int alpha = 50)
   {
      Owner.CustomDrawPoint(this, DrawPointAs.Area, color, style, width, true, fill, alpha);
   }

   public void DrawArea(Color fill, int alpha)
   {
      DrawArea(Color.Empty, LineStyle, LineWidth, fill, alpha);
   }

   public void DrawArea()
   {
      DrawArea(Color.Empty, 30);
   }

   public void DrawChannel(Color fill, int alpha)
   {
      DrawArea(Color.Empty, LineStyle, LineWidth, fill, alpha);
   }

   public void DrawChannel(XSeries series, Color fill, int alpha)
   {
      Owner.CustomDrawPoint(this, DrawPointAs.Area, Color.Empty, LineStyle, LineWidth, true, fill, alpha, (series != null) ? series.Name : string.Empty);
   }

   public void DrawChannel(XSeries series)
   {
      DrawChannel(series, Color.Empty, 30);
   }

   public void DrawSection(Color color, LineStyles style, int width, int delta)
   {
      Owner.CustomDrawPoint(this, DrawPointAs.TrendLine, color, style, width, delta, true);
   }

   public void DrawSection(int delta)
   {
      DrawSection(Color.Empty, LineStyle, LineWidth, delta);
   }

   public static int PercentToAlpha(int percent)
   {
      int num = percent * 255 / 100;
      if (num < 0 || num > 255)
      {
         num = 120;
      }
      return num;
   }

   public static int AlphaToPercent(int alpha)
   {
      int num = alpha * 100 / 255;
      if (num < 0 || num > 100)
      {
         num = 50;
      }
      return num;
   }
}

ensh
Сообщения: 229
Зарегистрирован: 28 июн 2017, 13:56
Благодарил (а): 4 раза
Поблагодарили: 41 раз

Re: ФИЛЬТР КАЛМАНА!

Непрочитанное сообщение ensh » 25 ноя 2024, 22:14

Я так понял, что используется одна текущая точка [0], а на самом деле это как-то должно скользить по графику

Аватара пользователя
Den
Сообщения: 377
Зарегистрирован: 09 фев 2016, 15:52
Благодарил (а): 17 раз
Поблагодарили: 5 раз

Re: ФИЛЬТР КАЛМАНА!

Непрочитанное сообщение Den » 25 ноя 2024, 23:58

ensh писал(а):Я так понял, что используется одна текущая точка [0], а на самом деле это как-то должно скользить по графику


индикатор, не сдвигает значения для обработки всех точек графика. В текущем коде используется только одна текущая точка [0]. Нужно обеспечить обработку значений для всех точек исторического графика, а не только для последней.

А если изменить метод Evaluate() так, чтобы он обрабатывал все доступные значения для графика, используя подход со сдвигом данных, который подходит для обработки временных рядов?
код, чтобы сделать фильтр Калмана более подходящим для анализа всех данных графика:

Код: Выделить всё

void Evaluate() {
    Print("Начало выполнения Evaluate");

    // Адаптивные параметры P1 и P2 могут быть основаны на рыночной волатильности
    double atr = ATR(Input, 14);
    Print("ATR: ", atr);

    double P1 = MathMax(atr, 0.5);
    double P2 = MathMax(atr * 1.5, 1.0);
    Print("P1: ", P1, " P2: ", P2);

    // Обновляем глобальные переменные P1 и P2
    SetGlobalVariable("P1", P1);
    SetGlobalVariable("P2", P2);

    if (CurrentIndex > P) {
        // Цикл по всем точкам данных на графике для применения фильтра Калмана
        for (int i = CurrentIndex - 1; i >= 0; i--) {
            double WMA1 = WMA(Input, (int)(1 * P))[i];
            double WMA2 = WMA(Input, (int)(2 * P))[i];
            Print("WMA1: ", WMA1, " WMA2: ", WMA2);

            double MMA = 2.0 * WMA1 - WMA2;
            double P3 = MathTruncate(MathSqrt(P));

            double sum = 0.0;
            double sumZ = 0.0;

            for (int j = 0; j < P3; j++) {
                double mmaValue = (j < ArraySize(hmaHistory) && hmaHistory[j] != 0.0) ? hmaHistory[j] : MMA;
                sum += mmaValue * (P3 - j);
                sumZ += (j + 1);
            }

            double HMA = sum / sumZ;
            Print("HMA: ", HMA);

            // Сдвиг элементов массива вправо и добавление нового значения в начало
            ArrayCopy(hmaHistory, hmaHistory, 1, 0, ArraySize(hmaHistory) - 1);
            hmaHistory[0] = HMA;

            // Устанавливаем визуализацию для тренда вверх или вниз
            if (hmaHistory[1] != 0.0 && HMA > hmaHistory[1]) {
                HMA_TrendUp[i] = HMA;
                HMA_TrendUp.DrawLine(Color.DeepSkyBlue, Line.Solid, 6);
                HMA_Shadow[i] = HMA;
                HMA_Shadow.DrawLine(Color.LightSkyBlue, Line.Solid, 10);
            } else if (hmaHistory[1] != 0.0) {
                HMA_TrendDown[i] = HMA;
                HMA_TrendDown.DrawLine(Color.OrangeRed, Line.Solid, 6);
                HMA_Shadow[i] = HMA;
                HMA_Shadow.DrawLine(Color.DarkOrange, Line.Solid, 10);
            }
        }
    }
}

Аватара пользователя
Den
Сообщения: 377
Зарегистрирован: 09 фев 2016, 15:52
Благодарил (а): 17 раз
Поблагодарили: 5 раз

Re: ФИЛЬТР КАЛМАНА!

Непрочитанное сообщение Den » 26 ноя 2024, 00:03

Изменения в kalmanEstimate и kalmanErrorCovariance не включены: Код, связанный с фильтром Калмана, пока не включен, чтобы сначала убедиться, что индикатор отображает правильно значения HMA. После этого можно будет добавить и отладить код Калмана, чтобы улучшить сглаживание данных.

только вот проблема - компилятор не выдает вообще никакого сообщения при компилировании. :D

Аватара пользователя
Den
Сообщения: 377
Зарегистрирован: 09 фев 2016, 15:52
Благодарил (а): 17 раз
Поблагодарили: 5 раз

Re: ФИЛЬТР КАЛМАНА!

Непрочитанное сообщение Den » 26 ноя 2024, 00:04

Den писал(а):Изменения в kalmanEstimate и kalmanErrorCovariance не включены: Код, связанный с фильтром Калмана, пока не включен, чтобы сначала убедиться, что индикатор отображает правильно значения HMA. После этого можно будет добавить и отладить код Калмана, чтобы улучшить сглаживание данных.

только вот проблема - компилятор не выдает вообще никакого сообщения при компилировании. :D


P.S. а, ну понятно из-за void и кучи других мелочей типа имени.
Вложения
Image 213.png

Аватара пользователя
Den
Сообщения: 377
Зарегистрирован: 09 фев 2016, 15:52
Благодарил (а): 17 раз
Поблагодарили: 5 раз

Re: ФИЛЬТР КАЛМАНА!

Непрочитанное сообщение Den » 26 ноя 2024, 03:50

в АДу модифицированный или интерпретируемый язык, который близок к C#, но имеет свои собственные правила и особенности?
Cреда не понимает C# в чистом виде и ожидает другого синтаксиса?
Есть какая-нибудь отличная от Terminal 4.0. Skripti poljzova документация?

Аватара пользователя
Den
Сообщения: 377
Зарегистрирован: 09 фев 2016, 15:52
Благодарил (а): 17 раз
Поблагодарили: 5 раз

Re: ФИЛЬТР КАЛМАНА!

Непрочитанное сообщение Den » 26 ноя 2024, 10:53

ensh писал(а):Класс XSeries определяется так, из рефлектора сборки TA.dll:



ensh, какой рефлектор ?

ensh
Сообщения: 229
Зарегистрирован: 28 июн 2017, 13:56
Благодарил (а): 4 раза
Поблагодарили: 41 раз

Re: ФИЛЬТР КАЛМАНА!

Непрочитанное сообщение ensh » 26 ноя 2024, 16:51

Ищешь ILSpy,, находишь в git. Качаешь zip архив, в архиве екзешник им открываешь dll и смотришь.
ILSpy встроен в Visual Studio оттуда тоже можно смотреть

ensh
Сообщения: 229
Зарегистрирован: 28 июн 2017, 13:56
Благодарил (а): 4 раза
Поблагодарили: 41 раз

Re: ФИЛЬТР КАЛМАНА!

Непрочитанное сообщение ensh » 26 ноя 2024, 16:57

Den писал(а):в АДу модифицированный или интерпретируемый язык, который близок к C#, но имеет свои собственные правила и особенности?
Cреда не понимает C# в чистом виде и ожидает другого синтаксиса?
Есть какая-нибудь отличная от Terminal 4.0. Skripti poljzova документация?


Полный C#!
Изначально был JavaScript.
Потом перевели в С#. От Java Script остались function, но они в сборке транслирубтся в void.
Обсуждали уже, что можно заинжектить любые сборки и фигачить на C# что хочешь.
В итоге, для каждого индикатора или стратегии создается стандартная C# сборка и при добавлении на график или в робота, эта сборка грузиться в терминал и стандартно вызывается для отрисовки или выполнения чегото
Последний раз редактировалось ensh 26 ноя 2024, 17:02, всего редактировалось 1 раз.

ensh
Сообщения: 229
Зарегистрирован: 28 июн 2017, 13:56
Благодарил (а): 4 раза
Поблагодарили: 41 раз

Re: ФИЛЬТР КАЛМАНА!

Непрочитанное сообщение ensh » 26 ноя 2024, 16:59

Den писал(а):Изменения в kalmanEstimate и kalmanErrorCovariance не включены: Код, связанный с фильтром Калмана, пока не включен, чтобы сначала убедиться, что индикатор отображает правильно значения HMA. После этого можно будет добавить и отладить код Калмана, чтобы улучшить сглаживание данных.

только вот проблема - компилятор не выдает вообще никакого сообщения при компилировании. :D

и не должен) сборка в папочке появилась - все норм


Вернуться в «Пользовательские индикаторы»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 2 гостя