-1

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:

enter image description here

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:

https://github.com/dharmatech/coinbase-pro-bchavez-price-history/blob/master/coinbase-pro-bchavez-price-history.ipynb

A video demonstrating the notebook is available here:

https://www.youtube.com/watch?v=Xl5vx9XFKyo

dharmatech
  • 8,979
  • 8
  • 42
  • 88
  • 1
    Looks fine to me, 290 days looks like a reasonable batch size. I would store the history in a SQL Database. – Charles Nov 30 '21 at 08:49
  • Yup, I think storing in a database would be good for a larger application. Just wanted a simple working example to demonstrate the approach as well as something that works well in a small notebook example. – dharmatech Nov 30 '21 at 12:00
  • 1
    CB recommends subscribing to the websocket for the products you want to track and save the data to get a complete history. – genericHCU Dec 07 '21 at 14:29

1 Answers1

1

Is there a better or more efficient way to get the entire price history for a given product?

Looks like you have a solution to getting the history. Saving it locally will prevent you from having to get it every time you need it. Now that you have the history and need to maintain the current prices... from: getCandles docs

Historical rate data may be incomplete. No data is published for intervals where there are no ticks. Historical rates should not be polled frequently. If you need real-time information, use the trade and book endpoints along with the websocket feed.

genericHCU
  • 4,394
  • 2
  • 22
  • 34
  • Hey Travis. So I've been able to get the complete trading history for the Kraken exchange. I talk about my approach in these two posts. [link](https://stackoverflow.com/questions/70207939/importing-a-1-3gb-csv-file-into-sqlite-via-ef-core) [link](https://stackoverflow.com/questions/70242275/slow-queries-with-sqlite-database-generated-by-ef-core-indices-are-present) – dharmatech Dec 07 '21 at 22:28
  • Maybe someday Coinbase will offer a similar CSV containing their trading history. – dharmatech Dec 07 '21 at 22:28