Skip to content

Commit

Permalink
Gateways
Browse files Browse the repository at this point in the history
  • Loading branch information
artemiusgreat committed Jun 4, 2024
1 parent 5cd3497 commit 3b3167f
Show file tree
Hide file tree
Showing 114 changed files with 2,518 additions and 991 deletions.
3 changes: 2 additions & 1 deletion Client/Client.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Canvas.Views.Web" Version="3.0.8" />
<PackageReference Include="Canvas.Views.Web" Version="3.1.4" />
<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\Schwab\Libs\Schwab.csproj" />
<ProjectReference Include="..\Gateways\Simulation\Libs\Simulation.csproj" />
</ItemGroup>

Expand Down
7 changes: 2 additions & 5 deletions Client/Components/BaseComponent.razor.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
using Distribution.Services;
using Microsoft.AspNetCore.Components;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace Client.Components
{
public class BaseComponent : ComponentBase
{
private static object protection = new();

/// <summary>
/// Updater
/// </summary>
Expand All @@ -18,10 +15,10 @@ public class BaseComponent : ComponentBase
/// <summary>
/// Render
/// </summary>
protected virtual Task Render(Action action) => Updater.Send(() =>
protected virtual Task Render(Action action, bool isRemovable = true) => Updater.Send(() =>
{
action();
InvokeAsync(StateHasChanged);
}).Task;
}, isRemovable).Task;
}
}
23 changes: 14 additions & 9 deletions Client/Components/ChartsComponent.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public partial class ChartsComponent : IDisposable
/// <summary>
/// Points
/// </summary>
protected virtual IList<IShape> Shapes { get; set; } = new List<IShape>();
protected virtual IList<IShape> Shapes { get; set; } = [];

/// <summary>
/// Series
Expand All @@ -31,13 +31,13 @@ public partial class ChartsComponent : IDisposable
/// <summary>
/// Indices
/// </summary>
protected virtual IDictionary<long, IGroupShape> Indices { get; set; } = new Dictionary<long, IGroupShape>();
protected virtual IDictionary<long, IShape> Indices { get; set; } = new Dictionary<long, IShape>();

