Skip to content
Open
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
812 changes: 812 additions & 0 deletions csharp/TraderBot/AbstractTradingService.cs

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions csharp/TraderBot/ApiProviderSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace TraderBot;

public class ApiProviderSettings
{
public string Provider { get; set; } = "Tinkoff";
}

public class InvestApiSettings
{
public string? AccessToken { get; set; }
public string? AppName { get; set; }
}
8 changes: 8 additions & 0 deletions csharp/TraderBot/Interfaces/IAccount.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace TraderBot.Interfaces;

public interface IAccount
{
string Id { get; }
string Name { get; }
DateTime OpenedDate { get; }
}
16 changes: 16 additions & 0 deletions csharp/TraderBot/Interfaces/IInstrument.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace TraderBot.Interfaces;

public interface IInstrument
{
string Figi { get; }
string Ticker { get; }
int Lot { get; }
decimal MinPriceIncrement { get; }
TradingInstrumentType InstrumentType { get; }
}

public enum TradingInstrumentType
{
Etf,
Shares
}
19 changes: 19 additions & 0 deletions csharp/TraderBot/Interfaces/IOperation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace TraderBot.Interfaces;

public interface IOperation
{
string Id { get; }
TradingOperationType OperationType { get; }
DateTime Date { get; }
long Quantity { get; }
decimal Price { get; }
long QuantityRest { get; }
IEnumerable<ITrade>? Trades { get; }
long GetActualQuantity();
}

public enum TradingOperationType
{
Buy,
Sell
}
48 changes: 48 additions & 0 deletions csharp/TraderBot/Interfaces/IOrder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
namespace TraderBot.Interfaces;

public interface IOrder
{
string OrderId { get; }
string Figi { get; }
TradingOrderDirection Direction { get; }
long LotsRequested { get; set; }
decimal InitialSecurityPrice { get; }
decimal InitialOrderPrice { get; }
}

public interface IOrderRequest
{
string OrderId { get; }
string AccountId { get; }
TradingOrderDirection Direction { get; }
TradingOrderType OrderType { get; }
string Figi { get; }
long Quantity { get; }
decimal Price { get; }
}

public interface IOrderResponse
{
string OrderId { get; }
string Figi { get; }
TradingOrderDirection Direction { get; }
long LotsRequested { get; }
decimal InitialSecurityPrice { get; }
}

public interface ICancelOrderResponse
{
string OrderId { get; }
}

public enum TradingOrderDirection
{
Buy,
Sell
}

public enum TradingOrderType
{
Limit,
Market
}
18 changes: 18 additions & 0 deletions csharp/TraderBot/Interfaces/IOrderBook.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace TraderBot.Interfaces;

public interface IOrderBookStream : IAsyncEnumerable<IOrderBook>
{
}

public interface IOrderBook
{
string Figi { get; }
IEnumerable<IOrderBookEntry> Bids { get; }
IEnumerable<IOrderBookEntry> Asks { get; }
}

public interface IOrderBookEntry
{
decimal Price { get; }
long Quantity { get; }
}
26 changes: 26 additions & 0 deletions csharp/TraderBot/Interfaces/IPosition.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
namespace TraderBot.Interfaces;

public interface IPosition
{
string Figi { get; }
decimal Balance { get; }
}

public interface IPortfolio
{
IEnumerable<IPortfolioPosition> Positions { get; }
IEnumerable<IMoneyValue> Money { get; }
IEnumerable<IMoneyValue> Blocked { get; }
}

public interface IPortfolioPosition
{
string Figi { get; }
decimal Quantity { get; }
}

public interface IMoneyValue
{
string Currency { get; }
decimal Value { get; }
}
31 changes: 31 additions & 0 deletions csharp/TraderBot/Interfaces/ITrades.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
namespace TraderBot.Interfaces;

public interface ITradesStream : IAsyncEnumerable<ITradeData>
{
}

public interface ITradeData
{
TradeDataType DataType { get; }
IOrderTrades? OrderTrades { get; }
}

public interface IOrderTrades
{
string OrderId { get; }
TradingOrderDirection Direction { get; }
IEnumerable<ITrade> Trades { get; }
}

public interface ITrade
{
long Quantity { get; }
decimal Price { get; }
DateTime DateTime { get; }
}

