Context
Let's say I'd like to retrieve the complete price history for bitcoin using the following nuget package for C#:
https://github.com/bchavez/Coinbase.Pro
Here's the approach I'm taking:
using System.IO;
using System.Text.Json;
using Coinbase.Pro;
using Coinbase.Pro.Models;
var api_key = File.ReadAllText(
Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
"coinbase-pro-api-key"),
System.Text.Encoding.UTF8);
var api_secret = File.ReadAllText(
Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
"coinbase-pro-api-secret"),
System.Text.Encoding.UTF8);
var api_passphrase = File.ReadAllText(
Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
"coinbase-pro-api-passphrase"),
System.Text.Encoding.UTF8);
var client = new CoinbaseProClient(new Config()
{
ApiKey = api_key,
Secret = api_secret,
Passphrase = api_passphrase
});
List<Candle> GetData(string product_id)
{
var path = String.Format("{0}.json", product_id);
if (File.Exists(path))
{
Console.WriteLine("Loading from file {0}", path);
return JsonSerializer.Deserialize<List<Candle>>(File.ReadAllText(path));
}
else
{
Console.WriteLine("Downloading");
var b = DateTime.Today;
var a = b - TimeSpan.FromDays(290);
var ls = new List<Candle>();
while (true)
{
Console.WriteLine("Retrieving from {0:yyyy-MM-dd} to {1:yyyy-MM-dd}", a, b);
var result = client.MarketData.GetHistoricRatesAsync(product_id, a, b, 86400).Result;
if (result.Count() > 0)
{
ls.AddRange(result);
b = a;
a = b - TimeSpan.FromDays(290);
}
else
{
break;
}
}
var ls_ordered = ls.OrderBy(candle => candle.Time);
var json = JsonSerializer.Serialize(ls_ordered);
File.WriteAllTextAsync(path, json).Wait();
return ls_ordered.ToList();
}
}
Given that code, I can retrieve the price history for bitcoin with the following:
var data = GetData("BTC-USD");
The returned data looks as follows in .NET interactive:
Explanation
The GetData
function will get the most recent 290 days of price data for the given product id. If data was found, it then asks for the previous set of 290 days. It continues until the API returns no data for the price range.
It then serializes the data to a file. Future calls to GetData
will return the data from the file instead of making API calls.
Question
Is there a better or more efficient way to get the entire price history for a given product?
Notes
Here's the complete C# notebook which demonstrates the approach:
A video demonstrating the notebook is available here: