ExchangeSharp

repository·main·Indexed 20 days ago

https://github.com/digitalruby/exchangesharp

A C# library for interacting with exchange services, featuring specific implementations for the NDAX exchange. The library provides data models for account balances, instruments, orders, and trade history, as well as utilities for normalizing NDAX API and websocket responses into standardized ExchangeSharp formats. Built for .NET Core SDK 3.0.

Tokens
3.9K
Snippets
14
Records
18
Agent score
73%

What's inside ExchangeSharp

  1. Build and deploy a NuGet package for ExchangeSharp

    main

    To deploy a new NuGet package, follow these steps:

    1. Update Versions: Ensure that the assembly info versions are updated and the package version in ExchangeSharp.csproj is changed.
    2. Enable Package Building: In the project settings, navigate to the package tab and turn on NuGet package building.
    3. Build: Perform a build in Release mode.
    4. Locate Package: The resulting package will be located in bin/Release.
    5. Fix Summary Tag: Due to a Visual Studio bug, the summary tag is not automatically transferred. You must manually copy the summary tag from the .csproj file into the .nuspec file after the build is complete.
  2. Create a release version via command line

    main

    To create a release build of the ExchangeSharpConsole project, use the dotnet publish command. You must specify a Release configuration, an output directory, and a Runtime Identifier (RID) corresponding to your target platform.

    Replace <RID> with your specific platform identifier (e.g., win-x64, linux-x64, or osx-x64).

    dotnet publish src/ExchangeSharpConsole -o $PWD/dist -c Release -r <RID>
  3. Create a release version using Visual Studio

    main

    On Windows, you can publish the project through the Visual Studio GUI:

    1. Open ExchangeSharp.sln in Visual Studio.
    2. Right-click the project you wish to publish.
    3. Select Publish.
    4. Use the interface to configure the target platform, .NET Core version, and self-contained binary settings.
  4. Understand the NDAX Generic API Response structure

    main

    When interacting with the NDAX exchange via ExchangeSharp, API responses are mapped to a GenericResponse model. This model represents the standard envelope for NDAX API calls, containing success status and error details.

    Note that this class is internal to ExchangeNDAXAPI and is used for deserializing JSON responses from the NDAX endpoints. If you are debugging failed requests, check the ErrorMsg and ErrorCode fields to identify the specific reason for the failure.

    // The JSON structure mapped by GenericResponse:
    {
      "result": bool,
      "errormsg": string,
      "errorcode": int,
      "detail": int
    }
  5. Convert NDAX TradeData to NDAXTrade

    main

    The TradeData class (internal to ExchangeNDAXAPI) represents the raw data structure received from the NDAX API. You can convert this raw data into a consumer-friendly NDAXTrade object using the ToExchangeTrade() method. This method maps the raw JSON fields to the standard ExchangeTrade properties, including calculating IsBuy based on the TakerSide and converting the Unix timestamp to a DateTime.

    Note that NDAXTrade inherits from ExchangeTrade, providing a standardized interface for trade information across the library.

    // Assuming you have access to a TradeData instance from the API
    NDAXTrade trade = tradeData.ToExchangeTrade();
    
    Console.WriteLine($"Trade ID: {trade.Id}, Price: {trade.Price}, IsBuy: {trade.IsBuy}");
  6. Convert NDAX Instrument to ExchangeMarket

    main

    The Instrument class within the ExchangeNDAXAPI namespace provides a ToExchangeMarket() method to map NDAX-specific instrument data into a standardized ExchangeMarket object.

    When converting, the following mapping logic is applied:

    • BaseCurrency is mapped from Product1Symbol.
    • QuoteCurrency is mapped from Product2Symbol.
    • IsActive is true if SessionStatus is equal to "running" (case-insensitive).
    • MarginEnabled is hardcoded to false.
    • MarketId and AltMarketSymbol are derived from the InstrumentId string representation.
    • MarketSymbol is mapped from Symbol.

    This is useful for normalizing NDAX trading pair data into the common ExchangeSharp format.

    // Example of converting an NDAX instrument to a standard ExchangeMarket
    ExchangeMarket market = ndaxInstrument.ToExchangeMarket();
    
    Console.WriteLine($"Market: {market.MarketSymbol} ({market.BaseCurrency}/{market.QuoteCurrency})");
    Console.WriteLine($"Active: {market.IsActive}");
  7. Deserialize NDAX websocket message payloads with MessageFrame.PayloadAs<T>()

    main

    The MessageFrame class is used to represent a message received via the NDAX websocket. The actual data of the message is contained in a JSON-formatted string within the Payload property. To work with the data as a typed object, use the PayloadAs<T>() method, which deserializes the payload string into the specified type T using Newtonsoft.Json.

    // Assuming 'frame' is an instance of MessageFrame received from the NDAX API
    var myData = frame.PayloadAs<MyExpectedDataType>();
  8. Convert NDAX deposit info to ExchangeDepositDetails

    main

    The ToExchangeDepositDetails method in the NDAXDepositInfo class converts raw NDAX deposit data into a standardized ExchangeDepositDetails object.

    Behavior:

    • If the API response indicates failure (Result == false), it throws an APIException containing the Errormsg.
    • It parses the DepositInfo JSON string (expected to be a JArray) and extracts the last element as the address.
    • It automatically handles address tags by splitting the address string using the delimiters ?dt= or ?memoid=.
    • It returns an ExchangeDepositDetails object containing the Address, the extracted AddressTag (if any), and the provided cryptoCode.
    // Assuming an instance of NDAXDepositInfo is available from the NDAX API
    ExchangeDepositDetails details = ndaxDepositInfo.ToExchangeDepositDetails("BTC");
    
    Console.WriteLine($"Address: {details.Address}");
    Console.WriteLine($"Tag: {details.AddressTag}");
  9. Convert NDAX Order to ExchangeOrderResult

    main

    The Order class (internal to ExchangeNDAXAPI) provides a ToExchangeOrderResult method to map raw NDAX order data into a standardized ExchangeOrderResult.

    To use this method, you must provide a Dictionary<string, long> that maps market symbols (e.g., "BTC/CAD") to their corresponding NDAX instrument IDs. The method performs the following mappings:

    • Side: Maps "buy" (case-insensitive) to IsBuy = true.
    • OrderState: Maps NDAX states to ExchangeAPIOrderResult:
      • working $\rightarrow$ Open
      • rejected $\rightarrow$ Rejected
      • canceled or expired $\rightarrow$ Canceled
      • fullyexecuted $\rightarrow$ Filled
      • unknown $\rightarrow$ Unknown
    • MarketSymbol: Resolved by looking up the Instrument ID in the provided mapping.
    • OrderDate: Derived from ReceiveTime using UnixTimeStampToDateTimeMilliseconds().

    Note: If the OrderState is not one of the recognized values, the method throws a NotImplementedException.

    // Assuming access to an instance of the internal Order class via ExchangeNDAXAPI
    var symbolMapping = new Dictionary<string, long> { { "BTC/CAD", 123 } };
    ExchangeOrderResult result = ndaxOrder.ToExchangeOrderResult(symbolMapping);
    
    // result properties:
    // result.Amount == ndaxOrder.Quantity
    // result.IsBuy == (ndaxOrder.Side == "buy")
    // result.MarketSymbol == "BTC/CAD"
    // result.Price == ndaxOrder.Price
    // result.Result == ExchangeAPIOrderResult
    // result.OrderDate == DateTime
    // result.OrderId == ndaxOrder.OrderId.ToString()
  10. Convert NDAX TradeHistory to ExchangeTrade

    main

    The TradeHistory class is an internal data model used by ExchangeNDAXAPI.OnGetHistoricalTradesAsync(). It provides a ToExchangeTrade() method to map the raw NDAX trade data into a standardized ExchangeTrade object used by the library.

    Key mapping logic:

    • Amount is mapped from Quantity.
    • Id is mapped from TradeId (converted to string).
    • Price is mapped from Price.
    • IsBuy is determined by checking if Side equals "buy" (case-insensitive).
    • Timestamp is converted from TradeTime (Unix milliseconds) to a DateTime.
    • Flags are set to ExchangeTradeFlags.IsBuy if the side is "buy".
    // Example of how the internal model maps to the public ExchangeTrade
    ExchangeTrade trade = ndaxTradeHistory.ToExchangeTrade();