public enum TradeDataType
{
OrderTrades,
Ping
}
16 changes: 16 additions & 0 deletions csharp/TraderBot/Interfaces/ITradingApiProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace TraderBot.Interfaces;

public interface ITradingApiProvider
{
Task InitializeAsync();
Task<IEnumerable<IAccount>> GetAccountsAsync();
Task<IInstrument> GetInstrumentAsync(string ticker, TradingInstrumentType instrumentType);
Task<IOrderBookStream> SubscribeToOrderBookAsync(string figi, int depth);
Task<ITradesStream> SubscribeToTradesAsync(string accountId);
Task<IEnumerable<IOrder>> GetOrdersAsync(string accountId);
Task<IEnumerable<IPosition>> GetPositionsAsync(string accountId);
Task<IPortfolio> GetPortfolioAsync(string accountId);
Task<IEnumerable<IOperation>> GetOperationsAsync(string accountId, string figi, DateTime from, DateTime to);
Task<IOrderResponse> PlaceOrderAsync(IOrderRequest orderRequest);
Task<ICancelOrderResponse> CancelOrderAsync(string accountId, string orderId);
}
48 changes: 43 additions & 5 deletions csharp/TraderBot/Program.cs
Original file line number Diff line number Diff line change
@@ -1,29 +1,67 @@
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration.UserSecrets;
using Microsoft.Extensions.Logging;
using Tinkoff.InvestApi;
using TraderBot;
using TraderBot.Interfaces;
using TraderBot.Providers;

var builder = Host.CreateDefaultBuilder(args);
var host = builder
.ConfigureServices((context, services) =>
{
// Register settings
services.AddSingleton(_ =>
{
var section = context.Configuration.GetSection(nameof(TradingSettings));
return section.Get<TradingSettings>();
return section.Get<TradingSettings>()!;
});
services.AddHostedService<TradingService>();

services.AddSingleton(_ =>
{
var section = context.Configuration.GetSection(nameof(ApiProviderSettings));
return section.Get<ApiProviderSettings>() ?? new ApiProviderSettings();
});

services.AddSingleton(_ =>
{
var section = context.Configuration.GetSection(nameof(InvestApiSettings));
return section.Get<InvestApiSettings>()!;
});

// Register API providers
services.AddInvestApiClient((_, settings) =>
{
var section = context.Configuration.GetSection(nameof(InvestApiSettings));
var loadedSettings = section.Get<InvestApiSettings>();
settings.AccessToken = loadedSettings.AccessToken;
settings.AccessToken = loadedSettings!.AccessToken;
settings.AppName = loadedSettings.AppName;
context.Configuration.Bind(settings);
});

// Register the trading API provider based on configuration
services.AddSingleton<ITradingApiProvider>(provider =>
{
var apiProviderSettings = provider.GetRequiredService<ApiProviderSettings>();

switch (apiProviderSettings.Provider.ToLowerInvariant())
{
case "tinkoff":
var investApi = provider.GetRequiredService<InvestApiClient>();
var tinkoffLogger = provider.GetRequiredService<ILogger<TinkoffApiProvider>>();
return new TinkoffApiProvider(investApi, tinkoffLogger);
case "mock":
var mockLogger = provider.GetRequiredService<ILogger<MockApiProvider>>();
return new MockApiProvider(mockLogger);
default:
throw new InvalidOperationException($"Unsupported API provider: {apiProviderSettings.Provider}");
}
});

// Register the trading service
services.AddHostedService<AbstractTradingService>();
})
.Build();

await host.RunAsync();
await host.RunAsync();
29 changes: 29 additions & 0 deletions csharp/TraderBot/Program.cs.bak
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration.UserSecrets;
using Tinkoff.InvestApi;
using TraderBot;

var builder = Host.CreateDefaultBuilder(args);
var host = builder
.ConfigureServices((context, services) =>
{
services.AddSingleton(_ =>
{
var section = context.Configuration.GetSection(nameof(TradingSettings));
return section.Get<TradingSettings>();
});
services.AddHostedService<TradingService>();
services.AddInvestApiClient((_, settings) =>
{
var section = context.Configuration.GetSection(nameof(InvestApiSettings));
var loadedSettings = section.Get<InvestApiSettings>();
settings.AccessToken = loadedSettings.AccessToken;
settings.AppName = loadedSettings.AppName;
context.Configuration.Bind(settings);
});
})
.Build();

await host.RunAsync();
Loading
Loading