Skip to content

Commit

Permalink
Merge pull request #5 from paa-listas/feature-cache
Browse files Browse the repository at this point in the history
Added cache capabilities to local call of REST API "/rest/instruments…
  • Loading branch information
franluiscarrillo authored Nov 8, 2023
2 parents 55863ba + 4ad416a commit 86fe1d3
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 1 deletion.
24 changes: 23 additions & 1 deletion Primary.Examples/GetInstrumentsAndDataExample.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using System;
using NUnit.Framework;

using System;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;

Expand All @@ -22,6 +25,25 @@ public static async Task Run()
Console.WriteLine($"{instrument.Market},{instrument.Symbol},{instrument.Currency},{instrument.Description},{instrument.PriceConversionFactor}");
}


// Get instruments with file cache
Console.WriteLine("Getting available instruments with file cache...");
string cacheFile = ".\\dummy.tmp";
// Remove cache to test it.
if(System.IO.File.Exists(cacheFile)) System.IO.File.Delete(cacheFile);

// 1st call -> Lengthy operation
var allIInstrumentsFileCache = await api.GetAllInstrumentsFileCache(cacheFile);
Trace.Assert(allIInstrumentsFileCache != null);
Trace.Assert(allIInstrumentsFileCache.Count() == allIInstruments.Count());

// 2do call -> Fast operation
var allInstrumentsFileCache2 = await api.GetAllInstrumentsFileCache(cacheFile);
Trace.Assert(allIInstrumentsFileCache != null);
Trace.Assert(allIInstrumentsFileCache.Count() == allInstrumentsFileCache2.Count());



// Get all the dollar futures and their trades
var fiveDaysAgo = DateTime.Today.AddDays(-5);

Expand Down
50 changes: 50 additions & 0 deletions Primary/Api.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

using Primary.Data;
using Primary.Data.Orders;
using Primary.Serialization;
using Primary.WebSockets;

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Net.Http;
Expand Down Expand Up @@ -87,6 +90,53 @@ public async Task<IEnumerable<Instrument>> GetAllInstruments()
return data.Instruments;
}

/// <summary>
/// Same as <see cref="GetAllInstruments"/> but with cache capabilities
/// </summary>
/// <param name="fileCacheName">(optional) File to use as cache</param>
/// <param name="cacheValidAntiquity">(optional) How long the cache is valid, in days.</param>
/// <returns>Instruments information or null if information can not be retrieved</returns>
public async Task<IEnumerable<Instrument>> GetAllInstrumentsFileCache(string fileCacheName = null, uint cacheValidAntiquity = 1)
{
IEnumerable<Instrument> instrumentDetail = null;
Serialization.CacheInstrumentsDetails cache = null;
bool shouldRefresh = false;

if (fileCacheName == null)
fileCacheName = System.IO.Path.GetTempPath() + "AllMarketInstrumentsDetailsCache.json";


if (System.IO.File.Exists(fileCacheName) == true)
{
cache = InstrumentsDetailsSerializer.DesSerializeInstrumentDetail(fileCacheName);
if (cache != null && (DateTime.Now.Date - cache.CacheDate.Date).Days < (int)cacheValidAntiquity)
{
shouldRefresh = false;
instrumentDetail = cache.InstrumentDetailList;
cache = null;
}
else
shouldRefresh = true;
}
else
shouldRefresh = true;

if (shouldRefresh)
{
instrumentDetail = await GetAllInstruments();
if (instrumentDetail != null)
{
cache = new CacheInstrumentsDetails();
cache.CacheDate = DateTime.Now.Date;
cache.InstrumentDetailList = new List<Instrument>(instrumentDetail);
InstrumentsDetailsSerializer.SerializeInstrumentsDetails(cache, fileCacheName);
cache = null;
}
}

return instrumentDetail;
}

private class GetAllInstrumentsResponse
{
[JsonProperty("instruments")]
Expand Down
56 changes: 56 additions & 0 deletions Primary/Serialization/InstrumentsDetailsSerializer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using System.Text.Json;

using Primary.Data;
using System.IO;
using System.Diagnostics;

namespace Primary.Serialization
{
internal class CacheInstrumentsDetails
{
/// <summary>
/// Timestamp of the cached information
/// </summary>
public DateTime CacheDate { get; set; }
public List<Instrument> InstrumentDetailList { get; set; } = new List<Instrument>();
}

internal static class InstrumentsDetailsSerializer
{
public static void SerializeInstrumentsDetails(CacheInstrumentsDetails cache, string fileName)
{
var options = new JsonSerializerOptions { WriteIndented = true };
string info = JsonSerializer.Serialize<CacheInstrumentsDetails>(cache, options);
File.WriteAllText(fileName, info);
}

public static CacheInstrumentsDetails DesSerializeInstrumentDetail(string fileName)
{
CacheInstrumentsDetails cache = null;
try
{
if (File.Exists(fileName) == true)
{
string info = File.ReadAllText(fileName);
var options = new JsonSerializerOptions { WriteIndented = true };
cache = new CacheInstrumentsDetails();
cache = JsonSerializer.Deserialize<CacheInstrumentsDetails>(info, options);
}
}
catch (System.Text.Json.JsonException jex)
{
Trace.TraceError(jex.Message);
cache = null;
}
catch (Exception ex)
{
Trace.TraceError(ex.Message);
cache = null;
}

return cache;
}
}
}

0 comments on commit 86fe1d3

Please sign in to comment.