refactor structs to records, add new classes for financial calculations, implement EMA and SMA with circular buffer. Generate random financial data using GBM model. Also, test the SMA calculation with sample data.

This commit is contained in:
Miha Kralj
2024-07-28 21:26:44 -07:00
parent ef534393db
commit 3455baaf6c
95 changed files with 8661 additions and 7012 deletions
+3 -3
View File
@@ -13,7 +13,7 @@ Alphavantage - Free API to collect 100 recent daily quotes. It requires a (free)
*/
public class Alphavantage_Feed : TBars
{
public enum Interval { Month, Week, Day, Hour, Min30, Min15, Min5, Min1}
public enum Interval { Month, Week, Day, Hour, Min30, Min15, Min5, Min1 }
public Alphavantage_Feed(string Symbol = "IBM", string APIkey = "demo")
{
System.Net.Http.HttpClient client = new();
@@ -22,8 +22,8 @@ public class Alphavantage_Feed : TBars
var msg = client.GetStringAsync(req).Result;
var jres = JsonSerializer.Deserialize<JsonDocument>(msg).RootElement;
jres.TryGetProperty("Time Series (Daily)", out JsonElement json);
if (json.ValueKind == JsonValueKind.Undefined) {throw new InvalidOperationException("Stock symbol "+Symbol+" not found"); }
if (json.ValueKind == JsonValueKind.Undefined) { throw new InvalidOperationException("Stock symbol " + Symbol + " not found"); }
foreach (var val in json.EnumerateObject()) { base.Add(GetOHLC(val)); }
base.Reverse();
}
+22 -18
View File
@@ -23,41 +23,45 @@ public class GBM_Feed : TBars
private double seed;
readonly double drift, volatility;
readonly int precision;
public GBM_Feed(int Bars = 252, double Volatility = 1.0, double Drift = 0.05, double Seed = 100.0, int Precision = 2) {
public GBM_Feed(int Bars = 252, double Volatility = 1.0, double Drift = 0.05, double Seed = 100.0, int Precision = 2)
{
this.seed = Seed;
volatility = Volatility*0.01;
drift = Drift*0.01;
volatility = Volatility * 0.01;
drift = Drift * 0.01;
precision = Precision;
for (int i = 0; i <Bars; i++) {
for (int i = 0; i < Bars; i++)
{
DateTime Timestamp = DateTime.Today.AddDays(i - Bars);
this.Add(Timestamp);
}
}
public void Add(bool update = false) {this.Add(DateTime.Now, update);}
public void Add(DateTime timestamp, bool update = false) {
double Open = GBM_value(seed, volatility*volatility, drift, precision);
public void Add(bool update = false) { this.Add(DateTime.Now, update); }
public void Add(DateTime timestamp, bool update = false)
{
double Open = GBM_value(seed, volatility * volatility, drift, precision);
double Close = GBM_value(Open, volatility, drift, precision);
double OCMax = Math.Max(Open,Close);
double High = (GBM_value(seed, volatility*0.5, 0, precision));
High = (High<OCMax)? (2 * OCMax) - High : High;
double OCMax = Math.Max(Open, Close);
double High = (GBM_value(seed, volatility * 0.5, 0, precision));
High = (High < OCMax) ? (2 * OCMax) - High : High;
double OCMin = Math.Min(Open,Close);
double Low = (GBM_value(seed, volatility*0.5, 0, precision));
Low = (Low>OCMin)? (2 * OCMin) - Low : Low;
double OCMin = Math.Min(Open, Close);
double Low = (GBM_value(seed, volatility * 0.5, 0, precision));
Low = (Low > OCMin) ? (2 * OCMin) - Low : Low;
double Volume = GBM_value(seed*10, volatility*2, Drift:0, precision: 1);
double Volume = GBM_value(seed * 10, volatility * 2, Drift: 0, precision: 1);
base.Add((timestamp, Open, High, Low, Close, Volume), update);
seed = Close;
}
private static double GBM_value(double Seed, double Volatility, double Drift, int precision) {
private static double GBM_value(double Seed, double Volatility, double Drift, int precision)
{
Random rnd = new();
double U1 = 1.0-rnd.NextDouble();
double U2 = 1.0-rnd.NextDouble();
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 Math.Round(Seed * Math.Exp( Drift - (Volatility*Volatility*0.5) + (Volatility * Z)), digits: precision);
return Math.Round(Seed * Math.Exp(Drift - (Volatility * Volatility * 0.5) + (Volatility * Z)), digits: precision);
}
}
+23 -21
View File
@@ -14,34 +14,36 @@ Yahoo Finance - Free API feed to collect daily market quotes
*/
public class Yahoo_Feed : TBars
{
public Yahoo_Feed(string Symbol = "IBM", int Period = 252) {
Period = (int)(Period*1.45);
string requestUrl = "https://query1.finance.yahoo.com/v8/finance/chart/"+
Symbol+"?interval=1d&period1="+
(int)new DateTimeOffset(DateTime.UtcNow.AddDays(-Period+1)).ToUnixTimeSeconds()+"&period2="+
public Yahoo_Feed(string Symbol = "IBM", int Period = 252)
{
Period = (int)(Period * 1.45);
string requestUrl = "https://query1.finance.yahoo.com/v8/finance/chart/" +
Symbol + "?interval=1d&period1=" +
(int)new DateTimeOffset(DateTime.UtcNow.AddDays(-Period + 1)).ToUnixTimeSeconds() + "&period2=" +
(int)new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds();
System.Net.Http.HttpClient client = new();
var msg = client.GetStringAsync(requestUrl).Result;
var jresult = JsonSerializer.Deserialize<JsonDocument>(msg).RootElement;
jresult.TryGetProperty("chart",out JsonElement json);
json.TryGetProperty("result",out json);
json[0].TryGetProperty("timestamp",out JsonElement datetime);
json[0].TryGetProperty("indicators",out json);
json.TryGetProperty("quote",out json);
json[0].TryGetProperty("open",out JsonElement open);
json[0].TryGetProperty("high",out JsonElement high);
json[0].TryGetProperty("low",out JsonElement low);
json[0].TryGetProperty("close",out JsonElement close);
json[0].TryGetProperty("volume",out JsonElement volume);
jresult.TryGetProperty("chart", out JsonElement json);
json.TryGetProperty("result", out json);
json[0].TryGetProperty("timestamp", out JsonElement datetime);
json[0].TryGetProperty("indicators", out json);
json.TryGetProperty("quote", out json);
json[0].TryGetProperty("open", out JsonElement open);
json[0].TryGetProperty("high", out JsonElement high);
json[0].TryGetProperty("low", out JsonElement low);
json[0].TryGetProperty("close", out JsonElement close);
json[0].TryGetProperty("volume", out JsonElement volume);
for (int i=0; i<datetime.GetArrayLength(); i++) {
for (int i = 0; i < datetime.GetArrayLength(); i++)
{
DateTime d = DateTimeOffset.FromUnixTimeSeconds(long.Parse(datetime[i].GetRawText())).DateTime;
double o = Math.Round(double.Parse(open[i].GetRawText()),3);
double h = Math.Round(double.Parse(high[i].GetRawText()),3);
double l = Math.Round(double.Parse(low[i].GetRawText()),3);
double c = Math.Round(double.Parse(close[i].GetRawText()),3);
double v = Math.Round(double.Parse(volume[i].GetRawText()),3);
double o = Math.Round(double.Parse(open[i].GetRawText()), 3);
double h = Math.Round(double.Parse(high[i].GetRawText()), 3);
double l = Math.Round(double.Parse(low[i].GetRawText()), 3);
double c = Math.Round(double.Parse(close[i].GetRawText()), 3);
double v = Math.Round(double.Parse(volume[i].GetRawText()), 3);
base.Add(d, o, h, l, c, v);
}
}