Skip to content

Commit

Permalink
Fix balances methods (#864)
Browse files Browse the repository at this point in the history
  • Loading branch information
v36u authored Jan 5, 2025
1 parent b545420 commit b6c0fe4
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 1 deletion.
47 changes: 46 additions & 1 deletion src/ExchangeSharp/API/Exchanges/MEXC/ExchangeMEXCAPI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,6 @@ protected override async Task<Dictionary<string, decimal>> OnGetAmountsAvailable
{
Currency = x["asset"].Value<string>(),
AvailableBalance = x["free"].Value<decimal>()
+ x["locked"].Value<decimal>()
}
)
.ToDictionary(k => k.Currency, v => v.AvailableBalance);
Expand Down Expand Up @@ -475,6 +474,51 @@ await _socket.SendMessageAsync(new WebSocketSubscription
}
);
}

protected override Task ProcessRequestAsync(
IHttpWebRequest request,
Dictionary<string, object>? payload
)
{
if (
CanMakeAuthenticatedRequest(payload)
|| (payload == null && request.RequestUri.AbsoluteUri.Contains("userDataStream"))
)
{
request.AddHeader("X-MEXC-APIKEY", PublicApiKey!.ToUnsecureString());
}
return base.ProcessRequestAsync(request, payload);
}

protected override Uri ProcessRequestUrl(
UriBuilder url,
Dictionary<string, object>? payload,
string? method
)
{
if (CanMakeAuthenticatedRequest(payload))
{
// payload is ignored, except for the nonce which is added to the url query - bittrex puts all the "post" parameters in the url query instead of the request body
var query = (url.Query ?? string.Empty).Trim('?', '&');
string newQuery =
"timestamp="
+ payload!["nonce"].ToStringInvariant()
+ (query.Length != 0 ? "&" + query : string.Empty)
+ (
payload.Count > 1
? "&" + CryptoUtility.GetFormForPayload(payload, false)
: string.Empty
);
string signature = CryptoUtility.SHA256Sign(
newQuery,
CryptoUtility.ToUnsecureBytesUTF8(PrivateApiKey)
);
newQuery += "&signature=" + signature;
url.Query = newQuery;
return url.Uri;
}
return base.ProcessRequestUrl(url, payload, method);
}

private async Task<JToken> GetBalance()
{
Expand Down Expand Up @@ -515,6 +559,7 @@ private static ExchangeOrderResult ParseOrder(JToken token)
Amount = token["origQty"].ConvertInvariant<decimal>(),
AmountFilled = token["executedQty"].ConvertInvariant<decimal>(),
Price = token["price"].ConvertInvariant<decimal>(),
AveragePrice = token["price"].ConvertInvariant<decimal>(),
IsBuy = token["side"].ToStringInvariant() == "BUY",
OrderDate = token["time"].ConvertInvariant<long>().UnixTimeStampToDateTimeMilliseconds(),
Result = ParseOrderStatus(token["status"].ToStringInvariant())
Expand Down
70 changes: 70 additions & 0 deletions src/ExchangeSharpConsole/Options/BalancesOption.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using CommandLine;
using ExchangeSharpConsole.Options.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ExchangeSharpConsole.Options;

[Verb(
"balances",
HelpText = "Displays the account balances for an exchange."
)]
public class BalancesOption : BaseOption, IOptionPerExchange, IOptionWithKey
{
public override async Task RunCommand()
{
using var api = await GetExchangeInstanceAsync(ExchangeName);

api.LoadAPIKeys(KeyPath);

if (Mode.Equals("all", StringComparison.OrdinalIgnoreCase))
{
Console.WriteLine("All Balances:");

var balances = await api.GetAmountsAsync();

foreach (var balance in balances)
{
Console.WriteLine($"{balance.Key}: {balance.Value}");
}

Console.WriteLine();
}
else if (Mode.Equals("trade", StringComparison.OrdinalIgnoreCase))
{
Console.WriteLine("Balances available for trading:");

var balances = await api.GetAmountsAvailableToTradeAsync();

foreach (var balance in balances)
{
Console.WriteLine($"{balance.Key}: {balance.Value}");
}

Console.WriteLine();
}
else
{
throw new ArgumentException($"Invalid mode: {Mode}");
}
}

public string ExchangeName { get; set; }

[Option(
'm',
"mode",
Required = true,
HelpText = "Mode of execution."
+ "\n\tPossible values are \"all\" or \"trade\"."
+ "\n\t\tall: Displays all funds, regardless if they are locked or not."
+ "\n\t\ttrade: Displays the funds that can be used, at the current moment, to trade."
)]

public string Mode { get; set; }

public string KeyPath { get; set; }
}
1 change: 1 addition & 0 deletions src/ExchangeSharpConsole/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public partial class Program

public Type[] CommandOptions { get; } =
{
typeof(BalancesOption),
typeof(BuyOption),
typeof(CancelOrderOption),
typeof(CandlesOption),
Expand Down

0 comments on commit b6c0fe4

Please sign in to comment.