Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
public void ResetDefaultExchangeParameters() => ExchangeParameters.ResetStaticParameters();
public SharedClientInfo Discover() => SharedUtils.GetClientInfo(CryptoComExchange.Metadata, this);

private readonly static HashSet<string> _knownExchangeFiat = ["EUR", "USD", "BRL", "GBP", "CAD", "HKD", "KRW", "TWD", "RUB", "SGD"];

#region Asset client
GetAssetsOptions IAssetsRestClient.GetAssetsOptions { get; } = new GetAssetsOptions(_exchangeName, true);
Expand Down Expand Up @@ -388,6 +389,7 @@
#endregion

#region Spot Symbol client
SharedSymbolCatalog? ISpotSymbolRestClient.SpotSymbolCatalog => ExchangeSymbolCache.GetSymbolCatalog(_exchangeName, _topicSpotId, EnvironmentName, null);
GetSpotSymbolsOptions ISpotSymbolRestClient.GetSpotSymbolsOptions { get; } = new GetSpotSymbolsOptions(_exchangeName, false);

async Task<HttpResult<SharedSpotSymbol[]>> ISpotSymbolRestClient.GetSpotSymbolsAsync(GetSymbolsRequest request, CancellationToken ct)
Expand All @@ -400,18 +402,61 @@
if (!result.Success)
return HttpResult.Fail<SharedSpotSymbol[]>(result);

var data = result.Data.Where(x => x.SymbolType == Enums.SymbolType.Spot);
var data = result.Data
.Where(x => x.SymbolType == Enums.SymbolType.Spot)
.Select(x => ParseSymbol(x))
.ToArray();

var response = HttpResult.Ok(result, data.Select(s => new SharedSpotSymbol(s.BaseAsset, s.QuoteAsset, s.Symbol, s.Tradable)
ExchangeSymbolCache.UpdateSymbolInfo(_topicSpotId, EnvironmentName, null, data);
return HttpResult.Ok(result, SharedUtils.ApplySymbolFilter(data, request));
}

private SharedSpotSymbol ParseSymbol(CryptoComSymbol s)
{
var result = new SharedSpotSymbol(s.BaseAsset, s.QuoteAsset, s.Symbol, s.Tradable)
{
QuantityStep = s.QuantityTickSize,
PriceStep = s.PriceTickSize,
PriceDecimals = s.PriceDecimals,
QuantityDecimals = s.QuantityDecimals
}).ToArray());
QuantityDecimals = s.QuantityDecimals,
DisplayName = s.DisplayName
};

ExchangeSymbolCache.UpdateSymbolInfo(_topicSpotId, EnvironmentName, null, response.Data!);
return response;
if (s.ProductType == ProductType.Equity ||
s.ProductType == ProductType.EquityIndex)
{
result.BaseAssetType = SharedAssetType.TradFi;
result.BaseAssetSubType = SharedAssetSubType.Equity;
}
else if (s.ProductType == ProductType.Commodities)
{
result.BaseAssetType = SharedAssetType.TradFi;
result.BaseAssetSubType = SharedAssetSubType.Commodity;
}
else if (s.ProductType == ProductType.Currencies)
{
result.BaseAssetType = SharedAssetType.Fiat;
}
else if (s.ProductType == ProductType.DigitalCurrencies)
{
result.BaseAssetType = SharedAssetType.Crypto;
if (LibraryHelpers.IsStableCoin(result.BaseAsset))
result.BaseAssetSubType = SharedAssetSubType.StableCoin;
}

if (_knownExchangeFiat.Contains(s.QuoteAsset))
{
result.QuoteAssetType = SharedAssetType.Fiat;
}
else
{
result.QuoteAssetType = SharedAssetType.Crypto;

if (LibraryHelpers.IsStableCoin(s.QuoteAsset))
result.QuoteAssetSubType = SharedAssetSubType.StableCoin;
}

return result;
}

async Task<ExchangeCallResult<SharedSymbol[]>> ISpotSymbolRestClient.GetSpotSymbolsForBaseAssetAsync(string baseAsset)
Expand Down Expand Up @@ -882,7 +927,7 @@
#endregion

#region Futures Symbol client

SharedSymbolCatalog? IFuturesSymbolRestClient.FuturesSymbolCatalog => ExchangeSymbolCache.GetSymbolCatalog(_exchangeName, _topicFuturesId, EnvironmentName, null);
GetFuturesSymbolsOptions IFuturesSymbolRestClient.GetFuturesSymbolsOptions { get; } = new GetFuturesSymbolsOptions(_exchangeName, false);
async Task<HttpResult<SharedFuturesSymbol[]>> IFuturesSymbolRestClient.GetFuturesSymbolsAsync(GetSymbolsRequest request, CancellationToken ct)
{
Expand All @@ -894,10 +939,18 @@
if (!result.Success)
return HttpResult.Fail<SharedFuturesSymbol[]>(result);

var data = result.Data.Where(x => x.SymbolType != SymbolType.Spot && x.SymbolType != SymbolType.CroStake);
if (request.TradingMode != null)
data = data.Where(x => request.TradingMode == TradingMode.PerpetualLinear ? x.SymbolType == SymbolType.PerpetualSwap : x.SymbolType == SymbolType.DeliveryFuture);
var response = HttpResult.Ok(result, data.Select(s => new SharedFuturesSymbol(
var data = result.Data
.Where(x => x.SymbolType != SymbolType.Spot && x.SymbolType != SymbolType.CroStake)
.Select(x => ParseFuturesSymbol(x))
.ToArray();

ExchangeSymbolCache.UpdateSymbolInfo(_topicFuturesId, EnvironmentName, null, data);
return HttpResult.Ok(result, SharedUtils.ApplySymbolFilter(data, request));
}

private SharedFuturesSymbol ParseFuturesSymbol(CryptoComSymbol s)
{
var result = new SharedFuturesSymbol(
s.SymbolType == SymbolType.PerpetualSwap ? TradingMode.PerpetualLinear : TradingMode.DeliveryLinear, s.BaseAsset, s.QuoteAsset, s.Symbol, s.Tradable)
{
QuantityStep = s.QuantityTickSize,
Expand All @@ -907,11 +960,46 @@
DeliveryTime = s.ExpiryTime,
ContractSize = s.ContractSize > 0 ? s.ContractSize.Value : 1m,
MaxLongLeverage = s.MaxLeverage,
MaxShortLeverage = s.MaxLeverage
}).ToArray());
MaxShortLeverage = s.MaxLeverage,
DisplayName = s.DisplayName
};

if (s.ProductType == ProductType.Equity
|| (s.ProductType == ProductType.PreIpo) // pre-ipo
|| (s.ProductType == ProductType.EquityIndex)) // etfs
{
result.BaseAssetType = SharedAssetType.TradFi;
result.BaseAssetSubType = SharedAssetSubType.Equity;
}
else if (s.ProductType == ProductType.Commodities)
{
result.BaseAssetType = SharedAssetType.TradFi;
result.BaseAssetSubType = SharedAssetSubType.Commodity;
}
else if (s.ProductType == ProductType.Currencies)
{
result.BaseAssetType = SharedAssetType.Fiat;
}
else if (s.ProductType == ProductType.DigitalCurrencies)
{
result.BaseAssetType = SharedAssetType.Crypto;
if (LibraryHelpers.IsStableCoin(result.BaseAsset))
result.BaseAssetSubType = SharedAssetSubType.StableCoin;
}

if (_knownExchangeFiat.Contains(s.QuoteAsset))
{
result.QuoteAssetType = SharedAssetType.Fiat;
}
else
{
result.QuoteAssetType = SharedAssetType.Crypto;

if (LibraryHelpers.IsStableCoin(s.QuoteAsset))
result.QuoteAssetSubType = SharedAssetSubType.StableCoin;
}

ExchangeSymbolCache.UpdateSymbolInfo(_topicFuturesId, EnvironmentName, null, response.Data!);
return response;
return result;
}

async Task<ExchangeCallResult<SharedSymbol[]>> IFuturesSymbolRestClient.GetFuturesSymbolsForBaseAssetAsync(string baseAsset)
Expand Down Expand Up @@ -1614,7 +1702,7 @@

private OrderType GetOrderType(PlaceFuturesTriggerOrderRequest request)
{
#warning needs testing

Check warning on line 1705 in CryptoCom.Net/Clients/ExchangeApi/CryptoComRestClientExchangeApiShared.cs

View workflow job for this annotation

GitHub Actions / build

#warning: 'needs testing'

Check warning on line 1705 in CryptoCom.Net/Clients/ExchangeApi/CryptoComRestClientExchangeApiShared.cs

View workflow job for this annotation

GitHub Actions / build

#warning: 'needs testing'

Check warning on line 1705 in CryptoCom.Net/Clients/ExchangeApi/CryptoComRestClientExchangeApiShared.cs

View workflow job for this annotation

GitHub Actions / build

#warning: 'needs testing'

Check warning on line 1705 in CryptoCom.Net/Clients/ExchangeApi/CryptoComRestClientExchangeApiShared.cs

View workflow job for this annotation

GitHub Actions / build

#warning: 'needs testing'

Check warning on line 1705 in CryptoCom.Net/Clients/ExchangeApi/CryptoComRestClientExchangeApiShared.cs

View workflow job for this annotation

GitHub Actions / build

#warning: 'needs testing'

Check warning on line 1705 in CryptoCom.Net/Clients/ExchangeApi/CryptoComRestClientExchangeApiShared.cs

View workflow job for this annotation

GitHub Actions / build

#warning: 'needs testing'

Check warning on line 1705 in CryptoCom.Net/Clients/ExchangeApi/CryptoComRestClientExchangeApiShared.cs

View workflow job for this annotation

GitHub Actions / build

#warning: 'needs testing'

Check warning on line 1705 in CryptoCom.Net/Clients/ExchangeApi/CryptoComRestClientExchangeApiShared.cs

View workflow job for this annotation

GitHub Actions / build

#warning: 'needs testing'

Check warning on line 1705 in CryptoCom.Net/Clients/ExchangeApi/CryptoComRestClientExchangeApiShared.cs

View workflow job for this annotation

GitHub Actions / build

#warning: 'needs testing'

Check warning on line 1705 in CryptoCom.Net/Clients/ExchangeApi/CryptoComRestClientExchangeApiShared.cs

View workflow job for this annotation

GitHub Actions / build

#warning: 'needs testing'
if (request.OrderDirection == SharedTriggerOrderDirection.Exit && request.PriceDirection == SharedTriggerPriceDirection.PriceAbove)
return request.OrderPrice == null ? OrderType.TakeProfit : OrderType.TakeProfitLimit;

Expand Down
2 changes: 1 addition & 1 deletion CryptoCom.Net/CryptoCom.Net.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="CryptoExchange.Net" Version="12.1.0" />
<PackageReference Include="CryptoExchange.Net" Version="12.2.0" />
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="10.0.101">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
2 changes: 1 addition & 1 deletion CryptoCom.Net/Objects/Models/CryptoComSymbol.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public record CryptoComSymbol
/// ["<c>expiry_timestamp_ms</c>"] Expiry timestamp
/// </summary>
[JsonPropertyName("expiry_timestamp_ms")]
public DateTime ExpiryTime { get; set; }
public DateTime? ExpiryTime { get; set; }
/// <summary>
/// ["<c>underlying_symbol</c>"] Underlying symbol
/// </summary>
Expand Down
Loading