version bump to 0.1.14

This commit is contained in:
Miha Kralj
2022-05-12 08:48:43 -07:00
parent 80991f38d7
commit 7dc024bc33
6 changed files with 187 additions and 174 deletions
+1 -1
View File
@@ -29,7 +29,7 @@
<PlatformTarget>anycpu</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\Source\**\*.cs" Exclude="..\Source\obj\**;..\Source\Basics\*_Feed.cs">
<Compile Include="..\Source\**\*.cs" Exclude="..\Source\obj\**;..\Source\Feeds\**">
<Link>QuanTAlib\%(RecursiveDir)%(Filename)%(Extension)</Link>
</Compile>
</ItemGroup>
@@ -1,112 +1,124 @@
namespace QuanTAlib;
using System;
using System.Text.Json;
/* <summary>
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
</summary> */
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<JsonDocument>(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<JsonDocument>(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<JsonDocument>(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;
/* <summary>
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
</summary> */
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<JsonDocument>(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<JsonDocument>(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<JsonDocument>(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"
};
}
@@ -1,60 +1,60 @@
namespace QuanTAlib;
using System;
/* <summary>
GBM - Geometric Brownian Motion is a random simulator of market movement, returning List<Quote>
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
</summary> */
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 <Bars; i++) {
DateTime Timestamp = DateTime.Today.AddDays(i - Bars);
this.Add(Timestamp);
}
}
public void Add(DateTime timestamp, bool update = false) {
double Open = GBM_value(seed, volatility*volatility, drift);
double Close = GBM_value(Open, volatility, drift);
double OCMax = Math.Max(Open,Close);
double High = (GBM_value(seed, volatility*0.5, 0));
High = (High<OCMax)? 2*OCMax-High : High;
double OCMin = Math.Min(Open,Close);
double Low = (GBM_value(seed, volatility*0.5, 0));
Low = (Low>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;
/* <summary>
GBM - Geometric Brownian Motion is a random simulator of market movement, returning List<Quote>
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
</summary> */
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 <Bars; i++) {
DateTime Timestamp = DateTime.Today.AddDays(i - Bars);
this.Add(Timestamp);
}
}
public void Add(DateTime timestamp, bool update = false) {
double Open = GBM_value(seed, volatility*volatility, drift);
double Close = GBM_value(Open, volatility, drift);
double OCMax = Math.Max(Open,Close);
double High = (GBM_value(seed, volatility*0.5, 0));
High = (High<OCMax)? 2*OCMax-High : High;
double OCMin = Math.Min(Open,Close);
double Low = (GBM_value(seed, volatility*0.5, 0));
Low = (Low>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);
}
}
+3 -3
View File
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Version>0.1.13</Version>
<releaseNotes>Added MACD, RSI, CCI, ALMA, LINREG</releaseNotes>
<Version>0.1.14</Version>
<releaseNotes></releaseNotes>
<Title>QuanTAlib</Title>
<Product>Library of Technical Indicators for .NET</Product>
<Description>Quantitative Technical Analysis library for both real-time (streaming) and historical data analysis</Description>
@@ -11,7 +11,7 @@
<Authors>Miha Kralj</Authors>
<Copyright>Miha Kralj</Copyright>
<PackageReadmeFile>readme.md</PackageReadmeFile>
<TargetFrameworks>net7.0;net6.0;netcoreapp3.1;netstandard2.1</TargetFrameworks>
<TargetFrameworks>net7.0;net6.0</TargetFrameworks>
<ImplicitUsings>disable</ImplicitUsings>
<LangVersion>preview</LangVersion>
<Nullable>disable</Nullable>
+1
View File
@@ -0,0 +1 @@