Skip to content

Commit

Permalink
Gateways
Browse files Browse the repository at this point in the history
  • Loading branch information
artemiusgreat committed Dec 3, 2024
1 parent 89ae075 commit b0fb9aa
Show file tree
Hide file tree
Showing 30 changed files with 2,068 additions and 1,817 deletions.
2 changes: 1 addition & 1 deletion Core/Indicators/PerformanceIndicator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class PerformanceIndicator : Indicator<PointModel, PerformanceIndicator>
/// <returns></returns>
public PerformanceIndicator Calculate(IList<IAccount> accounts)
{
Point.Last = accounts.Sum(o => o.Balance + o.Positions.Sum(v => v.Value.GetGainEstimate()));
Point.Last = accounts.Sum(o => o.Balance + o.Positions.Sum(v => v.Value.GetGainEstimate() ?? 0));

return this;
}
Expand Down
5 changes: 5 additions & 0 deletions Core/Models/Instruments/InstrumentModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ namespace Terminal.Core.Domains
{
public class InstrumentModel : ICloneable
{
/// <summary>
/// ID
/// </summary>
public virtual string Id { get; set; }

/// <summary>
/// Name
/// </summary>
Expand Down
27 changes: 19 additions & 8 deletions Core/Models/Transactions/OrderModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,30 @@ namespace Terminal.Core.Models
public class OrderModel : ICloneable
{
/// <summary>
/// Id
/// Name
/// </summary>
public virtual string Id { get; set; }
public virtual string Name => Transaction?.Instrument?.Name;

/// <summary>
/// Name
/// Basis name
/// </summary>
public virtual string Name => Transaction?.Instrument?.Name;
public virtual string BasisName => Transaction?.Instrument?.Basis?.Name;

/// <summary>
/// Client order ID
/// </summary>
public virtual string Id { get; set; }

/// <summary>
/// Group
/// </summary>
public virtual string Descriptor { get; set; }

/// <summary>
/// Current PnL
/// </summary>
public virtual double? Gain { get; set; }

/// <summary>
/// Min possible PnL in account's currency
/// </summary>
Expand Down Expand Up @@ -166,7 +176,7 @@ public OrderModel()
/// <returns></returns>
public double? GetPointsEstimate(double? price = null)
{
return (((price ?? GetCloseEstimate()) - Price) * GetDirection()) ?? 0;
return ((price ?? GetCloseEstimate()) - Price) * GetDirection();
}

/// <summary>
Expand All @@ -179,10 +189,11 @@ public OrderModel()
var volume = Transaction.CurrentVolume;
var instrument = Transaction.Instrument;
var step = instrument.StepValue / instrument.StepSize;
var estimate = (volume * GetPointsEstimate(price) * step * instrument.Leverage - instrument.Commission) ?? 0;
var estimate = volume * GetPointsEstimate(price) * step * instrument.Leverage - instrument.Commission;

GainMin = Math.Min(GainMin ?? estimate, estimate);
GainMax = Math.Max(GainMax ?? estimate, estimate);
Gain = estimate ?? Gain ?? 0;
GainMin = Math.Min(GainMin ?? 0, Gain.Value);
GainMax = Math.Max(GainMax ?? 0, Gain.Value);

return estimate;
}
Expand Down
2 changes: 1 addition & 1 deletion Derivative/Pages/Cointegration.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ await OnChart<PortfolioEditor>(async (caption, response, items) =>
await InvokeAsync(StateHasChanged);
}

Groups[caption].ForEach(async o => await Show(o.Value, response, items));
await Task.WhenAll(Groups[caption].Select(async o => await Show(o.Value, response, items)));
});
}

Expand Down
2 changes: 1 addition & 1 deletion Derivative/Pages/Gex.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ await OnChart<SubscriptionEditor>(async (caption, response) =>
{
Groups[caption] = new Dictionary<string, SectionModel> { [caption] = new SectionModel { Collection = [] } };
await InvokeAsync(StateHasChanged);
Groups[caption].ForEach(async o => await Subscribe(o.Value, response));
await Task.WhenAll(Groups[caption].Select(async o => await Subscribe(o.Value, response)));
});
}

Expand Down
5 changes: 2 additions & 3 deletions Derivative/Pages/Options.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ public async Task Group(

if (string.Equals(combine, "Yes"))
{
Groups[caption].ForEach(async o => await action(o.Value, options));
await Task.WhenAll(Groups[caption].Select(async o => await action(o.Value, options)));
return;
}

Expand All @@ -176,8 +176,7 @@ public async Task Group(
.ToDictionary(o => groups.Keys.ElementAt(o), o => null as CanvasView);

await InvokeAsync(StateHasChanged);

Groups[caption].ForEach(async o => await action(o.Value, groups[o.Key]));
await Task.WhenAll(Groups[caption].Select(async o => await action(o.Value, groups[o.Key])));
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion Derivative/Pages/Portfolio.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ await OnChart<PortfolioEditor>(async (caption, response, items) =>
await InvokeAsync(StateHasChanged);
}

Groups[caption].ForEach(async o => await Show(o.Value, response, items));
await Task.WhenAll(Groups[caption].Select(async o => await Show(o.Value, response, items)));
});
}

Expand Down
2 changes: 1 addition & 1 deletion Derivative/Pages/Profile.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ await OnChart<OptionEditor>(async (caption, response) =>
await InvokeAsync(StateHasChanged);
}

Groups[caption].ForEach(async o => await Show(o.Value, response));
await Task.WhenAll(Groups[caption].Select(async o => await Show(o.Value, response)));
});
}

