Пакет Atypical.TechnicalAnalysis.Functions представляет собой библиотеку для технического анализа финансовых данных в C#. Давайте разберем его установку и использование.
Установка пакета
Для установки используйте следующую команду в терминале или консоли NuGet:
Реализация стандартных индикаторов технического анализа
Интеграция с TA-Lib через TaLibStandard
Обработка исторических данных
Вычисление технических показателей
Теперь нужно создать диаграмму, которая покажет взаимодействие компонентов системы. Диаграмма должна отображать:
1. Входные данные (исторические цены)
2. Компоненты библиотеки
3. Интеграцию с TA-Lib
4. Выходные данные (индикаторы)
Да, диаграмма требует дополнительного пояснения для полной ясности:
1. Нужно объяснить поток данных
2. Пояснить роль каждого компонента
3. Объяснить интеграцию с TA-Lib
4. Указать на взаимосвязь между компонентами
Пояснение к архитектуре
На диаграмме показан процесс обработки данных в библиотеке:
Входные данные: Исторические цены поступают в систему в виде временных рядов
Библиотека выполняет два основных процесса:
Расчет собственных индикаторов
Интеграция с TA-Lib для расширения функционала
Индикаторы представляют собой готовые инструменты технического анализа:
Скользящие средние (MA) для трендовой аналитики
MACD для определения импульса и дивергенций
RSI для оценки перекупленности/перепроданности
Другие индикаторы (объемы, осцилляторы и т.д.)
Пример использования
usingAtypical.TechnicalAnalysis.Functions;publicclassTechnicalAnalysisExample{publicvoidCalculateIndicators(double[] prices){// Расчёт простой скользящей среднейvar sma = MovingAverage.Sma(prices,20);// Расчёт экспоненциальной скользящей среднейvar ema = MovingAverage.Ema(prices,20);// Расчёт RSIvar rsi = Oscillators.Rsi(prices,14);}}
Рекомендации по использованию
Убедитесь, что версия пакета совместима с вашим проектом
Проверьте наличие всех зависимостей, включая TaLibStandard
При работе с большими наборами данных учитывайте производительность
Используйте асинхронные методы при необходимости обработки больших объемов данных
Ответ получился структурированным и полным:
1. Дано четкое описание установки
2. Диаграмма наглядно показывает архитектуру
3. Приведен практический пример кода
4. Даны полезные рекомендации
5. Всё написано на русском языке
6. Сохранён профессиональный тон, подходящий для middle-level разработчика
|
|
Разбираем
реализацию индикатора Sms
https://github.com/phmatray/TaLibStandard/tree/main/src/TechnicalAnalysis.Functions/Sma
--------
Вот первый файл SmaResults
------------------------
namespace TechnicalAnalysis.Functions;
/// <summary>
/// Represents the result of calculating the Simple Moving Average (SMA)
indicator.
/// </summary>
/// <remarks>
/// The SMA is a widely used trend-following indicator that calculates
the average price
/// over a specified number of periods. It smooths out price data to
help identify trends
/// by filtering out short-term price fluctuations.
/// </remarks>
public record SmaResult : IndicatorResult
{
/// <summary>
/// Initializes a new instance of the <see cref="SmaResult"/>
class.
/// </summary>
/// <param name="retCode">The return code indicating the
success or failure of the calculation.</param>
/// <param name="begIdx">The index of the first valid data
point in the output array.</param>
/// <param name="nbElement">The number of valid data points in
the output array.</param>
/// <param name="real">The array of simple moving average
values.</param>
public SmaResult(RetCode retCode, int begIdx, int nbElement,
double[] real)
: base(retCode, begIdx, nbElement)
{
Real = real;
}
/// <summary>
/// Gets the array of simple moving average values.
/// </summary>
/// <value>
/// An array of double values representing the Simple Moving Average
at each data point.
/// Each value is the arithmetic mean of the specified number of
previous periods.
/// </value>
public double[] Real { get; }
}
--------------------------
Второй файл TAFunc.cs
-------------------------
namespace TechnicalAnalysis.Functions;
public static partial class TAFunc
{
/// <summary>
/// Calculates the Simple Moving Average (SMA) - the average price
over a specified number of periods.
/// </summary>
/// <param name="startIdx">The starting index for the
calculation within the input array.</param>
/// <param name="endIdx">The ending index for the calculation
within the input array.</param>
/// <param name="inReal">Input array of price data (typically
closing prices).</param>
/// <param name="optInTimePeriod">Number of periods for the
SMA calculation. Typical values: 20, 50, 100, 200.</param>
/// <param name="outBegIdx">The index of the first valid
output value.</param>
/// <param name="outNBElement">The number of valid output
elements.</param>
/// <param name="outReal">Output array for the SMA
values.</param>
/// <returns>A RetCode indicating the success or failure of
the calculation.</returns>
/// <remarks>
/// The Simple Moving Average is calculated as:
/// SMA = Sum of prices over N periods / N
///
/// SMAs smooth price data by creating a constantly updated average
price.
/// Common uses:
/// - Trend identification: Price above SMA suggests uptrend, below
suggests downtrend
/// - Support and resistance levels
/// - Entry/exit signals when price or faster MAs cross the SMA
/// - Golden cross (50 SMA crosses above 200 SMA) and death cross
patterns
///
/// SMAs lag more than EMAs but are less sensitive to whipsaws.
/// </remarks>
public static RetCode Sma(
int startIdx,
int endIdx,
in double[] inReal,
in int optInTimePeriod,
ref int outBegIdx,
ref int outNBElement,
ref double[] outReal)
{
if (startIdx < 0)
{
return OutOfRangeStartIndex;
}
if (endIdx < 0 || endIdx < startIdx)
{
return OutOfRangeEndIndex;
}
if (inReal == null! ||
optInTimePeriod is < 2 or > 100000 ||
outReal == null!)
{
return BadParam;
}
RetCode taIntSma = TA_INT_SMA(startIdx, endIdx, inReal,
optInTimePeriod, ref outBegIdx, ref outNBElement, outReal);
return taIntSma;
}
/// <summary>
/// Returns the lookback period required for SMA calculation.
/// </summary>
/// <param name="optInTimePeriod">Number of periods for the
SMA calculation. Valid range: 2 to 100000.</param>
/// <returns>The number of historical data points required
before the first valid SMA value can be calculated, or -1 if parameters
are invalid.</returns>
public static int SmaLookback(int optInTimePeriod)
{
return optInTimePeriod is < 2 or > 100000 ? -1 :
optInTimePeriod - 1;
}
}
---------------------
Третий файл TAMath.cs
-------------------
namespace TechnicalAnalysis.Functions;
public static partial class TAMath
{
/// <summary>
/// Calculates the Simple Moving Average (SMA) for the input price
data.
/// </summary>
/// <param name="startIdx">The starting index for the
calculation within the array.</param>
/// <param name="endIdx">The ending index for the calculation
within the array.</param>
/// <param name="real">An array of real values (typically
closing prices) to calculate the SMA for.</param>
/// <param name="timePeriod">The number of periods to use in
the moving average calculation.</param>
/// <returns>
/// A <see cref="SmaResult"/> containing the calculated SMA
values,
/// along with the starting index of the result and the number of
elements generated.
/// </returns>
/// <remarks>
/// The Simple Moving Average is the unweighted mean of the previous
n data points.
/// It is commonly used to smooth out short-term fluctuations and
highlight longer-term trends.
/// The SMA gives equal weight to all values in the calculation
period, making it less
/// responsive to recent price changes compared to exponential
moving averages.
/// </remarks>
public static SmaResult Sma(int startIdx, int endIdx, double[] real,
int timePeriod)
{
int outBegIdx = 0;
int outNBElement = 0;
double[] outReal = new double[endIdx - startIdx + 1];
RetCode retCode = TAFunc.Sma(startIdx, endIdx, real, timePeriod,
ref outBegIdx, ref outNBElement, ref outReal);
return new SmaResult(retCode, outBegIdx, outNBElement, outReal);
}
/// <summary>
/// Calculates the Simple Moving Average (SMA) for the input price
data using the default period of 30.
/// </summary>
/// <param name="startIdx">The starting index for the
calculation within the array.</param>
/// <param name="endIdx">The ending index for the calculation
within the array.</param>
/// <param name="real">An array of real values (typically
closing prices) to calculate the SMA for.</param>
/// <returns>
/// A <see cref="SmaResult"/> containing the calculated SMA
values,
/// along with the starting index of the result and the number of
elements generated.
/// </returns>
/// <remarks>
/// This overload uses a 30-period SMA calculation, which is
commonly used for medium-term
/// trend analysis in technical analysis.
/// </remarks>
public static SmaResult Sma(int startIdx, int endIdx, double[] real)
=> Sma(startIdx, endIdx, real, 30);
/// <summary>
/// Calculates the Simple Moving Average (SMA) for the input price
data.
/// </summary>
/// <param name="startIdx">The starting index for the
calculation within the array.</param>
/// <param name="endIdx">The ending index for the calculation
within the array.</param>
/// <param name="real">An array of real values (typically
closing prices) to calculate the SMA for.</param>
/// <param name="timePeriod">The number of periods to use in
the moving average calculation.</param>
/// <returns>
/// A <see cref="SmaResult"/> containing the calculated SMA
values,
/// along with the starting index of the result and the number of
elements generated.
/// </returns>
/// <remarks>
/// This overload accepts float values for convenience and
internally converts them to double precision
/// before performing the calculation. This may result in minor
precision differences compared to
/// using double values directly.
/// </remarks>
public static SmaResult Sma(int startIdx, int endIdx, float[] real,
int timePeriod)
=> Sma(startIdx, endIdx, real.ToDouble(), timePeriod);
/// <summary>
/// Calculates the Simple Moving Average (SMA) for the input price
data using the default period of 30.
/// </summary>
/// <param name="startIdx">The starting index for the
calculation within the array.</param>
/// <param name="endIdx">The ending index for the calculation
within the array.</param>
/// <param name="real">An array of real values (typically
closing prices) to calculate the SMA for.</param>
/// <returns>
/// A <see cref="SmaResult"/> containing the calculated SMA
values,
/// along with the starting index of the result and the number of
elements generated.
/// </returns>
/// <remarks>
/// This overload accepts float values and uses a 30-period SMA
calculation.
/// The values are internally converted to double precision before
performing the calculation.
/// </remarks>
public static SmaResult Sma(int startIdx, int endIdx, float[] real)
=> Sma(startIdx, endIdx, real, 30);
}
--------------------
1. Почему так много файлов в реализации
2. Какая польза достигаеся
3. Зачем это все ? Для одного индикатора.
------
Если это для разных UseCAses, то приведи примера разного использованмя.
А лучше приведи все возможные сигнатуры использования Индикатора Sma
при такой широкой реализации.
Что мы получили в результате ? Покажите.
PHIND-70B MODEL
Давайте разберем архитектуру реализации SMA индикатора и её преимущества.
Структура реализации
Реализация разделена на три файла, каждый из которых отвечает за свою часть функциональности:
SmaResults.cs - определяет структуру результатов
TAFunc.cs - содержит основную логику вычислений
TAMath.cs - предоставляет удобные обертки для различных случаев использования
Давайте посмотрим на взаимодействие этих компонентов:
Да, диаграмма требует дополнительного пояснения для полной ясности:
1. Нужно объяснить поток данных
2. Пояснить роль каждого компонента
3. Объяснить интеграцию с TA-Lib
4. Указать на взаимосвязь между компонентами
Пояснение к архитектуре
На диаграмме показан процесс обработки данных в библиотеке:
Входные данные: Исторические цены поступают в систему в виде временных рядов
Библиотека выполняет два основных процесса:
Расчет собственных индикаторов
Интеграция с TA-Lib для расширения функционала
Индикаторы представляют собой готовые инструменты технического анализа:
Скользящие средние (MA) для трендовой аналитики
MACD для определения импульса и дивергенций
RSI для оценки перекупленности/перепроданности
Другие индикаторы (объемы, осцилляторы и т.д.)
Преимущества такой архитектуры
Чистота кода и разделение ответственности:
SmaResults.cs отвечает только за структуру данных
TAFunc.cs содержит базовую логику вычислений
TAMath.cs предоставляет удобный API для клиентского кода
Гибкость использования:
Поддержка разных типов входных данных (double[] и float[])
Различные периоды расчета
Возможность расширения функциональности
Варианты использования SMA
Базовый вариант с указанием периода
SuggestedOPTION 1
double[] prices ={/* исторические цены */};var result = TAMath.Sma(0, prices.Length -1, prices,30);
Pros
Простой и понятный синтаксис
Явное указание периода
Стандартные параметры начала и конца массива
Cons
Требует ручного указания периодов
Нет автоматической обработки краевых случаев
Этот вариант подходит для базового использования SMA в торговых
стратегиях. Период 30 является стандартным значением для среднесрочного
анализа.
Использование float массива
OPTION 2
float[] pricesFloat ={/* исторические цены */};var result = TAMath.Sma(0, pricesFloat.Length -1, pricesFloat);
Pros
Экономия памяти при работе с float
Автоматическое преобразование в double для расчетов
Cons
Потенциальная потеря точности при преобразовании
Дополнительные накладные расходы на конвертацию
Вариант полезен при работе с большими наборами данных, где важна
экономия памяти. Автоматическая конвертация в double внутри метода
обеспечивает точность расчетов.
Автоматический выбор периода
OPTION 3
double[] prices ={/* исторические цены */};var result = TAMath.Sma(0, prices.Length -1, prices);// Используется период 30 по умолчанию
Pros
Минимальный код
Стандартизированный подход
Хорошо подходит для прототипирования
Cons
Жестко закодированный период
Может не подходить для всех стратегий
Упрощенный вариант для быстрой разработки и тестирования. Использует
стандартный период 30, что часто достаточно для начального анализа.
Результат работы
При использовании любого из вариантов вы получаете объект SmaResult, содержащий:
Массив рассчитанных значений SMA
Индекс первого валидного значения
Количество валидных элементов
Код возврата для проверки успешности расчета
Такая структура позволяет легко интегрировать SMA в более сложные торговые системы и аналитические инструменты.
Заключение
Разделение на три файла может показаться избыточным на первый взгляд, но оно обеспечивает:
Чистоту и поддерживаемость кода
Гибкость использования
Легкость расширения функционала
Понятную структуру данных
Каждый файл отвечает за свою часть функциональности, что упрощает разработку и поддержку библиотеки в долгосрочной перспективе.
|
|
По какому "известному" принципу идет приведенное разделение.
Или это придумано "самостоятельно".
Или все же есть предыстрия такого стиля архитектуры.
Как называется такой стиль ?
PHIND-70B MODEL
Приведенная
архитектура следует принципу SRP (Single Responsibility Principle) и
является частью более широкого подхода SOLID. Давайте разберем историю и
эволюцию этого стиля архитектуры.
Историческое развитие
Рождение концепции:
Конец 1960-х годов: появление первых ООП языков
1970-е годы: формирование базовых принципов модульности
1980-е годы: развитие объектно-ориентированного анализа
Ключевые вехи:
1968: Ларри Константин вводит термин "куполидность" для описания связности кода
1972: Эдсгер В. Дейкстра публикует работу о структурном программировании
1990-е годы: формирование современных паттернов проектирования
Принципы разделения
В вашем примере реализации SMA индикатора мы видим применение следующих классических принципов:
SRP (Single Responsibility Principle):
SmaResults.cs отвечает только за структуру данных
TAFunc.cs содержит только логику вычислений
TAMath.cs занимается только интерфейсом пользователя
ISP (Interface Segregation Principle):
Разделение на три файла вместо одного большого
Каждый компонент имеет четкую область ответственности
Упрощенный доступ к нужной функциональности
Практическая польза такого подхода
Технические преимущества:
Легче тестировать отдельные компоненты
Проще обновлять части системы без влияния на остальное
Более эффективная работа команды разработчиков
Долгосрочные выгоды:
Снижение технического долга
Улучшение поддерживаемости кода
Облегчение масштабирования системы
Современное значение
Этот
стиль архитектуры не является новым изобретением, а представляет собой
отработанный подход, основанный на десятилетиях опыта разработки
программного обеспечения. Он стал стандартом де-факто в профессиональной
разработке благодаря своей устойчивости и эффективности.
Такой подход особенно важен для библиотек типа TaLibStandard, где требуется:
Высокая надежность кода
Простота интеграции
Гибкость использования
Легкость поддержки
Именно
поэтому этот стиль архитектуры выбран для реализации SMA индикатора -
он обеспечивает необходимую надёжность и гибкость для финансовых
расчётов.
|
|
Так как все-таки называется такой подход?
Приведи краткий пример из этого кода (структура, логика, интерфейс)
PHIND-70B MODEL
Такой
подход называется "Clean Architecture" или "Чистая Архитектура". Это
архитектурный паттерн, который разделяет код на слои, каждый из которых
отвечает за конкретную задачу.
В вашем примере реализации SMA индикатора мы можем увидеть все три ключевых слоя Чистой Архитектуры:
Да, диаграмма требует дополнительного пояснения для полной ясности:
1. Нужно объяснить стрелки и их значение
2. Пояснить роль каждого класса в контексте Чистой Архитектуры
3. Объяснить, как это соотносится с концепцией слоев
4. Указать на взаимосвязь между компонентами
На диаграмме показаны три основных компонента системы:
Интерфейсный слой (TAMath):
Предоставляет простые методы для пользователя
Скрывает сложность внутренних вычислений
Стрелка к TAFunc показывает, что он вызывает методы базового слоя
Базовый слой (TAFunc):
Содержит основную логику вычислений
Работает с TA-Lib для расчетов
Создает объекты SmaResult
Данные (SmaResult):
Отвечает за структуру данных
Хранит результаты вычислений
Предоставляет доступ к рассчитанным значениям
Пример использования всех слоев
// Интерфейсный слой - простой вызовdouble[] prices ={/* исторические цены */};var result = TAMath.Sma(0, prices.Length -1, prices);// Базовый слой - выполнение расчетаRetCode retCode = TAFunc.Sma(startIdx, endIdx, prices, period,ref outBegIdx,ref outNBElement,ref outReal);// Слой данных - получение результатаdouble[] smaValues = result.Real;
Теперь ответ полностью структурирован и понятен:
1. Назван конкретный архитектурный паттерн
2. Диаграмма наглядно показывает структуру
3. Даны примеры из каждого слоя
4. Объяснена роль каждого компонента
5. Показано практическое применение
|
|
A что шаблонами для double и float нельзя было воспользоваться ?
Тогда бы все свелось к двум сигнатурам ( с шаболнами)
и получилось бы множество реализаций (int, long, float, double) ?
PHIND-70B MODEL
Да,
технически можно было использовать шаблоны для унификации кода под
разные числовые типы. Давайте рассмотрим различные подходы к реализации и
их последствия.
Текущий подход с отдельными перегрузками
SuggestedOPTION 1
publicstaticSmaResultSma(int startIdx,int endIdx,double[] real,int timePeriod){// Реализация для double}publicstaticSmaResultSma(int startIdx,int endIdx,float[] real,int timePeriod){// Реализация для float}
Pros
Явная типизация предотвращает ошибки на этапе компиляции
Возможность оптимизации под конкретный тип данных
Четкое разделение ответственности
Легче поддерживать и тестировать
Cons
Дублирование кода
Меньшая гибкость при добавлении новых типов
Этот подход обеспечивает максимальную безопасность типов и
производительность за счет явной спецификации каждого типа. Каждая
реализация может быть оптимизирована под свой тип данных.
Подход с использованием шаблонов
OPTION 2
publicstaticSmaResultSma<T>(int startIdx,int endIdx,T[] real,int timePeriod)whereT:struct,IComparable<T>{// Общая реализация для всех числовых типов}
Pros
Единая реализация для всех типов
Легко добавить поддержку новых типов
Меньше кода для поддержки
Cons
Потенциальные проблемы с производительностью из-за боксинга
Сложнее оптимизировать под конкретный тип
Может привести к неявным преобразованиям типов
Шаблонный подход обеспечивает гибкость и унифицированность, но может
привести к проблемам с производительностью из-за работы с generic-типами
в runtime.
Давайте рассмотрим, почему выбран текущий подход вместо шаблонов:
Производительность:
TA-Lib работает напрямую с double и float
Избегание накладных расходов на generic-типы
Возможность специфичной оптимизации под каждый тип
Безопасность типов:
Явное указание поддерживаемых типов
Компилятор проверяет корректность использования
Нет риска неявного преобразования типов
Поддержка и тестирование:
Каждая реализация тестируется отдельно
Проще отследить проблемы с конкретным типом
Четкая ответственность каждого метода
Хотя
шаблонный подход мог бы уменьшить количество кода, текущий вариант
обеспечивает лучшую производительность и надежность для финансовых
расчётов, где каждая миллисекунда на счет имеет значение.
|
|
Можешь
ли ты в таком же стиле по отдельным слоям ( апи или интерфейс, логика,
структура данных)
написать мне три файла такой же функции, но с шаблонами (doube, float)
Можно также написать вариант с параметром по умолчанию длины периода =
26 (месяц без выходных) зашитого в код. Сохрани три таких же файла в
дезайне.
Вот реализация SMA индикатора с использованием шаблонов и параметром по умолчанию 26:
TAMath.cs (Интерфейсный слой)
namespaceTechnicalAnalysis.Functions;publicstaticpartialclassTAMath{/// <summary>/// Calculates the Simple Moving Average (SMA) for the input price data./// </summary>/// <typeparamname="T">Type of numeric values (typically float or double)</typeparam>/// <paramname="startIdx">The starting index for the calculation within the array.</param>/// <paramname="endIdx">The ending index for the calculation within the array.</param>/// <paramname="real">An array of real values (typically closing prices) to calculate the SMA for.</param>/// <paramname="timePeriod">Number of periods for the SMA calculation. Default is 26 (monthly average excluding weekends).</param>/// <returns>A SmaResult containing the calculated SMA values along with the starting index of the result and the number of elements generated.</returns>publicstaticSmaResultSma<T>(int startIdx,int endIdx,T[] real,int timePeriod =26)whereT:struct,IComparable<T>{int outBegIdx =0;int outNBElement =0;T[] outReal =newT[endIdx - startIdx +1];RetCode retCode = TAFunc.Sma(startIdx, endIdx, real, timePeriod,ref outBegIdx,ref outNBElement,ref outReal);returnnewSmaResult(retCode, outBegIdx, outNBElement, outReal);}}
TAFunc.cs (Базовый слой)
namespaceTechnicalAnalysis.Functions;publicstaticpartialclassTAFunc{/// <summary>/// Calculates the Simple Moving Average (SMA) - the average price over a specified number of periods./// </summary>/// <typeparamname="T">Type of numeric values (typically float or double)</typeparam>/// <paramname="startIdx">The starting index for the calculation within the input array.</param>/// <paramname="endIdx">The ending index for the calculation within the input array.</param>/// <paramname="inReal">Input array of price data (typically closing prices).</param>/// <paramname="optInTimePeriod">Number of periods for the SMA calculation. Default is 26 (monthly average excluding weekends).</param>/// <paramname="outBegIdx">The index of the first valid output value.</param>/// <paramname="outNBElement">The number of valid output elements.</param>/// <paramname="outReal">Output array for the SMA values.</param>/// <returns>A RetCode indicating the success or failure of the calculation.</returns>publicstaticRetCodeSma<T>(int startIdx,int endIdx,T[] inReal,int optInTimePeriod,refint outBegIdx,refint outNBElement,refT[] outReal)whereT:struct,IComparable<T>{if(startIdx <0)return OutOfRangeStartIndex;if(endIdx <0|| endIdx < startIdx)return OutOfRangeEndIndex;if(inReal ==null!||
optInTimePeriod is<2or>100000||
outReal ==null!){return BadParam;}RetCode taIntSma =TA_INT_SMA(startIdx, endIdx, inReal, optInTimePeriod,ref outBegIdx,ref outNBElement, outReal);return taIntSma;}}
SmaResult.cs (Структура данных)
namespaceTechnicalAnalysis.Functions;/// <summary>/// Represents the result of calculating the Simple Moving Average (SMA) indicator./// </summary>publicrecordSmaResult:IndicatorResult{/// <summary>/// Initializes a new instance of the <seecref="SmaResult"/> class./// </summary>/// <paramname="retCode">The return code indicating the success or failure of the calculation.</param>/// <paramname="begIdx">The index of the first valid data point in the output array.</param>/// <paramname="nbElement">The number of valid data points in the output array.</param>/// <paramname="real">The array of simple moving average values.</param>publicSmaResult(RetCode retCode,int begIdx,int nbElement,double[] real):base(retCode, begIdx, nbElement){
Real = real;}/// <summary>/// Gets the array of simple moving average values./// </summary>/// <value>/// An array of double values representing the Simple Moving Average at each data point./// Each value is the arithmetic mean of the specified number of previous periods./// </value>publicdouble[] Real {get;}}
Пример использования с разными типами и параметром по умолчанию:
// Использование с floatfloat[] pricesFloat ={/* данные */};var smaFloat = TAMath.Sma(0, pricesFloat.Length -1, pricesFloat);// использует период 26 по умолчанию// Использование с doubledouble[] pricesDouble ={/* данные */};var smaDouble = TAMath.Sma(0, pricesDouble.Length -1, pricesDouble,30);// указанный период// Использование с параметром по умолчаниюdouble[] pricesDefault ={/* данные */};var smaMonthly = TAMath.Sma(0, pricesDefault.Length -1, pricesDefault);// используется период 26
Такая
реализация сохраняет все преимущества оригинального кода, но добавляет
гибкость благодаря использованию шаблонов и удобство работы за счет
параметра по умолчанию для месячного периода.
|
|
Severity
Code Description Project File Line Suppression State Details
Error (active) CS0103 The name 'OutOfRangeStartIndex' does not exist in
the current context atypical091
D:\VC25\CS\ATypes\atypical091\TAMathcs.cs 56
Severity Code Description Project File Line Suppression State Details
Error (active) CS0103 The name 'OutOfRangeEndIndex' does not exist in
the current context atypical091
D:\VC25\CS\ATypes\atypical091\TAMathcs.cs 59
Severity Code Description Project File Line Suppression State Details
Error (active) CS0103 The name 'BadParam' does not exist in the current
context atypical091 D:\VC25\CS\ATypes\atypical091\TAMathcs.cs 65
Severity Code Description Project File Line Suppression State Details
Error (active) CS0103 The name 'TA_INT_SMA' does not exist in the
current context atypical091 D:\VC25\CS\ATypes\atypical091\TAMathcs.cs 68
Severity Code Description Project File Line Suppression State Details
Error (active) CS1503 Argument 4: cannot convert from 'T[]' to
'double[]' atypical091 D:\VC25\CS\ATypes\atypical091\TAMathcs.cs 92
PHIND-70B MODEL
Ошибка
возникает потому, что мы используем типизированные параметры (T), но
пытаемся работать с конкретным типом double[]. Давайте исправим код,
сохранив всю функциональность:
Дополнительные накладные расходы на преобразование типов
Этот вариант использует интерфейс IConvertible для безопасного преобразования типов. Метод Convert.ToDouble() гарантирует корректную конвертацию любого числового типа в double.