Skip to content

Commit

Permalink
Scheduler
Browse files Browse the repository at this point in the history
  • Loading branch information
artemiusgreat committed Mar 26, 2024
1 parent 8d7d030 commit b447e73
Show file tree
Hide file tree
Showing 47 changed files with 777 additions and 748 deletions.
7 changes: 4 additions & 3 deletions Client/Client.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Canvas.Views.Web" Version="1.8.1" />
<PackageReference Include="Estimator" Version="1.0.1" />
<PackageReference Include="MudBlazor" Version="6.12.0" />
<PackageReference Include="Canvas.Views.Web" Version="3.0.8" />
<PackageReference Include="Estimator" Version="1.0.2" />
<PackageReference Include="MudBlazor" Version="6.19.1" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Gateways\Alpaca\Libs\Alpaca.csproj" />
<ProjectReference Include="..\Gateways\Simulation\Libs\Simulation.csproj" />
</ItemGroup>

Expand Down
22 changes: 8 additions & 14 deletions Client/Components/BaseComponent.razor.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Distribution.Services;
using Microsoft.AspNetCore.Components;
using Schedule.Runners;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace Client.Components
Expand All @@ -10,23 +11,16 @@ public class BaseComponent : ComponentBase
/// <summary>
/// Updater
/// </summary>
protected virtual TimeRunner Updater { get; set; } = new()
{
Count = 1,
Span = TimeSpan.FromMilliseconds(100)
};
protected virtual ScheduleService Updater { get; set; } = new ScheduleService();

/// <summary>
/// Render
/// </summary>
protected virtual Task Render(Action action)
protected virtual Task Render(Action action) => Updater.Send(() =>
{
return Updater.Send(() =>
{
action();
InvokeAsync(StateHasChanged);

}).Task;
}
action();
InvokeAsync(StateHasChanged);
Thread.Sleep(1);
}).Task;
}
}
20 changes: 3 additions & 17 deletions Client/Components/ChartsComponent.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

