Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BL3P: added buy/sell/cancel #475

Merged
merged 14 commits into from
Nov 5, 2019
72 changes: 44 additions & 28 deletions ExchangeSharp/API/Common/APIRequestMaker.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*
/*
MIT LICENSE

Copyright 2017 Digital Ruby, LLC - http://www.digitalruby.com
Expand All @@ -14,7 +14,6 @@ The above copyright notice and this permission notice shall be included in all c
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace ExchangeSharp
Expand All @@ -27,79 +26,93 @@ public sealed class APIRequestMaker : IAPIRequestMaker
{
private readonly IAPIRequestHandler api;

private class InternalHttpWebRequest : IHttpWebRequest
internal class InternalHttpWebRequest : IHttpWebRequest
{
internal readonly HttpWebRequest request;
internal readonly HttpWebRequest Request;
internal static WebProxy Proxy;

static InternalHttpWebRequest()
{
var httpProxy = Environment.GetEnvironmentVariable("http_proxy");
httpProxy ??= Environment.GetEnvironmentVariable("HTTP_PROXY");

if (string.IsNullOrEmpty(httpProxy))
return;

var uri = new Uri(httpProxy);
Proxy = new WebProxy(uri);
}

public InternalHttpWebRequest(Uri fullUri)
{
request = (HttpWebRequest.Create(fullUri) as HttpWebRequest ?? throw new NullReferenceException("Failed to create HttpWebRequest"));
request.KeepAlive = false;
Request = (HttpWebRequest.Create(fullUri) as HttpWebRequest ?? throw new NullReferenceException("Failed to create HttpWebRequest"));
Request.Proxy = Proxy;
Request.KeepAlive = false;
}

public void AddHeader(string header, string value)
{
switch (header.ToStringLowerInvariant())
{
case "content-type":
request.ContentType = value;
Request.ContentType = value;
break;

case "content-length":
request.ContentLength = value.ConvertInvariant<long>();
Request.ContentLength = value.ConvertInvariant<long>();
break;

case "user-agent":
request.UserAgent = value;
Request.UserAgent = value;
break;

case "accept":
request.Accept = value;
Request.Accept = value;
break;

case "connection":
request.Connection = value;
Request.Connection = value;
break;

default:
request.Headers[header] = value;
Request.Headers[header] = value;
break;
}
}

public Uri RequestUri
{
get { return request.RequestUri; }
get { return Request.RequestUri; }
}

public string Method
{
get { return request.Method; }
set { request.Method = value; }
get { return Request.Method; }
set { Request.Method = value; }
}

public int Timeout
{
get { return request.Timeout; }
set { request.Timeout = value; }
get { return Request.Timeout; }
set { Request.Timeout = value; }
}

public int ReadWriteTimeout
{
get { return request.ReadWriteTimeout; }
set { request.ReadWriteTimeout = value; }
get { return Request.ReadWriteTimeout; }
set { Request.ReadWriteTimeout = value; }
}

public async Task WriteAllAsync(byte[] data, int index, int length)
{
using (Stream stream = await request.GetRequestStreamAsync())
using (Stream stream = await Request.GetRequestStreamAsync())
{
await stream.WriteAsync(data, 0, data.Length);
}
}
}

private class InternalHttpWebResponse : IHttpWebResponse
internal class InternalHttpWebResponse : IHttpWebResponse
{
private readonly HttpWebResponse response;

Expand Down Expand Up @@ -175,7 +188,7 @@ public async Task<string> MakeRequestAsync(string url, string? baseUrl = null, D
try
{
RequestStateChanged?.Invoke(this, RequestMakerState.Begin, uri.AbsoluteUri);// when start make a request we send the uri, this helps developers to track the http requests.
response = await request.request.GetResponseAsync() as HttpWebResponse;
response = await request.Request.GetResponseAsync() as HttpWebResponse;
if (response == null)
{
throw new APIException("Unknown response from server");
Expand All @@ -191,16 +204,19 @@ public async Task<string> MakeRequestAsync(string url, string? baseUrl = null, D
}
using (Stream responseStream = response.GetResponseStream())
using (StreamReader responseStreamReader = new StreamReader(responseStream))
responseString = responseStreamReader.ReadToEnd();
responseString = responseStreamReader.ReadToEnd();

if (response.StatusCode != HttpStatusCode.OK)
{
// 404 maybe return empty responseString
if (string.IsNullOrWhiteSpace(responseString))
{
// 404 maybe return empty responseString
if (string.IsNullOrWhiteSpace(responseString))
{
throw new APIException(string.Format("{0} - {1}", response.StatusCode.ConvertInvariant<int>(), response.StatusCode));
}
throw new APIException(responseString);
}

throw new APIException(responseString);
}

api.ProcessResponse(new InternalHttpWebResponse(response));
RequestStateChanged?.Invoke(this, RequestMakerState.Finished, responseString);
}
Expand Down
37 changes: 37 additions & 0 deletions ExchangeSharp/API/Exchanges/BL3P/BL3PException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System;
using System.Runtime.Serialization;
using ExchangeSharp.API.Exchanges.BL3P.Models;

namespace ExchangeSharp.API.Exchanges.BL3P
{
[Serializable]
johnnyasantoss marked this conversation as resolved.
Show resolved Hide resolved
internal class BL3PException : Exception
{
public string ErrorCode { get; }

internal BL3PException(BL3PResponsePayloadError error)
: this(error?.Message)
{
if (error == null)
throw new ArgumentNullException(nameof(error));
ErrorCode = error.ErrorCode;
}

public BL3PException(string message)
: base(message)
{
}

public BL3PException(string message, Exception inner)
: base(message, inner)
{
}

protected BL3PException(
SerializationInfo info,
StreamingContext context
) : base(info, context)
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using ExchangeSharp.API.Exchanges.BL3P.Models;
using ExchangeSharp.Dependencies.Converters;
using Newtonsoft.Json;

namespace ExchangeSharp.API.Exchanges.BL3P.Converters
{
internal class BL3PResponseConverter<TSuccess> : JsonComplexObjectConverter<BL3PResponsePayload>
where TSuccess : BL3PResponsePayload, new()
{
protected override BL3PResponsePayload Create(JsonReader reader)
{
while (reader.Read())
{
if (reader.TokenType != JsonToken.PropertyName)
{
continue;
}

var prop = (string) reader.Value;

switch (prop)
{
// this is the first prop on an error object
case "code":
return new BL3PResponsePayloadError();
default:
return new TSuccess();
}
}

throw new JsonException("Could not locate key property in json.");
}
}
}
8 changes: 8 additions & 0 deletions ExchangeSharp/API/Exchanges/BL3P/Enums/BL3PCurrencyFee.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace ExchangeSharp.API.Exchanges.BL3P.Enums
{
public enum BL3PCurrencyFee : byte
{
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be internal

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can't be made internal, because, it's one of the settings of ExchangeBL3PAPI. See prop ExchangeBL3PAPI.DefaultFeeCurrency.

BTC = 0,
EUR = 1
}
}
11 changes: 11 additions & 0 deletions ExchangeSharp/API/Exchanges/BL3P/Enums/BL3POrderStatus.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace ExchangeSharp.API.Exchanges.BL3P.Enums
{
internal enum BL3POrderStatus
{
Pending = 0,
Open,
Closed,
Cancelled,
Placed
}
}
8 changes: 8 additions & 0 deletions ExchangeSharp/API/Exchanges/BL3P/Enums/BL3POrderType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace ExchangeSharp.API.Exchanges.BL3P.Enums
{
internal enum BL3POrderType
{
johnnyasantoss marked this conversation as resolved.
Show resolved Hide resolved
Bid,
Ask
}
}
9 changes: 9 additions & 0 deletions ExchangeSharp/API/Exchanges/BL3P/Enums/BL3PResponseType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace ExchangeSharp.API.Exchanges.BL3P.Enums
{
internal enum BL3PResponseType
{
johnnyasantoss marked this conversation as resolved.
Show resolved Hide resolved
Unknown = 0,
Error,
Success
}
}
Loading