Expand Down
24 changes: 12 additions & 12 deletions Gateway/Alpaca/Libs/Adapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,7 @@ public override async Task<ResponseModel<StatusEnum>> Connect()

await Task.WhenAll(_streamingClients.Values.Select(o => o.ConnectAndAuthenticateAsync()));
await GetAccount([]);

Account.Instruments.ForEach(async o => await Subscribe(o.Value));
await Task.WhenAll(Account.Instruments.Values.Select(Subscribe));

response.Data = StatusEnum.Success;
}
Expand Down Expand Up @@ -182,24 +181,27 @@ public override Task<ResponseModel<StatusEnum>> Disconnect()
/// </summary>
/// <param name="instrument"></param>
/// <returns></returns>
public override Task<ResponseModel<StatusEnum>> Unsubscribe(InstrumentModel instrument)
public override async Task<ResponseModel<StatusEnum>> Unsubscribe(InstrumentModel instrument)
{
var response = new ResponseModel<StatusEnum>();

void unsubscribe<T>() where T : class, ISubscriptionHandler
async Task unsubscribe<T>() where T : class, ISubscriptionHandler
{
if (_subscriptions.TryGetValue(instrument.Name, out var subs))
{
subs.ForEach(async o => await (_streamingClients[instrument.Type.Value] as T).UnsubscribeAsync(o));
foreach (var sub in subs)
{
await (_streamingClients[instrument.Type.Value] as T).UnsubscribeAsync(sub);
}
}
}

try
{
switch (instrument.Type)
{
case InstrumentEnum.Coins: unsubscribe<IAlpacaCryptoStreamingClient>(); break;
case InstrumentEnum.Shares: unsubscribe<IAlpacaDataStreamingClient>(); break;
case InstrumentEnum.Coins: await unsubscribe<IAlpacaCryptoStreamingClient>(); break;
case InstrumentEnum.Shares: await unsubscribe<IAlpacaDataStreamingClient>(); break;
}

response.Data = StatusEnum.Success;
Expand All @@ -209,7 +211,7 @@ void unsubscribe<T>() where T : class, ISubscriptionHandler
response.Errors.Add(new ErrorModel { ErrorMessage = $"{e}" });
}

return Task.FromResult(response);
return response;
}

/// <summary>
Expand All @@ -231,12 +233,10 @@ void unsubscribe<T>() where T : class, ISubscriptionHandler
Account.Orders = orders.Data.GroupBy(o => o.Id).ToDictionary(o => o.Key, o => o.FirstOrDefault()).Concurrent();
Account.Positions = positions.Data.GroupBy(o => o.Name).ToDictionary(o => o.Key, o => o.FirstOrDefault()).Concurrent();

orders
positions
.Data
.Select(o => o.Transaction.Instrument)
.Concat(positions.Data.Select(o => o.Transaction.Instrument))
.Where(o => Account.Instruments.ContainsKey(o.Name) is false)
.ForEach(o => Account.Instruments[o.Name] = o);
.ForEach(o => Account.Instruments[o.Name] = o.Transaction.Instrument);

response.Data = Account;
}
Expand Down
49 changes: 31 additions & 18 deletions Gateway/Alpaca/Libs/Maps/ExternalMap.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using Alpaca.Markets;
using System.Drawing;
using System.Linq;
using System.Xml.Linq;
using Terminal.Core.Enums;
using Terminal.Core.Models;

Expand All @@ -23,7 +21,22 @@ public static NewOrderRequest GetOrder(OrderModel order)
var orderType = GetOrderType(order.Type);
var duration = GetTimeInForce(order.TimeSpan);
var exOrder = new NewOrderRequest(name, volume, side, orderType, duration);
var braces = order.Orders.Where(o => o.Instruction is InstructionEnum.Brace);
var braces = order
.Orders
.Where(o => o.Instruction is InstructionEnum.Brace)
.Where(o => Equals(o.Name, order.Name));

exOrder.ClientOrderId = order.Id;

switch (order.Type)
{
case OrderTypeEnum.Stop: exOrder.StopPrice = (decimal)order.Price; break;
case OrderTypeEnum.Limit: exOrder.LimitPrice = (decimal)order.Price; break;
case OrderTypeEnum.StopLimit:
exOrder.LimitPrice = (decimal)order.Price;
exOrder.StopPrice = (decimal)order.ActivationPrice;
break;
}

if (braces.Any())
{
Expand All @@ -38,21 +51,6 @@ public static NewOrderRequest GetOrder(OrderModel order)
return exOrder;
}

/// <summary>
/// Get price for brackets
/// </summary>
/// <param name="order"></param>
/// <param name="direction"></param>
/// <returns></returns>
protected static double? GetBracePrice(OrderModel order, double direction)
{
var nextOrder = order
.Orders
.FirstOrDefault(o => (o.Price - order.Price) * direction > 0);

return nextOrder?.Price;
}

/// <summary>
/// Get order duration
/// </summary>
Expand Down Expand Up @@ -89,5 +87,20 @@ public static OrderType GetOrderType(OrderTypeEnum? orderType)

return OrderType.Market;
}

/// <summary>
/// Get price for brackets
/// </summary>
/// <param name="order"></param>
/// <param name="direction"></param>
/// <returns></returns>
protected static double? GetBracePrice(OrderModel order, double direction)
{
var nextOrder = order
.Orders
.FirstOrDefault(o => (o.Price - order.Price) * direction > 0);

return nextOrder?.Price;
}
}
}
Loading

0 comments on commit b0fb9aa

Please sign in to comment.