Skip to content

Commit

Permalink
Tests fix (#664)
Browse files Browse the repository at this point in the history
BinanceGroupCommon OnGetCurrenciesAsync fix.
ExchangePoloniexAPI ParseOrderTrades handle ExchangeOrderResult.AmountFilled as nullable.
  • Loading branch information
BZ-CO authored Sep 28, 2021
1 parent 890b000 commit d9fc563
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 56 deletions.
24 changes: 12 additions & 12 deletions ExchangeSharp.sln
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,34 @@ VisualStudioVersion = 16.0.29318.209
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SolutionItems", "SolutionItems", "{1AA29282-C764-47CA-83AB-A6017E941D76}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
.gitignore = .gitignore
azure-pipelines.yml = azure-pipelines.yml
CODE_OF_CONDUCT.md = CODE_OF_CONDUCT.md
CONTRIBUTING.md = CONTRIBUTING.md
global.json = global.json
icon.png = icon.png
ISSUE_TEMPLATE.md = ISSUE_TEMPLATE.md
LICENSE.txt = LICENSE.txt
logo.png = logo.png
README.md = README.md
.gitignore = .gitignore
.editorconfig = .editorconfig
azure-pipelines.yml = azure-pipelines.yml
global.json = global.json
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{51222217-63AE-4881-9972-E0966299D416}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExchangeSharpConsole", "src\ExchangeSharpConsole\ExchangeSharpConsole.csproj", "{2CC066B2-715E-43F2-B50F-4BCD80164B7D}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExchangeSharpConsole", "src\ExchangeSharpConsole\ExchangeSharpConsole.csproj", "{2CC066B2-715E-43F2-B50F-4BCD80164B7D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExchangeSharp", "src\ExchangeSharp\ExchangeSharp.csproj", "{E9321D38-DBCF-4387-9547-47EABF60423F}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExchangeSharp", "src\ExchangeSharp\ExchangeSharp.csproj", "{E9321D38-DBCF-4387-9547-47EABF60423F}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{83784E6A-9582-4001-9491-C70BBA71334F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExchangeSharpTests", "tests\ExchangeSharpTests\ExchangeSharpTests.csproj", "{DF09A8D9-9BC2-4B50-BE45-A83C9D29B994}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExchangeSharpTests", "tests\ExchangeSharpTests\ExchangeSharpTests.csproj", "{DF09A8D9-9BC2-4B50-BE45-A83C9D29B994}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{9E02A8EA-70EE-4C89-80C6-BD2EC51854CE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExchangeSharpWinForms", "examples\ExchangeSharpWinForms\ExchangeSharpWinForms.csproj", "{571623F9-1652-4669-8E17-A6FAD1426181}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExchangeSharpWinForms", "examples\ExchangeSharpWinForms\ExchangeSharpWinForms.csproj", "{571623F9-1652-4669-8E17-A6FAD1426181}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExchangeSharp.Forms", "src\ExchangeSharp.Forms\ExchangeSharp.Forms.csproj", "{0EA8DE09-C8D4-410E-A345-D172A72EC77C}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExchangeSharp.Forms", "src\ExchangeSharp.Forms\ExchangeSharp.Forms.csproj", "{0EA8DE09-C8D4-410E-A345-D172A72EC77C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -64,14 +64,14 @@ Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {46DCEF62-6B50-4260-8C47-4368B05CFAB4}
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{2CC066B2-715E-43F2-B50F-4BCD80164B7D} = {51222217-63AE-4881-9972-E0966299D416}
{E9321D38-DBCF-4387-9547-47EABF60423F} = {51222217-63AE-4881-9972-E0966299D416}
{DF09A8D9-9BC2-4B50-BE45-A83C9D29B994} = {83784E6A-9582-4001-9491-C70BBA71334F}
{571623F9-1652-4669-8E17-A6FAD1426181} = {9E02A8EA-70EE-4C89-80C6-BD2EC51854CE}
{0EA8DE09-C8D4-410E-A345-D172A72EC77C} = {51222217-63AE-4881-9972-E0966299D416}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {46DCEF62-6B50-4260-8C47-4368B05CFAB4}
EndGlobalSection
EndGlobal
24 changes: 11 additions & 13 deletions src/ExchangeSharp/API/Exchanges/BinanceGroup/BinanceGroupCommon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,19 +88,17 @@ public async Task<IEnumerable<ExchangeOrderResult>> GetMyTradesAsync(string? mar
protected override async Task<IReadOnlyDictionary<string, ExchangeCurrency>> OnGetCurrenciesAsync()
{
var result = await MakeJsonRequestAsync<List<Currency>>("/capital/config/getall", BaseUrlSApi);

return result.ToDictionary(x => x.Coin.ToUpper(), x => {
var network = x.NetworkList.FirstOrDefault(x => x.IsDefault);
return new ExchangeCurrency
{
Name = x.Coin,
FullName = x.Name,
DepositEnabled = network?.DepositEnable ?? x.DepositAllEnable,
WithdrawalEnabled = network?.WithdrawEnable ?? x.WithdrawAllEnable,
MinConfirmations = network?.MinConfirm ?? 0,
MinWithdrawalSize = decimal.Parse(network?.WithdrawMin ?? "0"),
TxFee = decimal.Parse(network?.WithdrawFee ?? "0")
};

return result.ToDictionary(x => x.AssetCode, x => new ExchangeCurrency
{
Name = x.AssetCode,
FullName = x.AssetName,
DepositEnabled = x.EnableCharge ?? false,
WithdrawalEnabled = x.EnableWithdraw.GetValueOrDefault(false),
MinConfirmations = x.ConfirmTimes.GetValueOrDefault(0),
MinWithdrawalSize = x.MinProductWithdraw.GetValueOrDefault(decimal.Zero),
TxFee = x.FeeRate.GetValueOrDefault(decimal.Zero),
CoinType = x.ParentCode
});
}

Expand Down
154 changes: 127 additions & 27 deletions src/ExchangeSharp/API/Exchanges/BinanceGroup/Models/Currency.cs
Original file line number Diff line number Diff line change
@@ -1,49 +1,149 @@
using System;
using Newtonsoft.Json;

namespace ExchangeSharp.BinanceGroup
{
public class Currency
{
[JsonProperty("coin")]
public string Coin { get; set; }
[JsonProperty("id")]
public long? Id { get; set; }

[JsonProperty("depositAllEnable")]
public bool DepositAllEnable { get; set; }
[JsonProperty("assetCode")]
public string AssetCode { get; set; }

[JsonProperty("free")]
public string Free { get; set; }
[JsonProperty("assetName")]
public string AssetName { get; set; }

[JsonProperty("freeze")]
public string Freeze { get; set; }
[JsonProperty("unit")]
public string Unit { get; set; }

[JsonProperty("ipoable")]
public string Ipoable { get; set; }
[JsonProperty("transactionFee")]
public double? TransactionFee { get; set; }

[JsonProperty("ipoing")]
public string Ipoing { get; set; }
[JsonProperty("commissionRate")]
public long? CommissionRate { get; set; }

[JsonProperty("freeAuditWithdrawAmt")]
public long? FreeAuditWithdrawAmt { get; set; }

[JsonProperty("freeUserChargeAmount")]
public long? FreeUserChargeAmount { get; set; }

[JsonProperty("minProductWithdraw")]
public decimal? MinProductWithdraw { get; set; }

[JsonProperty("withdrawIntegerMultiple")]
public float? WithdrawIntegerMultiple { get; set; }

[JsonProperty("confirmTimes")]
public int? ConfirmTimes { get; set; }

[JsonProperty("chargeLockConfirmTimes")]
public int? ChargeLockConfirmTimes { get; set; }

[JsonProperty("createTime")]
public object CreateTime { get; set; }

[JsonProperty("test")]
public long? Test { get; set; }

[JsonProperty("url")]
public Uri Url { get; set; }

[JsonProperty("addressUrl")]
public Uri AddressUrl { get; set; }

[JsonProperty("blockUrl")]
public string BlockUrl { get; set; }

[JsonProperty("enableCharge")]
public bool? EnableCharge { get; set; }

[JsonProperty("enableWithdraw")]
public bool? EnableWithdraw { get; set; }

[JsonProperty("regEx")]
public string RegEx { get; set; }

[JsonProperty("regExTag")]
public string RegExTag { get; set; }

[JsonProperty("gas")]
public long? Gas { get; set; }

[JsonProperty("parentCode")]
public string ParentCode { get; set; }

[JsonProperty("isLegalMoney")]
public bool IsLegalMoney { get; set; }
public bool? IsLegalMoney { get; set; }

[JsonProperty("reconciliationAmount")]
public long? ReconciliationAmount { get; set; }

[JsonProperty("seqNum")]
public long? SeqNum { get; set; }

[JsonProperty("chineseName")]
public string ChineseName { get; set; }

[JsonProperty("cnLink")]
public Uri CnLink { get; set; }

[JsonProperty("enLink")]
public Uri EnLink { get; set; }

[JsonProperty("logoUrl")]
public string LogoUrl { get; set; }

[JsonProperty("fullLogoUrl")]
public Uri FullLogoUrl { get; set; }

[JsonProperty("forceStatus")]
public bool? ForceStatus { get; set; }

[JsonProperty("resetAddressStatus")]
public bool? ResetAddressStatus { get; set; }

[JsonProperty("chargeDescCn")]
public object ChargeDescCn { get; set; }

[JsonProperty("chargeDescEn")]
public object ChargeDescEn { get; set; }

[JsonProperty("assetLabel")]
public object AssetLabel { get; set; }

[JsonProperty("sameAddress")]
public bool? SameAddress { get; set; }

[JsonProperty("depositTipStatus")]
public bool? DepositTipStatus { get; set; }

[JsonProperty("dynamicFeeStatus")]
public bool? DynamicFeeStatus { get; set; }

[JsonProperty("depositTipEn")]
public object DepositTipEn { get; set; }

[JsonProperty("locked")]
public string Locked { get; set; }
[JsonProperty("depositTipCn")]
public object DepositTipCn { get; set; }

[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("assetLabelEn")]
public object AssetLabelEn { get; set; }

[JsonProperty("storage")]
public string Storage { get; set; }
[JsonProperty("supportMarket")]
public object SupportMarket { get; set; }

[JsonProperty("trading")]
public bool Trading { get; set; }
[JsonProperty("feeReferenceAsset")]
public string FeeReferenceAsset { get; set; }

[JsonProperty("withdrawAllEnable")]
public bool WithdrawAllEnable { get; set; }
[JsonProperty("feeRate")]
public decimal? FeeRate { get; set; }

[JsonProperty("withdrawing")]
public string Withdrawing { get; set; }
[JsonProperty("feeDigit")]
public long? FeeDigit { get; set; }

[JsonProperty("networkList")]
public CurrencyNetwork[] NetworkList { get; set; }
[JsonProperty("legalMoney")]
public bool? LegalMoney { get; set; }
}
}
13 changes: 10 additions & 3 deletions src/ExchangeSharp/API/Exchanges/Poloniex/ExchangePoloniexAPI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -166,11 +166,16 @@ public void ParseOrderTrades(IEnumerable<JToken> trades, ExchangeOrderResult ord
decimal tradeAmt = trade["amount"].ConvertInvariant<decimal>();
decimal tradeRate = trade["rate"].ConvertInvariant<decimal>();

order.AveragePrice = (order.AveragePrice.GetValueOrDefault(decimal.Zero) * order.AmountFilled + tradeAmt * tradeRate) / (order.AmountFilled + tradeAmt);
order.AveragePrice =
(order.AveragePrice.GetValueOrDefault(decimal.Zero) *
order.AmountFilled.GetValueOrDefault(decimal.Zero) + tradeAmt * tradeRate) /
(order.AmountFilled.GetValueOrDefault(decimal.Zero) + tradeAmt);
if (order.Amount == 0m)
{
order.Amount += tradeAmt;
}

order.AmountFilled = order.AmountFilled.GetValueOrDefault(decimal.Zero);
order.AmountFilled += tradeAmt;

if (order.OrderDate == DateTime.MinValue)
Expand All @@ -179,10 +184,11 @@ public void ParseOrderTrades(IEnumerable<JToken> trades, ExchangeOrderResult ord
}

// fee is a percentage taken from the traded amount rounded to 8 decimals
order.Fees = order.Fees.GetValueOrDefault(decimal.Zero);
order.Fees += CalculateFees(tradeAmt, tradeRate, order.IsBuy, trade["fee"].ConvertInvariant<decimal>());
}

if (order.AmountFilled >= order.Amount)
if (order.AmountFilled.GetValueOrDefault(decimal.Zero) >= order.Amount)
{
order.Result = ExchangeAPIOrderResult.Filled;
}
Expand All @@ -191,6 +197,7 @@ public void ParseOrderTrades(IEnumerable<JToken> trades, ExchangeOrderResult ord
order.Result = ExchangeAPIOrderResult.FilledPartially;
}
// Poloniex does not provide a way to get the original price
order.AveragePrice = order.AveragePrice?.Normalize();
order.Price = order.AveragePrice;
}

Expand Down Expand Up @@ -246,7 +253,7 @@ private void ParseCompletedOrderDetails(List<ExchangeOrderResult> orders, JToken
IEnumerable<JToken> tradesForOrder = trades.Where(x => x["orderNumber"].ToStringInvariant() == orderNum);
ExchangeOrderResult order = new ExchangeOrderResult { OrderId = orderNum, MarketSymbol = marketSymbol };
ParseOrderTrades(tradesForOrder, order);
order.Price = order.AveragePrice;
//order.Price = order.AveragePrice;
order.Result = ExchangeAPIOrderResult.Filled;
orders.Add(order);
}
Expand Down
15 changes: 15 additions & 0 deletions src/ExchangeSharp/Utility/DecimalExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace ExchangeSharp.Utility
{
public static class DecimalExtensions
{
/// <summary>
/// Remove trailing zeros.
/// </summary>
/// <param name="value">The decimal value to normalize.</param>
/// <returns></returns>
public static decimal Normalize(this decimal value)
{
return value / 1.0000000000000000000000000000m;
}
}
}
2 changes: 1 addition & 1 deletion tests/ExchangeSharpTests/ExchangeBinanceAPITests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ public async Task CurrenciesParsedCorrectly()
bnb.MinConfirmations.Should().Be(30);
bnb.FullName.Should().Be("Binance Coin");
bnb.Name.Should().Be("BNB");
bnb.TxFee.Should().Be(0.23m);
bnb.TxFee.Should().Be(0.006m);
bnb.CoinType.Should().Be("ETH");

bnb.BaseAddress.Should().BeNullOrEmpty("api does not provide this info");
Expand Down

0 comments on commit d9fc563

Please sign in to comment.