SquidEyes.TechAnalysis is a collection of high-performance C#/.NET 7.0 technical indicators with a hand-curated set of matching unit-tests.
| Code | Name | Indicator | Kind |
|---|---|---|---|
| ATR | Average True Range | AtrIndicator | Statistics |
| BBAND | Bollinger Bands | BollingerBandsIndicator | Channels |
| CCI | Commodity Channel Index | CciIndicator | Oscillator |
| DEMA | Double Exponential Moving Average | DemaIndicator | Moving Average |
| EMA | Exponential Moving Average | EmaIndicator | Moving Average |
| KAMA | Kaufman's Adaptive Moving Average | KamaIndicator | Moving Average |
| KLTNR | Keltner Channel | KelnerChannelIndicator | Channels |
| LINREG | Linear Regression | LinRegIndicator | Regression |
| MACD | Moving Average Convergence Divergence | MacdIndicator | Statistics |
| SMA | Simple Moving Average | SmaIndicator | Moving Average |
| SMMA | Smoothed Moving Average | SmmaIndicator | Moving Average |
| STDDEV | Standard Deviation | StdDevIndicator | Statistics |
| STOCH | Stochastics Oscillator | StochasticsIndicator | Oscillator |
| TEMA | Triple Exponential Moving Average | TemaIndicator | Moving Average |
| WMA | Weighted Moving Average | WmaIndicator | Moving Average |
To be clear, there are a good number of C#-based technical indicator libraries (i.e. Trady, Stock Indicators, TA-Lib.NETCore, and NetTrader, just to name a few), but the author found each of these to be objectionable for one or more reasons:
- Poor performance (whether from use of decimals or otherwise)
- Poor standardization
- No provision for float-based candles
- Reliance upon inflexible and inbuilt result-persistence layers
To take a rather simple example, an EmaIndicator might be used as follows:
// Add the result to a chart, perform a calculation, etc.
static void PrintResult(BasicResult result) =>
Debug.WriteLine($"{result.CloseOn} ={result.Value}");
// CloseOn,Open,High,Low,Close[,Volume] data in CSV multi-line format
const string CSV = """
05/15/2023 14:36:00,12872.75,12873.75,12866,12870.75
05/15/2023 14:37:00,12871.25,12871.5,12864.75,12869.5
05/15/2023 14:38:00,12869.25,12871.75,12867.5,12871.25
05/15/2023 14:39:00,12871,12873.75,12869.5,12872.75
05/15/2023 14:40:00,12872.75,12873.75,12867.75,12870.5
""";
// Optionally include Volume as a sixth field per line
// e.g., 05/15/2023 14:36:00,12872.75,12873.75,12866,12870.75,15000
// Most of the indicators return BasicResult, but a few return
// custom results (BollingerIndicator, MacddIndicator, etc.)
var indicator = new EmaIndicator(period: 3,
priceToUse: PriceToUse.Close, maxResults: 10000);
// Parse the data then
foreach (var fields in new CsvEnumerator(CSV.ToStream(), 5))
{
var candle = new TestCandle()
{
CloseOn = DateTime.Parse(fields[0]),
Open = double.Parse(fields[1]),
High = double.Parse(fields[2]),
Low = double.Parse(fields[3]),
Close = double.Parse(fields[4]),
Volume = (fields.Length > 5 ? double.Parse(fields[5]) : 10000 + (double.Parse(fields[2]) - double.Parse(fields[3])) * 1000)
};
// Adds the current result to the indicator's results
// collection (a reversed SlidingBuffer) then returns
// that result directly
_ = indicator.AddAndCalc(candle);
if (!indicator.IsPrimed)
continue;
// A result may also be obtained via a [0..maxResults - 1]
// index on the indicator, with zero being the most recent
PrintResult(indicator[2]);
}Contributions are always welcome (see CONTRIBUTING.md for details)
Supper-Duper Extra-Important Caveat: THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
FINAL WARNING: The use of this code may (literally!) lead to your losing thousands of dollars or more. Caveat Emptor!!