namespace Client.Components
{
public partial class ChartsComponent : IDisposable, IAsyncDisposable
public partial class ChartsComponent : IDisposable
{
/// <summary>
/// Reference to view control
Expand Down Expand Up @@ -89,7 +89,7 @@ public virtual Task UpdateItems(IList<KeyValuePair<string, PointModel>> inputs,

var domain = new DomainModel
{
IndexDomain = new[] { Shapes.Count - (count ?? Shapes.Count), Shapes.Count }
IndexDomain = new int[] { Shapes.Count - (count ?? Shapes.Count), Shapes.Count }
};

return Render(() => View.Update(domain, Shapes));
Expand All @@ -108,20 +108,6 @@ public virtual void Clear()
/// <summary>
/// Dispose
/// </summary>
/// <returns></returns>
public virtual ValueTask DisposeAsync()
{
Dispose();

return new ValueTask(Task.CompletedTask);
}

/// <summary>
/// Dispose
/// </summary>
public virtual void Dispose()
{
View?.DisposeAsync();
}
public virtual void Dispose() => View?.Dispose();
}
}
65 changes: 45 additions & 20 deletions Client/Components/PageComponent.razor.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Configuration;
using Schedule.Runners;
using System;
using System.Linq;
using System.Threading.Tasks;
using Terminal.Core.Domains;
using Terminal.Core.Services;

namespace Client.Components
{
Expand All @@ -23,43 +22,69 @@ public partial class PageComponent
public virtual OrdersComponent OrdersView { get; set; }
public virtual PositionsComponent PositionsView { get; set; }
public virtual StatementsComponent StatementsView { get; set; }
public virtual IConnector Adapter { get; set; }
public virtual IGateway Adapter { get; set; }
public virtual Action Setup { get; set; }

public virtual async Task OnConnect()
{
OnDisconnect();
Setup();
try
{
OnDisconnect();
Setup();

IsConnection = true;
IsSubscription = true;
IsConnection = true;
IsSubscription = true;

await Adapter.Connect();
await Adapter.Connect();
}
catch (Exception e)
{
Console.WriteLine(e);
}
}

public virtual void OnDisconnect()
{
IsConnection = false;
IsSubscription = false;
try
{
Adapter?.Disconnect();

Adapter?.Disconnect();
ChartsView.Clear();
ReportsView.Clear();

ChartsView.Clear();
ReportsView.Clear();
IsConnection = false;
IsSubscription = false;
}
catch (Exception e)
{
Console.WriteLine(e);
}
}

public virtual async Task OnSubscribe()
public virtual void OnSubscribe()
{
IsSubscription = true;

await Adapter.Subscribe();
try
{
IsSubscription = true;
Adapter.Account.Instruments.ForEach(o => Adapter.Subscribe(o.Key));
}
catch (Exception e)
{
Console.WriteLine(e);
}
}

public virtual void OnUnsubscribe()
{
IsSubscription = false;

Adapter.Unsubscribe();
try
{
IsSubscription = false;
Adapter.Account.Instruments.ForEach(o => Adapter.Unsubscribe(o.Key));
}
catch (Exception e)
{
Console.WriteLine(e);
}
}

public virtual void OnOpenStatements()
Expand Down
3 changes: 3 additions & 0 deletions Client/Pages/Coins.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@page "/coins"

<PageComponent @ref="View"></PageComponent>
166 changes: 166 additions & 0 deletions Client/Pages/Coins.razor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
using Alpaca;
using Canvas.Core.Models;
using Canvas.Core.Shapes;
using Client.Components;
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Configuration;
using SkiaSharp;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Terminal.Core.Domains;
using Terminal.Core.Enums;
using Terminal.Core.Indicators;
using Terminal.Core.Models;

namespace Client.Pages
{
public partial class Coins
{
[Inject] IConfiguration Configuration { get; set; }

/// <summary>
/// Strategy
/// </summary>
const string _asset = "BTCUSD";

protected virtual IAccount Account { get; set; }
protected virtual PageComponent View { get; set; }
protected virtual PerformanceIndicator Performance { get; set; }

protected override async Task OnAfterRenderAsync(bool setup)
{
if (setup)
{
var indUp = new ComponentModel { Color = SKColors.DeepSkyBlue };
var indDown = new ComponentModel { Color = SKColors.OrangeRed };
var indAreas = new GroupShape();
var indCharts = new GroupShape();

indCharts.Groups["Range"] = new AreaShape { Component = indUp };
indAreas.Groups["Prices"] = indCharts;

await View.ChartsView.Create(indAreas);

var pnlGain = new ComponentModel { Color = SKColors.OrangeRed, Size = 5 };
var pnlBalance = new ComponentModel { Color = SKColors.Black };
var pnlAreas = new GroupShape();
var pnlCharts = new GroupShape();

pnlCharts.Groups["PnL"] = new LineShape { Component = pnlGain };
pnlCharts.Groups["Balance"] = new AreaShape { Component = pnlBalance };
pnlAreas.Groups["Performance"] = pnlCharts;

await View.ReportsView.Create(pnlAreas);

View.Setup = () =>
{
Account = new Account
{
Name = "Demo",
Balance = 25000,
Instruments = new Dictionary<string, Instrument>
{
[_asset] = new Instrument { Name = _asset },
}
};

// organizations/65659d9f-81c5-4b3b-ad84-fbca8aad60c5/apiKeys/af337ce4-9b36-49c8-8c5c-63858f111dfa
// -----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIEnZS9VkznxoLHnHO+gJ8ht/pxLhybl4E+XXhSfgrxF5oAoGCCqGSM49\nAwEHoUQDQgAEO2jBy6XKCG4ksmyCnijcxSxTOrX5nRXGHl/Jg9ThtU+wDomO5+0I\nCbWemshTjfO9NfHnaFm3cHrXpY2WilxW+g==\n-----END EC PRIVATE KEY-----\n

// 6mb099rhmbg
// 35793761dc5d2cfb20e233a119d6a214
// XeMjlgaDDSO401h9f4u7C9XbvTwx8s+YS4pUkxi8N1JPYQL/VE1sDjD4Ew3oDgH3qIeYDb2rWqn/VVfMidk0jQ==
View.Adapter = new Adapter
{
Account = Account,
//ConsumerKey = "35793761dc5d2cfb20e233a119d6a214",
//ConsumerSecret = "XeMjlgaDDSO401h9f4u7C9XbvTwx8s+YS4pUkxi8N1JPYQL/VE1sDjD4Ew3oDgH3qIeYDb2rWqn/VVfMidk0jQ==",
ConsumerKey = "account-ANUzTVQTkYcHyk7wo3QI",
ConsumerSecret = "4VgrY182eCM6m6pv1jVqWpPsXNwj",
DataUri = "https://api.sandbox.gemini.com"
//Source = "https://api-public.sandbox.exchange.coinbase.com",
//StreamSource = "wss://ws-feed-public.sandbox.exchange.coinbase.com"
};

Performance = new PerformanceIndicator { Name = "Balance" };

Account
.Instruments
.Values
.ForEach(o => o.Points.CollectionChanged += (_, e) => e
.NewItems
.OfType<PointModel>()
.ForEach(o => { }));
};
}

await base.OnAfterRenderAsync(setup);
}

private (string, string) OpenPositions(IInstrument assetBuy, IInstrument assetSell)
{
var orderSell = new OrderModel
{
Side = OrderSideEnum.Sell,
Type = OrderTypeEnum.Market,
Transaction = new()
{
Volume = 1,
Instrument = assetSell
}
};

var orderBuy = new OrderModel
{
Side = OrderSideEnum.Buy,
Type = OrderTypeEnum.Market,
Transaction = new()
{
Volume = 1,
Instrument = assetBuy
}
};

View.Adapter.CreateOrders(orderBuy);
View.Adapter.CreateOrders(orderSell);

var account = View.Adapter.Account;
var buy = account.ActivePositions.Values.First(o => o.Order.Side == OrderSideEnum.Buy);
var sell = account.ActivePositions.Values.First(o => o.Order.Side == OrderSideEnum.Sell);

//points.Add(new PointModel { Time = buy.Time, Name = nameof(OrderSideEnum.Buy), Last = buy.OpenPrices.Last().Price });
//points.Add(new PointModel { Time = sell.Time, Name = nameof(OrderSideEnum.Sell), Last = sell.OpenPrices.Last().Price });

return (orderSell.Transaction.Id, orderBuy.Transaction.Id);
}

private void ClosePositions()
{
foreach (var position in View.Adapter.Account.ActivePositions.Values)
{
var side = OrderSideEnum.Buy;

if (Equals(position.Order.Side, OrderSideEnum.Buy))
{
side = OrderSideEnum.Sell;
}

var order = new OrderModel
{
Side = side,
Type = OrderTypeEnum.Market,
Transaction = new()
{
Volume = position.Order.Transaction.Volume,
Instrument = position.Order.Transaction.Instrument
}
};

View.Adapter.CreateOrders(order);

//points.Add(new PointModel { Time = order.Time, Name = nameof(OrderSideEnum.Buy), Last = price });
}
}
}
}
Loading

0 comments on commit b447e73

Please sign in to comment.