/// <summary>
/// Define chart model
/// </summary>
/// <param name="group"></param>
public virtual async Task Create(IGroupShape group)
public virtual async Task Create(IShape group)
{
(View.Item = group)
.Groups
Expand All @@ -58,18 +58,23 @@ public virtual Task UpdateItems(IList<KeyValuePair<string, PointModel>> inputs,
{
var inputValue = input.Value;
var index = inputValue.Time.Value.Ticks;
var previousPoint = (Shapes.ElementAtOrDefault(Shapes.Count - 2) ?? View.Item.Clone()) as IGroupShape;
var areaKey = Maps.Get(input.Key);

if (Indices.TryGetValue(index, out IGroupShape currentPoint) is false)
if (areaKey is null)
{
currentPoint = previousPoint.Clone() as IGroupShape;
continue;
}

if (Indices.TryGetValue(index, out IShape currentPoint) is false)
{
currentPoint = (Shapes.LastOrDefault()?.Clone() ?? View.Item.Clone()) as IShape;
currentPoint.X = index;

Shapes.Add(currentPoint);
Indices[index] = currentPoint;
}

var series = currentPoint?.Groups?.Get(Maps.Get(input.Key))?.Groups?.Get(input.Key);
var series = currentPoint?.Groups?.Get(areaKey)?.Groups?.Get(input.Key);

if (series is not null)
{
Expand All @@ -89,7 +94,7 @@ public virtual Task UpdateItems(IList<KeyValuePair<string, PointModel>> inputs,

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

return Render(() => View.Update(domain, Shapes));
Expand All @@ -102,7 +107,7 @@ public virtual void Clear()
{
Shapes.Clear();
Indices.Clear();
UpdateItems(Array.Empty<KeyValuePair<string, PointModel>>(), 0);
Render(() => View.Update(new DomainModel { IndexDomain = [0, 0] }, Shapes), false);
}

/// <summary>
Expand Down
10 changes: 5 additions & 5 deletions Client/Components/PageComponent.razor
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

<MudPaper Class="w-100 d-flex mb-6 py-4">

<MudIconButton Style="@(IsConnection ? "display: none" : "display: block")" Color="Color.Success" Variant="Variant.Outlined" Size="Size.Large" Icon="@Icons.Material.Filled.PlayCircle" Class="ml-4" @onclick="OnConnect"></MudIconButton>
<MudIconButton Style="@(IsConnection ? "display: block" : "display: none")" Color="Color.Error" Variant="Variant.Outlined" Size="Size.Large" Icon="@Icons.Material.Filled.Cancel" Class="ml-4" @onclick="OnDisconnect"></MudIconButton>
<MudIconButton Style="@(IsConnection ? "display: none" : "display: block")" Color="Color.Success" Variant="Variant.Outlined" Size="Size.Large" Icon="@Icons.Material.Filled.PlayCircle" Class="ml-4" @onclick="Connect"></MudIconButton>
<MudIconButton Style="@(IsConnection ? "display: block" : "display: none")" Color="Color.Error" Variant="Variant.Outlined" Size="Size.Large" Icon="@Icons.Material.Filled.Cancel" Class="ml-4" @onclick="Disconnect"></MudIconButton>

@if (IsConnection)
{
<MudIconButton Style="@(IsSubscription ? "display: none" : "display: block")" Color="Color.Success" Variant="Variant.Outlined" Size="Size.Large" Icon="@Icons.Material.Filled.Loop" Class="ml-4" @onclick="OnSubscribe"></MudIconButton>
<MudIconButton Style="@(IsSubscription ? "display: block" : "display: none")" Color="Color.Error" Variant="Variant.Outlined" Size="Size.Large" Icon="@Icons.Material.Filled.PauseCircle" Class="ml-4" @onclick="OnUnsubscribe"></MudIconButton>
<MudIconButton Style="@(IsSubscription ? "display: none" : "display: block")" Color="Color.Success" Variant="Variant.Outlined" Size="Size.Large" Icon="@Icons.Material.Filled.Loop" Class="ml-4" @onclick="Subscribe"></MudIconButton>
<MudIconButton Style="@(IsSubscription ? "display: block" : "display: none")" Color="Color.Error" Variant="Variant.Outlined" Size="Size.Large" Icon="@Icons.Material.Filled.PauseCircle" Class="ml-4" @onclick="Unsubscribe"></MudIconButton>
}

</MudPaper>
Expand Down Expand Up @@ -81,7 +81,7 @@
<MudIcon Icon="@Icons.Material.Filled.Info" class="mr-3"></MudIcon>
<MudText>Statements</MudText>
<MudText>
<a href="#" @onclick:stopPropagation="true" @onclick:preventDefault="true" @onclick="OnOpenStatements" class="updater ml-4">Update</a>
<a href="#" @onclick:stopPropagation="true" @onclick:preventDefault="true" @onclick="OpenState" class="updater ml-4">Update</a>
</MudText>
</div>
</TitleContent>
Expand Down
23 changes: 11 additions & 12 deletions Client/Components/PageComponent.razor.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using Distribution.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Configuration;
using System;
using System.Linq;
using System.Threading.Tasks;
Expand All @@ -11,8 +9,6 @@ namespace Client.Components
{
public partial class PageComponent
{
[Inject] IConfiguration Configuration { get; set; }

/// <summary>
/// Controls
/// </summary>
Expand All @@ -25,27 +21,30 @@ public partial class PageComponent
public virtual PositionsComponent PositionsView { get; set; }
public virtual StatementsComponent StatementsView { get; set; }
public virtual IGateway Adapter { get; set; }
public virtual Action Setup { get; set; }
public virtual Action OnPreConnect { get; set; }
public virtual Action OnPostConnect { get; set; }

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

IsConnection = true;
IsSubscription = true;

await Adapter.Connect();

OnPostConnect();
}
catch (Exception e)
{
InstanceService<MessageService>.Instance.OnMessage($"{e}");
}
}

public virtual void OnDisconnect()
public virtual void Disconnect()
{
try
{
Expand All @@ -63,7 +62,7 @@ public virtual void OnDisconnect()
}
}

public virtual void OnSubscribe()
public virtual void Subscribe()
{
try
{
Expand All @@ -76,7 +75,7 @@ public virtual void OnSubscribe()
}
}

public virtual void OnUnsubscribe()
public virtual void Unsubscribe()
{
try
{
Expand All @@ -89,7 +88,7 @@ public virtual void OnUnsubscribe()
}
}

public virtual void OnOpenStatements()
public virtual void OpenState()
{
if (Adapter?.Account is not null)
{
Expand Down
110 changes: 61 additions & 49 deletions Client/Pages/Orders.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,60 +33,72 @@ 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();
await CreateViews();
View.OnPreConnect = CreateAccounts;
View.OnPostConnect = () =>
{
View.DealsView.UpdateItems(Account.Positions);
View.OrdersView.UpdateItems(Account.ActiveOrders);
View.PositionsView.UpdateItems(Account.ActivePositions);
};
}

indCharts.Groups["Ups"] = new BarShape { Component = indUp };
indCharts.Groups["Downs"] = new BarShape { Component = indDown };
indAreas.Groups["Prices"] = indCharts;
await base.OnAfterRenderAsync(setup);
}

await View.ChartsView.Create(indAreas);
protected virtual async Task CreateViews()
{
var indUp = new ComponentModel { Color = SKColors.DeepSkyBlue };
var indDown = new ComponentModel { Color = SKColors.OrangeRed };
var indAreas = new Shape();
var indCharts = new Shape();

var pnlGain = new ComponentModel { Color = SKColors.OrangeRed, Size = 5 };
var pnlBalance = new ComponentModel { Color = SKColors.Black };
var pnlAreas = new GroupShape();
var pnlCharts = new GroupShape();
indCharts.Groups["Ups"] = new BarShape { Component = indUp };
indCharts.Groups["Downs"] = new BarShape { Component = indDown };
indAreas.Groups["Prices"] = indCharts;

pnlCharts.Groups["PnL"] = new LineShape { Component = pnlGain };
pnlCharts.Groups["Balance"] = new AreaShape { Component = pnlBalance };
pnlAreas.Groups["Performance"] = pnlCharts;
await View.ChartsView.Create(indAreas);

await View.ReportsView.Create(pnlAreas);
var pnlGain = new ComponentModel { Color = SKColors.OrangeRed, Size = 5 };
var pnlBalance = new ComponentModel { Color = SKColors.Black };
var pnlAreas = new Shape();
var pnlCharts = new Shape();

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

await View.ReportsView.Create(pnlAreas);
}

protected virtual void CreateAccounts()
{
Account = new Account
{
Descriptor = "Demo",
Instruments = new Dictionary<string, Instrument>
{
Account = new Account
{
Descriptor = "Demo",
Instruments = new Dictionary<string, Instrument>
{
[_asset] = new Instrument { Name = _asset }
}
};

View.Adapter = new Adapter
{
Account = Account,
ConsumerKey = Configuration["Alpaca:Token"],
ConsumerSecret = Configuration["Alpaca:Secret"],
StreamUri = "wss://stream.data.alpaca.markets/v2/test"
};

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

Account
.Instruments
.Values
.ForEach(o => o.Points.CollectionChanged += (_, e) => e
.NewItems
.OfType<PointModel>()
.ForEach(async o => await OnData(o)));
};
}
[_asset] = new Instrument { Name = _asset }
}
};

await base.OnAfterRenderAsync(setup);
View.Adapter = new Adapter
{
Account = Account,
ConsumerKey = Configuration["Alpaca:Token"],
ConsumerSecret = Configuration["Alpaca:Secret"],
StreamUri = "wss://stream.data.alpaca.markets/v2/test"
};

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

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

private async Task OnData(PointModel point)
Expand Down Expand Up @@ -138,8 +150,8 @@ private void OpenPositions(IInstrument assetBuy, IInstrument assetSell)
}
};

View.Adapter.SendOrders(orderBuy);
View.Adapter.SendOrders(orderSell);
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);
Expand Down Expand Up @@ -171,7 +183,7 @@ private void ClosePositions()
}
};

View.Adapter.SendOrders(order);
View.Adapter.CreateOrders(order);

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

0 comments on commit 3b3167f

Please sign in to comment.