Skip to content

Instantly share code, notes, and snippets.

@Kikimora
Created June 16, 2020 15:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Kikimora/96c52e53052fea7d6945c0b11a15c216 to your computer and use it in GitHub Desktop.
Save Kikimora/96c52e53052fea7d6945c0b11a15c216 to your computer and use it in GitHub Desktop.
/*
* This code is an adaptation from out bot framework, I have not compiled it, use it as an illtration.
*/
/*
* This code demonstrate how to get HttpClient with authentiaction cookie. HttpClient and API refresh cookie as needed, this is completely transparent process.
*/
var cookies = new CookieContainer();
var httpClient = new HttpClient(CreateHttpHandler()) { BaseAddress = new Uri("https://trade.alt5pro.com", "frontoffice/") };
var body = new JObject
{
{"email", "user@example.com"},
{"password", "XYZABC123"}
};
var response = await httpClient.PostAsJsonAsync("api/sign-in", body, token).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
//If you want to see auth cookie
var exchangeCookies = cookies.GetCookies(httpClient.BaseAddress);
var authCookie = exchangeCookies[".AspNetCore.Identity.Application"];
//Call API, cookies sent automaticaly
var response = await httpClient.GetAsync("api/orders/my", token).Success().ConfigureAwait(false);
//Web socket connection with SignalR
/*
* This code demonstrate how to connect to SignalR web socket interface and load open orders. Code assume there is some queue that recceive open order updates, ReportXYZ methods queue data
into this queue.
*/
const string OpenOrdersChannelName = "OpenOrders";
async Task SubscribeToOrdersAsync(CancellationToken token)
{
HubConnection connection = null;
try
{
connection = new HubConnectionBuilder()
.ConfigureJsonProtocol()
.WithUrl(new Uri("https://trade.alt5pro.com", "/frontoffice/ws/account"), HttpTransportType.WebSockets)
.Build();
await connection.StartAsync(token);
}
catch (Exception)
{
await connection.DisposeAsync();
throw;
}
ReadAccountSocketAsync(connection, token);
}
async void ReadAccountSocketAsync(HubConnection connection, CancellationToken token)
{
try
{
/*
* Open Orders channel delver updates as arrays of OrderData objects.
* First array contains all open orders at a time of connection. Next arrays will contain updates to open orders.
*/
var channel = await connection.StreamAsChannelAsync<OrderData[]>(OpenOrdersChannelName, token);
var snapshot = true;
while (await channel.WaitToReadAsync(token))
{
while (channel.TryRead(out var orders))
{
for (var index = 0; index < orders.Length; index++)
{
var order = orders[index];
ReportOrder(order, index, orders.Length);
}
}
if (snapshot)
{
ReportOrderStreamOpened();
snapshot = false;
}
}
ReportOrderStreamClosed();
}
catch (Exception e)
{
if (IsAuthError(e))
{
ReportAccountDisconnect(e);
}
ReportOrderStreamClosed(token.IsCancellationRequested ? null : e);
}
finally
{
await connection.DisposeAsync();
}
}
bool IsAuthError(Exception e)
{
return e.Message.Contains("unauthorized", StringComparison.InvariantCultureIgnoreCase) || e.Message.Contains("401");
}
void ReportOrderStreamOpened() => /* Push order stream opened event */
void ReportOrderStreamClosed(Exception e) => /* Push order stream closed event */
void ReportOrder(OrderData order, int index, int listSize) => /* Push order update */
[DataContract]
public class OrderResponse
{
[DataMember(Name = "order")]
public OrderData Order { get; set; }
}
[DataContract]
public class OrderData
{
[DataMember(Name = "orderId")]
public string OrderId { get; set; }
[DataMember(Name = "total")]
public decimal Total { get; set; }
[DataMember(Name = "orderType")]
public OrderType OrderType { get; set; }
[DataMember(Name = "commission")]
public decimal Commission { get; set; }
[DataMember(Name = "createdAt")]
public DateTime CreatedAt { get; set; }
[DataMember(Name = "unitsFilled")]
public decimal UnitsFilled { get; set; }
[DataMember(Name = "isPending")]
public bool IsPending { get; set; }
[DataMember(Name = "status")]
[JsonConverter(typeof(StringEnumConverter))]
public OrderStatus Status { get; set; }
[DataMember(Name = "type")]
public string Type { get; set; }
private decimal _amount;
[DataMember(Name = "requestedAmount")]
public decimal RequestedAmount
{
get => _amount;
set => _amount = value;
}
[DataMember(Name = "amount")]
public decimal Amount
{
get => _amount;
set => _amount = value;
}
[DataMember(Name = "isLimit")]
public bool IsLimit { get; set; }
[DataMember(Name = "instrument")]
public string Instrument { get; set; }
private decimal _price;
[DataMember(Name = "requestedPrice")]
public decimal RequestedPrice
{
get => _price;
set => _price = value;
}
[DataMember(Name = "price")]
public decimal Price
{
get => _price;
set => _price = value;
}
[DataMember(Name = "remainingAmount")]
public decimal RemainingAmount { get; set; }
[DataMember(Name = "tradedAmount")]
public decimal TradedAmount { get; set; }
[DataMember(Name = "trades")]
public List<TradeInfo> Trades { get; set; }
[DataContract]
public class TradeInfo
{
[DataMember(Name = "accountId")]
public long AccountId { get; set; }
[DataMember(Name = "amount")]
public string Amount { get; set; }
[DataMember(Name = "price")]
public string Price { get; set; }
}
public OrderSide Side
{
get => Type == "buy" ? OrderSide.Buy : OrderSide.Sell;
set => Type = value == OrderSide.Buy ? "buy" : "sell";
}
public override string ToString()
{
return $"{nameof(OrderId)}: {OrderId}, {nameof(Total)}: {Total}, {nameof(OrderType)}: {OrderType}, {nameof(Commission)}: {Commission}, {nameof(CreatedAt)}: {CreatedAt}, {nameof(UnitsFilled)}: {UnitsFilled}, {nameof(IsPending)}: {IsPending}, {nameof(Status)}: {Status}, {nameof(Type)}: {Type}, {nameof(RequestedAmount)}: {RequestedAmount}, {nameof(Amount)}: {Amount}, {nameof(IsLimit)}: {IsLimit}, {nameof(Instrument)}: {Instrument}, {nameof(RequestedPrice)}: {RequestedPrice}, {nameof(Price)}: {Price}, {nameof(RemainingAmount)}: {RemainingAmount}, {nameof(Side)}: {Side}";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment