Набор индикаторов


Набор индикаторов
Atom
3/10/2011


Здравствуйте.
Сталкиваюсь с проблемой написания индикаторов на C#.
Может есть смысл сделать какой-то набор готовый и вложить в апи, например такой набор:
SMA, EMA, WMA, FRAMA, RSI, MACD, Bollinger Bands, ADX, Parabolic Sar. Если кто уже реализовывал, поделитесь пожалуйста.

Tags:


Thanks:


1 2  >
Mikhail Sukhov

Avatar
Date: 3/10/2011
Reply


russ Go to
Здравствуйте.
Сталкиваюсь с проблемой написания индикаторов на C#.
Может есть смысл сделать какой-то набор готовый и вложить в апи, например такой набор:
SMA, EMA, WMA, FRAMA, RSI, MACD, Bollinger Bands, ADX, Parabolic Sar. Если кто уже реализовывал, поделитесь пожалуйста.


Была бы классная идея. Есть наработки? Мои - те что в примерах (SMA, EMA).
Thanks:

aerv

Avatar
Date: 3/11/2011
Reply


Кое что есть:
SMA, EMA, WMA, StDev. Код:
Code
using 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

Avatar
Date: 3/11/2011
Reply


aerv Go to
Кое что есть:
SMA, EMA, WMA, StDev. Код:


А что не отнаследовали скользящие? Кода дублируемого получилось много.
Thanks:

russ

Avatar
Date: 3/11/2011
Reply


Mikhail Sukhov Go to
russ Go to
Здравствуйте.
Сталкиваюсь с проблемой написания индикаторов на C#.
Может есть смысл сделать какой-то набор готовый и вложить в апи, например такой набор:
SMA, EMA, WMA, FRAMA, RSI, MACD, Bollinger Bands, ADX, Parabolic Sar. Если кто уже реализовывал, поделитесь пожалуйста.


Была бы классная идея. Есть наработки? Мои - те что в примерах (SMA, EMA).

К сожалению нет, поэтому начал писать на QPILE, т.к. там можно получить значения индикаторов из свечи. Но ваша апи это супер мега крутая вещь, на ней сделал программу другую. Вот щас планирую роботов переписать на стокшарп, но индикаторы стопорят.
Thanks:

Mikhail Sukhov

Avatar
Date: 3/11/2011
Reply


russ Go to
К сожалению нет, поэтому начал писать на QPILE, т.к. там можно получить значения индикаторов из свечи. Но ваша апи это супер мега крутая вещь, на ней сделал программу другую. Вот щас планирую роботов переписать на стокшарп, но индикаторы стопорят.


Выводите значения индюков в таблицу и экспортируйте, как показано здесь.
Thanks:

russ

Avatar
Date: 3/11/2011
Reply


Mikhail Sukhov Go to
russ Go to
К сожалению нет, поэтому начал писать на QPILE, т.к. там можно получить значения индикаторов из свечи. Но ваша апи это супер мега крутая вещь, на ней сделал программу другую. Вот щас планирую роботов переписать на стокшарп, но индикаторы стопорят.


Выводите значения индюков в таблицу и экспортируйте, как показано здесь.

ОО, отличное решение, спасибо большое.
Thanks:

aerv

Avatar
Date: 3/11/2011
Reply


Mikhail Sukhov Go to
aerv Go to
Кое что есть:
SMA, EMA, WMA, StDev. Код:


А что не отнаследовали скользящие? Кода дублируемого получилось много.

Большой необходимости в этом нет. Кода-то всего ничего. Каждый индикатор в отдельном файле и помещается на экран. Пока, вполне можно обойтись и без этого рефакторинга, но хуже от реализации Вашего предложения, конечно же не будет. [smile]
Thanks:

maze9a

Avatar
Date: 5/19/2011
Reply


Mikhail Sukhov Go to

Выводите значения индюков в таблицу и экспортируйте, как показано здесь.


Линк не работает.
Thanks:

Alexander

Avatar
Date: 5/19/2011
Reply


maze9a Go to
Mikhail Sukhov Go to

Выводите значения индюков в таблицу и экспортируйте, как показано здесь.


Линк не работает.


Документация с тех пор переехала:
тут актуальная.
Thanks:

Yura

Avatar
Date: 11/23/2011
Reply


Здравствуйте.
Что вы можете сказать по поводу показателя Херста и RS анализа. Есть наработки, но что-то там не правильно высчитывается. Не могу понять что( .. Может разберемся вместе?
Thanks:
1 2  >

Attach files by dragging & dropping, , or pasting from the clipboard.

loading
clippy