├── .gitignore
├── Bitfinex
├── packages.config
├── Bitfinex.nuspec
├── Models
│ ├── Candles.cs
│ ├── Stats.cs
│ ├── Books.cs
│ ├── Trades.cs
│ ├── Common.cs
│ └── Tickers.cs
├── Properties
│ └── AssemblyInfo.cs
├── JsonConverters
│ ├── StatResultConverter.cs
│ ├── CandleResultConverter.cs
│ ├── BookResultConverter.cs
│ ├── TradeResultConverter.cs
│ └── TickerResultConverter.cs
├── BitfinexRestClient.cs
├── TickersClient.cs
├── BooksClient.cs
├── Bitfinex.csproj
├── StatsClient.cs
├── TradesClient.cs
├── CandlesClient.cs
└── IBitfinexRestClient.cs
├── Bitfinex.Tests
├── packages.config
├── Properties
│ └── AssemblyInfo.cs
├── postman.json
├── Models
│ ├── TickersTests.cs
│ ├── StatsTests.cs
│ ├── BooksTests.cs
│ ├── CandlesTests.cs
│ └── TradesTests.cs
└── Bitfinex.Tests.csproj
├── BitfinexAPI.sln
├── README.md
└── LICENSE.txt
/.gitignore:
--------------------------------------------------------------------------------
1 | /Bitfinex/bin
2 | /Bitfinex/obj
3 | /Bitfinex.Tests/bin
4 | /Bitfinex.Tests/obj
5 | /TestResults
6 | /packages
7 | /.vs
8 |
--------------------------------------------------------------------------------
/Bitfinex/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/Bitfinex.Tests/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Bitfinex.Tests/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | [assembly: AssemblyTitle("DynamicSites.Bitfinex.Tests")]
6 | [assembly: AssemblyDescription("")]
7 | [assembly: AssemblyConfiguration("")]
8 | [assembly: AssemblyCompany("")]
9 | [assembly: AssemblyProduct("DynamicSites.Bitfinex.Tests")]
10 | [assembly: AssemblyCopyright("Copyright © 2017")]
11 | [assembly: AssemblyTrademark("")]
12 | [assembly: AssemblyCulture("")]
13 |
14 | [assembly: ComVisible(false)]
15 |
16 | [assembly: Guid("7839f97d-69d4-4125-b543-223b0d307222")]
17 |
18 | // [assembly: AssemblyVersion("1.0.*")]
19 | [assembly: AssemblyVersion("1.0.0.0")]
20 | [assembly: AssemblyFileVersion("1.0.0.0")]
21 |
--------------------------------------------------------------------------------
/Bitfinex/Bitfinex.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Bitfinex
5 | $version$
6 | Jeremy Andrews
7 | Jeremy Andrews
8 | https://github.com/jandrews377/bitfinex-rest/blob/master/LICENSE.txt
9 | https://github.com/jandrews377/bitfinex-rest
10 | false
11 | A C# implementation of the Bitfinex REST API Version 2.0
12 | For full release notes see https://github.com/jandrews377/bitfinex-rest/blob/master/releasenotes.markdown
13 | Copyright 2017
14 | BITFINEX
15 |
16 |
--------------------------------------------------------------------------------
/Bitfinex.Tests/postman.json:
--------------------------------------------------------------------------------
1 | {
2 | "variables": [],
3 | "info": {
4 | "name": "Bitfinex",
5 | "_postman_id": "6bfee292-bc0e-38ab-e875-843d23de444f",
6 | "description": "",
7 | "schema": "https://schema.getpostman.com/json/collection/v2.0.0/collection.json"
8 | },
9 | "item": [
10 | {
11 | "name": "https://api.bitfinex.com/v2/tickers?symbols=tBTCUSD,fUSD",
12 | "request": {
13 | "url": {
14 | "raw": "https://api.bitfinex.com/v2/tickers?symbols=tBTCUSD,fUSD",
15 | "protocol": "https",
16 | "host": [
17 | "api",
18 | "bitfinex",
19 | "com"
20 | ],
21 | "path": [
22 | "v2",
23 | "tickers"
24 | ],
25 | "query": [
26 | {
27 | "key": "symbols",
28 | "value": "tBTCUSD,fUSD",
29 | "equals": true,
30 | "description": ""
31 | }
32 | ],
33 | "variable": []
34 | },
35 | "method": "GET",
36 | "header": [],
37 | "body": {},
38 | "description": ""
39 | },
40 | "response": []
41 | }
42 | ]
43 | }
--------------------------------------------------------------------------------
/Bitfinex/Models/Candles.cs:
--------------------------------------------------------------------------------
1 | namespace Bitfinex.Models
2 | {
3 | public class Candle
4 | {
5 | ///
6 | /// Millisecond timestamp
7 | ///
8 | public decimal MTS { get; set; }
9 |
10 | ///
11 | /// First execution during the time frame
12 | ///
13 | public double Open { get; set; }
14 |
15 | ///
16 | /// Last execution during the time frame
17 | ///
18 | public double Close { get; set; }
19 |
20 | ///
21 | /// Highest execution during the time frame
22 | ///
23 | public double High { get; set; }
24 |
25 | ///
26 | /// Lowest execution during the timeframe
27 | ///
28 | public double Low { get; set; }
29 |
30 | ///
31 | /// Quantity of symbol traded within the timeframe
32 | ///
33 | public double Volume { get; set; }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Bitfinex/Models/Stats.cs:
--------------------------------------------------------------------------------
1 | namespace Bitfinex.Models
2 | {
3 | public class Key
4 | {
5 | public string Value { get; set; }
6 |
7 | public static Key TotalOpenPosition => new Key("pos.size");
8 |
9 | public static Key TotalActiveFunding => new Key("funding.size");
10 | public static Key ActiveFundingUsedInPositions => new Key("credits.size");
11 | public static Key ActiveFundingUsedInPositionsPerTradingSymbol => new Key("credits.size.sym");
12 |
13 | private Key(string value)
14 | {
15 | Value = value;
16 | }
17 |
18 | public override string ToString()
19 | {
20 | return Value;
21 | }
22 | }
23 |
24 | public class Side
25 | {
26 | public string Value { get; set; }
27 |
28 | public static Side Long => new Side("long");
29 | public static Side Short => new Side("short");
30 |
31 | private Side(string value)
32 | {
33 | Value = value;
34 | }
35 |
36 | public override string ToString()
37 | {
38 | return Value;
39 | }
40 | }
41 |
42 | public class Stat
43 | {
44 | ///
45 | /// Millisecond timestamp
46 | ///
47 | public decimal MTS { get; set; }
48 |
49 | ///
50 | /// Total amount
51 | ///
52 | public double Value { get; set; }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/Bitfinex/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("DynamicSites.Bitfinex.Framework")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("DynamicSites.Bitfinex.Framework")]
13 | [assembly: AssemblyCopyright("Copyright © 2017")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("9a3385ac-7e13-4b18-9831-99e487744b97")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/BitfinexAPI.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.26430.6
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bitfinex.Tests", "Bitfinex.Tests\Bitfinex.Tests.csproj", "{7839F97D-69D4-4125-B543-223B0D307222}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bitfinex", "Bitfinex\Bitfinex.csproj", "{9A3385AC-7E13-4B18-9831-99E487744B97}"
9 | EndProject
10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{35712D31-73E3-46A7-BD18-BD299BBC5A16}"
11 | ProjectSection(SolutionItems) = preProject
12 | Bitfinex.nuspec = Bitfinex.nuspec
13 | LICENSE.txt = LICENSE.txt
14 | README.md = README.md
15 | EndProjectSection
16 | EndProject
17 | Global
18 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
19 | Debug|Any CPU = Debug|Any CPU
20 | Release|Any CPU = Release|Any CPU
21 | EndGlobalSection
22 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
23 | {7839F97D-69D4-4125-B543-223B0D307222}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
24 | {7839F97D-69D4-4125-B543-223B0D307222}.Debug|Any CPU.Build.0 = Debug|Any CPU
25 | {7839F97D-69D4-4125-B543-223B0D307222}.Release|Any CPU.ActiveCfg = Release|Any CPU
26 | {7839F97D-69D4-4125-B543-223B0D307222}.Release|Any CPU.Build.0 = Release|Any CPU
27 | {9A3385AC-7E13-4B18-9831-99E487744B97}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
28 | {9A3385AC-7E13-4B18-9831-99E487744B97}.Debug|Any CPU.Build.0 = Debug|Any CPU
29 | {9A3385AC-7E13-4B18-9831-99E487744B97}.Release|Any CPU.ActiveCfg = Release|Any CPU
30 | {9A3385AC-7E13-4B18-9831-99E487744B97}.Release|Any CPU.Build.0 = Release|Any CPU
31 | EndGlobalSection
32 | GlobalSection(SolutionProperties) = preSolution
33 | HideSolutionNode = FALSE
34 | EndGlobalSection
35 | EndGlobal
36 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Bitfinex REST API Version 2.0 Client 
2 |
3 | This is a C# implementation of the Bitfinex REST API Version 2.0 (BETA) found here:
4 |
5 | https://bitfinex.readme.io/v2/docs/getting-started
6 |
7 | At this stage it is an ALPHA state. Only the Public Endpoint (https://bitfinex.readme.io/v2/docs/rest-public) has been implemented. In the coming weeks the Authenticated Endpoint (https://bitfinex.readme.io/v2/docs/rest-auth) will be added.
8 |
9 | ### License: Apache License 2.0
10 |
11 | ### Features
12 |
13 | * Easy installation using [NuGet](https://www.nuget.org/packages/Bitfinex)
14 | * Synchronous and Asynchronous methods
15 |
16 | ```csharp
17 | var client = new BitfinexRestClient();
18 | var tickers = client.GetTickers(new string[] { "tBTCUSD", "tLTCUSD", "fUS" });
19 |
20 | foreach (var ticker in tickers)
21 | {
22 | var output = new StringBuilder();
23 | output.AppendLine($"FlashReturnRate: {ticker.FlashReturnRate}");
24 | output.AppendLine($"BidPeriod: {ticker.BidPeriod}");
25 | output.AppendLine($"AskPeriod: {ticker.AskPeriod}");
26 | output.AppendLine($"Symbol: {ticker.Symbol}");
27 | output.AppendLine($"Bid: {ticker.Bid}");
28 | output.AppendLine($"BidSize: {ticker.BidSize}");
29 | output.AppendLine($"Ask: {ticker.Ask}");
30 | output.AppendLine($"AskSize: {ticker.AskSize}");
31 | output.AppendLine($"DailyChange: {ticker.DailyChange}");
32 | output.AppendLine($"DailyChangePercent: {ticker.DailyChangePercent}");
33 | output.AppendLine($"LastPrice: {ticker.LastPrice}");
34 | output.AppendLine($"Volume: {ticker.Volume}");
35 | output.AppendLine($"High: {ticker.High}");
36 | output.AppendLine($"Low: {ticker.Low}");
37 |
38 | Console.WriteLine(output);
39 | }
40 | ```
41 |
42 | Donations gratefully accepted.
43 | Bitcoin: 1NPee1eCWQqmsQwqatdfpgogDrfuwqUZhQ
44 | Ethereum: 0x04f11eefc870ce139954a94cfbf75bdcaf4ede40
45 |
--------------------------------------------------------------------------------
/Bitfinex/JsonConverters/StatResultConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Bitfinex.Models;
4 | using Newtonsoft.Json;
5 | using Newtonsoft.Json.Linq;
6 |
7 | namespace Bitfinex.JsonConverters
8 | {
9 | public class StatsResultConverter : JsonConverter
10 | {
11 | public override bool CanConvert(Type objectType)
12 | {
13 | return objectType == typeof(List);
14 | }
15 |
16 | public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
17 | {
18 | var array = JArray.Load(reader);
19 |
20 | var results = new List();
21 |
22 | foreach (var item in array)
23 | {
24 | var stat = JsonConvert.DeserializeObject(item.ToString(), new StatResultConverter());
25 | results.Add(stat);
26 | }
27 |
28 | return results;
29 | }
30 |
31 | public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
32 | {
33 | throw new NotImplementedException();
34 | }
35 |
36 | public override bool CanWrite => false;
37 | }
38 |
39 | public class StatResultConverter : JsonConverter
40 | {
41 | public override bool CanConvert(Type objectType)
42 | {
43 | return objectType == typeof(Stat);
44 | }
45 |
46 | public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
47 | JsonSerializer serializer)
48 | {
49 | var array = JArray.Load(reader);
50 |
51 | return new Stat
52 | {
53 | MTS = (decimal)array[0],
54 | Value = (double)array[1]
55 | };
56 | }
57 |
58 | public override bool CanWrite => false;
59 |
60 | public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
61 | {
62 | throw new NotImplementedException();
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/Bitfinex/Models/Books.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Bitfinex.Models
4 | {
5 | public enum Precision
6 | {
7 | P0, P1, P2, P3, R0
8 | }
9 |
10 | public interface IBook
11 | {
12 | ///
13 | /// Price level
14 | ///
15 | double Price { get; set; }
16 |
17 | ///
18 | /// Rate level
19 | ///
20 | double Rate { get; set; }
21 |
22 | ///
23 | /// Period level (Funding only)
24 | ///
25 | double Period { get; set; }
26 |
27 | ///
28 | /// Number of orders at that price level
29 | ///
30 | int Count { get; set; }
31 |
32 | ///
33 | /// Total amount available at that price level.
34 | ///
35 | double Amount { get; set; }
36 | }
37 |
38 | public class Book
39 | {
40 | ///
41 | /// Number of orders at that price level
42 | ///
43 | public int Count { get; set; }
44 |
45 | ///
46 | /// Total amount available at that price level.
47 | ///
48 | public double Amount { get; set; }
49 | }
50 |
51 | public class TradingBook : Book, IBook
52 | {
53 | ///
54 | /// Price level
55 | ///
56 | public double Price { get; set; }
57 |
58 | [Obsolete]
59 | public double Rate { get; set; }
60 |
61 | [Obsolete]
62 | public double Period { get; set; }
63 | }
64 |
65 | public class FundingBook : Book, IBook
66 | {
67 | ///
68 | /// Rate at which funding transaction occurred
69 | ///
70 | public double Rate { get; set; }
71 |
72 | ///
73 | /// Amount of time the funding transaction was for
74 | ///
75 | public double Period { get; set; }
76 |
77 | [Obsolete]
78 | public double Price { get; set; }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/Bitfinex/Models/Trades.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Bitfinex.Models
4 | {
5 | public interface ITrade
6 | {
7 | decimal ID { get; set; }
8 |
9 | ///
10 | /// Millisecond timestamp
11 | ///
12 | decimal MTS { get; set; }
13 |
14 | ///
15 | /// How much was bought (positive) or sold (negative)
16 | ///
17 | double Amount { get; set; }
18 |
19 | ///
20 | /// Price at which the trade was executed
21 | ///
22 | double Price { get; set; }
23 |
24 | ///
25 | /// Rate at which funding transaction occurred
26 | ///
27 | double Rate { get; set; }
28 |
29 | ///
30 | /// Amount of time the funding transaction was for
31 | ///
32 | TimeSpan Period { get; set; }
33 | }
34 |
35 | public class Trade
36 | {
37 | public decimal ID { get; set; }
38 |
39 | ///
40 | /// Millisecond timestamp
41 | ///
42 | public decimal MTS { get; set; }
43 |
44 | ///
45 | /// How much was bought (positive) or sold (negative)
46 | ///
47 | public double Amount { get; set; }
48 | }
49 |
50 | public class TradingTrade : Trade, ITrade
51 | {
52 | ///
53 | /// Price at which the trade was executed
54 | ///
55 | public double Price { get; set; }
56 |
57 | [Obsolete]
58 | public double Rate { get; set; }
59 |
60 | [Obsolete]
61 | public TimeSpan Period { get; set; }
62 | }
63 |
64 | public class FundingTrade : Trade, ITrade
65 | {
66 | ///
67 | /// Rate at which funding transaction occurred
68 | ///
69 | public double Rate { get; set; }
70 |
71 | ///
72 | /// Amount of time the funding transaction was for
73 | ///
74 | public TimeSpan Period { get; set; }
75 |
76 | [Obsolete]
77 | public double Price { get; set; }
78 | }
79 | }
--------------------------------------------------------------------------------
/Bitfinex/JsonConverters/CandleResultConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Bitfinex.Models;
4 | using Newtonsoft.Json;
5 | using Newtonsoft.Json.Linq;
6 |
7 | namespace Bitfinex.JsonConverters
8 | {
9 | public class CandlesResultConverter : JsonConverter
10 | {
11 | public override bool CanConvert(Type objectType)
12 | {
13 | return objectType == typeof(List);
14 | }
15 |
16 | public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
17 | {
18 | var array = JArray.Load(reader);
19 |
20 | var results = new List();
21 |
22 | foreach (var item in array)
23 | {
24 | var candle = JsonConvert.DeserializeObject(item.ToString(), new CandleResultConverter());
25 | results.Add(candle);
26 | }
27 |
28 | return results;
29 | }
30 |
31 | public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
32 | {
33 | throw new NotImplementedException();
34 | }
35 |
36 | public override bool CanWrite => false;
37 | }
38 |
39 | public class CandleResultConverter : JsonConverter
40 | {
41 | public override bool CanConvert(Type objectType)
42 | {
43 | return objectType == typeof(Candle);
44 | }
45 |
46 | public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
47 | JsonSerializer serializer)
48 | {
49 | var array = JArray.Load(reader);
50 |
51 | return new Candle
52 | {
53 | MTS = (decimal)array[0],
54 | Open = (double)array[1],
55 | Close = (double)array[2],
56 | High = (double)array[3],
57 | Low = (double)array[4],
58 | Volume = (double)array[5]
59 | };
60 | }
61 |
62 | public override bool CanWrite => false;
63 |
64 | public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
65 | {
66 | throw new NotImplementedException();
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/Bitfinex/BitfinexRestClient.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading;
3 | using System.Threading.Tasks;
4 | using Bitfinex.Models;
5 | using Newtonsoft.Json;
6 | using RestSharp;
7 | using static System.String;
8 |
9 | namespace Bitfinex
10 | {
11 | public partial class BitfinexRestClient : IBitfinexRestClient
12 | {
13 | private RestClient _client;
14 |
15 | private string _baseUrl = "https://api.bitfinex.com/v2";
16 |
17 | public string BaseUrl
18 | {
19 | get => _baseUrl;
20 | set
21 | {
22 | _baseUrl = value;
23 | _client = new RestClient(_baseUrl);
24 | }
25 | }
26 |
27 | public CancellationToken CancellationToken { get; set; }
28 |
29 | public BitfinexRestClient()
30 | {
31 | _client = new RestClient(BaseUrl);
32 | CancellationToken = new CancellationTokenSource().Token;
33 | }
34 |
35 | #region private
36 | ///
37 | /// Deserializes JSON to the specified type.
38 | ///
39 | ///
40 | ///
41 | ///
42 | ///
43 | private static object DeserializeObject(string json, JsonConverter converter)
44 | {
45 | try
46 | {
47 | return JsonConvert.DeserializeObject(json, converter);
48 | }
49 | catch (JsonReaderException ex)
50 | {
51 | throw new Exception("Error deserializing response", ex);
52 | }
53 | }
54 |
55 | ///
56 | /// Issue our request. Check our response for an exception as Bitfinex returns Status: OK even when an exception is returned.
57 | ///
58 | ///
59 | ///
60 | ///
61 | private async Task GetResponseAsync(IRestRequest request, CancellationToken token)
62 | {
63 | var response = await _client.ExecuteTaskAsync(request, token);
64 | if (!IsNullOrEmpty(response.ErrorMessage)) throw new Exception(response.ErrorMessage);
65 |
66 | BitfinexException exception = null;
67 | try
68 | {
69 | exception = JsonConvert.DeserializeObject(response.Content, new ExceptionResultConverter());
70 | }
71 | catch (Exception)
72 | {
73 | // ignored
74 | }
75 |
76 | if (exception != null) throw new Exception($"({exception.ErrorCode}) {exception.Message}");
77 |
78 | return response;
79 | }
80 | #endregion
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/Bitfinex/JsonConverters/BookResultConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Bitfinex.Models;
4 | using Newtonsoft.Json;
5 | using Newtonsoft.Json.Linq;
6 |
7 | namespace Bitfinex.JsonConverters
8 | {
9 | public class BooksResultConverter : JsonConverter
10 | {
11 | public override bool CanConvert(Type objectType)
12 | {
13 | return objectType == typeof(List);
14 | }
15 |
16 | public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
17 | {
18 | var array = JArray.Load(reader);
19 |
20 | var results = new List();
21 |
22 | foreach (var item in array)
23 | {
24 | var Book = JsonConvert.DeserializeObject(item.ToString(), new BookResultConverter());
25 | results.Add(Book);
26 | }
27 |
28 | return results;
29 | }
30 |
31 | public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
32 | {
33 | throw new NotImplementedException();
34 | }
35 |
36 | public override bool CanWrite => false;
37 | }
38 |
39 | public class BookResultConverter : JsonConverter
40 | {
41 | public override bool CanConvert(Type objectType)
42 | {
43 | return objectType == typeof(IBook);
44 | }
45 |
46 | public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
47 | JsonSerializer serializer)
48 | {
49 | var array = JArray.Load(reader);
50 |
51 | switch (array.Count)
52 | {
53 | case 3:
54 | return JArrayToTradingBook(array);
55 | case 4:
56 | return JArrayToFundingBook(array);
57 | }
58 |
59 | return null;
60 | }
61 |
62 | public override bool CanWrite => false;
63 |
64 | public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
65 | {
66 | throw new NotImplementedException();
67 | }
68 |
69 | private TradingBook JArrayToTradingBook(JArray array)
70 | {
71 | return new TradingBook
72 | {
73 | Price = (double)array[0],
74 | Count = (int)array[1],
75 | Amount = (double)array[2]
76 | };
77 | }
78 |
79 | private FundingBook JArrayToFundingBook(JArray array)
80 | {
81 | return new FundingBook
82 | {
83 | Rate = (double)array[0],
84 | Period = (int)array[1],
85 | Count = (int)array[2],
86 | Amount = (double)array[3]
87 | };
88 | }
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/Bitfinex/JsonConverters/TradeResultConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Bitfinex.Models;
4 | using Newtonsoft.Json;
5 | using Newtonsoft.Json.Linq;
6 |
7 | namespace Bitfinex.JsonConverters
8 | {
9 | public class TradesResultConverter : JsonConverter
10 | {
11 | public override bool CanConvert(Type objectType)
12 | {
13 | return objectType == typeof(List);
14 | }
15 |
16 | public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
17 | {
18 | var array = JArray.Load(reader);
19 |
20 | var results = new List();
21 |
22 | foreach (var item in array)
23 | {
24 | var trade = JsonConvert.DeserializeObject(item.ToString(), new TradeResultConverter());
25 | results.Add(trade);
26 | }
27 |
28 | return results;
29 | }
30 |
31 | public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
32 | {
33 | throw new NotImplementedException();
34 | }
35 |
36 | public override bool CanWrite => false;
37 | }
38 |
39 | public class TradeResultConverter : JsonConverter
40 | {
41 | public override bool CanConvert(Type objectType)
42 | {
43 | return objectType == typeof(ITrade);
44 | }
45 |
46 | public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
47 | JsonSerializer serializer)
48 | {
49 | var array = JArray.Load(reader);
50 |
51 | switch (array.Count)
52 | {
53 | case 4:
54 | return JArrayToTradingTrade(array);
55 | case 5:
56 | return JArrayToFundingTrade(array);
57 | }
58 |
59 | return null;
60 | }
61 |
62 | public override bool CanWrite => false;
63 |
64 | public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
65 | {
66 | throw new NotImplementedException();
67 | }
68 |
69 | private TradingTrade JArrayToTradingTrade(JArray array)
70 | {
71 | return new TradingTrade
72 | {
73 | ID = (decimal)array[0],
74 | MTS = (decimal)array[1],
75 | Amount = (double)array[2],
76 | Price = (double)array[3]
77 | };
78 | }
79 |
80 | private FundingTrade JArrayToFundingTrade(JArray array)
81 | {
82 | // TO-DO: Confirm that the value for 'Period' that is returned is actually milliseconds.
83 |
84 | return new FundingTrade
85 | {
86 | ID = (decimal)array[0],
87 | MTS = (decimal)array[1],
88 | Amount = (double)array[2],
89 | Rate = (double)array[3],
90 | Period = new TimeSpan(0,0,0,0,(int)array[4])
91 | };
92 | }
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/Bitfinex/TickersClient.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading.Tasks;
3 | using Bitfinex.JsonConverters;
4 | using Bitfinex.Models;
5 | using RestSharp;
6 | using static System.String;
7 |
8 | namespace Bitfinex
9 | {
10 | // All our Ticker methods.
11 |
12 | public partial class BitfinexRestClient
13 | {
14 | ///
15 | /// Get a high-level overview of the specified symbol. It shows you the current best bid and ask, as well as the last trade price. It also includes information such as daily volume and how much the price has moved over the last day.
16 | ///
17 | /// A symbol (eg BTCUSD) prefixed with either t (for Trading) or f (for Funding). eg tBTCUSD
18 | /// Ticker
19 | public ITicker GetTicker(string symbol)
20 | {
21 | return GetTickerAsync(symbol).Result;
22 | }
23 |
24 | ///
25 | /// Get a high-level overview of the specified symbols. It shows you the current best bid and ask, as well as the last trade price. It also includes information such as daily volume and how much the price has moved over the last day.
26 | ///
27 | /// A list of symbols (eg BTCUSD) prefixed with either t (for Trading) or f (for Funding). eg tBTCUSD
28 | /// List of tickers
29 | public List GetTickers(string[] symbols)
30 | {
31 | return GetTickersAsync(symbols).Result;
32 | }
33 |
34 | ///
35 | /// Get a high-level overview of the specified symbol. It shows you the current best bid and ask, as well as the last trade price. It also includes information such as daily volume and how much the price has moved over the last day.
36 | ///
37 | /// A symbol (eg BTCUSD) prefixed with either t (for Trading) or f (for Funding). eg tBTCUSD
38 | /// Ticker
39 | public async Task GetTickerAsync(string symbol)
40 | {
41 | var tickers = await GetTickersAsync(new[] { symbol });
42 | return tickers[0];
43 | }
44 |
45 | ///
46 | /// Get a high-level overview of the specified symbols. It shows you the current best bid and ask, as well as the last trade price. It also includes information such as daily volume and how much the price has moved over the last day.
47 | ///
48 | /// A list of symbols (eg BTCUSD) prefixed with either t (for Trading) or f (for Funding). eg tBTCUSD
49 | /// List of tickers
50 | public async Task> GetTickersAsync(string[] symbols)
51 | {
52 | var symbolsString = Join(",", symbols);
53 |
54 | string url = $"tickers?symbols={symbolsString}";
55 | var request = new RestRequest(url, Method.GET);
56 |
57 | var response = await GetResponseAsync(request, CancellationToken);
58 |
59 | return (List)DeserializeObject>(response.Content, new TickersResultConverter());
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/Bitfinex/BooksClient.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading.Tasks;
3 | using Bitfinex.JsonConverters;
4 | using Bitfinex.Models;
5 | using RestSharp;
6 |
7 | namespace Bitfinex
8 | {
9 | // All our Books methods.
10 |
11 | public partial class BitfinexRestClient
12 | {
13 | ///
14 | /// Retrieve state of the Bitfinex order book. It is provided on a price aggregated basis, with customizable precision.
15 | ///
16 | /// The symbol you want information about.
17 | /// Level of price aggregation (P0, P1, P2, P3, R0)
18 | /// List of books
19 | public List GetBooks(string symbol, Precision precision)
20 | {
21 | return getBooksAsync(symbol, precision, null).Result;
22 | }
23 |
24 | ///
25 | /// Retrieve state of the Bitfinex order book. It is provided on a price aggregated basis, with customizable precision.
26 | ///
27 | /// The symbol you want information about.
28 | /// Level of price aggregation (P0, P1, P2, P3, R0)
29 | /// Number of price points
30 | /// List of books
31 | public List GetBooks(string symbol, Precision precision, int len)
32 | {
33 | return getBooksAsync(symbol, precision, len).Result;
34 | }
35 |
36 | ///
37 | /// Retrieve state of the Bitfinex order book. It is provided on a price aggregated basis, with customizable precision.
38 | ///
39 | /// The symbol you want information about.
40 | /// Level of price aggregation (P0, P1, P2, P3, R0)
41 | /// List of books
42 | public async Task> GetBooksAsync(string symbol, Precision precision)
43 | {
44 | return await getBooksAsync(symbol, precision, null);
45 | }
46 |
47 | ///
48 | /// Retrieve state of the Bitfinex order book. It is provided on a price aggregated basis, with customizable precision.
49 | ///
50 | /// The symbol you want information about.
51 | /// Level of price aggregation (P0, P1, P2, P3, R0)
52 | /// Number of price points
53 | /// List of books
54 | public async Task> GetBooksAsync(string symbol, Precision precision, int len)
55 | {
56 | return await getBooksAsync(symbol, precision, len);
57 | }
58 |
59 | private async Task> getBooksAsync(string symbol, Precision precision, int? len)
60 | {
61 | var url = $"book/{symbol}/{precision}";
62 | if (len.GetValueOrDefault() != 0) url = url + "?len=" + len;
63 |
64 | var request = new RestRequest(url, Method.GET);
65 |
66 | var response = await GetResponseAsync(request, CancellationToken);
67 |
68 | return (List)DeserializeObject>(response.Content, new BooksResultConverter());
69 | }
70 | }
71 | }
--------------------------------------------------------------------------------
/Bitfinex.Tests/Models/TickersTests.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Bitfinex.JsonConverters;
3 | using Bitfinex.Models;
4 | using Microsoft.VisualStudio.TestTools.UnitTesting;
5 | using Newtonsoft.Json;
6 |
7 | namespace Bitfinex.Tests.Models
8 | {
9 | [TestClass]
10 | public class TickersTests
11 | {
12 |
13 | [TestMethod]
14 | public void TickerDeserializeTest1()
15 | {
16 | //GET: https://api.bitfinex.com/v2/tickers?symbols=tETHBTC
17 |
18 | string json = "[ \"tETHBTC\", 0.1386, 0.58674268, 0.1391, 89.87488593, -0.00099, -0.0071, 0.13899, 87521.10872248, 0.14331, 0.12951 ]";
19 |
20 | var ticker = JsonConvert.DeserializeObject(json, new TickerResultConverter());
21 |
22 | Assert.AreEqual("ETHBTC", ticker.Symbol);
23 | Assert.AreEqual(0.1386, ticker.Bid);
24 | Assert.AreEqual(0.58674268, ticker.BidSize);
25 | Assert.AreEqual(0.1391, ticker.Ask);
26 | Assert.AreEqual(89.87488593, ticker.AskSize);
27 | Assert.AreEqual(-0.00099, ticker.DailyChange);
28 | Assert.AreEqual(-0.0071, ticker.DailyChangePercent);
29 | Assert.AreEqual(0.13899, ticker.LastPrice);
30 | Assert.AreEqual(87521.10872248, ticker.Volume);
31 | Assert.AreEqual(0.14331, ticker.High);
32 | Assert.AreEqual(0.12951, ticker.Low);
33 |
34 | }
35 |
36 | [TestMethod]
37 | public void TickerDeserializeTest2()
38 | {
39 | //GET: https://api.bitfinex.com/v2/tickers?symbols=fUSD
40 |
41 | string json = "[ \"fUSD\", 0.00171431, 0.00156, 30, 998501.81496333, 0.0015, 2, 183396.25235139, -0.0001294, -0.0767, 0.0015586, 55302424.0576984, 0, 0 ]";
42 |
43 | var ticker = JsonConvert.DeserializeObject(json, new TickerResultConverter());
44 |
45 | Assert.AreEqual("USD", ticker.Symbol);
46 | Assert.AreEqual(0.00171431, ticker.FlashReturnRate);
47 | Assert.AreEqual(0.00156, ticker.Bid);
48 | Assert.AreEqual(30, ticker.BidPeriod);
49 | Assert.AreEqual(998501.81496333, ticker.BidSize);
50 | Assert.AreEqual(0.0015, ticker.Ask);
51 | Assert.AreEqual(2, ticker.AskPeriod);
52 | Assert.AreEqual(183396.25235139, ticker.AskSize);
53 | Assert.AreEqual(-0.0001294, ticker.DailyChange);
54 | Assert.AreEqual(-0.0767, ticker.DailyChangePercent);
55 | Assert.AreEqual(0.0015586, ticker.LastPrice);
56 | Assert.AreEqual(55302424.0576984, ticker.Volume);
57 | Assert.AreEqual(0, ticker.High);
58 | Assert.AreEqual(0, ticker.Low);
59 | }
60 |
61 | [TestMethod]
62 | public void TickerDeserializeTest3()
63 | {
64 | //GET: https://api.bitfinex.com/v2/tickers?symbols=tBTCUSD,fUSD
65 |
66 | string json = "[ [ \"tBTCUSD\", 2367, 0.5569, 2367.7, 1.34457976, 88.8, 0.039, 2367.7, 52265.08783943, 2397, 2046 ]," +
67 | " [\"fUSD\", 0.00170975, 0.00145, 30, 1527.14753183, 0.00149, 2, 183396.25235139, -0.00015242, -0.0915, 0.00151348, 55001789.95285199, 0, 0 ] ]";
68 |
69 | var tickers = JsonConvert.DeserializeObject>(json, new TickersResultConverter());
70 |
71 | Assert.AreEqual(2, tickers.Count);
72 |
73 | }
74 |
75 | [TestMethod]
76 | public void TickerClientTest()
77 | {
78 | var client = new BitfinexRestClient();
79 | var ticker = client.GetTicker("tBTCUSD");
80 |
81 | Assert.AreEqual("BTCUSD", ticker.Symbol);
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/Bitfinex/Bitfinex.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {9A3385AC-7E13-4B18-9831-99E487744B97}
8 | Library
9 | Properties
10 | Bitfinex
11 | Bitfinex
12 | v4.5.2
13 | 512
14 |
15 |
16 | true
17 | full
18 | false
19 | bin\Debug\
20 | DEBUG;TRACE
21 | prompt
22 | 4
23 |
24 |
25 | pdbonly
26 | true
27 | bin\Release\
28 | TRACE
29 | prompt
30 | 4
31 |
32 |
33 |
34 | ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll
35 |
36 |
37 | ..\packages\RestSharp.105.2.3\lib\net452\RestSharp.dll
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/Bitfinex/JsonConverters/TickerResultConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Bitfinex.Models;
4 | using Newtonsoft.Json;
5 | using Newtonsoft.Json.Linq;
6 |
7 | namespace Bitfinex.JsonConverters
8 | {
9 | public class TickersResultConverter : JsonConverter
10 | {
11 | public override bool CanConvert(Type objectType)
12 | {
13 | return objectType == typeof(List);
14 | }
15 |
16 | public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
17 | {
18 | var array = JArray.Load(reader);
19 |
20 | var results = new List();
21 |
22 | foreach (var item in array)
23 | {
24 | var ticker = JsonConvert.DeserializeObject(item.ToString(), new TickerResultConverter());
25 | results.Add(ticker);
26 | }
27 |
28 | return results;
29 | }
30 |
31 | public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
32 | {
33 | throw new NotImplementedException();
34 | }
35 |
36 | public override bool CanWrite => false;
37 | }
38 |
39 | public class TickerResultConverter : JsonConverter
40 | {
41 | public override bool CanConvert(Type objectType)
42 | {
43 | return objectType == typeof(ITicker);
44 | }
45 |
46 | public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
47 | JsonSerializer serializer)
48 | {
49 | var array = JArray.Load(reader);
50 |
51 | var symbol = (string) array[0];
52 |
53 | if (symbol.StartsWith("t")) return JArrayToTradingTicker(array);
54 | if (symbol.StartsWith("f")) return JArrayToFundingTicker(array);
55 |
56 | return null;
57 | }
58 |
59 | public override bool CanWrite => false;
60 |
61 | public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
62 | {
63 | throw new NotImplementedException();
64 | }
65 |
66 | private TradingTicker JArrayToTradingTicker(JArray array)
67 | {
68 | string symbol = (string)array[0];
69 | string symbolStripped = symbol.Substring(1);
70 |
71 | return new TradingTicker
72 | {
73 | Symbol = symbolStripped,
74 | Bid = (double)array[1],
75 | BidSize = (double)array[2],
76 | Ask = (double)array[3],
77 | AskSize = (double)array[4],
78 | DailyChange = (double)array[5],
79 | DailyChangePercent = (double)array[6],
80 | LastPrice = (double)array[7],
81 | Volume = (double)array[8],
82 | High = (double)array[9],
83 | Low = (double)array[10]
84 | };
85 | }
86 |
87 | private FundingTicker JArrayToFundingTicker(JArray array)
88 | {
89 | string symbol = (string)array[0];
90 | string symbolStripped = symbol.Substring(1);
91 |
92 | return new FundingTicker
93 | {
94 | Symbol = symbolStripped,
95 | FlashReturnRate = (double)array[1],
96 | Bid = (double)array[2],
97 | BidPeriod = (int)array[3],
98 | BidSize = (double)array[4],
99 | Ask = (double)array[5],
100 | AskPeriod = (int)array[6],
101 | AskSize = (double)array[7],
102 | DailyChange = (double)array[8],
103 | DailyChangePercent = (double)array[9],
104 | LastPrice = (double)array[10],
105 | Volume = (double)array[11],
106 | High = (double)array[12],
107 | Low = (double)array[13]
108 | };
109 | }
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/Bitfinex/Models/Common.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Newtonsoft.Json;
3 | using Newtonsoft.Json.Linq;
4 |
5 | namespace Bitfinex.Models
6 | {
7 | public enum Symbol
8 | {
9 | BTCUSD,
10 | LTCUSD,
11 | LTCBTC,
12 | ETHUSD,
13 | ETHBTC,
14 | ETCBTC,
15 | ETCUSD,
16 | RRTUSD,
17 | RRTBTC,
18 | ZECUSD,
19 | ZECBTC,
20 | XMRUSD,
21 | XMRBTC,
22 | DSHUSD,
23 | DSHBTC,
24 | BCCBTC,
25 | BCUBTC,
26 | BCCUSD,
27 | BCUUSD,
28 | XRPUSD,
29 | XRPBTC,
30 | IOTUSD,
31 | IOTBTC,
32 | IOTETH,
33 | EOSUSD,
34 | EOSBTC,
35 | EOSETH,
36 | SANUSD,
37 | SANBTC,
38 | SANETH,
39 | OMGUSD,
40 | OMGBTC,
41 | OMGETH,
42 | BCHUSD,
43 | BCHBTC,
44 | BCHETH
45 | }
46 |
47 | public class TradeSymbol
48 | {
49 | private const string Prefix = "t";
50 |
51 | private Symbol _symbol { get; }
52 |
53 | public string Value => Prefix + _symbol;
54 |
55 | public static explicit operator TradeSymbol(Symbol symbol)
56 | {
57 | return new TradeSymbol(symbol);
58 | }
59 |
60 | public TradeSymbol(Symbol symbol)
61 | {
62 | _symbol = symbol;
63 | }
64 |
65 | public override string ToString()
66 | {
67 | return Prefix + _symbol;
68 | }
69 | }
70 |
71 |
72 | public enum SortDirection
73 | {
74 | OldestToNewest = 1, NewestToOldest = -1
75 | }
76 |
77 | public class TimeFrame
78 | {
79 | public string Value { get; set; }
80 |
81 | public static TimeFrame Minute => new TimeFrame("1m");
82 | public static TimeFrame Minute5 => new TimeFrame("5m");
83 | public static TimeFrame Minute15 => new TimeFrame("15m");
84 | public static TimeFrame Minute30 => new TimeFrame("30m");
85 | public static TimeFrame Hour => new TimeFrame("1h");
86 | public static TimeFrame Hour3 => new TimeFrame("3h");
87 | public static TimeFrame Hour6 => new TimeFrame("6h");
88 | public static TimeFrame Hour12 => new TimeFrame("12h");
89 | public static TimeFrame Day => new TimeFrame("1D");
90 | public static TimeFrame Week => new TimeFrame("7D");
91 | public static TimeFrame Fortnight => new TimeFrame("14D");
92 | public static TimeFrame Month => new TimeFrame("1M");
93 |
94 | private TimeFrame(string value)
95 | {
96 | Value = value;
97 | }
98 |
99 | public override string ToString()
100 | {
101 | return Value;
102 | }
103 | }
104 |
105 | public class Section
106 | {
107 | public string Value { get; set; }
108 |
109 | public static Section Last => new Section("last");
110 | public static Section Historical => new Section("hist");
111 |
112 | private Section(string value)
113 | {
114 | Value = value;
115 | }
116 |
117 | public override string ToString()
118 | {
119 | return Value;
120 | }
121 | }
122 |
123 | public class BitfinexException : Exception
124 | {
125 | public int ErrorCode { get; set; }
126 | public string Message { get; set; }
127 | }
128 |
129 | public class ExceptionResultConverter : JsonConverter
130 | {
131 | public override bool CanConvert(Type objectType)
132 | {
133 | return objectType == typeof(BitfinexException);
134 | }
135 |
136 | public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
137 | {
138 | var array = JArray.Load(reader);
139 |
140 | if ((string)array[0] == "error")
141 | {
142 |
143 | return new BitfinexException
144 | {
145 | ErrorCode = (int)array[1],
146 | Message = (string)array[2]
147 | };
148 | }
149 |
150 | return null;
151 | }
152 |
153 | public override bool CanWrite => false;
154 |
155 | public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
156 | {
157 | throw new NotImplementedException();
158 | }
159 | }
160 | }
161 |
--------------------------------------------------------------------------------
/Bitfinex/StatsClient.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Threading.Tasks;
4 | using Bitfinex.JsonConverters;
5 | using Bitfinex.Models;
6 | using RestSharp;
7 |
8 | namespace Bitfinex
9 | {
10 | // All our Stats methods.
11 |
12 | public partial class BitfinexRestClient
13 | {
14 | ///
15 | /// Get statistics about the requested pair.
16 | ///
17 | /// Allowed values: "funding.size", "credits.size", "credits.size.sym", "pos.size"
18 | /// The symbol you want information about.
19 | /// Available values: "long", "short"
20 | /// Available values: "last", "hist"
21 | /// List of MTS and Value stats for the requested pair
22 | public List GetStats(Key key, Symbol symbol, Side side, Section section)
23 | {
24 | return getStatsAsync(key, symbol, side, section).Result;
25 | }
26 |
27 | ///
28 | /// Get statistics about the requested pair.
29 | ///
30 | /// Allowed values: "funding.size", "credits.size", "credits.size.sym", "pos.size"
31 | /// The symbol you want information about.
32 | /// Available values: "long", "short"
33 | /// Available values: "last", "hist"
34 | /// Default new > old
35 | /// List of MTS and Value stats for the requested pair
36 | public List GetStats(Key key, Symbol symbol, Side side, Section section, SortDirection sortDirection)
37 | {
38 | return getStatsAsync(key, symbol, side, section, sortDirection).Result;
39 | }
40 |
41 | ///
42 | /// Get statistics about the requested pair.
43 | ///
44 | /// Allowed values: "funding.size", "credits.size", "credits.size.sym", "pos.size"
45 | /// The symbol you want information about.
46 | /// Available values: "long", "short"
47 | /// Available values: "last", "hist"
48 | /// List of MTS and Value stats for the requested pair
49 | public async Task> GetStatsAsync(Key key, Symbol symbol, Side side, Section section)
50 | {
51 | return await getStatsAsync(key, symbol, side, section);
52 | }
53 |
54 | ///
55 | /// Get statistics about the requested pair.
56 | ///
57 | /// Allowed values: "funding.size", "credits.size", "credits.size.sym", "pos.size"
58 | /// The symbol you want information about.
59 | /// Available values: "long", "short"
60 | /// Available values: "last", "hist"
61 | /// Default new > old
62 | /// List of MTS and Value stats for the requested pair
63 | public async Task> GetStatsAsync(Key key, Symbol symbol, Side side, Section section, SortDirection sortDirection)
64 | {
65 | return await getStatsAsync(key, symbol, side, section, sortDirection);
66 | }
67 |
68 | private async Task> getStatsAsync(Key key, Symbol symbol, Side side, Section section, SortDirection? sortDirection = null)
69 | {
70 | var size = TimeFrame.Minute;
71 |
72 | var url = $"stats1/{key}:{size}:{(TradeSymbol)symbol}:{side}/{section}";
73 | if (sortDirection != null) url = url + "?sort=" + (int)sortDirection;
74 |
75 | var request = new RestRequest(url, Method.GET);
76 |
77 | var response = await GetResponseAsync(request, CancellationToken);
78 |
79 | // We could have recieved a single stat.
80 | try
81 | {
82 | var stat = (Stat)DeserializeObject(response.Content, new StatResultConverter());
83 | if (stat != null) return new List() { stat };
84 | }
85 | catch (Exception)
86 | {
87 | // ignored
88 | }
89 |
90 | return (List)DeserializeObject>(response.Content, new StatsResultConverter());
91 | }
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/Bitfinex/Models/Tickers.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Bitfinex.Models
4 | {
5 | public interface ITicker
6 | {
7 | ///
8 | /// Flash Return Rate - average of all fixed rate funding over the last hour
9 | ///
10 | double FlashReturnRate { get; set; }
11 |
12 | ///
13 | /// Bid period covered in days
14 | ///
15 | int BidPeriod { get; set; }
16 |
17 | ///
18 | /// Ask period covered in days
19 | ///
20 | int AskPeriod { get; set; }
21 |
22 | string Symbol { get; set; }
23 |
24 | ///
25 | /// Price of last highest bid
26 | ///
27 | double Bid { get; set; }
28 |
29 | ///
30 | /// Size of the last highest bid
31 | ///
32 | double BidSize { get; set; }
33 |
34 | ///
35 | /// Price of last lowest ask
36 | ///
37 | double Ask { get; set; }
38 |
39 | ///
40 | /// Size of the last lowest ask
41 | ///
42 | double AskSize { get; set; }
43 |
44 | ///
45 | /// Amount that the last price has changed since yesterday
46 | ///
47 | double DailyChange { get; set; }
48 |
49 | ///
50 | /// Amount that the price has changed expressed in percentage terms
51 | ///
52 | double DailyChangePercent { get; set; }
53 |
54 | ///
55 | /// Price of the last trade
56 | ///
57 | double LastPrice { get; set; }
58 |
59 | ///
60 | /// Daily volume
61 | ///
62 | double Volume { get; set; }
63 |
64 |
65 | ///
66 | /// Daily high
67 | ///
68 | double High { get; set; }
69 |
70 | ///
71 | /// Daily low
72 | ///
73 | double Low { get; set; }
74 | }
75 |
76 | public class TradingTicker : Ticker, ITicker
77 | {
78 | [Obsolete]
79 | public double FlashReturnRate { get; set; }
80 |
81 | [Obsolete]
82 | public int BidPeriod { get; set; }
83 |
84 | [Obsolete]
85 | public int AskPeriod { get; set; }
86 | }
87 |
88 | public class FundingTicker : Ticker, ITicker
89 | {
90 | ///
91 | /// Flash Return Rate - average of all fixed rate funding over the last hour
92 | ///
93 | public double FlashReturnRate { get; set; }
94 |
95 | ///
96 | /// Bid period covered in days
97 | ///
98 | public int BidPeriod { get; set; }
99 |
100 | ///
101 | /// Ask period covered in days
102 | ///
103 | public int AskPeriod { get; set; }
104 | }
105 |
106 | public class Ticker
107 | {
108 | public string Symbol { get; set; }
109 |
110 | ///
111 | /// Price of last highest bid
112 | ///
113 | public double Bid { get; set; }
114 |
115 | ///
116 | /// Size of the last highest bid
117 | ///
118 | public double BidSize { get; set; }
119 |
120 | ///
121 | /// Price of last lowest ask
122 | ///
123 | public double Ask { get; set; }
124 |
125 | ///
126 | /// Size of the last lowest ask
127 | ///
128 | public double AskSize { get; set; }
129 |
130 | ///
131 | /// Amount that the last price has changed since yesterday
132 | ///
133 | public double DailyChange { get; set; }
134 |
135 | ///
136 | /// Amount that the price has changed expressed in percentage terms
137 | ///
138 | public double DailyChangePercent { get; set; }
139 |
140 | ///
141 | /// Price of the last trade
142 | ///
143 | public double LastPrice { get; set; }
144 |
145 | ///
146 | /// Daily volume
147 | ///
148 | public double Volume { get; set; }
149 |
150 | ///
151 | /// Daily high
152 | ///
153 | public double High { get; set; }
154 |
155 | ///
156 | /// Daily low
157 | ///
158 | public double Low { get; set; }
159 | }
160 | }
161 |
--------------------------------------------------------------------------------
/Bitfinex.Tests/Bitfinex.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {7839F97D-69D4-4125-B543-223B0D307222}
8 | Library
9 | Properties
10 | Bitfinex.Tests
11 | Bitfinex.Tests
12 | v4.5.2
13 | 512
14 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
15 | 15.0
16 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
17 | $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages
18 | False
19 | UnitTest
20 |
21 |
22 |
23 |
24 | true
25 | full
26 | false
27 | bin\Debug\
28 | DEBUG;TRACE
29 | prompt
30 | 4
31 |
32 |
33 | pdbonly
34 | true
35 | bin\Release\
36 | TRACE
37 | prompt
38 | 4
39 |
40 |
41 |
42 | ..\packages\MSTest.TestFramework.1.1.18\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll
43 |
44 |
45 | ..\packages\MSTest.TestFramework.1.1.18\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll
46 |
47 |
48 | ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 | {9a3385ac-7e13-4b18-9831-99e487744b97}
64 | Bitfinex
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
75 |
76 |
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/Bitfinex.Tests/Models/StatsTests.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Bitfinex.JsonConverters;
3 | using Bitfinex.Models;
4 | using Microsoft.VisualStudio.TestTools.UnitTesting;
5 | using Newtonsoft.Json;
6 |
7 | namespace Bitfinex.Tests.Models
8 | {
9 | [TestClass]
10 | public class StatsTests
11 | {
12 | [TestMethod]
13 | public void StatsDeserializeTest1()
14 | {
15 | //GET: https://api.bitfinex.com/v2/stats1/pos.size:1m:tBTCUSD:long/hist
16 | string json = "[ [ 1500093840000, 15231.85983157 ], [ 1500093780000, 15222.20717334 ], [ 1500093720000, 15232.36907505 ], [ 1500093660000, 15228.48695498 ], [ 1500093600000, 15229.10184868 ], [ 1500093540000, 15222.826221 ], [ 1500093480000, 15219.26732882 ], [ 1500093420000, 15224.30928207 ], [ 1500093360000, 15230.89866354 ], [ 1500093300000, 15220.86558719 ], [ 1500093240000, 15226.95297291 ], [ 1500093180000, 15225.29479749 ], [ 1500093120000, 15241.31420914 ], [ 1500093060000, 15293.55050882 ], [ 1500093000000, 15293.60275019 ], [ 1500092940000, 15290.91730215 ], [ 1500092880000, 15289.19255742 ], [ 1500092820000, 15295.95908076 ], [ 1500092760000, 15296.97433591 ], [ 1500092700000, 15311.40258141 ], [ 1500092640000, 15313.66587808 ], [ 1500092580000, 15318.39892697 ], [ 1500092520000, 15320.59299776 ], [ 1500092460000, 15325.2897859 ], [ 1500092400000, 15398.21133439 ], [ 1500092340000, 15400.24352068 ], [ 1500092280000, 15403.7085432 ], [ 1500092220000, 15411.30088097 ], [ 1500092160000, 15416.12045021 ], [ 1500092100000, 15413.86114722 ], [ 1500092040000, 15399.15144811 ], [ 1500091980000, 15422.14545073 ], [ 1500091920000, 15424.60621835 ], [ 1500091860000, 15425.89809248 ], [ 1500091800000, 15416.92356844 ], [ 1500091740000, 15394.64693962 ], [ 1500091680000, 15408.01395342 ], [ 1500091620000, 15408.42273459 ], [ 1500091560000, 15431.66084099 ], [ 1500091500000, 15440.32333756 ], [ 1500091440000, 15438.89097298 ], [ 1500091380000, 15428.85219372 ], [ 1500091320000, 15429.10151933 ], [ 1500091260000, 15439.93907027 ], [ 1500091200000, 15432.4930594 ], [ 1500091140000, 15405.65069239 ], [ 1500091080000, 15373.78321039 ], [ 1500091020000, 15318.22377754 ], [ 1500090960000, 15269.37540778 ], [ 1500090900000, 15299.09734332 ], [ 1500090840000, 15333.89672277 ], [ 1500090780000, 15357.80946038 ], [ 1500090720000, 15353.04964833 ], [ 1500090660000, 15353.28792585 ], [ 1500090600000, 15352.22412785 ], [ 1500090540000, 15352.06143252 ], [ 1500090480000, 15336.62951844 ], [ 1500090420000, 15333.25901925 ], [ 1500090360000, 15320.13558957 ], [ 1500090300000, 15320.73408149 ], [ 1500090240000, 15311.54725422 ], [ 1500090180000, 15306.25371221 ], [ 1500090120000, 15306.3637642 ], [ 1500090060000, 15270.90919689 ], [ 1500090000000, 15233.06690044 ], [ 1500089940000, 15218.81492598 ], [ 1500089880000, 15217.33416351 ], [ 1500089820000, 15214.19321812 ], [ 1500089760000, 15211.33440694 ], [ 1500089700000, 15275.17695305 ], [ 1500089640000, 15269.80908519 ], [ 1500089580000, 15316.08834545 ], [ 1500089520000, 15329.31148792 ], [ 1500089460000, 15338.80853724 ], [ 1500089400000, 15350.79856656 ], [ 1500089340000, 15357.38565195 ], [ 1500089280000, 15480.48521171 ], [ 1500089220000, 15479.23740771 ], [ 1500089160000, 15479.03740771 ], [ 1500089100000, 15480.36830215 ], [ 1500089040000, 15480.15977308 ], [ 1500088980000, 15471.1140165 ], [ 1500088920000, 15470.28860656 ], [ 1500088860000, 15467.86359383 ], [ 1500088800000, 15473.44259383 ], [ 1500088740000, 15473.44259383 ], [ 1500088680000, 15473.37657767 ], [ 1500088620000, 15464.62341721 ], [ 1500088560000, 15439.77642582 ], [ 1500088500000, 15436.91659359 ], [ 1500088440000, 15435.21215708 ], [ 1500088380000, 15439.85816968 ], [ 1500088320000, 15440.00508375 ], [ 1500088260000, 15440.01328803 ], [ 1500088200000, 15477.66892043 ], [ 1500088140000, 15473.41498496 ], [ 1500088080000, 15471.93962585 ], [ 1500088020000, 15476.27890248 ], [ 1500087960000, 15468.04539202 ], [ 1500087900000, 15467.27761746 ], [ 1500087840000, 15476.67295242 ], [ 1500087780000, 15464.59910546 ], [ 1500087720000, 15468.88825221 ], [ 1500087660000, 15463.95204925 ], [ 1500087600000, 15481.00653205 ], [ 1500087540000, 15482.93320915 ], [ 1500087480000, 15481.39998574 ], [ 1500087420000, 15481.01823029 ], [ 1500087360000, 15459.57938083 ], [ 1500087300000, 15448.05521381 ], [ 1500087240000, 15435.04350378 ], [ 1500087180000, 15427.45971061 ], [ 1500087120000, 15494.45581034 ], [ 1500087060000, 15506.46048953 ], [ 1500087000000, 15510.59625666 ], [ 1500086940000, 15527.59412255 ], [ 1500086880000, 15529.46401016 ], [ 1500086820000, 15524.67755702 ], [ 1500086760000, 15517.59401016 ], [ 1500086700000, 15519.3946787 ] ]";
17 |
18 | var stats = JsonConvert.DeserializeObject>(json, new StatsResultConverter());
19 |
20 | Assert.AreEqual(120, stats.Count);
21 |
22 | var stat = stats[0];
23 |
24 | Assert.AreEqual(1500093840000, stat.MTS);
25 | Assert.AreEqual(15231.85983157, stat.Value);
26 | }
27 |
28 | [TestMethod]
29 | public void StatsDeserializeTest2()
30 | {
31 | //GET: https://api.bitfinex.com/v2/stats1/pos.size:1m:tBTCUSD:long/last
32 | string json = "[ 1500093780000, 15222.20717334 ]";
33 |
34 | var stat = JsonConvert.DeserializeObject(json, new StatResultConverter());
35 |
36 | Assert.AreEqual(1500093780000, stat.MTS);
37 | Assert.AreEqual(15222.20717334, stat.Value);
38 | }
39 |
40 | [TestMethod]
41 | public void StatsClientSectionLastTest()
42 | {
43 | var client = new BitfinexRestClient();
44 | var stats = client.GetStats(Key.TotalOpenPosition, Symbol.BTCUSD, Side.Long, Section.Last, SortDirection.OldestToNewest);
45 |
46 | Assert.AreEqual(1, stats.Count);
47 | }
48 |
49 | [TestMethod]
50 | public void StatsClientSectionHistoricalTest()
51 | {
52 | var client = new BitfinexRestClient();
53 | var stats = client.GetStats(Key.TotalOpenPosition, Symbol.BTCUSD, Side.Long, Section.Historical, SortDirection.OldestToNewest);
54 |
55 | Assert.IsTrue(stats.Count > 1);
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/Bitfinex/TradesClient.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading.Tasks;
3 | using Bitfinex.JsonConverters;
4 | using Bitfinex.Models;
5 | using RestSharp;
6 | using static System.String;
7 | using System;
8 |
9 | namespace Bitfinex
10 | {
11 | // All our Trade methods.
12 |
13 | public partial class BitfinexRestClient
14 | {
15 | ///
16 | /// Get pertinent details of trades, such as price, size and time.
17 | ///
18 | /// The symbol you want information about.
19 | /// List of trades
20 | public List GetTrades(string symbol)
21 | {
22 | return getTradesAsync(symbol).Result;
23 | }
24 |
25 | ///
26 | /// Get pertinent details of trades, such as price, size and time.
27 | ///
28 | /// The symbol you want information about.
29 | /// Number of records
30 | /// List of trades
31 | public List GetTrades(string symbol, int limit)
32 | {
33 | return getTradesAsync(symbol, limit).Result;
34 | }
35 |
36 | ///
37 | /// Get pertinent details of trades, such as price, size and time.
38 | ///
39 | /// The symbol you want information about.
40 | /// Number of records
41 | /// Millisecond start time
42 | /// List of trades
43 | public List GetTrades(string symbol, int limit, long start)
44 | {
45 | return getTradesAsync(symbol, limit, start).Result;
46 | }
47 |
48 | ///
49 | /// Get pertinent details of trades, such as price, size and time.
50 | ///
51 | /// The symbol you want information about.
52 | /// Number of records
53 | /// Millisecond start time
54 | /// Millisecond end time
55 | /// List of trades
56 | public List GetTrades(string symbol, int limit, long start, long end)
57 | {
58 | return getTradesAsync(symbol, limit, start, end).Result;
59 | }
60 |
61 | ///
62 | /// Get pertinent details of trades, such as price, size and time.
63 | ///
64 | /// The symbol you want information about.
65 | /// Number of records
66 | /// Millisecond start time
67 | /// Millisecond end time
68 | ///
69 | /// List of trades
70 | public List GetTrades(string symbol, int limit, long start, long end, SortDirection sortDirection)
71 | {
72 | return getTradesAsync(symbol, limit, start, end, sortDirection).Result;
73 | }
74 |
75 | ///
76 | /// Get pertinent details of trades, such as price, size and time.
77 | ///
78 | /// The symbol you want information about.
79 | /// List of trades
80 | public async Task> GetTradesAsync(string symbol)
81 | {
82 | return await getTradesAsync(symbol);
83 | }
84 |
85 | ///
86 | /// Get pertinent details of trades, such as price, size and time.
87 | ///
88 | /// The symbol you want information about.
89 | /// Number of records (default 120)
90 | /// List of trades
91 | public async Task> GetTradesAsync(string symbol, int limit)
92 | {
93 | return await getTradesAsync(symbol, limit);
94 | }
95 |
96 | ///
97 | /// Get pertinent details of trades, such as price, size and time.
98 | ///
99 | /// The symbol you want information about.
100 | /// Number of records (default 120)
101 | /// Millisecond start time (default 0)
102 | /// List of trades
103 | public async Task> GetTradesAsync(string symbol, int limit, long start)
104 | {
105 | return await getTradesAsync(symbol, limit, start);
106 | }
107 |
108 | ///
109 | /// Get pertinent details of trades, such as price, size and time.
110 | ///
111 | /// The symbol you want information about.
112 | /// Number of records (default 120)
113 | /// Millisecond start time (default 0)
114 | /// Millisecond end time (default 0)
115 | /// List of trades
116 | public async Task> GetTradesAsync(string symbol, int limit, long start, long end)
117 | {
118 | return await getTradesAsync(symbol, limit, start, end);
119 | }
120 |
121 | ///
122 | /// Get pertinent details of trades, such as price, size and time.
123 | ///
124 | /// The symbol you want information about.
125 | /// Number of records (default 120)
126 | /// Millisecond start time (default 0)
127 | /// Millisecond end time (default 0)
128 | /// Default new > old
129 | /// List of trades
130 | public async Task> GetTradesAsync(string symbol, int limit, long start, long end, SortDirection sortDirection)
131 | {
132 | return await getTradesAsync(symbol, limit, start, end, sortDirection);
133 | }
134 |
135 | private async Task> getTradesAsync(string symbol, int? limit = null, long? start = null, long? end = null, SortDirection? sortDirection = null)
136 | {
137 | var parameters = new List();
138 | if (limit.GetValueOrDefault() != 0) parameters.Add("limit=" + limit);
139 | if (start.GetValueOrDefault() != 0) parameters.Add("start=" + start);
140 | if (end.GetValueOrDefault() != 0) parameters.Add("end=" + end);
141 | if (sortDirection != null) parameters.Add("sort=" + (int)sortDirection);
142 |
143 | string url = $"trades/{symbol}/hist";
144 | if (parameters.Count > 0) url = url + "?" + Join("&", parameters.ToArray());
145 |
146 | var request = new RestRequest(url, Method.GET);
147 |
148 | var response = await GetResponseAsync(request, CancellationToken);
149 |
150 | return (List)DeserializeObject>(response.Content, new TradesResultConverter());
151 | }
152 |
153 | }
154 | }
155 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
10 |
11 | "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
12 |
13 | "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
14 |
15 | "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
16 |
17 | "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
18 |
19 | "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
20 |
21 | "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
22 |
23 | "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
24 |
25 | "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
26 |
27 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
28 |
29 | 2. Grant of Copyright License.
30 |
31 | Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
32 |
33 | 3. Grant of Patent License.
34 |
35 | Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
36 |
37 | 4. Redistribution.
38 |
39 | You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
40 |
41 | You must give any other recipients of the Work or Derivative Works a copy of this License; and
42 | You must cause any modified files to carry prominent notices stating that You changed the files; and
43 | You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
44 | If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
45 | You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
46 |
47 | 5. Submission of Contributions.
48 |
49 | Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
50 |
51 | 6. Trademarks.
52 |
53 | This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
54 |
55 | 7. Disclaimer of Warranty.
56 |
57 | Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
58 |
59 | 8. Limitation of Liability.
60 |
61 | In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
62 |
63 | 9. Accepting Warranty or Additional Liability.
64 |
65 | While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
66 |
67 | END OF TERMS AND CONDITIONS
--------------------------------------------------------------------------------
/Bitfinex.Tests/Models/BooksTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Bitfinex.JsonConverters;
4 | using Bitfinex.Models;
5 | using Microsoft.VisualStudio.TestTools.UnitTesting;
6 | using Newtonsoft.Json;
7 |
8 | namespace Bitfinex.Tests.Models
9 | {
10 | [TestClass]
11 | public class BooksTests
12 | {
13 | [TestMethod]
14 | public void BooksDeserializeTest1()
15 | {
16 | //GET: https://api.bitfinex.com/v2/book/fUSD/P0?len=5
17 | string json = "[ [ 8819908, 1499993669662, -42.48113687, 0.00026573, 2 ], [ 8819907, 1499993669637, -93.08533495, 0.00026571, 2 ], [ 8819906, 1499993669606, -80.23924126, 0.0002657, 2 ], [ 8819905, 1499993669580, -80.23924126, 0.0002657, 2 ], [ 8819904, 1499993669555, -90.44483913, 0.0002657, 2 ], [ 8819903, 1499993669508, -53.77420134, 0.0002657, 2 ], [ 8819902, 1499993669472, -53.77420134, 0.0002657, 2 ], [ 8819901, 1499993669408, -53.77420134, 0.0002657, 2 ], [ 8819900, 1499993669374, -2.6136619, 0.0002657, 2 ], [ 8819895, 1499993667107, -51.16053944, 0.0002657, 2 ], [ 8819894, 1499993667086, -53.77420134, 0.0002657, 2 ], [ 8819893, 1499993667057, -53.77420134, 0.0002657, 2 ], [ 8819892, 1499993667031, -2474.20793604, 0.0002657, 2 ], [ 8819891, 1499993667006, -53.77420134, 0.00026563, 2 ], [ 8819890, 1499993666980, -53.77420134, 0.00026563, 2 ], [ 8819889, 1499993666960, -53.77420134, 0.00026563, 2 ], [ 8819888, 1499993666933, -53.77420134, 0.00026563, 2 ], [ 8819887, 1499993666907, -53.77420134, 0.00026563, 2 ], [ 8819886, 1499993666887, -53.77420134, 0.00026563, 2 ], [ 8819885, 1499993666863, -53.77420134, 0.00026563, 2 ], [ 8819884, 1499993666843, -646.52363859, 0.00026563, 2 ], [ 8819883, 1499993666818, -4948.41587208, 0.00026563, 2 ], [ 8819882, 1499993666767, -87.03953651, 0.00026563, 2 ], [ 8819881, 1499993666727, -80.23924126, 0.00026562, 2 ], [ 8819880, 1499993666691, -80.23924126, 0.00026562, 2 ], [ 8819879, 1499993666658, -90.44483913, 0.00026562, 2 ], [ 8819878, 1499993666630, -53.77420134, 0.0002656, 2 ], [ 8819877, 1499993666605, -53.77420134, 0.0002656, 2 ], [ 8819876, 1499993666573, -80.23924126, 0.00026494, 2 ], [ 8819875, 1499993666536, -80.23924126, 0.00026494, 2 ], [ 8819874, 1499993666505, -4083.5268, 0.00026494, 2 ], [ 8819873, 1499993666478, -50, 0.0002649, 2 ], [ 8819872, 1499993666447, -1768.6234, 0.0002648, 2 ], [ 8819871, 1499993666416, -98.37, 0.0002648, 3 ], [ 8819870, 1499993666371, -169.69, 0.0002648, 3 ], [ 8819869, 1499993666311, -80.23924126, 0.0002647, 2 ], [ 8819868, 1499993666288, -90.44483913, 0.0002647, 2 ], [ 8819867, 1499993666256, -2474.20793604, 0.0002647, 2 ], [ 8819866, 1499993666222, -5081.18275562, 0.00026468, 2 ], [ 8819865, 1499993666200, -11078.18090284, 0.00026468, 2 ], [ 8819864, 1499993666152, -900.84877392, 0.00026368, 2 ], [ 8819839, 1499993661552, -24.08470096, 0.00026368, 2 ], [ 8819838, 1499993661481, -73.62422513, 0.00026368, 2 ], [ 8819832, 1499993655549, -20561.66978856, 0.00026468, 2 ], [ 8819831, 1499993654708, -14.1942157, 0.00026468, 2 ], [ 8819829, 1499993654659, -2.45249997, 0.00022719, 2 ], [ 8819827, 1499993653789, -47.54750003, 0.00022719, 2 ], [ 8819826, 1499993653730, -0.215336, 0.00026468, 2 ], [ 8819825, 1499993653665, -6163.58260527, 0.00026468, 2 ], [ 8819824, 1499993653601, -1962.84, 0.00026467, 2 ], [ 8819823, 1499993653567, -1326.7468018, 0.00026465, 2 ], [ 8819822, 1499993653459, -56.90229132, 0.00026387, 2 ], [ 8819821, 1499993653411, -237.783, 0.00026387, 2 ], [ 8819820, 1499993653372, -111.95655804, 0.00026368, 2 ], [ 8819819, 1499993653337, -80.23924126, 0.0002617, 2 ], [ 8819818, 1499993653277, -596.14230575, 0.0002617, 2 ], [ 8819817, 1499993653250, -80.23924126, 0.00023966, 2 ], [ 8819815, 1499993653196, -80.23924126, 0.00023966, 2 ], [ 8819814, 1499993653159, -80.23924126, 0.00023966, 2 ], [ 8819813, 1499993653100, -80.23924126, 0.00023966, 2 ], [ 8819812, 1499993653074, -80.23924126, 0.00023966, 2 ], [ 8819811, 1499993652976, -80.23924126, 0.00023966, 2 ], [ 8819810, 1499993652937, -451, 0.000236, 2 ], [ 8819809, 1499993652914, -56.90229132, 0.0002296, 2 ], [ 8819808, 1499993652888, -56.24275274, 0.0002296, 2 ], [ 8819807, 1499993652857, -56.24275274, 0.0002296, 2 ], [ 8819806, 1499993652812, -90.44483913, 0.00022749, 2 ], [ 8819805, 1499993652734, -1882.80746053, 0.00022749, 2 ], [ 8819804, 1499993652652, -85.14923868, 0.0002274, 2 ], [ 8819803, 1499993652628, -1408.82154882, 0.0002273, 2 ], [ 8819802, 1499993652569, -1408.82154882, 0.0002273, 2 ], [ 8819801, 1499993652510, -599.4112884, 0.0002273, 2 ], [ 8819799, 1499993652458, -599.4112884, 0.0002273, 2 ], [ 8819798, 1499993652356, -90.44483913, 0.0002273, 2 ], [ 8819797, 1499993652294, -4287.06443826, 0.0002273, 2 ], [ 8819796, 1499993651901, -779.58632982, 0.0002273, 2 ], [ 8819775, 1499993648738, -86.4999999, 0.0002273, 2 ], [ 8819773, 1499993647636, -215.50975942, 0.0002273, 2 ], [ 8819772, 1499993646194, -29.67599058, 0.0002273, 2 ], [ 8819765, 1499993643036, -54.1290761, 0.0002273, 2 ], [ 8819759, 1499993639396, -1.66913336, 0.0002273, 2 ], [ 8819756, 1499993638220, -179.39355176, 0.0002273, 2 ], [ 8819755, 1499993638152, -50, 0.0002273, 2 ], [ 8819754, 1499993638118, -50, 0.0002273, 2 ], [ 8819753, 1499993638081, -68.79399651, 0.0002273, 2 ], [ 8819752, 1499993635466, -190.02840302, 0.0002273, 2 ], [ 8819751, 1499993633585, -0.19886031, 0.0002273, 2 ], [ 8819750, 1499993632156, -44.3313754, 0.0002273, 2 ], [ 8819748, 1499993628217, -15.38736476, 0.0002273, 2 ], [ 8819747, 1499993628140, -65.45692284, 0.0002271, 2 ], [ 8819746, 1499993628040, -57.25490182, 0.0002271, 2 ], [ 8819745, 1499993625767, -25.019, 0.0002271, 2 ], [ 8819744, 1499993624420, -4.75883443, 0.0002271, 2 ], [ 8819743, 1499993622485, -753.56998339, 0.0002271, 2 ], [ 8819742, 1499993621593, -568.21882918, 0.0002271, 2 ], [ 8819741, 1499993621541, -599.4112884, 0.0002271, 2 ], [ 8819740, 1499993621484, -110.97509029, 0.0002271, 2 ], [ 8819739, 1499993621416, -50, 0.00022492, 2 ], [ 8819738, 1499993621357, -50, 0.00022481, 2 ], [ 8819737, 1499993621272, -602.16479213, 0.00022465, 2 ], [ 8819736, 1499993621192, -5.3639181, 0.00022465, 2 ], [ 8819732, 1499993584813, -50, 0.00022465, 2 ], [ 8819731, 1499993353283, -19, 0.0002659, 2 ], [ 8819729, 1499993352687, -967.61447872, 0.0002659, 2 ], [ 8819727, 1499993352105, -1167.98962257, 0.0002659, 2 ], [ 8819725, 1499993351249, -16023.36348933, 0.0002659, 2 ], [ 8819724, 1499993351230, -2098.64941318, 0.0002659, 2 ], [ 8819719, 1499993347667, -71.1836148, 0.0002659, 2 ], [ 8819718, 1499993347647, -135.7293452, 0.0002658, 2 ], [ 8819717, 1499993347624, -509.22367437, 0.0002658, 2 ], [ 8819712, 1499993346579, -52.37534993, 0.0002658, 2 ], [ 8819708, 1499993343496, -0.65331699, 0.0002658, 2 ], [ 8819707, 1499993343468, -2530.78440774, 0.0002658, 2 ], [ 8819706, 1499993343446, -1263.84, 0.0002658, 2 ], [ 8819705, 1499993343424, -120.35886189, 0.000265, 2 ], [ 8819704, 1499993343403, -120.35886189, 0.000265, 2 ], [ 8819703, 1499993343380, -120.35886189, 0.000265, 2 ], [ 8819702, 1499993343358, -147.42764988, 0.000265, 2 ], [ 8819701, 1499993342997, -1.30474549, 0.000265, 2 ], [ 8819697, 1499993341704, -7127.22537711, 0.000265, 2 ]]";
18 |
19 | // TO-DO: Broken endpoint?
20 |
21 | }
22 |
23 | [TestMethod]
24 | public void BooksDeserializeTest2()
25 | {
26 | //GET: https://api.bitfinex.com/v2/book/tBTCUSD/P0?len=5
27 | string json = "[ [ 2317.9,2,3.54219284 ],[ 2317.1,1,0.9589 ],[ 2317,1,2.965041 ],[ 2315.2,1,7.64043703 ],[ 2315,2,24.62799232 ],[ 2318,4,-4.18890282 ],[ 2318.6,1,-1.8 ],[ 2318.9,1,-1.0761 ],[ 2319,2,-14 ],[ 2319.4,1,-2.79672805 ] ]";
28 |
29 | var books = JsonConvert.DeserializeObject>(json, new BooksResultConverter());
30 |
31 | Assert.AreEqual(10, books.Count);
32 |
33 | var book = books[0];
34 |
35 | Assert.AreEqual(3.54219284, book.Amount);
36 | Assert.AreEqual(2, book.Count);
37 | Assert.AreEqual(2317.9, book.Price);
38 | }
39 |
40 | [TestMethod]
41 | public void BooksClientTest()
42 | {
43 | var client = new BitfinexRestClient();
44 | var books = client.GetBooks("tBTCUSD", Precision.P0, 5);
45 |
46 | Assert.AreEqual(10, books.Count);
47 | }
48 |
49 | [TestMethod]
50 | public void BooksClientWrongSymbolTest()
51 | {
52 | try
53 | {
54 | var client = new BitfinexRestClient();
55 | client.GetBooks("fUSD", Precision.P0, 5);
56 | }
57 | catch (Exception ex)
58 | {
59 | if (ex.InnerException != null) Assert.AreEqual(ex.InnerException.Message, "(10020) symbol: invalid");
60 | }
61 | }
62 |
63 | [TestMethod]
64 | public void BooksClientIncorrectEndpointTest()
65 | {
66 | try
67 | {
68 | var client = new BitfinexRestClient { BaseUrl = "https://api.bitfinexf.com/v2" };
69 |
70 | client.GetBooks("fUSD", Precision.P0, 5);
71 | }
72 | catch (Exception ex)
73 | {
74 | if (ex.InnerException != null)
75 | Assert.AreEqual(ex.InnerException.Message,
76 | "The remote name could not be resolved: 'api.bitfinexf.com'");
77 | }
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/Bitfinex.Tests/Models/CandlesTests.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Bitfinex.JsonConverters;
3 | using Bitfinex.Models;
4 | using Microsoft.VisualStudio.TestTools.UnitTesting;
5 | using Newtonsoft.Json;
6 |
7 | namespace Bitfinex.Tests.Models
8 | {
9 | [TestClass]
10 | public class CandlesTests
11 | {
12 | [TestMethod]
13 | public void CandlesDeserializeTest1()
14 | {
15 | //GET: https://api.bitfinex.com/v2/candles/trade:1m:tBTCUSD/hist
16 | string json = "[ [ 1500162180000, 1995.7, 1987.2, 1995.7, 1987.2, 22.97632724 ], [ 1500162120000, 1995, 1995.7, 1997, 1994.5, 17.4851571 ], [ 1500162060000, 1999.7, 1996.86868653, 1999.7, 1995, 34.40969878 ], [ 1500162000000, 1997.9, 1999.6, 2000.4, 1997.8, 6.03225561 ], [ 1500161940000, 1996.4, 1998, 1998, 1996.2, 3.79828954 ], [ 1500161880000, 1995.6, 1995.9, 1997.8964698, 1995.4, 25.90021105 ], [ 1500161820000, 1983.6, 1994.6, 1995.72670513, 1983.6, 50.64021199 ], [ 1500161760000, 1982.8, 1983.5, 1984.9, 1980, 70.17040888 ], [ 1500161700000, 1981.5, 1981.5, 1986.3, 1980, 122.59006551 ], [ 1500161640000, 1989.9, 1981.5, 1990, 1979.1, 124.62594331 ], [ 1500161580000, 2002, 1989.9, 2002, 1985.2, 467.48905936 ], [ 1500161520000, 2005.7, 2001.9, 2006, 2001.9, 4.89232837 ], [ 1500161460000, 2007, 2005.9, 2007.6, 2005.9, 12.27400103 ], [ 1500161400000, 2011, 2007, 2011.1, 2007, 3.67709528 ], [ 1500161340000, 2016.8, 2011, 2016.8, 2011, 20.01826389 ], [ 1500161280000, 2016.8, 2016.8, 2016.9, 2016.8, 5.97632501 ], [ 1500161220000, 2020, 2017, 2020, 2016.5, 3.63460356 ], [ 1500161160000, 2019.5, 2016.62496486, 2020.4, 2016.05397415, 11.93354221 ], [ 1500161100000, 2016.1, 2019.4, 2020.9, 2016.1, 9.30303567 ], [ 1500161040000, 2018, 2019.2, 2019.5, 2015.02619089, 4.079675 ], [ 1500160980000, 2020.05090907, 2015.59718159, 2020.62189978, 2015.59718159, 17.7406763 ], [ 1500160920000, 2020.7, 2020.05090907, 2023.1, 2020, 37.96354923 ], [ 1500160860000, 2026.7, 2020.7, 2026.7, 2020.7, 17.33498322 ], [ 1500160800000, 2027.9, 2028, 2029.1, 2026, 35.88429581 ], [ 1500160740000, 2032.8, 2030, 2032.8, 2029.2, 5.13418676 ], [ 1500160680000, 2034.9, 2030.4, 2034.9, 2030.2, 6.09735201 ], [ 1500160620000, 2034.9, 2034.8, 2035, 2034.8, 2.79991912 ], [ 1500160560000, 2033.8, 2034.8, 2036, 2033.7, 29.46490015 ], [ 1500160500000, 2036.9, 2036.1, 2036.9, 2036.1, 3.8529104 ], [ 1500160440000, 2037.6, 2041.2, 2041.2, 2037.6, 1.70119642 ], [ 1500160380000, 2039.9, 2039.4, 2044.6, 2039.3, 3.1983107 ], [ 1500160320000, 2042.6, 2043.3, 2043.5, 2038.5, 10.08400001 ], [ 1500160260000, 2035.8, 2037.1, 2042.66214091, 2033.2, 6.70065163 ], [ 1500160200000, 2035.8, 2032.5, 2036, 2032.5, 9.87 ], [ 1500160140000, 2039.8, 2036.2, 2039.8, 2035.8, 8.48168178 ], [ 1500160080000, 2038.6, 2039.8, 2039.8, 2038.5, 2.97000969 ], [ 1500160020000, 2042.4, 2038.6, 2045.8, 2037.6, 0.27645094 ], [ 1500159960000, 2046.4, 2042.1, 2046.4, 2042, 3.53193462 ], [ 1500159900000, 2045.7, 2046.8, 2046.9, 2045.7, 3.26026574 ], [ 1500159840000, 2046.9, 2047.8, 2048, 2046.6, 2.53834372 ], [ 1500159780000, 2046.9, 2046.9, 2047, 2045.3, 9.43997543 ], [ 1500159720000, 2045.8, 2046.8, 2050, 2045.5, 21.04432284 ], [ 1500159660000, 2040.8, 2044.4, 2050.1, 2040.7, 99.67203311 ], [ 1500159600000, 2032, 2036.9, 2036.9, 2031.81331756, 12.02780761 ], [ 1500159540000, 2027.9, 2032, 2032.6, 2027.6, 7.1549663 ], [ 1500159480000, 2027.9, 2027.1, 2027.9, 2027.1, 0.2233022 ], [ 1500159420000, 2027.01699565, 2027.9, 2028.9, 2026.7, 2.72581875 ], [ 1500159360000, 2031.3, 2026.10341053, 2034.7, 2026.10341053, 7.68789213 ], [ 1500159300000, 2031.6, 2031.2, 2034.8, 2027.5, 7.68397458 ], [ 1500159240000, 2032.61270454, 2031.9, 2035, 2031, 4.34505748 ], [ 1500159180000, 2037, 2032.4985064, 2037, 2032.4985064, 9.84218333 ], [ 1500159120000, 2038, 2036.8, 2038.1, 2035.2, 8.0394852 ], [ 1500159060000, 2038, 2038, 2038, 2038, 0.03557219 ], [ 1500159000000, 2041.9, 2039.5, 2041.9, 2038.4, 25.13458134 ], [ 1500158940000, 2042.1, 2042, 2042.1, 2042, 4.26789531 ], [ 1500158880000, 2043.3, 2043.3, 2043.3, 2043.3, 0.03698901 ], [ 1500158820000, 2042, 2043.2, 2043.2, 2042, 0.44716155 ], [ 1500158760000, 2043.2, 2043.2, 2043.3, 2042, 0.08153407 ], [ 1500158700000, 2040.8, 2043.1, 2047, 2040.8, 7.16597568 ], [ 1500158640000, 2040.2, 2042.5, 2042.5, 2038.4, 3.540761 ], [ 1500158580000, 2044.5, 2038.5, 2044.5, 2036.1528469, 12.97337617 ], [ 1500158520000, 2046.5, 2040.83497066, 2046.5, 2040.83497066, 26.10096069 ], [ 1500158460000, 2048.1, 2046.6, 2048.1, 2046.5, 4.06512445 ], [ 1500158400000, 2051.6, 2048.1, 2051.6, 2048.1, 0.90595857 ], [ 1500158340000, 2055.2, 2053.9, 2055.2, 2053.9, 1.62993384 ], [ 1500158280000, 2059, 2055.2, 2059, 2055.2, 4.92301136 ], [ 1500158220000, 2061, 2059.9, 2061, 2059.5, 10.994915 ], [ 1500158160000, 2061.3, 2063.9, 2063.9, 2061.2, 7.07495719 ], [ 1500158100000, 2056.1, 2061.3, 2061.4, 2056.1, 6.92721002 ], [ 1500158040000, 2057.1, 2057, 2057.8, 2057, 3.53238155 ], [ 1500157980000, 2058.1, 2057.1, 2058.2, 2057.1, 0.56829621 ], [ 1500157920000, 2054.1, 2057.9, 2057.9, 2054.1, 13.56914211 ], [ 1500157860000, 2048, 2052.9, 2064, 2046.8, 75.09458677 ], [ 1500157800000, 2049.5, 2048, 2049.5, 2048, 0.51927813 ], [ 1500157740000, 2044.9, 2049.3, 2049.3, 2044.8, 6.26535979 ], [ 1500157680000, 2039.7, 2043.8, 2043.8, 2039.7, 5.3953595 ], [ 1500157620000, 2039.8, 2039.7, 2039.8, 2038.3, 4.73073907 ], [ 1500157560000, 2042.31954649, 2039.9, 2045, 2039.8, 4.10262838 ], [ 1500157500000, 2046.6, 2042.31954649, 2046.6, 2042.31954649, 2.16118793 ], [ 1500157440000, 2051, 2046.6, 2051, 2046.6, 3.20495404 ], [ 1500157380000, 2051.6, 2051.6, 2051.6, 2051.6, 0.03023163 ], [ 1500157320000, 2056.2, 2051.6, 2056.2, 2051.6, 9.14784316 ], [ 1500157260000, 2056, 2053.9, 2056.4, 2053.9, 19.1085068 ], [ 1500157200000, 2058.9, 2059.7, 2059.7, 2056, 1.2736754 ], [ 1500157140000, 2058, 2059.7, 2059.7, 2057.6, 16.09856437 ], [ 1500157080000, 2055, 2057.6, 2058, 2054.3, 25.57670276 ], [ 1500157020000, 2052.8, 2054.9955401, 2055.2, 2051.9, 24.53272347 ], [ 1500156960000, 2053.4, 2053.2, 2053.5, 2052.8, 1.306931 ], [ 1500156900000, 2049.3, 2052.8, 2054, 2049.3, 6.61917221 ], [ 1500156840000, 2048.9, 2049.4, 2049.4, 2046.6, 1.29606497 ], [ 1500156780000, 2053, 2046.8, 2053.2, 2046.8, 12.69946234 ], [ 1500156720000, 2056.3, 2054.1, 2058.3, 2052.7, 43.78514919 ], [ 1500156660000, 2055.3, 2057.8, 2058, 2052.2, 60.36936131 ], [ 1500156600000, 2053.3, 2055.3, 2059.8, 2053.1, 9.93483066 ], [ 1500156540000, 2043.6, 2058.5, 2058.5, 2043.57572604, 40.15689708 ], [ 1500156480000, 2035.4, 2043.5, 2046.5, 2035.4, 30.94043752 ], [ 1500156420000, 2028.9, 2035.2, 2039.8, 2028.9, 24.75357457 ], [ 1500156360000, 2027.9, 2028.8, 2028.8, 2027, 6.76810539 ], [ 1500156300000, 2024.9, 2028, 2028, 2023.9, 46.63302101 ], [ 1500156240000, 2021.5, 2024, 2025.6, 2021.5, 9.81131154 ], [ 1500156180000, 2030.9, 2023.6, 2031, 2022.5, 99.04275051 ], [ 1500156120000, 2028, 2030.9, 2030.9, 2026.67440123, 23.13572439 ], [ 1500156060000, 2033.1, 2028.8, 2034.5, 2028.8, 118.38653001 ], [ 1500156000000, 2033.5, 2033.1, 2034.6, 2033, 126.50116941 ], [ 1500155940000, 2033, 2033, 2034.2, 2033, 1.15005113 ], [ 1500155880000, 2035, 2033, 2037.9, 2033, 6.73203763 ], [ 1500155820000, 2040, 2035.3, 2043.1, 2035.3, 116.30081003 ], [ 1500155760000, 2032.1, 2040, 2040.03558368, 2032.1, 64.09353059 ], [ 1500155700000, 2036.9, 2032.1, 2036.9, 2032.1, 15.56460969 ], [ 1500155640000, 2044, 2035.9, 2046.1, 2035.9, 21.29541685 ], [ 1500155580000, 2056, 2044, 2056, 2044, 42.63603848 ], [ 1500155520000, 2060, 2056, 2060, 2056, 6.48182999 ], [ 1500155460000, 2060, 2060, 2060.2, 2059.7, 32.36917066 ], [ 1500155400000, 2056.1, 2060, 2060.1, 2055, 217.46795998 ], [ 1500155340000, 2056.2, 2056, 2056.2, 2056, 3.73433892 ], [ 1500155280000, 2056.1, 2056.1, 2056.3, 2056, 13.37990461 ], [ 1500155220000, 2055.3, 2056.1, 2056.7, 2055, 11.36517902 ], [ 1500155160000, 2052, 2055.1, 2055.1, 2051.8, 27.46606242 ], [ 1500155100000, 2050.8, 2051.8, 2055, 2050.5, 12.07131499 ], [ 1500155040000, 2048.3, 2050.9, 2050.9, 2046, 76.65404401 ] ]";
17 |
18 | var candles = JsonConvert.DeserializeObject>(json, new CandlesResultConverter());
19 |
20 | Assert.AreEqual(120, candles.Count);
21 |
22 | var candle = candles[0];
23 |
24 | Assert.AreEqual(1500162180000, candle.MTS);
25 | Assert.AreEqual(1995.7, candle.Open);
26 | Assert.AreEqual(1987.2, candle.Close);
27 | Assert.AreEqual(1995.7, candle.High);
28 | Assert.AreEqual(1987.2, candle.Low);
29 | Assert.AreEqual(22.97632724, candle.Volume);
30 | }
31 |
32 | [TestMethod]
33 | public void CandlesDeserializeTest2()
34 | {
35 | //GET: https://api.bitfinex.com/v2/candles/trade:1m:tBTCUSD/last
36 | string json = "[ 1500162180000, 1995.7, 1995.7, 1995.7, 1995.7, 1.32939032 ]";
37 |
38 | var candle = JsonConvert.DeserializeObject(json, new CandleResultConverter());
39 |
40 | Assert.AreEqual(1500162180000, candle.MTS);
41 | Assert.AreEqual(1995.7, candle.Open);
42 | Assert.AreEqual(1995.7, candle.Close);
43 | Assert.AreEqual(1995.7, candle.High);
44 | Assert.AreEqual(1995.7, candle.Low);
45 | Assert.AreEqual(1.32939032, candle.Volume);
46 | }
47 |
48 | [TestMethod]
49 | public void CandlesClientSectionLastTest()
50 | {
51 | var client = new BitfinexRestClient();
52 | var candles = client.GetCandles(TimeFrame.Minute, Symbol.BTCUSD, Section.Last);
53 |
54 | Assert.AreEqual(1, candles.Count);
55 | }
56 |
57 | [TestMethod]
58 | public void CandlesClientSectionHistoricalTest()
59 | {
60 | var client = new BitfinexRestClient();
61 | var candles = client.GetCandles(TimeFrame.Minute, Symbol.BTCUSD, Section.Historical);
62 |
63 | Assert.IsTrue(candles.Count > 1);
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/Bitfinex/CandlesClient.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Threading.Tasks;
4 | using Bitfinex.JsonConverters;
5 | using Bitfinex.Models;
6 | using RestSharp;
7 | using static System.String;
8 |
9 | namespace Bitfinex
10 | {
11 | // All our Stats methods.
12 |
13 | public partial class BitfinexRestClient
14 | {
15 | ///
16 | /// Get charting candle info
17 | ///
18 | /// Available values: '1m', '5m', '15m', '30m', '1h', '3h', '6h', '12h', '1D', '7D', '14D', '1M'
19 | /// The symbol you want information about.
20 | /// Available values: "last", "hist"
21 | /// A list of candle information
22 | public List GetCandles(TimeFrame timeframe, Symbol symbol, Section section)
23 | {
24 | return getCandlesAsync(timeframe, symbol, section).Result;
25 | }
26 |
27 | ///
28 | /// Get charting candle info
29 | ///
30 | /// Available values: '1m', '5m', '15m', '30m', '1h', '3h', '6h', '12h', '1D', '7D', '14D', '1M'
31 | /// The symbol you want information about.
32 | /// Available values: "last", "hist"
33 | /// Number of candles requested
34 | /// A list of candle information
35 | public List GetCandles(TimeFrame timeframe, Symbol symbol, Section section, int limit)
36 | {
37 | return getCandlesAsync(timeframe, symbol, section, limit).Result;
38 | }
39 |
40 | ///
41 | /// Get charting candle info
42 | ///
43 | /// Available values: '1m', '5m', '15m', '30m', '1h', '3h', '6h', '12h', '1D', '7D', '14D', '1M'
44 | /// The symbol you want information about.
45 | /// Available values: "last", "hist"
46 | /// Number of candles requested
47 | /// Filter start (ms)
48 | /// A list of candle information
49 | public List GetCandles(TimeFrame timeframe, Symbol symbol, Section section, int limit, long start)
50 | {
51 | return getCandlesAsync(timeframe, symbol, section, limit, start).Result;
52 | }
53 |
54 | ///
55 | /// Get charting candle info
56 | ///
57 | /// Available values: '1m', '5m', '15m', '30m', '1h', '3h', '6h', '12h', '1D', '7D', '14D', '1M'
58 | /// The symbol you want information about.
59 | /// Available values: "last", "hist"
60 | /// Number of candles requested
61 | /// Filter start (ms)
62 | /// Filter end (ms)
63 | /// A list of candle information
64 | public List GetCandles(TimeFrame timeframe, Symbol symbol, Section section, int limit, long start, long end)
65 | {
66 | return getCandlesAsync(timeframe, symbol, section, limit, start, end).Result;
67 | }
68 |
69 | ///
70 | /// Get charting candle info
71 | ///
72 | /// Available values: '1m', '5m', '15m', '30m', '1h', '3h', '6h', '12h', '1D', '7D', '14D', '1M'
73 | /// The symbol you want information about.
74 | /// Available values: "last", "hist"
75 | /// Number of candles requested
76 | /// Filter start (ms)
77 | /// Filter end (ms)
78 | /// Default new > old
79 | /// A list of candle information
80 | public List GetCandles(TimeFrame timeframe, Symbol symbol, Section section, int limit, long start, long end, SortDirection sortDirection)
81 | {
82 | // TO-DO: The spec says that the start and end are string. We are handling as ints.
83 |
84 | return getCandlesAsync(timeframe, symbol, section, limit, start, end, sortDirection).Result;
85 | }
86 |
87 | ///
88 | /// Get charting candle info
89 | ///
90 | /// Available values: '1m', '5m', '15m', '30m', '1h', '3h', '6h', '12h', '1D', '7D', '14D', '1M'
91 | /// The symbol you want information about.
92 | /// Available values: "last", "hist"
93 | /// A list of candle information
94 | public async Task> GetCandlesAsync(TimeFrame timeframe, Symbol symbol, Section section)
95 | {
96 | return await getCandlesAsync(timeframe, symbol, section);
97 | }
98 |
99 | ///
100 | /// Get charting candle info
101 | ///
102 | /// Available values: '1m', '5m', '15m', '30m', '1h', '3h', '6h', '12h', '1D', '7D', '14D', '1M'
103 | /// The symbol you want information about.
104 | /// Available values: "last", "hist"
105 | /// Number of candles requested
106 | /// A list of candle information
107 | public async Task> GetCandlesAsync(TimeFrame timeframe, Symbol symbol, Section section, int limit)
108 | {
109 | return await getCandlesAsync(timeframe, symbol, section, limit);
110 | }
111 |
112 | ///
113 | /// Get charting candle info
114 | ///
115 | /// Available values: '1m', '5m', '15m', '30m', '1h', '3h', '6h', '12h', '1D', '7D', '14D', '1M'
116 | /// The symbol you want information about.
117 | /// Available values: "last", "hist"
118 | /// Number of candles requested
119 | /// Filter start (ms)
120 | /// A list of candle information
121 | public async Task> GetCandlesAsync(TimeFrame timeframe, Symbol symbol, Section section, int limit, long start)
122 | {
123 | return await getCandlesAsync(timeframe, symbol, section, limit, start);
124 | }
125 |
126 | ///
127 | /// Get charting candle info
128 | ///
129 | /// Available values: '1m', '5m', '15m', '30m', '1h', '3h', '6h', '12h', '1D', '7D', '14D', '1M'
130 | /// The symbol you want information about.
131 | /// Available values: "last", "hist"
132 | /// Number of candles requested
133 | /// Filter start (ms)
134 | /// Filter end (ms)
135 | /// A list of candle information
136 | public async Task> GetCandlesAsync(TimeFrame timeframe, Symbol symbol, Section section, int limit, long start, long end)
137 | {
138 | return await getCandlesAsync(timeframe, symbol, section, limit, start, end);
139 | }
140 |
141 | ///
142 | /// Get charting candle info
143 | ///
144 | /// Available values: '1m', '5m', '15m', '30m', '1h', '3h', '6h', '12h', '1D', '7D', '14D', '1M'
145 | /// The symbol you want information about.
146 | /// Available values: "last", "hist"
147 | /// Number of candles requested
148 | /// Filter start (ms)
149 | /// Filter end (ms)
150 | /// Default new > old
151 | /// A list of candle information
152 | public async Task> GetCandlesAsync(TimeFrame timeframe, Symbol symbol, Section section, int limit, long start, long end, SortDirection sortDirection)
153 | {
154 | return await getCandlesAsync(timeframe, symbol, section, limit, start, end, sortDirection);
155 | }
156 |
157 | private async Task> getCandlesAsync(TimeFrame timeframe, Symbol symbol, Section section, int? limit = null, long? start = null, long? end = null, SortDirection? sortDirection = null)
158 | {
159 | var parameters = new List();
160 | if (limit.GetValueOrDefault() != 0) parameters.Add("limit=" + limit);
161 | if (start.GetValueOrDefault() != 0) parameters.Add("start=" + start);
162 | if (end.GetValueOrDefault() != 0) parameters.Add("end=" + end);
163 | if (sortDirection != null) parameters.Add("sort=" + (int)sortDirection);
164 |
165 | string url = $"candles/trade:{timeframe}:{(TradeSymbol)symbol}/{section}";
166 | if (parameters.Count > 0) url = url + "?" + Join("&", parameters.ToArray());
167 |
168 | var request = new RestRequest(url, Method.GET);
169 |
170 | var response = await GetResponseAsync(request, CancellationToken);
171 |
172 | // We could have recieved a single candle.
173 | try
174 | {
175 | var candle = (Candle)DeserializeObject(response.Content, new CandleResultConverter());
176 | if (candle != null) return new List() { candle };
177 | }
178 | catch (Exception)
179 | {
180 | // ignored
181 | }
182 |
183 | return (List)DeserializeObject>(response.Content, new CandlesResultConverter());
184 | }
185 | }
186 | }
--------------------------------------------------------------------------------
/Bitfinex.Tests/Models/TradesTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Bitfinex.JsonConverters;
4 | using Bitfinex.Models;
5 | using Microsoft.VisualStudio.TestTools.UnitTesting;
6 | using Newtonsoft.Json;
7 |
8 | namespace Bitfinex.Tests.Models
9 | {
10 | [TestClass]
11 | public class TradesTests
12 | {
13 | [TestMethod]
14 | public void TradesDeserializeTest1()
15 | {
16 | //GET: https://api.bitfinex.com/v2/trades/fUSD/hist
17 | string json = "[ [ 8819908, 1499993669662, -42.48113687, 0.00026573, 2 ], [ 8819907, 1499993669637, -93.08533495, 0.00026571, 2 ], [ 8819906, 1499993669606, -80.23924126, 0.0002657, 2 ], [ 8819905, 1499993669580, -80.23924126, 0.0002657, 2 ], [ 8819904, 1499993669555, -90.44483913, 0.0002657, 2 ], [ 8819903, 1499993669508, -53.77420134, 0.0002657, 2 ], [ 8819902, 1499993669472, -53.77420134, 0.0002657, 2 ], [ 8819901, 1499993669408, -53.77420134, 0.0002657, 2 ], [ 8819900, 1499993669374, -2.6136619, 0.0002657, 2 ], [ 8819895, 1499993667107, -51.16053944, 0.0002657, 2 ], [ 8819894, 1499993667086, -53.77420134, 0.0002657, 2 ], [ 8819893, 1499993667057, -53.77420134, 0.0002657, 2 ], [ 8819892, 1499993667031, -2474.20793604, 0.0002657, 2 ], [ 8819891, 1499993667006, -53.77420134, 0.00026563, 2 ], [ 8819890, 1499993666980, -53.77420134, 0.00026563, 2 ], [ 8819889, 1499993666960, -53.77420134, 0.00026563, 2 ], [ 8819888, 1499993666933, -53.77420134, 0.00026563, 2 ], [ 8819887, 1499993666907, -53.77420134, 0.00026563, 2 ], [ 8819886, 1499993666887, -53.77420134, 0.00026563, 2 ], [ 8819885, 1499993666863, -53.77420134, 0.00026563, 2 ], [ 8819884, 1499993666843, -646.52363859, 0.00026563, 2 ], [ 8819883, 1499993666818, -4948.41587208, 0.00026563, 2 ], [ 8819882, 1499993666767, -87.03953651, 0.00026563, 2 ], [ 8819881, 1499993666727, -80.23924126, 0.00026562, 2 ], [ 8819880, 1499993666691, -80.23924126, 0.00026562, 2 ], [ 8819879, 1499993666658, -90.44483913, 0.00026562, 2 ], [ 8819878, 1499993666630, -53.77420134, 0.0002656, 2 ], [ 8819877, 1499993666605, -53.77420134, 0.0002656, 2 ], [ 8819876, 1499993666573, -80.23924126, 0.00026494, 2 ], [ 8819875, 1499993666536, -80.23924126, 0.00026494, 2 ], [ 8819874, 1499993666505, -4083.5268, 0.00026494, 2 ], [ 8819873, 1499993666478, -50, 0.0002649, 2 ], [ 8819872, 1499993666447, -1768.6234, 0.0002648, 2 ], [ 8819871, 1499993666416, -98.37, 0.0002648, 3 ], [ 8819870, 1499993666371, -169.69, 0.0002648, 3 ], [ 8819869, 1499993666311, -80.23924126, 0.0002647, 2 ], [ 8819868, 1499993666288, -90.44483913, 0.0002647, 2 ], [ 8819867, 1499993666256, -2474.20793604, 0.0002647, 2 ], [ 8819866, 1499993666222, -5081.18275562, 0.00026468, 2 ], [ 8819865, 1499993666200, -11078.18090284, 0.00026468, 2 ], [ 8819864, 1499993666152, -900.84877392, 0.00026368, 2 ], [ 8819839, 1499993661552, -24.08470096, 0.00026368, 2 ], [ 8819838, 1499993661481, -73.62422513, 0.00026368, 2 ], [ 8819832, 1499993655549, -20561.66978856, 0.00026468, 2 ], [ 8819831, 1499993654708, -14.1942157, 0.00026468, 2 ], [ 8819829, 1499993654659, -2.45249997, 0.00022719, 2 ], [ 8819827, 1499993653789, -47.54750003, 0.00022719, 2 ], [ 8819826, 1499993653730, -0.215336, 0.00026468, 2 ], [ 8819825, 1499993653665, -6163.58260527, 0.00026468, 2 ], [ 8819824, 1499993653601, -1962.84, 0.00026467, 2 ], [ 8819823, 1499993653567, -1326.7468018, 0.00026465, 2 ], [ 8819822, 1499993653459, -56.90229132, 0.00026387, 2 ], [ 8819821, 1499993653411, -237.783, 0.00026387, 2 ], [ 8819820, 1499993653372, -111.95655804, 0.00026368, 2 ], [ 8819819, 1499993653337, -80.23924126, 0.0002617, 2 ], [ 8819818, 1499993653277, -596.14230575, 0.0002617, 2 ], [ 8819817, 1499993653250, -80.23924126, 0.00023966, 2 ], [ 8819815, 1499993653196, -80.23924126, 0.00023966, 2 ], [ 8819814, 1499993653159, -80.23924126, 0.00023966, 2 ], [ 8819813, 1499993653100, -80.23924126, 0.00023966, 2 ], [ 8819812, 1499993653074, -80.23924126, 0.00023966, 2 ], [ 8819811, 1499993652976, -80.23924126, 0.00023966, 2 ], [ 8819810, 1499993652937, -451, 0.000236, 2 ], [ 8819809, 1499993652914, -56.90229132, 0.0002296, 2 ], [ 8819808, 1499993652888, -56.24275274, 0.0002296, 2 ], [ 8819807, 1499993652857, -56.24275274, 0.0002296, 2 ], [ 8819806, 1499993652812, -90.44483913, 0.00022749, 2 ], [ 8819805, 1499993652734, -1882.80746053, 0.00022749, 2 ], [ 8819804, 1499993652652, -85.14923868, 0.0002274, 2 ], [ 8819803, 1499993652628, -1408.82154882, 0.0002273, 2 ], [ 8819802, 1499993652569, -1408.82154882, 0.0002273, 2 ], [ 8819801, 1499993652510, -599.4112884, 0.0002273, 2 ], [ 8819799, 1499993652458, -599.4112884, 0.0002273, 2 ], [ 8819798, 1499993652356, -90.44483913, 0.0002273, 2 ], [ 8819797, 1499993652294, -4287.06443826, 0.0002273, 2 ], [ 8819796, 1499993651901, -779.58632982, 0.0002273, 2 ], [ 8819775, 1499993648738, -86.4999999, 0.0002273, 2 ], [ 8819773, 1499993647636, -215.50975942, 0.0002273, 2 ], [ 8819772, 1499993646194, -29.67599058, 0.0002273, 2 ], [ 8819765, 1499993643036, -54.1290761, 0.0002273, 2 ], [ 8819759, 1499993639396, -1.66913336, 0.0002273, 2 ], [ 8819756, 1499993638220, -179.39355176, 0.0002273, 2 ], [ 8819755, 1499993638152, -50, 0.0002273, 2 ], [ 8819754, 1499993638118, -50, 0.0002273, 2 ], [ 8819753, 1499993638081, -68.79399651, 0.0002273, 2 ], [ 8819752, 1499993635466, -190.02840302, 0.0002273, 2 ], [ 8819751, 1499993633585, -0.19886031, 0.0002273, 2 ], [ 8819750, 1499993632156, -44.3313754, 0.0002273, 2 ], [ 8819748, 1499993628217, -15.38736476, 0.0002273, 2 ], [ 8819747, 1499993628140, -65.45692284, 0.0002271, 2 ], [ 8819746, 1499993628040, -57.25490182, 0.0002271, 2 ], [ 8819745, 1499993625767, -25.019, 0.0002271, 2 ], [ 8819744, 1499993624420, -4.75883443, 0.0002271, 2 ], [ 8819743, 1499993622485, -753.56998339, 0.0002271, 2 ], [ 8819742, 1499993621593, -568.21882918, 0.0002271, 2 ], [ 8819741, 1499993621541, -599.4112884, 0.0002271, 2 ], [ 8819740, 1499993621484, -110.97509029, 0.0002271, 2 ], [ 8819739, 1499993621416, -50, 0.00022492, 2 ], [ 8819738, 1499993621357, -50, 0.00022481, 2 ], [ 8819737, 1499993621272, -602.16479213, 0.00022465, 2 ], [ 8819736, 1499993621192, -5.3639181, 0.00022465, 2 ], [ 8819732, 1499993584813, -50, 0.00022465, 2 ], [ 8819731, 1499993353283, -19, 0.0002659, 2 ], [ 8819729, 1499993352687, -967.61447872, 0.0002659, 2 ], [ 8819727, 1499993352105, -1167.98962257, 0.0002659, 2 ], [ 8819725, 1499993351249, -16023.36348933, 0.0002659, 2 ], [ 8819724, 1499993351230, -2098.64941318, 0.0002659, 2 ], [ 8819719, 1499993347667, -71.1836148, 0.0002659, 2 ], [ 8819718, 1499993347647, -135.7293452, 0.0002658, 2 ], [ 8819717, 1499993347624, -509.22367437, 0.0002658, 2 ], [ 8819712, 1499993346579, -52.37534993, 0.0002658, 2 ], [ 8819708, 1499993343496, -0.65331699, 0.0002658, 2 ], [ 8819707, 1499993343468, -2530.78440774, 0.0002658, 2 ], [ 8819706, 1499993343446, -1263.84, 0.0002658, 2 ], [ 8819705, 1499993343424, -120.35886189, 0.000265, 2 ], [ 8819704, 1499993343403, -120.35886189, 0.000265, 2 ], [ 8819703, 1499993343380, -120.35886189, 0.000265, 2 ], [ 8819702, 1499993343358, -147.42764988, 0.000265, 2 ], [ 8819701, 1499993342997, -1.30474549, 0.000265, 2 ], [ 8819697, 1499993341704, -7127.22537711, 0.000265, 2 ]]";
18 |
19 | var trades = JsonConvert.DeserializeObject>(json, new TradesResultConverter());
20 |
21 | Assert.AreEqual(120, trades.Count);
22 |
23 | var trade = trades[0];
24 |
25 | Assert.AreEqual(8819908, trade.ID);
26 | Assert.AreEqual(1499993669662, trade.MTS);
27 | Assert.AreEqual(-42.48113687, trade.Amount);
28 | Assert.AreEqual(0.00026573, trade.Rate);
29 | Assert.AreEqual(2, trade.Period.Milliseconds);
30 | }
31 |
32 | [TestMethod]
33 | public void TradesDeserializeTest2()
34 | {
35 | //GET: https://api.bitfinex.com/v2/trades/tBTCUSD/hist
36 | string json = "[ [ 43394880,1499994152000,0.17690843,2328.5 ], [ 43394873,1499994150000,0.18519263,2327.4 ], [ 43394867,1499994150000,1.14752541,2327.4 ], [ 43394855,1499994149000,0.05865396,2327.4 ], [ 43394846,1499994147000,0.02318898,2327.4 ], [ 43394836,1499994146000,0.23783591,2327.4 ], [ 43394834,1499994145000,0.02318898,2327.4 ], [ 43394826,1499994144000,0.32221829,2327.4 ], [ 43394819,1499994142000,0.37469225,2327.4 ], [ 43394816,1499994141000,0.03474767,2327.4 ], [ 43394814,1499994141000,0.02318898,2327.4 ], [ 43394810,1499994140000,0.02318898,2327.4 ], [ 43394807,1499994138000,0.02318898,2327.4 ], [ 43394805,1499994138000,0.02318898,2327.4 ], [ 43394774,1499994131000,0.40368858,2328.4 ], [ 43394772,1499994130000,-0.02203571,2325.6 ], [ 43394765,1499994127000,-0.97025747,2325 ], [ 43394764,1499994127000,-0.02974253,2325.1 ], [ 43394761,1499994125000,0.04901382,2328.826517 ], [ 43394749,1499994123000,0.03475254,2328.9 ], [ 43394748,1499994123000,0.38448517,2328.8 ], [ 43394746,1499994123000,0.02317404,2328.8 ], [ 43394736,1499994122000,0.3517295,2328.6 ], [ 43394731,1499994122000,0.0114784,2328.4 ], [ 43394726,1499994121000,0.06794646,2328.6 ], [ 43394725,1499994121000,0.07849665,2328.6 ], [ 43394724,1499994121000,0.08878369,2328.6 ], [ 43394722,1499994121000,0.02318898,2328.6 ], [ 43394720,1499994121000,0.17095246,2328.6 ], [ 43394721,1499994121000,0.41161218,2328.6 ], [ 43394719,1499994121000,1.32474152,2328.48422708 ], [ 43394715,1499994121000,0.79070252,2328.4 ], [ 43394714,1499994121000,0.40200175,2326 ], [ 43394711,1499994120000,-1,2325.8 ], [ 43394712,1499994120000,-1,2324.6 ], [ 43394709,1499994120000,0.02317703,2326 ], [ 43394708,1499994120000,-0.46084585,2326.1 ], [ 43394706,1499994120000,-0.02463224,2327.5 ], [ 43394707,1499994120000,-0.01326427,2327.4 ], [ 43394705,1499994120000,-0.02317802,2327.5 ], [ 43394703,1499994120000,-0.02971186,2327.5 ], [ 43394704,1499994120000,-0.02318898,2327.5 ], [ 43394702,1499994120000,0.06794895,2328.48422708 ], [ 43394698,1499994120000,-0.07849665,2328.5 ], [ 43394696,1499994120000,-0.58516317,2328.5 ], [ 43394694,1499994120000,-2.97594971,2328.5 ], [ 43394693,1499994120000,0.01023869,2328.6 ], [ 43394692,1499994120000,0.04725539,2328.6 ], [ 43394690,1499994120000,1.48713934,2328.6 ], [ 43394689,1499994119000,0.26265666,2328.6 ], [ 43394679,1499994118000,0.58516838,2328.5 ], [ 43394678,1499994118000,2.78,2328.4 ], [ 43394671,1499994117000,0.69470349,2328.5 ], [ 43394659,1499994116000,2.18,2328 ], [ 43394658,1499994116000,2,2328 ], [ 43394657,1499994116000,0.43688155,2327.4 ], [ 43394652,1499994115000,0.25954174,2327.4 ], [ 43394624,1499994114000,0.46085107,2327.3 ], [ 43394619,1499994114000,-1.092,2324.5 ], [ 43394594,1499994111000,0.29256214,2327.4 ], [ 43394593,1499994111000,0.7063306,2327.4 ], [ 43394589,1499994106000,0.27069119,2327.4 ], [ 43394582,1499994106000,1.27858048,2326.3 ], [ 43394585,1499994106000,0.62399278,2327.4 ], [ 43394584,1499994106000,0.09184,2327 ], [ 43394583,1499994106000,0.06101,2327 ], [ 43394576,1499994104000,0.094141,2326.3 ], [ 43394573,1499994104000,0.15572938,2326.3 ], [ 43394570,1499994103000,0.2442483,2326.3 ], [ 43394569,1499994103000,0.02318468,2326.3 ], [ 43394567,1499994102000,0.04332964,2326.3 ], [ 43394565,1499994101000,0.16078652,2326.3 ], [ 43394564,1499994101000,0.09263292,2325.2 ], [ 43394554,1499994100000,0.01450442,2325.2 ], [ 43394552,1499994100000,0.24479336,2325.2 ], [ 43394551,1499994100000,0.03473686,2325.2 ], [ 43394548,1499994100000,1.47532161,2325.2 ], [ 43394545,1499994099000,0.13801083,2325.2 ], [ 43394532,1499994092000,0.0347511,2326.3 ], [ 43394478,1499994077000,-0.07911615,2322.6 ], [ 43394466,1499994072000,0.03472337,2326.7 ], [ 43394436,1499994061000,-0.00255144,2324 ], [ 43394435,1499994061000,-0.05653288,2324.7 ], [ 43394434,1499994061000,-0.02974637,2324.8 ], [ 43394428,1499994059000,-0.19081844,2324.6 ], [ 43394426,1499994058000,-0.03,2324.6 ], [ 43394427,1499994058000,-0.22563985,2324.6 ], [ 43394421,1499994056000,0.02978511,2326.8 ], [ 43394402,1499994053000,0.02975149,2324.1 ], [ 43394401,1499994052000,0.02975149,2324.1 ], [ 43394400,1499994052000,-0.02975405,2324.2 ], [ 43394399,1499994052000,-0.05889999,2324.3 ], [ 43394390,1499994049000,0.24059868,2327 ], [ 43394389,1499994049000,2.15397713,2326.7 ], [ 43394373,1499994042000,0.2649,2326.9 ], [ 43394371,1499994041000,0.29952499,2326.8 ], [ 43394370,1499994041000,0.231,2326.7 ], [ 43394369,1499994041000,0.22570366,2326.5 ], [ 43394358,1499994038000,0.16658644,2326.8 ], [ 43394357,1499994038000,0.19205067,2326.3 ], [ 43394356,1499994037000,0.03103501,2326.3 ], [ 43394350,1499994037000,0.09209846,2326.3 ], [ 43394346,1499994036000,0.30647881,2326.3 ], [ 43394338,1499994035000,0.65932398,2326.3 ], [ 43394320,1499994026000,0.20895066,2326.1 ], [ 43394321,1499994026000,0.46331131,2326.5 ], [ 43394316,1499994023000,0.23867355,2326.1 ], [ 43394315,1499994023000,0.9607694,2326.1 ], [ 43394309,1499994022000,0.15718346,2326.1 ], [ 43394295,1499994016000,0.03842293,2326.1 ], [ 43394290,1499994014000,1.0187638,2326.2 ], [ 43394233,1499994008000,0.23819137,2326.4 ], [ 43394231,1499994008000,0.01613,2324.9 ], [ 43394232,1499994008000,0.18408,2324.9 ], [ 43394230,1499994007000,0.07501416,2324.8 ], [ 43394229,1499994007000,0.95048185,2324.7 ], [ 43394212,1499993988000,-0.04514027,2322.5 ], [ 43394210,1499993987000,0.01,2324.7 ], [ 43394206,1499993987000,-0.03370366,2322.4 ], [ 43394200,1499993987000,0.01001815,2324.7 ] ]";
37 |
38 | var trades = JsonConvert.DeserializeObject>(json, new TradesResultConverter());
39 |
40 | Assert.AreEqual(120, trades.Count);
41 |
42 | var trade = trades[0];
43 |
44 | Assert.AreEqual(43394880, trade.ID);
45 | Assert.AreEqual(1499994152000, trade.MTS);
46 | Assert.AreEqual(0.17690843, trade.Amount);
47 | Assert.AreEqual(2328.5, trade.Price);
48 | }
49 |
50 | [TestMethod]
51 | public void TradesClientTest()
52 | {
53 | var client = new BitfinexRestClient();
54 | var trades = client.GetTrades("tBTCUSD", 50, 0, 0, SortDirection.NewestToOldest);
55 |
56 | Assert.AreEqual(50, trades.Count);
57 | }
58 |
59 | [TestMethod]
60 | public void TradesClientTest2()
61 | {
62 | var client = new BitfinexRestClient();
63 | var trades = client.GetTrades("tBTCUSD", 120, 1501105149000, 1501115149000, SortDirection.NewestToOldest);
64 |
65 | Assert.AreEqual(120, trades.Count);
66 | }
67 |
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/Bitfinex/IBitfinexRestClient.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading;
3 | using System.Threading.Tasks;
4 | using Bitfinex.Models;
5 |
6 | namespace Bitfinex
7 | {
8 | public interface IBitfinexRestClient
9 | {
10 | ///
11 | /// Get charting candle info
12 | ///
13 | /// Available values: '1m', '5m', '15m', '30m', '1h', '3h', '6h', '12h', '1D', '7D', '14D', '1M'
14 | /// The symbol you want information about.
15 | /// Available values: "last", "hist"
16 | /// A list of candle information
17 | List GetCandles(TimeFrame timeframe, Symbol symbol, Section section);
18 |
19 | ///
20 | /// Get charting candle info
21 | ///
22 | /// Available values: '1m', '5m', '15m', '30m', '1h', '3h', '6h', '12h', '1D', '7D', '14D', '1M'
23 | /// The symbol you want information about.
24 | /// Available values: "last", "hist"
25 | /// Number of candles requested
26 | /// A list of candle information
27 | List GetCandles(TimeFrame timeframe, Symbol symbol, Section section, int limit);
28 |
29 | ///
30 | /// Get charting candle info
31 | ///
32 | /// Available values: '1m', '5m', '15m', '30m', '1h', '3h', '6h', '12h', '1D', '7D', '14D', '1M'
33 | /// The symbol you want information about.
34 | /// Available values: "last", "hist"
35 | /// Number of candles requested
36 | /// Filter start (ms)
37 | /// A list of candle information
38 | List GetCandles(TimeFrame timeframe, Symbol symbol, Section section, int limit, long start);
39 |
40 | ///
41 | /// Get charting candle info
42 | ///
43 | /// Available values: '1m', '5m', '15m', '30m', '1h', '3h', '6h', '12h', '1D', '7D', '14D', '1M'
44 | /// The symbol you want information about.
45 | /// Available values: "last", "hist"
46 | /// Number of candles requested
47 | /// Filter start (ms)
48 | /// Filter end (ms)
49 | /// A list of candle information
50 | List GetCandles(TimeFrame timeframe, Symbol symbol, Section section, int limit, long start, long end);
51 |
52 | ///
53 | /// Get charting candle info
54 | ///
55 | /// Available values: '1m', '5m', '15m', '30m', '1h', '3h', '6h', '12h', '1D', '7D', '14D', '1M'
56 | /// The symbol you want information about.
57 | /// Available values: "last", "hist"
58 | /// Number of candles requested
59 | /// Filter start (ms)
60 | /// Filter end (ms)
61 | /// Default new > old
62 | /// A list of candle information
63 | List GetCandles(TimeFrame timeframe, Symbol symbol, Section section, int limit, long start, long end, SortDirection sortDirection);
64 |
65 | ///
66 | /// Get charting candle info
67 | ///
68 | /// Available values: '1m', '5m', '15m', '30m', '1h', '3h', '6h', '12h', '1D', '7D', '14D', '1M'
69 | /// The symbol you want information about.
70 | /// Available values: "last", "hist"
71 | /// A list of candle information
72 | Task> GetCandlesAsync(TimeFrame timeframe, Symbol symbol, Section section);
73 |
74 | ///
75 | /// Get charting candle info
76 | ///
77 | /// Available values: '1m', '5m', '15m', '30m', '1h', '3h', '6h', '12h', '1D', '7D', '14D', '1M'
78 | /// The symbol you want information about.
79 | /// Available values: "last", "hist"
80 | /// Number of candles requested
81 | /// A list of candle information
82 | Task> GetCandlesAsync(TimeFrame timeframe, Symbol symbol, Section section, int limit);
83 |
84 | ///
85 | /// Get charting candle info
86 | ///
87 | /// Available values: '1m', '5m', '15m', '30m', '1h', '3h', '6h', '12h', '1D', '7D', '14D', '1M'
88 | /// The symbol you want information about.
89 | /// Available values: "last", "hist"
90 | /// Number of candles requested
91 | /// Filter start (ms)
92 | /// A list of candle information
93 | Task> GetCandlesAsync(TimeFrame timeframe, Symbol symbol, Section section, int limit, long start);
94 |
95 | ///
96 | /// Get charting candle info
97 | ///
98 | /// Available values: '1m', '5m', '15m', '30m', '1h', '3h', '6h', '12h', '1D', '7D', '14D', '1M'
99 | /// The symbol you want information about.
100 | /// Available values: "last", "hist"
101 | /// Number of candles requested
102 | /// Filter start (ms)
103 | /// Filter end (ms)
104 | /// A list of candle information
105 | Task> GetCandlesAsync(TimeFrame timeframe, Symbol symbol, Section section, int limit, long start, long end);
106 |
107 | ///
108 | /// Get charting candle info
109 | ///
110 | /// Available values: '1m', '5m', '15m', '30m', '1h', '3h', '6h', '12h', '1D', '7D', '14D', '1M'
111 | /// The symbol you want information about.
112 | /// Available values: "last", "hist"
113 | /// Number of candles requested
114 | /// Filter start (ms)
115 | /// Filter end (ms)
116 | /// Default new > old
117 | /// A list of candle information
118 | Task> GetCandlesAsync(TimeFrame timeframe, Symbol symbol, Section section, int limit, long start, long end, SortDirection sortDirection);
119 |
120 | ///
121 | /// Get pertinent details of trades, such as price, size and time.
122 | ///
123 | /// The symbol you want information about.
124 | /// List of trades
125 | List GetTrades(string symbol);
126 |
127 | ///
128 | /// Get pertinent details of trades, such as price, size and time.
129 | ///
130 | /// The symbol you want information about.
131 | /// Number of records
132 | /// List of trades
133 | List GetTrades(string symbol, int limit);
134 |
135 | ///
136 | /// Get pertinent details of trades, such as price, size and time.
137 | ///
138 | /// The symbol you want information about.
139 | /// Number of records
140 | /// Millisecond start time
141 | /// List of trades
142 | List GetTrades(string symbol, int limit, long start);
143 |
144 | ///
145 | /// Get pertinent details of trades, such as price, size and time.
146 | ///
147 | /// The symbol you want information about.
148 | /// Number of records
149 | /// Millisecond start time
150 | /// Millisecond end time
151 | /// List of trades
152 | List GetTrades(string symbol, int limit, long start, long end);
153 |
154 | ///
155 | /// Get pertinent details of trades, such as price, size and time.
156 | ///
157 | /// The symbol you want information about.
158 | /// Number of records
159 | /// Millisecond start time
160 | /// Millisecond end time
161 | ///
162 | /// List of trades
163 | List GetTrades(string symbol, int limit, long start, long end, SortDirection sortDirection);
164 |
165 | ///
166 | /// Get pertinent details of trades, such as price, size and time.
167 | ///
168 | /// The symbol you want information about.
169 | /// List of trades
170 | Task> GetTradesAsync(string symbol);
171 |
172 | ///
173 | /// Get pertinent details of trades, such as price, size and time.
174 | ///
175 | /// The symbol you want information about.
176 | /// Number of records (default 120)
177 | /// List of trades
178 | Task> GetTradesAsync(string symbol, int limit);
179 |
180 | ///
181 | /// Get pertinent details of trades, such as price, size and time.
182 | ///
183 | /// The symbol you want information about.
184 | /// Number of records (default 120)
185 | /// Millisecond start time (default 0)
186 | /// List of trades
187 | Task> GetTradesAsync(string symbol, int limit, long start);
188 |
189 | ///
190 | /// Get pertinent details of trades, such as price, size and time.
191 | ///
192 | /// The symbol you want information about.
193 | /// Number of records (default 120)
194 | /// Millisecond start time (default 0)
195 | /// Millisecond end time (default 0)
196 | /// List of trades
197 | Task> GetTradesAsync(string symbol, int limit, long start, long end);
198 |
199 | ///
200 | /// Get pertinent details of trades, such as price, size and time.
201 | ///
202 | /// The symbol you want information about.
203 | /// Number of records (default 120)
204 | /// Millisecond start time (default 0)
205 | /// Millisecond end time (default 0)
206 | /// Default new > old
207 | /// List of trades
208 | Task> GetTradesAsync(string symbol, int limit, long start, long end, SortDirection sortDirection);
209 |
210 | string BaseUrl { get; set; }
211 | CancellationToken CancellationToken { get; set; }
212 |
213 | ///
214 | /// Get a high-level overview of the specified symbol. It shows you the current best bid and ask, as well as the last trade price. It also includes information such as daily volume and how much the price has moved over the last day.
215 | ///
216 | /// A symbol (eg BTCUSD) prefixed with either t (for Trading) or f (for Funding). eg tBTCUSD
217 | /// Ticker
218 | ITicker GetTicker(string symbol);
219 |
220 | ///
221 | /// Get a high-level overview of the specified symbols. It shows you the current best bid and ask, as well as the last trade price. It also includes information such as daily volume and how much the price has moved over the last day.
222 | ///
223 | /// A list of symbols (eg BTCUSD) prefixed with either t (for Trading) or f (for Funding). eg tBTCUSD
224 | /// List of tickers
225 | List GetTickers(string[] symbols);
226 |
227 | ///
228 | /// Get a high-level overview of the specified symbol. It shows you the current best bid and ask, as well as the last trade price. It also includes information such as daily volume and how much the price has moved over the last day.
229 | ///
230 | /// A symbol (eg BTCUSD) prefixed with either t (for Trading) or f (for Funding). eg tBTCUSD
231 | /// Ticker
232 | Task GetTickerAsync(string symbol);
233 |
234 | ///
235 | /// Get a high-level overview of the specified symbols. It shows you the current best bid and ask, as well as the last trade price. It also includes information such as daily volume and how much the price has moved over the last day.
236 | ///
237 | /// A list of symbols (eg BTCUSD) prefixed with either t (for Trading) or f (for Funding). eg tBTCUSD
238 | /// List of tickers
239 | Task> GetTickersAsync(string[] symbols);
240 |
241 | ///
242 | /// Get statistics about the requested pair.
243 | ///
244 | /// Allowed values: "funding.size", "credits.size", "credits.size.sym", "pos.size"
245 | /// The symbol you want information about.
246 | /// Available values: "long", "short"
247 | /// Available values: "last", "hist"
248 | /// List of MTS and Value stats for the requested pair
249 | List GetStats(Key key, Symbol symbol, Side side, Section section);
250 |
251 | ///
252 | /// Get statistics about the requested pair.
253 | ///
254 | /// Allowed values: "funding.size", "credits.size", "credits.size.sym", "pos.size"
255 | /// The symbol you want information about.
256 | /// Available values: "long", "short"
257 | /// Available values: "last", "hist"
258 | /// Default new > old
259 | /// List of MTS and Value stats for the requested pair
260 | List GetStats(Key key, Symbol symbol, Side side, Section section, SortDirection sortDirection);
261 |
262 | ///
263 | /// Get statistics about the requested pair.
264 | ///
265 | /// Allowed values: "funding.size", "credits.size", "credits.size.sym", "pos.size"
266 | /// The symbol you want information about.
267 | /// Available values: "long", "short"
268 | /// Available values: "last", "hist"
269 | /// List of MTS and Value stats for the requested pair
270 | Task> GetStatsAsync(Key key, Symbol symbol, Side side, Section section);
271 |
272 | ///
273 | /// Get statistics about the requested pair.
274 | ///
275 | /// Allowed values: "funding.size", "credits.size", "credits.size.sym", "pos.size"
276 | /// The symbol you want information about.
277 | /// Available values: "long", "short"
278 | /// Available values: "last", "hist"
279 | /// Default new > old
280 | /// List of MTS and Value stats for the requested pair
281 | Task> GetStatsAsync(Key key, Symbol symbol, Side side, Section section, SortDirection sortDirection);
282 |
283 | ///
284 | /// Retrieve state of the Bitfinex order book. It is provided on a price aggregated basis, with customizable precision.
285 | ///
286 | /// The symbol you want information about.
287 | /// Level of price aggregation (P0, P1, P2, P3, R0)
288 | /// List of books
289 | List GetBooks(string symbol, Precision precision);
290 |
291 | ///
292 | /// Retrieve state of the Bitfinex order book. It is provided on a price aggregated basis, with customizable precision.
293 | ///
294 | /// The symbol you want information about.
295 | /// Level of price aggregation (P0, P1, P2, P3, R0)
296 | /// Number of price points
297 | /// List of books
298 | List GetBooks(string symbol, Precision precision, int len);
299 |
300 | ///
301 | /// Retrieve state of the Bitfinex order book. It is provided on a price aggregated basis, with customizable precision.
302 | ///
303 | /// The symbol you want information about.
304 | /// Level of price aggregation (P0, P1, P2, P3, R0)
305 | /// List of books
306 | Task> GetBooksAsync(string symbol, Precision precision);
307 |
308 | ///
309 | /// Retrieve state of the Bitfinex order book. It is provided on a price aggregated basis, with customizable precision.
310 | ///
311 | /// The symbol you want information about.
312 | /// Level of price aggregation (P0, P1, P2, P3, R0)
313 | /// Number of price points
314 | /// List of books
315 | Task> GetBooksAsync(string symbol, Precision precision, int len);
316 | }
317 | }
--------------------------------------------------------------------------------