Skip to content

Commit 07e9e1b

Browse files
committed
Fix balances methods
1 parent 5405908 commit 07e9e1b

File tree

3 files changed

+118
-2
lines changed

3 files changed

+118
-2
lines changed

src/ExchangeSharp/API/Exchanges/MEXC/ExchangeMEXCAPI.cs

+47-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Collections.Generic;
33
using System.Linq;
44
using System.Threading.Tasks;
@@ -238,7 +238,6 @@ protected override async Task<Dictionary<string, decimal>> OnGetAmountsAvailable
238238
{
239239
Currency = x["asset"].Value<string>(),
240240
AvailableBalance = x["free"].Value<decimal>()
241-
+ x["locked"].Value<decimal>()
242241
}
243242
)
244243
.ToDictionary(k => k.Currency, v => v.AvailableBalance);
@@ -369,6 +368,51 @@ protected override async Task OnCancelOrderAsync(string orderId, string marketSy
369368
await MakeJsonRequestAsync<JToken>("/order", BaseUrl, payload, "DELETE");
370369
}
371370

371+
protected override Task ProcessRequestAsync(
372+
IHttpWebRequest request,
373+
Dictionary<string, object>? payload
374+
)
375+
{
376+
if (
377+
CanMakeAuthenticatedRequest(payload)
378+
|| (payload == null && request.RequestUri.AbsoluteUri.Contains("userDataStream"))
379+
)
380+
{
381+
request.AddHeader("X-MEXC-APIKEY", PublicApiKey!.ToUnsecureString());
382+
}
383+
return base.ProcessRequestAsync(request, payload);
384+
}
385+
386+
protected override Uri ProcessRequestUrl(
387+
UriBuilder url,
388+
Dictionary<string, object>? payload,
389+
string? method
390+
)
391+
{
392+
if (CanMakeAuthenticatedRequest(payload))
393+
{
394+
// 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
395+
var query = (url.Query ?? string.Empty).Trim('?', '&');
396+
string newQuery =
397+
"timestamp="
398+
+ payload!["nonce"].ToStringInvariant()
399+
+ (query.Length != 0 ? "&" + query : string.Empty)
400+
+ (
401+
payload.Count > 1
402+
? "&" + CryptoUtility.GetFormForPayload(payload, false)
403+
: string.Empty
404+
);
405+
string signature = CryptoUtility.SHA256Sign(
406+
newQuery,
407+
CryptoUtility.ToUnsecureBytesUTF8(PrivateApiKey)
408+
);
409+
newQuery += "&signature=" + signature;
410+
url.Query = newQuery;
411+
return url.Uri;
412+
}
413+
return base.ProcessRequestUrl(url, payload, method);
414+
}
415+
372416
private async Task<JToken> GetBalance()
373417
{
374418
var token = await MakeJsonRequestAsync<JToken>("/account", payload: await GetNoncePayloadAsync());
@@ -408,6 +452,7 @@ private static ExchangeOrderResult ParseOrder(JToken token)
408452
Amount = token["origQty"].ConvertInvariant<decimal>(),
409453
AmountFilled = token["executedQty"].ConvertInvariant<decimal>(),
410454
Price = token["price"].ConvertInvariant<decimal>(),
455+
AveragePrice = token["price"].ConvertInvariant<decimal>(),
411456
IsBuy = token["side"].ToStringInvariant() == "BUY",
412457
OrderDate = token["time"].ConvertInvariant<long>().UnixTimeStampToDateTimeMilliseconds(),
413458
Result = ParseOrderStatus(token["status"].ToStringInvariant())
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
using CommandLine;
2+
using ExchangeSharpConsole.Options.Interfaces;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
using System.Text;
7+
using System.Threading.Tasks;
8+
9+
namespace ExchangeSharpConsole.Options;
10+
11+
[Verb(
12+
"balances",
13+
HelpText = "Displays the account balances for an exchange."
14+
)]
15+
public class BalancesOption : BaseOption, IOptionPerExchange, IOptionWithKey
16+
{
17+
public override async Task RunCommand()
18+
{
19+
using var api = await GetExchangeInstanceAsync(ExchangeName);
20+
21+
api.LoadAPIKeys(KeyPath);
22+
23+
if (Mode.Equals("all", StringComparison.OrdinalIgnoreCase))
24+
{
25+
Console.WriteLine("All Balances:");
26+
27+
var balances = await api.GetAmountsAsync();
28+
29+
foreach (var balance in balances)
30+
{
31+
Console.WriteLine($"{balance.Key}: {balance.Value}");
32+
}
33+
34+
Console.WriteLine();
35+
}
36+
else if (Mode.Equals("trade", StringComparison.OrdinalIgnoreCase))
37+
{
38+
Console.WriteLine("Balances available for trading:");
39+
40+
var balances = await api.GetAmountsAvailableToTradeAsync();
41+
42+
foreach (var balance in balances)
43+
{
44+
Console.WriteLine($"{balance.Key}: {balance.Value}");
45+
}
46+
47+
Console.WriteLine();
48+
}
49+
else
50+
{
51+
throw new ArgumentException($"Invalid mode: {Mode}");
52+
}
53+
}
54+
55+
public string ExchangeName { get; set; }
56+
57+
[Option(
58+
'm',
59+
"mode",
60+
Required = true,
61+
HelpText = "Mode of execution."
62+
+ "\n\tPossible values are \"all\" or \"trade\"."
63+
+ "\n\t\tall: Displays all funds, regardless if they are locked or not."
64+
+ "\n\t\ttrade: Displays the funds that can be used, at the current moment, to trade."
65+
)]
66+
67+
public string Mode { get; set; }
68+
69+
public string KeyPath { get; set; }
70+
}

src/ExchangeSharpConsole/Program.cs

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ public partial class Program
1414

1515
public Type[] CommandOptions { get; } =
1616
{
17+
typeof(BalancesOption),
1718
typeof(BuyOption),
1819
typeof(CancelOrderOption),
1920
typeof(CandlesOption),

0 commit comments

Comments
 (0)