diff --git a/Quantower/Quantower.csproj b/Quantower/Quantower.csproj
index 001f339f..79e26eb8 100644
--- a/Quantower/Quantower.csproj
+++ b/Quantower/Quantower.csproj
@@ -29,7 +29,7 @@
anycpu
-
+
QuanTAlib\%(RecursiveDir)%(Filename)%(Extension)
diff --git a/Source/Basics/Alphavantage_Feed.cs b/Source/Feeds/Alphavantage_Feed.cs
similarity index 90%
rename from Source/Basics/Alphavantage_Feed.cs
rename to Source/Feeds/Alphavantage_Feed.cs
index b7c59f00..efb97028 100644
--- a/Source/Basics/Alphavantage_Feed.cs
+++ b/Source/Feeds/Alphavantage_Feed.cs
@@ -1,112 +1,124 @@
-namespace QuanTAlib;
-using System;
-using System.Text.Json;
-
-/*
-Alphavantage - Free API to collect quotes for stock, Forex and crypto. It requires a (free) API key
- Get API key at https://www.alphavantage.co/support/#api-key
- Parameters:
- Symbol: stock ("AAPL"), crypto ("BTC") or forex pair (divided by dash: "USD-EUR")
- Extended: if true, return 2,000 rows. if false, return 100 rows
- Interval: enum with options of Month, Week, Day, Hour, Min30, Min15, Min5, Min1
- APIkey: unique Alphavantage API key
-
- */
-
-public class Alphavantage_Feed : TBars
-{
- //public enum Interval { Month, Week, Day, Hour, Min30, Min15, Min5, Min1}
- public Alphavantage_Feed(string Symbol = "IBM", bool Extended = false, Interval Interval = Interval.Day, string APIkey = "demo")
- {
-
- string outputsize = "compact";
- if (Extended) { outputsize = "full"; }
- System.Net.Http.HttpClient client = new();
-
- JsonElement json = new();
- var tokens = Symbol.Split("-");
- if (tokens.Count() > 1)
- {
- string req = "https://www.alphavantage.co/query?function=FX" + GetInterval(Interval) + "&from_symbol=" + tokens[0] + "&to_symbol=" + tokens[1] + "&outputsize=" + outputsize + "&apikey=" + APIkey;
- var msg = client.GetStringAsync(req).Result;
- var jres = JsonSerializer.Deserialize(msg).RootElement;
- switch (Interval)
- {
- case Interval.Month: jres.TryGetProperty("Time Series FX (Monthly)", out json); break;
- case Interval.Week: jres.TryGetProperty("Time Series FX (Weekly)", out json); break;
- case Interval.Day: jres.TryGetProperty("Time Series FX (Daily)", out json); break;
- case Interval.Hour: jres.TryGetProperty("Time Series FX (60min)", out json); break;
- case Interval.Min30: jres.TryGetProperty("Time Series FX (30min)", out json); break;
- case Interval.Min15: jres.TryGetProperty("Time Series FX (15min)", out json); break;
- case Interval.Min5: jres.TryGetProperty("Time Series FX (5min)", out json); break;
- case Interval.Min1: jres.TryGetProperty("Time Series FX (1min)", out json); break;
- }
-
- }
- if (json.ValueKind == JsonValueKind.Undefined)
- {
- string req = "https://www.alphavantage.co/query?function=TIME_SERIES" + GetInterval(Interval) + "&symbol=" + Symbol + "&outputsize=" + outputsize + "&apikey=" + APIkey;
- var msg = client.GetStringAsync(req).Result;
- var jres = JsonSerializer.Deserialize(msg).RootElement;
- switch (Interval)
- {
- case Interval.Month: jres.TryGetProperty("Monthly Time Series", out json); break;
- case Interval.Week: jres.TryGetProperty("Weekly Time Series", out json); break;
- case Interval.Day: jres.TryGetProperty("Time Series (Daily)", out json); break;
- case Interval.Hour: jres.TryGetProperty("Time Series (60min)", out json); break;
- case Interval.Min30: jres.TryGetProperty("Time Series (30min)", out json); break;
- case Interval.Min15: jres.TryGetProperty("Time Series (15min)", out json); break;
- case Interval.Min5: jres.TryGetProperty("Time Series (5min)", out json); break;
- case Interval.Min1: jres.TryGetProperty("Time Series (1min)", out json); break;
- }
- }
- if (json.ValueKind == JsonValueKind.Undefined)
- {
- string req;
- if ((int)Interval < 3) { req = "https://www.alphavantage.co/query?function=DIGITAL_CURRENCY" + GetInterval(Interval) + "&symbol=" + Symbol + "&market=USD&&outputsize=" + outputsize + "&apikey=" + APIkey; }
- else { req = "https://www.alphavantage.co/query?function=CRYPTO" + GetInterval(Interval) + "&symbol=" + Symbol + "&market=USD&&outputsize=" + outputsize + "&apikey=" + APIkey; }
- var msg = client.GetStringAsync(req).Result;
- var jres = JsonSerializer.Deserialize(msg).RootElement;
- switch (Interval)
- {
- case Interval.Month: jres.TryGetProperty("Time Series (Digital Currency Monthly)", out json); break;
- case Interval.Week: jres.TryGetProperty("Time Series (Digital Currency Weekly)", out json); break;
- case Interval.Day: jres.TryGetProperty("Time Series (Digital Currency Daily)", out json); break;
- case Interval.Hour: jres.TryGetProperty("Time Series Crypto (60min)", out json); break;
- case Interval.Min30: jres.TryGetProperty("Time Series Crypto (30min)", out json); break;
- case Interval.Min15: jres.TryGetProperty("Time Series Crypto (15min)", out json); break;
- case Interval.Min5: jres.TryGetProperty("Time Series Crypto (5min)", out json); break;
- case Interval.Min1: jres.TryGetProperty("Time Series Crypto (1min)", out json); break;
- }
- }
- if (json.ValueKind != JsonValueKind.Undefined)
- {
- foreach (var val in json.EnumerateObject()) { base.Add(GetOHLC(val)); }
- }
-
- }
- private (DateTime t, double o, double h, double l, double c, double v) GetOHLC(JsonProperty json)
- {
- double o, h, l, c, v;
- o = h = l = c = v = 0;
- DateTime date = Convert.ToDateTime(json.Name);
- foreach (var val in json.Value.EnumerateObject())
- {
- switch (val.Name)
- {
- case "1. open": o = Convert.ToDouble(val.Value.ToString()); break;
- case "1b. open (USD)": o = Convert.ToDouble(val.Value.ToString()); break;
- case "2. high": h = Convert.ToDouble(val.Value.ToString()); break;
- case "2b. high (USD)": h = Convert.ToDouble(val.Value.ToString()); break;
- case "3. low": l = Convert.ToDouble(val.Value.ToString()); break;
- case "3b. low (USD)": l = Convert.ToDouble(val.Value.ToString()); break;
- case "4. close": c = Convert.ToDouble(val.Value.ToString()); break;
- case "4b. close (USD)": c = Convert.ToDouble(val.Value.ToString()); break;
- case "5. adjusted close": c = Convert.ToDouble(val.Value.ToString()); break;
- case "5. volume": v = Convert.ToDouble(val.Value.ToString()); break;
- case "6. volume": v = Convert.ToDouble(val.Value.ToString()); break;
- }
- }
- return (date, o, h, l, c, v);
- }
+namespace QuanTAlib;
+using System;
+using System.Text.Json;
+
+/*
+Alphavantage - Free API to collect quotes for stock, Forex and crypto. It requires a (free) API key
+ Get API key at https://www.alphavantage.co/support/#api-key
+ Parameters:
+ Symbol: stock ("AAPL"), crypto ("BTC") or forex pair (divided by dash: "USD-EUR")
+ Extended: if true, return 2,000 rows. if false, return 100 rows
+ Interval: enum with options of Month, Week, Day, Hour, Min30, Min15, Min5, Min1
+ APIkey: unique Alphavantage API key
+
+ */
+
+public class Alphavantage_Feed : TBars
+{
+ public enum Interval { Month, Week, Day, Hour, Min30, Min15, Min5, Min1}
+ public Alphavantage_Feed(string Symbol = "IBM", bool Extended = false, Interval Interval = Interval.Day, string APIkey = "demo")
+ {
+
+ string outputsize = "compact";
+ if (Extended) { outputsize = "full"; }
+ System.Net.Http.HttpClient client = new();
+ JsonElement json = new();
+ var tokens = Symbol.Split("-");
+ if (tokens.Length > 1)
+ {
+ string req = "https://www.alphavantage.co/query?function=FX" + GetInterval(Interval) + "&from_symbol=" + tokens[0] + "&to_symbol=" + tokens[1] + "&outputsize=" + outputsize + "&apikey=" + APIkey;
+ var msg = client.GetStringAsync(req).Result;
+ var jres = JsonSerializer.Deserialize(msg).RootElement;
+ switch (Interval)
+ {
+ case Interval.Month: jres.TryGetProperty("Time Series FX (Monthly)", out json); break;
+ case Interval.Week: jres.TryGetProperty("Time Series FX (Weekly)", out json); break;
+ case Interval.Day: jres.TryGetProperty("Time Series FX (Daily)", out json); break;
+ case Interval.Hour: jres.TryGetProperty("Time Series FX (60min)", out json); break;
+ case Interval.Min30: jres.TryGetProperty("Time Series FX (30min)", out json); break;
+ case Interval.Min15: jres.TryGetProperty("Time Series FX (15min)", out json); break;
+ case Interval.Min5: jres.TryGetProperty("Time Series FX (5min)", out json); break;
+ case Interval.Min1: jres.TryGetProperty("Time Series FX (1min)", out json); break;
+ }
+
+ }
+ if (json.ValueKind == JsonValueKind.Undefined)
+ {
+ string req = "https://www.alphavantage.co/query?function=TIME_SERIES" + GetInterval(Interval) + "&symbol=" + Symbol + "&outputsize=" + outputsize + "&apikey=" + APIkey;
+ var msg = client.GetStringAsync(req).Result;
+ var jres = JsonSerializer.Deserialize(msg).RootElement;
+ switch (Interval)
+ {
+ case Interval.Month: jres.TryGetProperty("Monthly Time Series", out json); break;
+ case Interval.Week: jres.TryGetProperty("Weekly Time Series", out json); break;
+ case Interval.Day: jres.TryGetProperty("Time Series (Daily)", out json); break;
+ case Interval.Hour: jres.TryGetProperty("Time Series (60min)", out json); break;
+ case Interval.Min30: jres.TryGetProperty("Time Series (30min)", out json); break;
+ case Interval.Min15: jres.TryGetProperty("Time Series (15min)", out json); break;
+ case Interval.Min5: jres.TryGetProperty("Time Series (5min)", out json); break;
+ case Interval.Min1: jres.TryGetProperty("Time Series (1min)", out json); break;
+ }
+ }
+ if (json.ValueKind == JsonValueKind.Undefined)
+ {
+ string req;
+ if ((int)Interval < 3) { req = "https://www.alphavantage.co/query?function=DIGITAL_CURRENCY" + GetInterval(Interval) + "&symbol=" + Symbol + "&market=USD&&outputsize=" + outputsize + "&apikey=" + APIkey; }
+ else { req = "https://www.alphavantage.co/query?function=CRYPTO" + GetInterval(Interval) + "&symbol=" + Symbol + "&market=USD&&outputsize=" + outputsize + "&apikey=" + APIkey; }
+ var msg = client.GetStringAsync(req).Result;
+ var jres = JsonSerializer.Deserialize(msg).RootElement;
+ switch (Interval)
+ {
+ case Interval.Month: jres.TryGetProperty("Time Series (Digital Currency Monthly)", out json); break;
+ case Interval.Week: jres.TryGetProperty("Time Series (Digital Currency Weekly)", out json); break;
+ case Interval.Day: jres.TryGetProperty("Time Series (Digital Currency Daily)", out json); break;
+ case Interval.Hour: jres.TryGetProperty("Time Series Crypto (60min)", out json); break;
+ case Interval.Min30: jres.TryGetProperty("Time Series Crypto (30min)", out json); break;
+ case Interval.Min15: jres.TryGetProperty("Time Series Crypto (15min)", out json); break;
+ case Interval.Min5: jres.TryGetProperty("Time Series Crypto (5min)", out json); break;
+ case Interval.Min1: jres.TryGetProperty("Time Series Crypto (1min)", out json); break;
+ }
+ }
+ if (json.ValueKind != JsonValueKind.Undefined)
+ {
+ foreach (var val in json.EnumerateObject()) { base.Add(GetOHLC(val)); }
+ }
+
+ }
+ private static (DateTime t, double o, double h, double l, double c, double v) GetOHLC(JsonProperty json)
+ {
+ double o, h, l, c, v;
+ o = h = l = c = v = 0;
+ DateTime date = Convert.ToDateTime(json.Name);
+ foreach (var val in json.Value.EnumerateObject())
+ {
+ switch (val.Name)
+ {
+ case "1. open": o = Convert.ToDouble(val.Value.ToString()); break;
+ case "1b. open (USD)": o = Convert.ToDouble(val.Value.ToString()); break;
+ case "2. high": h = Convert.ToDouble(val.Value.ToString()); break;
+ case "2b. high (USD)": h = Convert.ToDouble(val.Value.ToString()); break;
+ case "3. low": l = Convert.ToDouble(val.Value.ToString()); break;
+ case "3b. low (USD)": l = Convert.ToDouble(val.Value.ToString()); break;
+ case "4. close": c = Convert.ToDouble(val.Value.ToString()); break;
+ case "4b. close (USD)": c = Convert.ToDouble(val.Value.ToString()); break;
+ case "5. adjusted close": c = Convert.ToDouble(val.Value.ToString()); break;
+ case "5. volume": v = Convert.ToDouble(val.Value.ToString()); break;
+ case "6. volume": v = Convert.ToDouble(val.Value.ToString()); break;
+ }
+ }
+ return (date, o, h, l, c, v);
+ }
+
+ private static string GetInterval(Interval interval = Interval.Day) => interval switch
+ {
+ Interval.Month => "_MONTHLY",
+ Interval.Week => "_WEEKLY",
+ Interval.Day => "_DAILY",
+ Interval.Hour => "_INTRADAY&interval=60min",
+ Interval.Min30 => "_INTRADAY&interval=30min",
+ Interval.Min15 => "_INTRADAY&interval=15min",
+ Interval.Min5 => "_INTRADAY&interval=5min",
+ Interval.Min1 => "_INTRADAY&interval=1min",
+ _ => "_DAILY"
+ };
}
\ No newline at end of file
diff --git a/Source/Basics/GBM_Feed.cs b/Source/Feeds/GBM_Feed.cs
similarity index 94%
rename from Source/Basics/GBM_Feed.cs
rename to Source/Feeds/GBM_Feed.cs
index 3efd8114..0e950683 100644
--- a/Source/Basics/GBM_Feed.cs
+++ b/Source/Feeds/GBM_Feed.cs
@@ -1,60 +1,60 @@
-namespace QuanTAlib;
-using System;
-
-/*
-GBM - Geometric Brownian Motion is a random simulator of market movement, returning List
- GBM can be used for testing indicators, validation and Monte Carlo simulations of strategies.
-
- Sample usage:
- GBM-Random data = new(); // generates 1 year (252) list of bars
- GBM-Random data = new(Bars: 1000); // generates 1,000 bars
- GBM-Random data = new(Bars: 252, Volatility: 0.05, Drift: 0.0005, Seed: 100.0)
-
- Parameters
- Bars: number of bars (quotes) requested
- Volatility: how dymamic/volatile the series should be; default is 1
- Drift: incremental drift due to annual interest rate; default is 5%
- Seed: starting value of the random series; should not be 0
-
-
*/
-
-public class GBM_Feed : TBars
-{
- double seed;
- readonly double drift, volatility;
- public GBM_Feed(int Bars = 252, double Volatility = 1.0, double Drift = 0.05, double Seed = 100.0) {
- seed = Seed;
- volatility = Volatility*0.01;
- drift = Drift*0.01;
- for (int i = 0; i OCMin)? 2*OCMin-Low : Low;
-
- double Volume = GBM_value(seed*10, volatility*2, Drift:0);
-
- base.Add((timestamp, Open, High, Low, Close, Volume), update);
- seed = Close;
- }
-
- private double GBM_value (double Seed, double Volatility, double Drift) {
- Random rnd = new((int)(DateTime.UtcNow.Ticks));
- double U1 = 1.0-rnd.NextDouble();
- double U2 = 1.0-rnd.NextDouble();
- double Z = Math.Sqrt(-2.0 * Math.Log(U1)) * Math.Sin(2.0 * Math.PI * U2);
- return Seed * Math.Exp( Drift - (Volatility*Volatility*0.5) + Volatility * Z);
- }
+namespace QuanTAlib;
+using System;
+
+/*
+GBM - Geometric Brownian Motion is a random simulator of market movement, returning List
+ GBM can be used for testing indicators, validation and Monte Carlo simulations of strategies.
+
+ Sample usage:
+ GBM-Random data = new(); // generates 1 year (252) list of bars
+ GBM-Random data = new(Bars: 1000); // generates 1,000 bars
+ GBM-Random data = new(Bars: 252, Volatility: 0.05, Drift: 0.0005, Seed: 100.0)
+
+ Parameters
+ Bars: number of bars (quotes) requested
+ Volatility: how dymamic/volatile the series should be; default is 1
+ Drift: incremental drift due to annual interest rate; default is 5%
+ Seed: starting value of the random series; should not be 0
+
+
*/
+
+public class GBM_Feed : TBars
+{
+ double seed;
+ readonly double drift, volatility;
+ public GBM_Feed(int Bars = 252, double Volatility = 1.0, double Drift = 0.05, double Seed = 100.0) {
+ seed = Seed;
+ volatility = Volatility*0.01;
+ drift = Drift*0.01;
+ for (int i = 0; i OCMin)? 2*OCMin-Low : Low;
+
+ double Volume = GBM_value(seed*10, volatility*2, Drift:0);
+
+ base.Add((timestamp, Open, High, Low, Close, Volume), update);
+ seed = Close;
+ }
+
+ private static double GBM_value (double Seed, double Volatility, double Drift) {
+ Random rnd = new((int)(DateTime.UtcNow.Ticks));
+ double U1 = 1.0-rnd.NextDouble();
+ double U2 = 1.0-rnd.NextDouble();
+ double Z = Math.Sqrt(-2.0 * Math.Log(U1)) * Math.Sin(2.0 * Math.PI * U2);
+ return Seed * Math.Exp( Drift - (Volatility*Volatility*0.5) + Volatility * Z);
+ }
}
\ No newline at end of file
diff --git a/Source/Basics/RND_Feed.cs b/Source/Feeds/RND_Feed.cs
similarity index 100%
rename from Source/Basics/RND_Feed.cs
rename to Source/Feeds/RND_Feed.cs
diff --git a/Source/QuanTAlib.csproj b/Source/QuanTAlib.csproj
index aaafccc1..5b5df76a 100644
--- a/Source/QuanTAlib.csproj
+++ b/Source/QuanTAlib.csproj
@@ -1,7 +1,7 @@
- 0.1.13
- Added MACD, RSI, CCI, ALMA, LINREG
+ 0.1.14
+
QuanTAlib
Library of Technical Indicators for .NET
Quantitative Technical Analysis library for both real-time (streaming) and historical data analysis
@@ -11,7 +11,7 @@
Miha Kralj
Miha Kralj
readme.md
- net7.0;net6.0;netcoreapp3.1;netstandard2.1
+ net7.0;net6.0
disable
preview
disable
diff --git a/docs/.nojekyll b/docs/.nojekyll
index e69de29b..8b137891 100644
--- a/docs/.nojekyll
+++ b/docs/.nojekyll
@@ -0,0 +1 @@
+