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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ jobs:
cache: true
cache-dependency-path: |
src/**/*.csproj
tests/**/*.csproj
src/**/global.json
src/**/NuGet.Config

Expand All @@ -50,9 +51,9 @@ jobs:
run: dotnet build --no-restore --configuration ${{ matrix.configuration }} --nologo

- name: Test
run: dotnet test --no-build --configuration ${{ matrix.configuration }} --collect:"XPlat Code Coverage" --logger "trx;LogFileName=test_results.trx" || echo "No tests found"
run: dotnet test BinanceBot.sln --no-build --configuration ${{ matrix.configuration }} --collect:"XPlat Code Coverage" --logger "trx;LogFileName=test_results.trx"

- name: Upload test results (TRX)
- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
Expand All @@ -61,7 +62,7 @@ jobs:
**/TestResults/**/*.trx
if-no-files-found: warn

- name: Upload code coverage (Cobertura)
- name: Upload code coverage
if: always()
uses: actions/upload-artifact@v4
with:
Expand Down
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -262,4 +262,7 @@ __pycache__/

# Environment variables
.env
!.env.example
!.env.example

# Logs
logs/*.log
Empty file added logs/.gitkeep
Empty file.
53 changes: 26 additions & 27 deletions src/BinanceBot.Market/Abstracts/BaseMarketBot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,45 +4,44 @@
using Binance.Net.Objects.Models.Spot;
using NLog;

namespace BinanceBot.Market
namespace BinanceBot.Market;

/// <summary>
/// Base Market Bot
/// </summary>
/// <typeparam name="TStrategy"></typeparam>
public abstract class BaseMarketBot<TStrategy> :
IMarketBot, IDisposable
where TStrategy : class, IMarketStrategy
{
/// <summary>
/// Base Market Bot
/// </summary>
/// <typeparam name="TStrategy"></typeparam>
public abstract class BaseMarketBot<TStrategy> :
IMarketBot, IDisposable
where TStrategy : class, IMarketStrategy
{
protected readonly Logger Logger;
protected readonly Logger Logger;

protected readonly TStrategy MarketStrategy;
protected readonly TStrategy MarketStrategy;


protected BaseMarketBot(string symbol, TStrategy marketStrategy, Logger logger)
{
Symbol = symbol ?? throw new ArgumentNullException(nameof(symbol));
MarketStrategy = marketStrategy ?? throw new ArgumentNullException(nameof(marketStrategy));
Logger = logger ?? LogManager.GetCurrentClassLogger();
}
protected BaseMarketBot(string symbol, TStrategy marketStrategy, Logger logger)
{
Symbol = symbol ?? throw new ArgumentNullException(nameof(symbol));
MarketStrategy = marketStrategy ?? throw new ArgumentNullException(nameof(marketStrategy));
Logger = logger ?? LogManager.GetCurrentClassLogger();
}


public string Symbol { get; }
public string Symbol { get; }


public abstract Task RunAsync();
public abstract Task RunAsync();

public abstract void Stop();
public abstract void Stop();

public abstract Task ValidateServerTimeAsync();
public abstract Task ValidateServerTimeAsync();

public abstract Task<IEnumerable<BinanceOrder>> GetOpenedOrdersAsync(string symbol);
public abstract Task<IEnumerable<BinanceOrder>> GetOpenedOrdersAsync(string symbol);

public abstract Task CancelOrdersAsync(IEnumerable<BinanceOrder> orders);
public abstract Task CancelOrdersAsync(IEnumerable<BinanceOrder> orders);

public abstract Task<BinancePlacedOrder> CreateOrderAsync(CreateOrderRequest order);
public abstract Task<BinancePlacedOrder> CreateOrderAsync(CreateOrderRequest order);


public abstract void Dispose();
}

public abstract void Dispose();
}
87 changes: 43 additions & 44 deletions src/BinanceBot.Market/Abstracts/IMarketBot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,51 +3,50 @@
using Binance.Net.Objects.Models.Spot;


namespace BinanceBot.Market
namespace BinanceBot.Market;

/// <summary>
/// Market Bot Interface
/// </summary>
public interface IMarketBot
{
/// <summary>
/// Market Bot Interface
/// Symbol
/// </summary>
string Symbol { get; }


/// <summary>
/// Run bot
/// </summary>
Task RunAsync();

/// <summary>
/// Stop bot
/// </summary>
void Stop();


/// <summary>
/// Validate connection w/ stock
/// </summary>
Task ValidateServerTimeAsync();

/// <summary>
/// Get currently opened orders
/// </summary>
/// <param name="symbol"></param>
Task<IEnumerable<BinanceOrder>> GetOpenedOrdersAsync(string symbol);

/// <summary>
/// Create new order
/// </summary>
/// <param name="order"></param>
Task<BinancePlacedOrder> CreateOrderAsync(CreateOrderRequest order);

/// <summary>
/// Cancel orders
/// </summary>
public interface IMarketBot
{
/// <summary>
/// Symbol
/// </summary>
string Symbol { get; }


/// <summary>
/// Run bot
/// </summary>
Task RunAsync();

/// <summary>
/// Stop bot
/// </summary>
void Stop();


/// <summary>
/// Validate connection w/ stock
/// </summary>
Task ValidateServerTimeAsync();

/// <summary>
/// Get currently opened orders
/// </summary>
/// <param name="symbol"></param>
Task<IEnumerable<BinanceOrder>> GetOpenedOrdersAsync(string symbol);

/// <summary>
/// Create new order
/// </summary>
/// <param name="order"></param>
Task<BinancePlacedOrder> CreateOrderAsync(CreateOrderRequest order);

/// <summary>
/// Cancel orders
/// </summary>
/// <param name="orders"></param>
Task CancelOrdersAsync(IEnumerable<BinanceOrder> orders);
}
/// <param name="orders"></param>
Task CancelOrdersAsync(IEnumerable<BinanceOrder> orders);
}
77 changes: 38 additions & 39 deletions src/BinanceBot.Market/Abstracts/IMarketDepthPublisher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,59 +2,58 @@
using System.Collections.Generic;
using BinanceBot.Market.Core;

namespace BinanceBot.Market
namespace BinanceBot.Market;

/// <summary>
/// Publisher of <see cref="MarketDepth"/> events
/// </summary>
public interface IMarketDepthPublisher
{
/// <summary>
/// Publisher of <see cref="MarketDepth"/> events
/// Order book was changed
/// </summary>
public interface IMarketDepthPublisher
{
/// <summary>
/// Order book was changed
/// </summary>
event EventHandler<MarketDepthChangedEventArgs> MarketDepthChanged;

/// <summary>
/// Best <seealso cref="MarketDepthPair"/> was changed
/// </summary>
event EventHandler<MarketBestPairChangedEventArgs> MarketBestPairChanged;
}


event EventHandler<MarketDepthChangedEventArgs> MarketDepthChanged;

/// <summary>
/// Order book changed event args
/// Best <seealso cref="MarketDepthPair"/> was changed
/// </summary>
public sealed class MarketBestPairChangedEventArgs : EventArgs
{
public MarketBestPairChangedEventArgs(MarketDepthPair marketBestPair)
{
MarketBestPair = marketBestPair ?? throw new ArgumentNullException(nameof(marketBestPair));
}
event EventHandler<MarketBestPairChangedEventArgs> MarketBestPairChanged;
}



public MarketDepthPair MarketBestPair { get; }
/// <summary>
/// Order book changed event args
/// </summary>
public sealed class MarketBestPairChangedEventArgs : EventArgs
{
public MarketBestPairChangedEventArgs(MarketDepthPair marketBestPair)
{
MarketBestPair = marketBestPair ?? throw new ArgumentNullException(nameof(marketBestPair));
}

public MarketDepthPair MarketBestPair { get; }
}

/// <summary>
/// Best <seealso cref="MarketDepthPair"/> changed event args
/// </summary>
public sealed class MarketDepthChangedEventArgs : EventArgs

/// <summary>
/// Best <seealso cref="MarketDepthPair"/> changed event args
/// </summary>
public sealed class MarketDepthChangedEventArgs : EventArgs
{
public MarketDepthChangedEventArgs(IEnumerable<Quote> asks, IEnumerable<Quote> bids, long updateTime)
{
public MarketDepthChangedEventArgs(IEnumerable<Quote> asks, IEnumerable<Quote> bids, long updateTime)
{
if (updateTime <= 0) throw new ArgumentOutOfRangeException(nameof(updateTime));
if (updateTime <= 0) throw new ArgumentOutOfRangeException(nameof(updateTime));

Asks = asks;
Bids = bids;
UpdateTime = updateTime;
}
Asks = asks;
Bids = bids;
UpdateTime = updateTime;
}


public IEnumerable<Quote> Asks { get; }
public IEnumerable<Quote> Asks { get; }

public IEnumerable<Quote> Bids { get; }
public IEnumerable<Quote> Bids { get; }

public long UpdateTime { get; }
}
public long UpdateTime { get; }
}
19 changes: 9 additions & 10 deletions src/BinanceBot.Market/Abstracts/IMarketStrategy.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
namespace BinanceBot.Market
{
namespace BinanceBot.Market;

/// <summary>
/// MarketStrategy interface
/// </summary>
/// <remarks>
/// As simple as possible now
/// </remarks>
public interface IMarketStrategy { }
}

/// <summary>
/// MarketStrategy interface
/// </summary>
/// <remarks>
/// As simple as possible now
/// </remarks>
public interface IMarketStrategy { }
2 changes: 1 addition & 1 deletion src/BinanceBot.Market/BinanceBot.Market.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<ItemGroup>
<PackageReference Include="Binance.Net" Version="8.5.1" />
<PackageReference Include="NLog" Version="6.0.5" />
<PackageReference Include="NLog" Version="6.0.6" />
</ItemGroup>

</Project>
Loading