Files
QuanTAlib/docs/getting_started.ipynb
T
2022-11-06 17:20:57 -08:00

12 KiB

Quick Start

In order to use this .NET Interactive Notebook and play along with QuanTAlib (outside of making your own app or plugging QuanTAlib into Quantower platform), you will need:

For impatient, here is a simple example of calculating three moving averages - SMA(data), EMA(SMA(data)) and WMA(EMA(SMA(data))) from 10 days of AAPL stock data using QuanTAlib:

In [ ]:
#r "nuget:QuanTAlib;"
using QuanTAlib;

YAHOO_Feed aapl = new(15, "AAPL");
TSeries data = aapl.Close;
SMA_Series sma = new(source: data, period: 5, useNaN: false);
EMA_Series ema = new(sma, period: 5);                   // by default, indicators expose all data, no NaN values
WMA_Series wma = new(ema, 5, useNaN: true);             // for the final calculation we can hide early data with NaNs

Console.Write($"index\t data\t\t sma(data)\t ema(sma(data))\t wma(ema(sma(data)))\n");
for (int i=0; i<data.Count; i++)
    Console.Write($"{i}\t {data[i].t:yyyy-MM-dd}\t {sma[i].v:f2}\t\t {ema[i].v:f2}\t\t {wma[i].v:f2}\n");
index	 data		 sma(data)	 ema(sma(data))	 wma(ema(sma(data)))
0	 2022-03-23	 170.21		 170.21		 NaN
1	 2022-03-24	 172.14		 170.85		 NaN
2	 2022-03-25	 173.00		 171.57		 NaN
3	 2022-03-28	 173.65		 172.26		 NaN
4	 2022-03-29	 174.71		 173.08		 172.07
5	 2022-03-30	 176.22		 174.13		 172.92
6	 2022-03-31	 176.33		 174.86		 173.74
7	 2022-04-01	 176.25		 175.32		 174.46
8	 2022-04-04	 176.82		 175.82		 175.09
9	 2022-04-05	 176.04		 175.89		 175.51
10	 2022-04-06	 174.85		 175.55		 175.62
11	 2022-04-07	 174.36		 175.15		 175.51

Understanding QuanTAlib data model

QuanTAlib expects that every data item is a tuple (TimeDate t, double v) and TSeries is a list of (t,v) tuples. There are several helpers built into the TSeries class to simplify adding elements:

In [ ]:
var item1 = (DateTime.Today, 105.3);        // (DateTime, Value) tuple
double item2 = 293.1;                       // a simple double

TSeries data = new();
data.Add(item1);                            // adding tuple variable
data.Add(item2);                            // QuanTAlib stamps the (double) with current time
data.Add(0);                                // directly adding a number (stamped with current time)
data.Add((DateTime.Now.AddDays(-3), 10));   // adding a tuple with timestamp 3 days ago

data
indexItem1Item2
02022-04-07 00:00:00Z
105.3
12022-04-07 21:57:46Z
293.1
22022-04-07 21:57:46Z
0
32022-04-04 21:57:46Z
10

TSeries list can display only values (without timestamps) or only timestamps (without values) by using .v or .t properties

In [ ]:
data.v
indexvalue
0
105.3
1
293.1
2
0
3
10

The last element on the list can be accessed by .Last() or by [^1] - and using .t (time) and .v (value) properties. Also, casting a TSeries into (double) will return the value of the last element

In [ ]:
bool IsTheSame = data.Last().v == data[^1].v;
double lastvalue = data;

lastvalue
10

All indicators are just modified TSeries classes; they get all required input during class construction (source of the datafeed, period...) and they automatically subscribe to events of the datafeed. Whenever datafeed gets a new value, indicator will calculate its own value. Indicators are also event publishers, so other indicators can subscribe to their results, chaining indicators together:

In [ ]:
TSeries t1 = new() {0,1,2,3,4,5,6,7,8,9}; // t1 is loaded with data and activated as a publisher
EMA_Series t2 = new(t1, 3);     // t2 will auto-load all history of t1 and wait for events from t1
ADD_Series t3 = new(t1, t2);    // t3 is an ADDition of t1 and t2 - will also load history and wait for t2 events
DIV_Series t4 = new(1, t3);     // t4 is calculating 1/t3 - and waiting for t3 events

TSeries t5 = new();             // a wild indicator appeared! And it is empty!
t4.Pub += t5.Sub;               // let us add a manual subscription to events coming from t4 - t5 is now listening to t4
t1.Add(0);                      // we add one new value to t1 - and trigger the full cascade of calculation! t5 is now full!

t5.v
indexvalue
0
Infinity
1
0.6666666666666666
2
0.3076923076923077
3
0.1951219512195122
4
0.1415929203539823
5
0.11072664359861592
6
0.09078014184397164
7
0.07687687687687687
8
0.06664931007550118
9
0.05881677197013211
10
0.2499389797412741

MACD compounded indicator

With QuanTAlib we can chain indicators together, creating complex compounded indicators. For example, we can create Moving Average Convergence/Divergence (MACD) indicators by chaining all required operations in a sequence:

In [ ]:
YAHOO_Feed aapl = new(20, "AAPL");
TSeries close = aapl.Close;                 // close will get data from history
EMA_Series slow = new(close,26);            // slow gets data from slow through pub-sub eventing
EMA_Series fast = new(close,12);            // fast gets data from slow (via eventing)
SUB_Series macd = new(fast,slow);           // macd is a SUBtraction: fast-slow
EMA_Series signal = new(macd,9);            // signal is EMA of macd
SUB_Series histogram = new(macd, signal);   // histogram is SUBtraction macd-signal

histogram.v
indexvalue
0
0
1
0.08934530370370339
2
0.3599908358509947
3
0.5984373224068585
4
0.9604679820661939
5
1.17393637722238
6
1.295101583309171
7
1.5073770108948183
8
1.4718244887751928
9
1.1537265475126177
10
0.8550987734004014
11
0.8650928385987653
12
0.5867583008849087
13
0.15053155636913873
14
-0.13622024638714825