Skip to content

Instantly share code, notes, and snippets.

@confessore
Created January 12, 2024 14:23
Show Gist options
  • Save confessore/fa30403dedd9e795952f88e26db476e5 to your computer and use it in GitHub Desktop.
Save confessore/fa30403dedd9e795952f88e26db476e5 to your computer and use it in GitHub Desktop.
CoinbaseATJob
// Copyright (c) Steven Confessore - Balanced Solutions Software. All Rights Reserved. Licensed under the MIT license. See LICENSE in the project root for license information.
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using backend.Contexts;
using backend.Models.Abstractions;
using backend.Models.Enums;
using backend.Models.Observations;
using backend.Models.Trends;
using CoinbaseAT.Interfaces;
using CoinbaseAT.Models;
using Microsoft.EntityFrameworkCore;
using Quartz;
namespace backend.Jobs;
[DisallowConcurrentExecution]
internal sealed class CoinbaseATJob : IJob
{
private readonly IDbContextFactory<DefaultDbContext> _defaultDbContextFactory;
private readonly ICoinbaseATClient _coinbaseATClient;
public CoinbaseATJob(
IDbContextFactory<DefaultDbContext> defaultDbContextFactory,
ICoinbaseATClient coinbaseATClient
)
{
_defaultDbContextFactory = defaultDbContextFactory;
_coinbaseATClient = coinbaseATClient;
}
private DefaultDbContext? DefaultDbContext { get; set; }
private Product? Product { get; set; }
private long Now { get; set; }
private DefaultObservation? Observation { get; set; }
private DefaultTrend? Trend { get; set; }
private readonly string _baseAsset = "USD";
private readonly string _tradeAsset = "ETH";
public async Task Execute(IJobExecutionContext context)
{
Now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
DefaultDbContext ??= await _defaultDbContextFactory.CreateDbContextAsync();
Product = await _coinbaseATClient.ProductsService.GetProductAsync(
$"{_tradeAsset}-{_baseAsset}"
);
Trend ??= CreateNewTrend(_baseAsset, _tradeAsset) as DefaultTrend;
Observation ??= CreateNewObservation(_baseAsset, _tradeAsset) as DefaultObservation;
if (Trend.Observations.Count < 6)
{
Trend.Observations.Add(Observation);
if (Trend.Observations.Count == 1)
{
Trend.TrendStart = Observation.CreatedAt;
}
Trend.TrendEnd = Observation.CreatedAt;
var ordered = Trend.Observations.OrderBy(x => x.Price);
Trend.LowPrice = ordered.FirstOrDefault().Price;
Trend.HighPrice = ordered.LastOrDefault().Price;
Trend.MeanPrice = (Trend.Observations.Sum(x => x.Price) / Trend.Observations.Count);
}
var trendExists = await DefaultDbContext.Trends.AnyAsync(x => x.Id == Trend.Id);
if (!trendExists)
{
await DefaultDbContext.Trends.AddAsync(Trend);
}
if (trendExists)
{
DefaultDbContext.Trends.Update(Trend);
}
await DefaultDbContext.SaveChangesAsync();
Observation = null;
if (Trend.Observations.Count == 6)
{
Trend = null;
}
GC.Collect();
}
public Trend CreateNewTrend(string baseAsset, string tradeAsset)
{
var trendId = Guid.NewGuid().ToString();
var trend = new DefaultTrend()
{
Id = trendId,
CreatedAt = Now,
TrendType = TrendType.Default,
BaseAsset = baseAsset,
TradeAsset = tradeAsset,
Observations = new Collection<Observation>()
};
return trend;
}
public Observation CreateNewObservation(string baseAsset, string tradeAsset)
{
return new DefaultObservation()
{
Id = Guid.NewGuid().ToString(),
CreatedAt = Now,
ObservationType = ObservationType.Default,
BaseAsset = baseAsset,
TradeAsset = tradeAsset,
Price = Convert.ToDecimal(Product.Price),
TrendId = Trend.Id
};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment