Skip to content

Commit

Permalink
Alpaca
Browse files Browse the repository at this point in the history
  • Loading branch information
artemiusgreat committed May 3, 2024
1 parent 283255f commit 3f1b35d
Show file tree
Hide file tree
Showing 112 changed files with 2,608 additions and 543 deletions.
2 changes: 1 addition & 1 deletion Client/Client.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<Nullable>disable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
</PropertyGroup>
Expand Down
2 changes: 1 addition & 1 deletion Client/Components/PositionsComponent.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public virtual Task UpdateItems(IDictionary<string, PositionModel> items)
Name = o.Order.Transaction.Instrument.Name,
Side = o.Order.Side ?? OrderSideEnum.None,
Size = o.Order.Transaction.Volume ?? 0,
OpenPrice = o.Orders.First().Transaction.Price ?? 0,
OpenPrice = o.Order.Transaction.Price ?? 0,
ClosePrice = o.ClosePriceEstimate ?? 0,
Gain = o.GainLossAverageEstimate ?? 0

Expand Down
2 changes: 1 addition & 1 deletion Client/Pages/Coins.razor → Client/Pages/Orders.razor
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
@page "/coins"
@page "/orders"

<PageComponent @ref="View"></PageComponent>
49 changes: 39 additions & 10 deletions Client/Pages/Coins.razor.cs → Client/Pages/Orders.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Configuration;
using SkiaSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
Expand All @@ -15,14 +16,14 @@

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

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

protected virtual IAccount Account { get; set; }
protected virtual PageComponent View { get; set; }
Expand All @@ -37,7 +38,8 @@ protected override async Task OnAfterRenderAsync(bool setup)
var indAreas = new GroupShape();
var indCharts = new GroupShape();

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

await View.ChartsView.Create(indAreas);
Expand All @@ -57,17 +59,19 @@ protected override async Task OnAfterRenderAsync(bool setup)
{
Account = new Account
{
Name = "Demo",
Balance = 25000,
Descriptor = "Demo",
Instruments = new Dictionary<string, Instrument>
{
[_asset] = new Instrument { Name = _asset },
[_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" };
Expand All @@ -78,13 +82,38 @@ protected override async Task OnAfterRenderAsync(bool setup)
.ForEach(o => o.Points.CollectionChanged += (_, e) => e
.NewItems
.OfType<PointModel>()
.ForEach(o => { }));
.ForEach(async o => await OnData(o)));
};
}

await base.OnAfterRenderAsync(setup);
}

private async Task OnData(PointModel point)
{
var instrument = Account.Instruments[_asset];
var series = instrument.Points;

if (series.Count > 1)
{
return;
}

var chartPoints = new List<KeyValuePair<string, PointModel>>();
var reportPoints = new List<KeyValuePair<string, PointModel>>();
var performance = Performance.Calculate([Account]);

chartPoints.Add(KeyValuePair.Create("Ups", new PointModel { Time = point.Time, Last = Math.Max(0, point.Last.Value) }));
reportPoints.Add(KeyValuePair.Create("Balance", new PointModel { Time = point.Time, Last = Account.Balance }));
reportPoints.Add(KeyValuePair.Create("PnL", new PointModel { Time = point.Time, Last = performance.Point.Last }));

await View.ChartsView.UpdateItems(chartPoints, 100);
await View.ReportsView.UpdateItems(reportPoints);
await View.DealsView.UpdateItems(Account.Positions);
await View.OrdersView.UpdateItems(Account.ActiveOrders);
await View.PositionsView.UpdateItems(Account.ActivePositions);
}

private void OpenPositions(IInstrument assetBuy, IInstrument assetSell)
{
var orderSell = new OrderModel
Expand All @@ -109,8 +138,8 @@ private void OpenPositions(IInstrument assetBuy, IInstrument assetSell)
}
};

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

var account = View.Adapter.Account;
var buy = account.ActivePositions.Values.First(o => o.Order.Side == OrderSideEnum.Buy);
Expand Down Expand Up @@ -142,7 +171,7 @@ private void ClosePositions()
}
};

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

//points.Add(new PointModel { Time = order.Time, Name = nameof(OrderSideEnum.Buy), Last = price });
}
Expand Down
13 changes: 6 additions & 7 deletions Client/Pages/Pairs.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ protected override async Task OnAfterRenderAsync(bool setup)
var indAreas = new GroupShape();
var indCharts = new GroupShape();

indCharts.Groups["Buy"] = new ArrowShape { Component = indUp };
indCharts.Groups["Sell"] = new ArrowShape { Component = indDown };
indCharts.Groups["Ups"] = new ArrowShape { Component = indUp };
indCharts.Groups["Downs"] = new ArrowShape { Component = indDown };
indCharts.Groups["Range"] = new AreaShape { Component = indUp };
indAreas.Groups["Prices"] = indCharts;

Expand All @@ -61,7 +61,6 @@ protected override async Task OnAfterRenderAsync(bool setup)
{
Account = new Account
{
Name = "Demo",
Balance = 25000,
Instruments = new Dictionary<string, Instrument>
{
Expand Down Expand Up @@ -106,7 +105,7 @@ private async Task OnData(PointModel point)

var chartPoints = new List<KeyValuePair<string, PointModel>>();
var reportPoints = new List<KeyValuePair<string, PointModel>>();
var performance = Performance.Calculate(new[] { Account });
var performance = Performance.Calculate([Account]);
var xPoint = seriesX.Last();
var yPoint = seriesY.Last();
var xAsk = xPoint.Ask;
Expand Down Expand Up @@ -176,8 +175,8 @@ private void OpenPositions(IInstrument assetBuy, IInstrument assetSell)
}
};

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

var account = View.Adapter.Account;
var buy = account.ActivePositions.Values.First(o => o.Order.Side == OrderSideEnum.Buy);
Expand Down Expand Up @@ -209,7 +208,7 @@ private void ClosePositions()
}
};

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

//points.Add(new PointModel { Time = order.Time, Name = nameof(OrderSideEnum.Buy), Last = price });
}
Expand Down
13 changes: 2 additions & 11 deletions Core/Core.csproj
Original file line number Diff line number Diff line change
@@ -1,23 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<Version>1.1.7</Version>
<Description>Internal package for trading and analysis</Description>
<Authors>artemiusgreat</Authors>
<Copyright>indemos.com</Copyright>
<PackageProjectUrl>http://indemos.com</PackageProjectUrl>
<RepositoryUrl>https://github.com/Indemos/Terminal</RepositoryUrl>
<PackageTags>finance trading market stock backtester algorithmic-trading</PackageTags>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Distribution" Version="2.0.5" />
<PackageReference Include="ExpressionMapper" Version="1.0.2" />
<PackageReference Include="FluentValidation.AspNetCore" Version="11.3.0" />
<PackageReference Include="SkiaSharp" Version="2.88.7" />
<PackageReference Include="SkiaSharp" Version="3.0.0-preview.2.1" />
<PackageReference Include="System.Interactive" Version="6.0.1" />
</ItemGroup>

Expand Down
10 changes: 5 additions & 5 deletions Core/Domains/Account.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public interface IAccount
/// <summary>
/// Name
/// </summary>
string Name { get; set; }
string Descriptor { get; set; }

/// <summary>
/// Currency
Expand Down Expand Up @@ -84,7 +84,7 @@ public class Account : IAccount
/// <summary>
/// Name
/// </summary>
public virtual string Name { get; set; }
public virtual string Descriptor { get; set; }

/// <summary>
/// Currency
Expand Down Expand Up @@ -126,11 +126,11 @@ public Account()
InitialBalance = 0.0;
Currency = nameof(CurrencyEnum.USD);

Orders = new ObservableCollection<OrderModel>();
Positions = new ObservableCollection<PositionModel>();
Orders = [];
Positions = [];
Instruments = new Dictionary<string, Instrument>();
ActiveOrders = new Dictionary<string, OrderModel>();
ActivePositions = new Dictionary<string, PositionModel>();
Instruments = new Dictionary<string, Instrument>();
}
}
}
45 changes: 6 additions & 39 deletions Core/Domains/Gateway.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,19 +60,13 @@ public interface IGateway : IDisposable
/// Send new orders
/// </summary>
/// <param name="orders"></param>
Task<ResponseMapModel<OrderModel>> CreateOrders(params OrderModel[] orders);

/// <summary>
/// Update orders
/// </summary>
/// <param name="orders"></param>
Task<ResponseMapModel<OrderModel>> UpdateOrders(params OrderModel[] orders);
Task<ResponseMapModel<OrderModel>> SendOrders(params OrderModel[] orders);

/// <summary>
/// Cancel orders
/// </summary>
/// <param name="orders"></param>
Task<ResponseMapModel<OrderModel>> DeleteOrders(params OrderModel[] orders);
Task<ResponseMapModel<OrderModel>> CancelOrders(params OrderModel[] orders);
}

/// <summary>
Expand Down Expand Up @@ -137,19 +131,13 @@ public Gateway()
/// Send new orders
/// </summary>
/// <param name="orders"></param>
public abstract Task<ResponseMapModel<OrderModel>> CreateOrders(params OrderModel[] orders);

/// <summary>
/// Update orders
/// </summary>
/// <param name="orders"></param>
public abstract Task<ResponseMapModel<OrderModel>> UpdateOrders(params OrderModel[] orders);
public abstract Task<ResponseMapModel<OrderModel>> SendOrders(params OrderModel[] orders);

/// <summary>
/// Cancel orders
/// </summary>
/// <param name="orders"></param>
public abstract Task<ResponseMapModel<OrderModel>> DeleteOrders(params OrderModel[] orders);
public abstract Task<ResponseMapModel<OrderModel>> CancelOrders(params OrderModel[] orders);

/// <summary>
/// Dispose
Expand All @@ -165,10 +153,10 @@ protected virtual IList<OrderModel> CorrectOrders(params OrderModel[] orders)
foreach (var nextOrder in orders)
{
nextOrder.Type ??= OrderTypeEnum.Market;
nextOrder.TimeSpan ??= OrderTimeSpanEnum.GTC;
nextOrder.TimeSpan ??= OrderTimeSpanEnum.Gtc;
nextOrder.Price ??= GetOpenPrice(nextOrder);
nextOrder.Transaction ??= new TransactionModel();
nextOrder.Transaction.Time ??= DateTime.Now;
nextOrder.Transaction.Price ??= GetOpenPrice(nextOrder);
nextOrder.Transaction.Status ??= OrderStatusEnum.None;
nextOrder.Transaction.Operation ??= OperationEnum.In;
}
Expand Down Expand Up @@ -237,26 +225,5 @@ protected virtual IList<IAccount> SetupAccounts(params IAccount[] accounts)

return accounts;
}

/// <summary>
/// Update points
/// </summary>
/// <param name="point"></param>
protected virtual IList<PointModel> SetupPoints(params PointModel[] points)
{
foreach (var point in points)
{
var instrument = Account.Instruments[point.Instrument.Name];
var estimates = Account.ActivePositions.Select(o => o.Value.GainLossEstimate).ToList();

point.Instrument = instrument;
point.TimeFrame = instrument.TimeFrame;

instrument.Points.Add(point);
instrument.PointGroups.Add(point, instrument.TimeFrame, true);
}

return points;
}
}
}
4 changes: 2 additions & 2 deletions Core/Domains/Instrument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ public Instrument()
Commission = 0.0;
ContractSize = 1.0;

Points = new ObservableTimeCollection<PointModel>();
PointGroups = new ObservableTimeCollection<PointModel>();
Points = [];
PointGroups = [];
}
}
}
11 changes: 6 additions & 5 deletions Core/Enums/OrderStatusEnum.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ public enum OrderStatusEnum : byte
Placed = 1,
Filled = 2,
Closed = 3,
Expired = 4,
Declined = 5,
Canceled = 6,
Completed = 7,
PartiallyFilled = 8
Pending = 4,
Expired = 5,
Declined = 6,
Canceled = 7,
Completed = 8,
Partitioned = 9
}
}
10 changes: 6 additions & 4 deletions Core/Enums/OrderTimeSpanEnum.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ namespace Terminal.Core.Enums
public enum OrderTimeSpanEnum : byte
{
None = 0,
Date = 1,
FOK = 2,
GTC = 3,
IOC = 4
Day = 1,
Fok = 2,
Gtc = 3,
Ioc = 4,
Omo = 5,
Omc = 6
}
}
1 change: 0 additions & 1 deletion Core/Models/Points/PointModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ public class PointModel : ICloneable
public PointModel()
{
Time = DateTime.Now;

Series = new Dictionary<string, PointModel>();
}

Expand Down
2 changes: 1 addition & 1 deletion Core/Models/ResponseItemModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ public class ResponseItemModel<T>
/// <summary>
/// Constructor
/// </summary>
public ResponseItemModel() => Errors = new List<ErrorModel>();
public ResponseItemModel() => Errors = [];
}
}
2 changes: 1 addition & 1 deletion Core/Models/ResponseMapModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ public class ResponseMapModel<T>
/// <summary>
/// Constructor
/// </summary>
public ResponseMapModel() => Items = new List<ResponseItemModel<T>>();
public ResponseMapModel() => Items = [];
}
}
Loading

0 comments on commit 3f1b35d

Please sign in to comment.