From 7dc024bc333ef7ccd9f73787b78f63859a995c34 Mon Sep 17 00:00:00 2001 From: Miha Kralj Date: Thu, 12 May 2022 08:48:43 -0700 Subject: [PATCH] version bump to 0.1.14 --- Quantower/Quantower.csproj | 2 +- Source/{Basics => Feeds}/Alphavantage_Feed.cs | 234 +++++++++--------- Source/{Basics => Feeds}/GBM_Feed.cs | 118 ++++----- Source/{Basics => Feeds}/RND_Feed.cs | 0 Source/QuanTAlib.csproj | 6 +- docs/.nojekyll | 1 + 6 files changed, 187 insertions(+), 174 deletions(-) rename Source/{Basics => Feeds}/Alphavantage_Feed.cs (90%) rename Source/{Basics => Feeds}/GBM_Feed.cs (94%) rename Source/{Basics => Feeds}/RND_Feed.cs (100%) 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 @@ +