Mikhail Sukhov
|
Date: 3/10/2011
russ Здравствуйте. Сталкиваюсь с проблемой написания индикаторов на C#. Может есть смысл сделать какой-то набор готовый и вложить в апи, например такой набор: SMA, EMA, WMA, FRAMA, RSI, MACD, Bollinger Bands, ADX, Parabolic Sar. Если кто уже реализовывал, поделитесь пожалуйста. Была бы классная идея. Есть наработки? Мои - те что в примерах (SMA, EMA).
|
|
Thanks:
|
|
|
|
|
aerv
|
Date: 3/11/2011
|
|
|
|
Кое что есть: SMA, EMA, WMA, StDev. Код: Codeusing System; using System.Collections.Generic; using System.Linq;
namespace Ecng.Community.Series { /// <summary> SMA - простая скользящая средняя. </summary> public class Sma { /// <summary> Создать простую скользящуюю среднюю. </summary> /// <param name="period"> Период расчета скользящей. </param> public Sma(int period) { if (period <= 0) throw new ArgumentException("Задан отрицательный или нулевой период для SMA"); Period = period; _buffer = new double[period]; }
/// <summary> Период сглаживания скользящей средней. </summary> public int Period { get; private set; }
/// <summary> Текущее значение. /// До тех пор пока индикатор не сформирован <see cref="IsFormed"/> равно 0</summary> public double Value { get; private set; }
/// <summary> Индикатор сформировался, т.е. добавлено достаточное количество значений. </summary> public bool IsFormed { get { return _count >= Period; } }
//readonly List<double> _buffer = new List<double>(); readonly double[] _buffer; int _i, _count; double _v;
/// <summary> Добавить новое значение. </summary> /// <param name="value">Новое значение.</param> /// <returns> Значение индикатора = <see cref="Value"/></returns> public double Add(double value) { /*int count = _buffer.Count; _buffer.Add(value); if (count >= Period) { Value = Value + (value - _buffer[ 0 ]) / Period; //Value = Value + value / Period; //Value -= _buffer[0]/Period; _buffer.RemoveAt(0); } else //Value = Value + value / Period; Value = (count * Value + value) / ++count; return Value;*/
// Более быстрый вариант if (_count >= Period) { _v += (value - _buffer[_i]) / Period; _count++; Value = _v; } else { _v = (_count*_v + value)/++_count; //Value = value; } _buffer[_i++] = value; if (_i >= Period) _i = 0; return Value; } }
/// <summary> Идникатор EMA - экспоненциальная скользящая средняя. </summary> public class Ema { /// <summary> Создать экспоненциальную скользящуюю среднюю. </summary> /// <param name="period"> Период расчета скользящей. </param> public Ema(int period) { if (period <= 0) throw new ArgumentException("Задан отрицательный или нулевой период для Ema"); Period = period; _k = 2.0 / (1.0 + Period); }
readonly double _k; int _count;
/// <summary> Период сглаживания скользящей средней. </summary> public int Period { get; private set; }
/// <summary> Текущее значение. </summary> public double Value { get; private set; }
/// <summary> Индикатор сформировался, т.е. добавлено достаточное количество значений. </summary> public bool IsFormed { get { return _count >= Period; } }
/// <summary> Добавить новое значение. </summary> /// <param name="value">Новое значение.</param> /// <returns> Значение индикатора = <see cref="Value"/></returns> public double Add(double value) { Value = _count < Period ? (_count * Value + value) / ++_count // Sma(period) : _k*(value - Value) + Value; // Ema(period) return Value; } }
/// <summary> Идникатор WMA - взвешенная скользящая средняя. /// Этот метод расчета скользящей средней придает больший вес самым недавним данным /// и меньший вес более старым данным (в то время как простая скользящая средняя /// придает всем данным одинаковый вес). /// </summary> public class Wma { /// <summary> Создать взвешенную скользящуюю среднюю. </summary> /// <param name="period"> Период расчета скользящей. </param> public Wma(int period) { if (period <= 0) throw new ArgumentException("Задан отрицательный или нулевой период для Wma"); Period = period; _buffer = new double[period]; }
/// <summary> Период сглаживания скользящей средней. </summary> public int Period { get; private set; }
/// <summary> Текущее значение. </summary> public double Value { get; private set; }
/// <summary> Индикатор сформировался, т.е. добавлено достаточное количество значений. </summary> public bool IsFormed { get { return _count >= Period; } }
//readonly List<double> _buffer = new List<double>(); int _w; readonly double[] _buffer; int _i, _count;
/// <summary> Добавить новое значение. </summary> /// <param name="value">Новое значение.</param> /// <returns> Значение индикатора = <see cref="Value"/></returns> public double Add(double value) { /*_buffer.Add(value); if (_buffer.Count > Period) _buffer.RemoveAt(0); else _w += _buffer.Count; // Суммарный вес
int wi = 1; // вес Value = _buffer.Sum(d => wi++ * d) / _w; return Value;*/
// Более быстрый вариант int count, j, period = Period; _count++; _buffer[_i++] = value; if (_i >= period) _i = 0; if (_count <= period) { count = _count; j = 0; _w += _count; // Суммарный вес } else { count = period; j = _i; } double v = 0; int wi = 1; // вес for (int i = 0; i < count; i++) { v += wi++ * _buffer[j]; if (++j >= period) j = 0; } Value = v / _w; return Value; } }
/// <summary> Идникатор StDev - стандартное отклонение. </summary> public class StDev { /// <summary> Создать индикатор "стандартное отклонение". </summary> /// <param name="period"> Период расчета скользящей. </param> public StDev(int period) { if (period <= 0) throw new ArgumentException("Задан отрицательный или нулевой период для Wma"); Period = period; //_buffer = new List<double>((int)Period + 1); _buffer = new double[period]; }
//readonly List<double> _buffer; readonly double[] _buffer; int _i, _count;
/// <summary> Период расчета. </summary> public int Period { get; private set; }
/// <summary> Текущее значение. </summary> public double Value { get; private set; }
/// <summary> Индикатор сформировался, т.е. добавлено достаточное количество значений. </summary> public bool IsFormed { get { return _count >= Period; } }
/// <summary> Добавить новое значение. </summary> /// <param name="value">Новое значение.</param> /// <returns> Значение индикатора = <see cref="Value"/></returns> public double Add(double value) { /*_buffer.Add(value); if (_buffer.Count > Period) _buffer.RemoveAt(0);
int count = _buffer.Count; if (count == 0) { Value = 0; return 0; } double sxx = 0.0, sma = 0; int start = 0; while (start < count) sma += _buffer[start++]; sma /= count;
start = 0; while (start < count) { var x = _buffer[ start++ ] - sma; sxx += x * x; } Value = Math.Sqrt(sxx / count); return Value;*/
// Более быстрый вариант _count++; _buffer[_i++] = value; if (_i >= Period) _i = 0;
int count = _count <= Period ? _count : Period; double sxx = 0.0, sma = 0; for (int i = 0; i < count; i++) sma += _buffer[i]; sma /= count;
for (int i = 0; i < count; i++) { var x = _buffer[i] - sma; sxx += x * x; } Value = Math.Sqrt(sxx / count); return Value; } } }
|
|
Thanks:
|
|
|
|
|
Mikhail Sukhov
|
Date: 3/11/2011
aerv Кое что есть: SMA, EMA, WMA, StDev. Код:
А что не отнаследовали скользящие? Кода дублируемого получилось много.
|
|
Thanks:
|
|
|
|
|
russ
|
Date: 3/11/2011
Mikhail Sukhov russ Здравствуйте. Сталкиваюсь с проблемой написания индикаторов на C#. Может есть смысл сделать какой-то набор готовый и вложить в апи, например такой набор: SMA, EMA, WMA, FRAMA, RSI, MACD, Bollinger Bands, ADX, Parabolic Sar. Если кто уже реализовывал, поделитесь пожалуйста. Была бы классная идея. Есть наработки? Мои - те что в примерах (SMA, EMA). К сожалению нет, поэтому начал писать на QPILE, т.к. там можно получить значения индикаторов из свечи. Но ваша апи это супер мега крутая вещь, на ней сделал программу другую. Вот щас планирую роботов переписать на стокшарп, но индикаторы стопорят.
|
|
Thanks:
|
|
|
|
|
Mikhail Sukhov
|
Date: 3/11/2011
russ К сожалению нет, поэтому начал писать на QPILE, т.к. там можно получить значения индикаторов из свечи. Но ваша апи это супер мега крутая вещь, на ней сделал программу другую. Вот щас планирую роботов переписать на стокшарп, но индикаторы стопорят. Выводите значения индюков в таблицу и экспортируйте, как показано здесь.
|
|
Thanks:
|
|
|
|
|
russ
|
Date: 3/11/2011
Mikhail Sukhov russ К сожалению нет, поэтому начал писать на QPILE, т.к. там можно получить значения индикаторов из свечи. Но ваша апи это супер мега крутая вещь, на ней сделал программу другую. Вот щас планирую роботов переписать на стокшарп, но индикаторы стопорят. Выводите значения индюков в таблицу и экспортируйте, как показано здесь. ОО, отличное решение, спасибо большое.
|
|
Thanks:
|
|
|
|
|
aerv
|
Date: 3/11/2011
Mikhail Sukhov aerv Кое что есть: SMA, EMA, WMA, StDev. Код:
А что не отнаследовали скользящие? Кода дублируемого получилось много. Большой необходимости в этом нет. Кода-то всего ничего. Каждый индикатор в отдельном файле и помещается на экран. Пока, вполне можно обойтись и без этого рефакторинга, но хуже от реализации Вашего предложения, конечно же не будет. [smile]
|
|
Thanks:
|
|
|
|
|
maze9a
|
Date: 5/19/2011
Mikhail Sukhov Выводите значения индюков в таблицу и экспортируйте, как показано здесь. Линк не работает.
|
|
Thanks:
|
|
|
|
|
Alexander
|
Date: 5/19/2011
maze9a Mikhail Sukhov Выводите значения индюков в таблицу и экспортируйте, как показано здесь. Линк не работает. Документация с тех пор переехала: тут актуальная.
|
|
Thanks:
|
|
|
|
|
Yura
|
Date: 11/23/2011
Здравствуйте. Что вы можете сказать по поводу показателя Херста и RS анализа. Есть наработки, но что-то там не правильно высчитывается. Не могу понять что( .. Может разберемся вместе?
|
|
Thanks:
|
|
|
|