diff --git a/.gitignore b/.gitignore
index a49625e3c..b5d4e16ef 100644
--- a/.gitignore
+++ b/.gitignore
@@ -57,7 +57,9 @@ _NCrunch_*
.vs
node_modules
**/launchSettings.json
+**/appsettings.json
**/appsettings.*.json
+!**/appsettings.Serilog.json
**/docker-compose.dev.yml
**/marginTradingSettings.json
**/*.ps1
diff --git a/BenchmarkRunner/BenchmarkRunner.csproj b/BenchmarkRunner/BenchmarkRunner.csproj
new file mode 100644
index 000000000..4269d8967
--- /dev/null
+++ b/BenchmarkRunner/BenchmarkRunner.csproj
@@ -0,0 +1,19 @@
+
+
+
+ Exe
+ netcoreapp2.2
+ ExternalOrderbooksBenchmark
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/BenchmarkRunner/Program.cs b/BenchmarkRunner/Program.cs
new file mode 100644
index 000000000..7297a1a71
--- /dev/null
+++ b/BenchmarkRunner/Program.cs
@@ -0,0 +1,17 @@
+// Copyright (c) 2019 Lykke Corp.
+// See the LICENSE file in the project root for more information.
+
+using BenchmarkDotNet.Running;
+using BenchmarkScenarios;
+
+namespace ExternalOrderbooksBenchmark
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ //var summary = BenchmarkRunner.Run();
+ var summary = BenchmarkRunner.Run();
+ }
+ }
+}
\ No newline at end of file
diff --git a/BenchmarkScenarios/BenchmarkScenarios.csproj b/BenchmarkScenarios/BenchmarkScenarios.csproj
new file mode 100644
index 000000000..45f794064
--- /dev/null
+++ b/BenchmarkScenarios/BenchmarkScenarios.csproj
@@ -0,0 +1,17 @@
+
+
+
+ netcoreapp2.2
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/BenchmarkScenarios/ConcurrentDictionaryVsReadWriteLockedDictionaryBenchmark.cs b/BenchmarkScenarios/ConcurrentDictionaryVsReadWriteLockedDictionaryBenchmark.cs
new file mode 100644
index 000000000..b5833f3b0
--- /dev/null
+++ b/BenchmarkScenarios/ConcurrentDictionaryVsReadWriteLockedDictionaryBenchmark.cs
@@ -0,0 +1,112 @@
+// Copyright (c) 2019 Lykke Corp.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using BenchmarkDotNet.Attributes;
+using MarginTrading.Backend.Core.Orderbooks;
+using MarginTrading.Common.Helpers;
+
+namespace BenchmarkScenarios
+{
+ [CoreJob]
+ [RPlotExporter, RankColumn]
+ public class ConcurrentDictionaryVsReadWriteLockedDictionaryBenchmark
+ {
+ private static readonly ReadWriteLockedDictionary> RwlDictionary =
+ new ReadWriteLockedDictionary>();
+
+ private static readonly ConcurrentDictionary> ConcurDictionary =
+ new ConcurrentDictionary>();
+
+ private static readonly ExternalOrderBook OrderBook = new ExternalOrderBook(
+ "test",
+ "test",
+ DateTime.Now,
+ new [] {new VolumePrice() {Price = 1, Volume = 1}},
+ new [] {new VolumePrice() {Price = 1, Volume = 1}}
+ );
+
+ private static readonly Action RwlActionAdd = () =>
+ {
+ RwlDictionary.AddOrUpdate("test",
+ k => UpdateOrderbooksDictionary(k, new Dictionary()),
+ UpdateOrderbooksDictionary);
+ };
+
+ private static readonly Action RwlActionGet = () =>
+ {
+ RwlDictionary.TryReadValue("test", (dataExist, assetPair, orderbooks)
+ => dataExist ? DoSomeJob(orderbooks) : null);
+ };
+
+ private static readonly Action ConcurActionAdd = () =>
+ {
+ ConcurDictionary.AddOrUpdate("test",
+ k => UpdateOrderbooksDictionary(k, new Dictionary()),
+ UpdateOrderbooksDictionary);
+ };
+
+ private static readonly Action ConcurActionGet = () =>
+ {
+ if (ConcurDictionary.TryGetValue("test", out var orderbooks))
+ {
+ DoSomeJob(orderbooks);
+ }
+ };
+
+ private readonly List _rwlDictionaryActions = new List
+ {
+ RwlActionAdd,
+ RwlActionGet,
+ RwlActionGet,
+ RwlActionGet,
+ RwlActionGet,
+ };
+
+ private readonly List _concurDictionaryActions = new List
+ {
+ ConcurActionAdd,
+ ConcurActionGet,
+ ConcurActionGet,
+ ConcurActionGet,
+ ConcurActionGet,
+ };
+
+ private static decimal? DoSomeJob(Dictionary orderbooks)
+ {
+ return !orderbooks.TryGetValue("test", out var orderBook)
+ ? null
+ : orderBook.Asks.FirstOrDefault()?.Price;
+ }
+
+ private static Dictionary UpdateOrderbooksDictionary(string assetPairId,
+ Dictionary dict)
+ {
+ dict[OrderBook.ExchangeName] = OrderBook;
+
+ return dict;
+ }
+
+ [Benchmark]
+ public void RwlDictionaryTest()
+ {
+ foreach (var action in _rwlDictionaryActions)
+ {
+ Task.Factory.StartNew(action);
+ }
+ }
+
+ [Benchmark]
+ public void ConcurDictionaryTest()
+ {
+ foreach (var action in _concurDictionaryActions)
+ {
+ Task.Factory.StartNew(action);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/BenchmarkScenarios/ExternalOrderbookServicesBenchmark.cs b/BenchmarkScenarios/ExternalOrderbookServicesBenchmark.cs
new file mode 100644
index 000000000..677de2f61
--- /dev/null
+++ b/BenchmarkScenarios/ExternalOrderbookServicesBenchmark.cs
@@ -0,0 +1,106 @@
+// Copyright (c) 2019 Lykke Corp.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Collections.Generic;
+using BenchmarkDotNet.Attributes;
+using Common.Log;
+using Lykke.MarginTrading.OrderBookService.Contracts;
+using MarginTrading.Backend.Core;
+using MarginTrading.Backend.Core.Orderbooks;
+using MarginTrading.Backend.Core.Repositories;
+using MarginTrading.Backend.Core.Settings;
+using MarginTrading.Backend.Services.AssetPairs;
+using MarginTrading.Backend.Services.Events;
+using MarginTrading.Backend.Services.Infrastructure;
+using MarginTrading.Backend.Services.Stp;
+using MarginTrading.Common.Services;
+using Moq;
+
+namespace BenchmarkScenarios
+{
+ [CoreJob]
+ [RPlotExporter, RankColumn]
+ public class ExternalOrderbookServicesBenchmark
+ {
+ private ExternalOrderbookService _service;
+
+ private LightweightExternalOrderbookService _lightweightService;
+
+ public ExternalOrderbookServicesBenchmark()
+ {
+ var doMock = new Mock();
+ doMock.Setup(a => a.IsDayOff(It.IsAny())).Returns(true);
+
+ _service = new ExternalOrderbookService(
+ Mock.Of>(),
+ Mock.Of(),
+ Mock.Of(),
+ Mock.Of(),
+ doMock.Object,
+ Mock.Of(),
+ Mock.Of(),
+ Mock.Of(),
+ Mock.Of(),
+ Mock.Of(),
+ new MarginTradingSettings() {DefaultExternalExchangeId = "test"});
+
+ _lightweightService = new LightweightExternalOrderbookService(
+ Mock.Of>(),
+ Mock.Of(),
+ Mock.Of(),
+ Mock.Of(),
+ Mock.Of(),
+ doMock.Object,
+ Mock.Of(),
+ Mock.Of(),
+ Mock.Of(),
+ Mock.Of(),
+ new MarginTradingSettings() {DefaultExternalExchangeId = "test"});
+ }
+
+ private static readonly ExternalOrderBook OrderBook = new ExternalOrderBook(
+ "test",
+ "test",
+ DateTime.Now,
+ new []
+ {
+ new VolumePrice {Price = 1, Volume = 1},
+ new VolumePrice {Price = 1, Volume = 1},
+ new VolumePrice {Price = 1, Volume = 1},
+ new VolumePrice {Price = 1, Volume = 1},
+ new VolumePrice {Price = 1, Volume = 1},
+ new VolumePrice {Price = 1, Volume = 1},
+ new VolumePrice {Price = 1, Volume = 1},
+ new VolumePrice {Price = 1, Volume = 1},
+ new VolumePrice {Price = 1, Volume = 1},
+ new VolumePrice {Price = 1, Volume = 1}
+ },
+ new []
+ {
+ new VolumePrice {Price = 1, Volume = 1},
+ new VolumePrice {Price = 1, Volume = 1},
+ new VolumePrice {Price = 1, Volume = 1},
+ new VolumePrice {Price = 1, Volume = 1},
+ new VolumePrice {Price = 1, Volume = 1},
+ new VolumePrice {Price = 1, Volume = 1},
+ new VolumePrice {Price = 1, Volume = 1},
+ new VolumePrice {Price = 1, Volume = 1},
+ new VolumePrice {Price = 1, Volume = 1},
+ new VolumePrice {Price = 1, Volume = 1},
+ }
+ );
+
+ [Benchmark]
+ public void Default()
+ {
+ _service.SetOrderbook(OrderBook);
+ }
+
+ [Benchmark]
+ public void Lightweight()
+ {
+ _lightweightService.SetOrderbook(OrderBook);
+ }
+ }
+}
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
index 8864d4a39..e01d32e6d 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,18 +1,13 @@
-MIT License
-
-Copyright (c) 2017
+Copyright (c) 2019 Lykke Corp.
Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
+of this software and associated documentation files (the “Software”), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
diff --git a/MarginTrading.sln b/MarginTrading.sln
index 28654502a..a1930fe7b 100644
--- a/MarginTrading.sln
+++ b/MarginTrading.sln
@@ -13,12 +13,11 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution items", "Solution items", "{805BE832-6AA9-4026-8131-309A1C5B570C}"
ProjectSection(SolutionItems) = preProject
.gitignore = .gitignore
+ README.md = README.md
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MarginTrading.Common", "src\MarginTrading.Common\MarginTrading.Common.csproj", "{28D8D798-8EF9-48BC-9F10-6E7823343CC9}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MarginTrading.Frontend", "src\MarginTrading.Frontend\MarginTrading.Frontend.csproj", "{23988B46-8A81-4324-B1F8-0FD2F5EFDD24}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MarginTrading.Backend", "src\MarginTrading.Backend\MarginTrading.Backend.csproj", "{E6A712C9-78F1-4573-B3A4-318FA4A6BA0D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MarginTrading.Backend.Services", "src\MarginTrading.Backend.Services\MarginTrading.Backend.Services.csproj", "{5030E6AA-4DDE-41EC-AE8A-609C2D7D5D37}"
@@ -29,32 +28,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MarginTrading.Backend.Core"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MarginTrading.AzureRepositories", "src\MarginTrading.AzureRepositories\MarginTrading.AzureRepositories.csproj", "{C78B5B26-4078-47FE-BCD1-CF6F9886A4FC}"
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "5. Wamp test client", "5. Wamp test client", "{18A6F48C-BAC6-4D92-A9AD-764E4F8BEB82}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MarginTrading.Client", "src\MarginTrading.Client\MarginTrading.Client.csproj", "{47A3C5B2-289D-41B9-8B73-F2C5995227A9}"
-EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "6. Brokers", "6. Brokers", "{E74A349A-3D48-4345-80E7-FD4C462864F0}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MarginTrading.AccountHistoryBroker", "src\MarginTrading.Brokers\MarginTrading.AccountHistoryBroker\MarginTrading.AccountHistoryBroker.csproj", "{08FFD2CD-50C4-4B84-BA9E-27667677E20C}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MarginTrading.OrderHistoryBroker", "src\MarginTrading.Brokers\MarginTrading.OrderHistoryBroker\MarginTrading.OrderHistoryBroker.csproj", "{02819188-B172-400E-9DBA-9A7E5C4F6266}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MarginTrading.OrderRejectedBroker", "src\MarginTrading.Brokers\MarginTrading.OrderRejectedBroker\MarginTrading.OrderRejectedBroker.csproj", "{BE0E8F09-2A68-426E-B457-5AA929CD998F}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MarginTrading.BrokerBase", "src\MarginTrading.Brokers\MarginTrading.BrokerBase\MarginTrading.BrokerBase.csproj", "{6B4B176C-58E3-4C66-96E2-91330192F238}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MarginTrading.AccountMarginEventsBroker", "src\MarginTrading.Brokers\MarginTrading.AccountMarginEventsBroker\MarginTrading.AccountMarginEventsBroker.csproj", "{2228A223-02B8-472C-98BC-8F71E8F0F604}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MarginTrading.DataReader", "src\MarginTrading.DataReader\MarginTrading.DataReader.csproj", "{88F0B500-1119-4292-A721-15B13BB1A4BA}"
-EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MarginTrading.Contract", "src\MarginTrading.Contract\MarginTrading.Contract.csproj", "{08346EF4-8525-4CE0-93C4-CCE510D27D88}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MarginTrading.Backend.Core.Mappers", "src\MarginTrading.Backend.Core.Mappers\MarginTrading.Backend.Core.Mappers.csproj", "{41948BD6-0CD9-4A2B-BAA3-02AD065AD52B}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MarginTrading.AccountReportsBroker", "src\MarginTrading.Brokers\MarginTrading.AccountReportsBroker\MarginTrading.AccountReportsBroker.csproj", "{9595DED9-58C9-4732-87B1-891AFC2282B1}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MarginTrading.Frontend.Tests", "tests\MarginTrading.Frontend.Tests\MarginTrading.Frontend.Tests.csproj", "{FE2B7AD8-4085-410A-8855-75F9FC650EFB}"
-EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MarginTrading.Backend.Contracts", "src\MarginTrading.Backend.Contracts\MarginTrading.Backend.Contracts.csproj", "{5EC22A63-BA3F-41A2-A70F-216B7E809390}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "3. Backend", "3. Backend", "{1EA2FA6D-0FEA-47D9-B8CE-EF31A1C54DCD}"
@@ -65,7 +46,13 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MarginTrading.ExternalOrder
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MarginTrading.OrderbookBestPricesBroker", "src\MarginTrading.Brokers\MarginTrading.OrderbookBestPricesBroker\MarginTrading.OrderbookBestPricesBroker.csproj", "{B9DD492A-58CC-4716-879F-725AE2218AB7}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MarginTrading.MigrateApp", "src\MarginTrading.Brokers\MarginTrading.MigrateApp\MarginTrading.MigrateApp.csproj", "{921B4212-E0C8-4422-A689-A19095BD5CDC}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MarginTrading.SqlRepositories", "src\MarginTrading.SqlRepositories\MarginTrading.SqlRepositories.csproj", "{115EFE4D-B269-4D62-944D-12C9FC1AE56A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MarginTrading.BrokerBase", "src\MarginTrading.Brokers\MarginTrading.BrokerBase\MarginTrading.BrokerBase.csproj", "{970E8EC9-C56E-44A1-AD1D-8DEB653C404E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BenchmarkRunner", "BenchmarkRunner\BenchmarkRunner.csproj", "{08EC2443-941D-4DA8-A7AE-F92D4BB12E0A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BenchmarkScenarios", "BenchmarkScenarios\BenchmarkScenarios.csproj", "{A479EF23-D993-45A3-983D-948A4BC8067E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -77,10 +64,6 @@ Global
{28D8D798-8EF9-48BC-9F10-6E7823343CC9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{28D8D798-8EF9-48BC-9F10-6E7823343CC9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{28D8D798-8EF9-48BC-9F10-6E7823343CC9}.Release|Any CPU.Build.0 = Release|Any CPU
- {23988B46-8A81-4324-B1F8-0FD2F5EFDD24}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {23988B46-8A81-4324-B1F8-0FD2F5EFDD24}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {23988B46-8A81-4324-B1F8-0FD2F5EFDD24}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {23988B46-8A81-4324-B1F8-0FD2F5EFDD24}.Release|Any CPU.Build.0 = Release|Any CPU
{E6A712C9-78F1-4573-B3A4-318FA4A6BA0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E6A712C9-78F1-4573-B3A4-318FA4A6BA0D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E6A712C9-78F1-4573-B3A4-318FA4A6BA0D}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -101,34 +84,10 @@ Global
{C78B5B26-4078-47FE-BCD1-CF6F9886A4FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C78B5B26-4078-47FE-BCD1-CF6F9886A4FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C78B5B26-4078-47FE-BCD1-CF6F9886A4FC}.Release|Any CPU.Build.0 = Release|Any CPU
- {47A3C5B2-289D-41B9-8B73-F2C5995227A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {47A3C5B2-289D-41B9-8B73-F2C5995227A9}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {47A3C5B2-289D-41B9-8B73-F2C5995227A9}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {47A3C5B2-289D-41B9-8B73-F2C5995227A9}.Release|Any CPU.Build.0 = Release|Any CPU
- {08FFD2CD-50C4-4B84-BA9E-27667677E20C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {08FFD2CD-50C4-4B84-BA9E-27667677E20C}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {08FFD2CD-50C4-4B84-BA9E-27667677E20C}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {08FFD2CD-50C4-4B84-BA9E-27667677E20C}.Release|Any CPU.Build.0 = Release|Any CPU
- {02819188-B172-400E-9DBA-9A7E5C4F6266}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {02819188-B172-400E-9DBA-9A7E5C4F6266}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {02819188-B172-400E-9DBA-9A7E5C4F6266}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {02819188-B172-400E-9DBA-9A7E5C4F6266}.Release|Any CPU.Build.0 = Release|Any CPU
- {BE0E8F09-2A68-426E-B457-5AA929CD998F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {BE0E8F09-2A68-426E-B457-5AA929CD998F}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {BE0E8F09-2A68-426E-B457-5AA929CD998F}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {BE0E8F09-2A68-426E-B457-5AA929CD998F}.Release|Any CPU.Build.0 = Release|Any CPU
- {6B4B176C-58E3-4C66-96E2-91330192F238}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {6B4B176C-58E3-4C66-96E2-91330192F238}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {6B4B176C-58E3-4C66-96E2-91330192F238}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {6B4B176C-58E3-4C66-96E2-91330192F238}.Release|Any CPU.Build.0 = Release|Any CPU
{2228A223-02B8-472C-98BC-8F71E8F0F604}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2228A223-02B8-472C-98BC-8F71E8F0F604}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2228A223-02B8-472C-98BC-8F71E8F0F604}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2228A223-02B8-472C-98BC-8F71E8F0F604}.Release|Any CPU.Build.0 = Release|Any CPU
- {88F0B500-1119-4292-A721-15B13BB1A4BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {88F0B500-1119-4292-A721-15B13BB1A4BA}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {88F0B500-1119-4292-A721-15B13BB1A4BA}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {88F0B500-1119-4292-A721-15B13BB1A4BA}.Release|Any CPU.Build.0 = Release|Any CPU
{08346EF4-8525-4CE0-93C4-CCE510D27D88}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{08346EF4-8525-4CE0-93C4-CCE510D27D88}.Debug|Any CPU.Build.0 = Debug|Any CPU
{08346EF4-8525-4CE0-93C4-CCE510D27D88}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -137,14 +96,6 @@ Global
{41948BD6-0CD9-4A2B-BAA3-02AD065AD52B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{41948BD6-0CD9-4A2B-BAA3-02AD065AD52B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{41948BD6-0CD9-4A2B-BAA3-02AD065AD52B}.Release|Any CPU.Build.0 = Release|Any CPU
- {9595DED9-58C9-4732-87B1-891AFC2282B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {9595DED9-58C9-4732-87B1-891AFC2282B1}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {9595DED9-58C9-4732-87B1-891AFC2282B1}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {9595DED9-58C9-4732-87B1-891AFC2282B1}.Release|Any CPU.Build.0 = Release|Any CPU
- {FE2B7AD8-4085-410A-8855-75F9FC650EFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {FE2B7AD8-4085-410A-8855-75F9FC650EFB}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {FE2B7AD8-4085-410A-8855-75F9FC650EFB}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {FE2B7AD8-4085-410A-8855-75F9FC650EFB}.Release|Any CPU.Build.0 = Release|Any CPU
{5EC22A63-BA3F-41A2-A70F-216B7E809390}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5EC22A63-BA3F-41A2-A70F-216B7E809390}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5EC22A63-BA3F-41A2-A70F-216B7E809390}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -161,29 +112,32 @@ Global
{B9DD492A-58CC-4716-879F-725AE2218AB7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B9DD492A-58CC-4716-879F-725AE2218AB7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B9DD492A-58CC-4716-879F-725AE2218AB7}.Release|Any CPU.Build.0 = Release|Any CPU
- {921B4212-E0C8-4422-A689-A19095BD5CDC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {921B4212-E0C8-4422-A689-A19095BD5CDC}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {921B4212-E0C8-4422-A689-A19095BD5CDC}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {921B4212-E0C8-4422-A689-A19095BD5CDC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {115EFE4D-B269-4D62-944D-12C9FC1AE56A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {115EFE4D-B269-4D62-944D-12C9FC1AE56A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {115EFE4D-B269-4D62-944D-12C9FC1AE56A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {115EFE4D-B269-4D62-944D-12C9FC1AE56A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {970E8EC9-C56E-44A1-AD1D-8DEB653C404E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {970E8EC9-C56E-44A1-AD1D-8DEB653C404E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {970E8EC9-C56E-44A1-AD1D-8DEB653C404E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {970E8EC9-C56E-44A1-AD1D-8DEB653C404E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {08EC2443-941D-4DA8-A7AE-F92D4BB12E0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {08EC2443-941D-4DA8-A7AE-F92D4BB12E0A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {08EC2443-941D-4DA8-A7AE-F92D4BB12E0A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {08EC2443-941D-4DA8-A7AE-F92D4BB12E0A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A479EF23-D993-45A3-983D-948A4BC8067E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A479EF23-D993-45A3-983D-948A4BC8067E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A479EF23-D993-45A3-983D-948A4BC8067E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A479EF23-D993-45A3-983D-948A4BC8067E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{28D8D798-8EF9-48BC-9F10-6E7823343CC9} = {84F3857F-CE2C-4A87-ACB2-809570092CF6}
- {23988B46-8A81-4324-B1F8-0FD2F5EFDD24} = {A1366CA2-DF4A-4E38-BD6C-895A399118B4}
{AFC440C0-68F0-447F-9C04-7614E6323B22} = {F9EA3679-8D3F-4DC2-B0A9-08801E02EE70}
{C78B5B26-4078-47FE-BCD1-CF6F9886A4FC} = {5AD188EF-3F19-4527-816C-A361746EE9C2}
- {47A3C5B2-289D-41B9-8B73-F2C5995227A9} = {18A6F48C-BAC6-4D92-A9AD-764E4F8BEB82}
- {08FFD2CD-50C4-4B84-BA9E-27667677E20C} = {E74A349A-3D48-4345-80E7-FD4C462864F0}
- {02819188-B172-400E-9DBA-9A7E5C4F6266} = {E74A349A-3D48-4345-80E7-FD4C462864F0}
- {BE0E8F09-2A68-426E-B457-5AA929CD998F} = {E74A349A-3D48-4345-80E7-FD4C462864F0}
- {6B4B176C-58E3-4C66-96E2-91330192F238} = {E74A349A-3D48-4345-80E7-FD4C462864F0}
{2228A223-02B8-472C-98BC-8F71E8F0F604} = {E74A349A-3D48-4345-80E7-FD4C462864F0}
- {88F0B500-1119-4292-A721-15B13BB1A4BA} = {A1366CA2-DF4A-4E38-BD6C-895A399118B4}
{08346EF4-8525-4CE0-93C4-CCE510D27D88} = {84F3857F-CE2C-4A87-ACB2-809570092CF6}
- {9595DED9-58C9-4732-87B1-891AFC2282B1} = {E74A349A-3D48-4345-80E7-FD4C462864F0}
- {FE2B7AD8-4085-410A-8855-75F9FC650EFB} = {F9EA3679-8D3F-4DC2-B0A9-08801E02EE70}
{5EC22A63-BA3F-41A2-A70F-216B7E809390} = {1EA2FA6D-0FEA-47D9-B8CE-EF31A1C54DCD}
{A3E8A724-1ACD-4C92-AC1E-91D4AFFD17FE} = {1EA2FA6D-0FEA-47D9-B8CE-EF31A1C54DCD}
{41948BD6-0CD9-4A2B-BAA3-02AD065AD52B} = {1EA2FA6D-0FEA-47D9-B8CE-EF31A1C54DCD}
@@ -192,7 +146,10 @@ Global
{E6A712C9-78F1-4573-B3A4-318FA4A6BA0D} = {A1366CA2-DF4A-4E38-BD6C-895A399118B4}
{AE4DA150-F395-4E80-B1A2-2D0D4FDB89D8} = {E74A349A-3D48-4345-80E7-FD4C462864F0}
{B9DD492A-58CC-4716-879F-725AE2218AB7} = {E74A349A-3D48-4345-80E7-FD4C462864F0}
- {921B4212-E0C8-4422-A689-A19095BD5CDC} = {E74A349A-3D48-4345-80E7-FD4C462864F0}
+ {115EFE4D-B269-4D62-944D-12C9FC1AE56A} = {5AD188EF-3F19-4527-816C-A361746EE9C2}
+ {970E8EC9-C56E-44A1-AD1D-8DEB653C404E} = {E74A349A-3D48-4345-80E7-FD4C462864F0}
+ {08EC2443-941D-4DA8-A7AE-F92D4BB12E0A} = {F9EA3679-8D3F-4DC2-B0A9-08801E02EE70}
+ {A479EF23-D993-45A3-983D-948A4BC8067E} = {F9EA3679-8D3F-4DC2-B0A9-08801E02EE70}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {16BCEC97-771D-46F8-BD02-379A8FC34CDD}
diff --git a/MarginTrading.sln.DotSettings b/MarginTrading.sln.DotSettings
new file mode 100644
index 000000000..5e9904edd
--- /dev/null
+++ b/MarginTrading.sln.DotSettings
@@ -0,0 +1,12 @@
+
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ Copyright (c) 2019 Lykke Corp.
+See the LICENSE file in the project root for more information.
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 39af52c07..df01dc160 100644
--- a/README.md
+++ b/README.md
@@ -1,29 +1,231 @@
-# README #
+# MarginTrading.Backend, MarginTrading.AccountMarginEventsBroker #
-This README would normally document whatever steps are necessary to get your application up and running.
+Margin trading core API. Broker to pass margin and liquidation events from message queue to storage.
+Below is the API description.
-### What is this repository for? ###
+## How to use in prod env? ##
-* Quick summary
-* Version
-* [Learn Markdown](https://bitbucket.org/tutorials/markdowndemo)
+1. Pull "mt-trading-core" docker image with a corresponding tag.
+2. Configure environment variables according to "Environment variables" section.
+3. Put secrets.json with endpoint data including the certificate:
+```json
+"Kestrel": {
+ "EndPoints": {
+ "HttpsInlineCertFile": {
+ "Url": "https://*:5130",
+ "Certificate": {
+ "Path": "",
+ "Password": ""
+ }
+ }
+}
+```
+4. Initialize all dependencies.
+5. Run.
-### How do I get set up? ###
+## How to run for debug? ##
-* Summary of set up
-* Configuration
-* Dependencies
-* Database configuration
-* How to run tests
-* Deployment instructions
+1. Clone repo to some directory.
+2. In MarginTrading.Backend root create a appsettings.dev.json with settings.
+3. Add environment variable "SettingsUrl": "appsettings.dev.json".
+4. VPN to a corresponding env must be connected and all dependencies must be initialized.
+5. Run.
-### Contribution guidelines ###
+## Startup process ##
-* Writing tests
-* Code review
-* Other guidelines
+1. Standard ASP.NET middlewares are initialised.
+2. Settings are loaded.
+3. Health checks are ran:
+- StartupDeduplicationService checks a "TradingEngine:DeduplicationTimestamp" in Redis and
+if DeduplicationTimestamp > (now - DeduplicationCheckPeriod) exception is thrown saying:
+"Trading Engine failed to start due to deduplication validation failure".
+- StartupQueuesCheckerService checks that OrderHistory and PositionHistory broker related queues are empty.
+Queue names are set in settings StartupQueuesChecker section with OrderHistoryQueueName and PositionHistoryQueueName.
+4. IoC container is built, all caches are warmed up.
+5. Scheduled jobs are initialised.
-### Who do I talk to? ###
+### Dependencies ###
-* Repo owner or admin
-* Other community or team contact
\ No newline at end of file
+TBD
+
+### Configuration ###
+
+Kestrel configuration may be passed through appsettings.json, secrets or environment.
+All variables and value constraints are default. For instance, to set host URL the following env variable may be set:
+```json
+{
+ "Kestrel__EndPoints__Http__Url": "http://*:5030"
+}
+```
+
+### Environment variables ###
+
+* *RESTART_ATTEMPTS_NUMBER* - number of restart attempts. If not set int.MaxValue is used.
+* *RESTART_ATTEMPTS_INTERVAL_MS* - interval between restarts in milliseconds. If not set 10000 is used.
+* *SettingsUrl* - defines URL of remote settings or path for local settings.
+
+### Settings ###
+
+Settings schema is:
+
+```json
+{
+ "AccountsManagementServiceClient": {
+ "ServiceUrl": "http://mt-account-management.mt.svc.cluster.local"
+ },
+ "Jobs": {
+ "NotificationsHubName": "",
+ "NotificationsHubConnectionString": ""
+ },
+ "MtBackend": {
+ "ApiKey": "MT Core backend api key",
+ "MtRabbitMqConnString": "amqp://login:password@rabbit-mt.mt.svc.cluster.local:5672",
+ "Db": {
+ "StorageMode": "SqlServer",
+ "LogsConnString": "logs connection string",
+ "MarginTradingConnString": "date connection string",
+ "StateConnString": "state connection string",
+ "SqlConnectionString": "sql connection string",
+ "OrdersHistorySqlConnectionString": "sql connection string",
+ "OrdersHistoryTableName": "OrdersHistory",
+ "PositionsHistorySqlConnectionString": "sql connection string",
+ "PositionsHistoryTableName": "PositionsHistory",
+ "QueryTimeouts":
+ {
+ "GetLastSnapshotTimeoutS": 120
+ }
+ },
+ "RabbitMqQueues": {
+ "OrderHistory": {
+ "ExchangeName": "lykke.mt.orderhistory"
+ },
+ "OrderRejected": {
+ "ExchangeName": "lykke.mt.orderrejected"
+ },
+ "OrderbookPrices": {
+ "ExchangeName": "lykke.mt.pricefeed"
+ },
+ "AccountStopout": {
+ "ExchangeName": "lykke.mt.account.stopout"
+ },
+ "AccountMarginEvents": {
+ "ExchangeName": "lykke.mt.account.marginevents"
+ },
+ "AccountStats": {
+ "ExchangeName": "lykke.mt.account.stats"
+ },
+ "Trades": {
+ "ExchangeName": "lykke.mt.trades"
+ },
+ "PositionHistory": {
+ "ExchangeName": "lykke.mt.position.history"
+ },
+ "ExternalOrder": {
+ "ExchangeName": "lykke.stpexchangeconnector.trades"
+ },
+ "MarginTradingEnabledChanged": {
+ "ExchangeName": "lykke.mt.enabled.changed"
+ },
+ "SettingsChanged": {
+ "ExchangeName": "MtCoreSettingsChanged"
+ }
+ },
+ "FxRateRabbitMqSettings": {
+ "ConnectionString": "amqp://login:pwd@rabbit-mt.mt.svc.cluster.local:5672",
+ "ExchangeName": "lykke.stpexchangeconnector.fxRates"
+ },
+ "StpAggregatorRabbitMqSettings": {
+ "ConnectionString": "amqp://login:pwd@rabbit-mt.mt.svc.cluster.local:5672",
+ "ExchangeName": "lykke.exchangeconnector.orderbooks",
+ "ConsumerCount": 10
+ },
+ "BlobPersistence": {
+ "QuotesDumpPeriodMilliseconds": 3400000,
+ "FxRatesDumpPeriodMilliseconds": 3500000,
+ "OrderbooksDumpPeriodMilliseconds": 3600000,
+ "OrdersDumpPeriodMilliseconds": 600000
+ },
+ "RequestLoggerSettings": {
+ "Enabled": false,
+ "MaxPartSize": 2048
+ },
+ "Telemetry": {
+ "LockMetricThreshold": 10
+ },
+ "ReportingEquivalentPricesSettings": [
+ {
+ "LegalEntity": "Default",
+ "EquivalentAsset": "EUR"
+ },
+ {
+ "LegalEntity": "UNKNOWN",
+ "EquivalentAsset": "USD"
+ }
+ ],
+ "UseAzureIdentityGenerator": false,
+ "WriteOperationLog": true,
+ "UseSerilog": false,
+ "ExchangeConnector": "FakeExchangeConnector",
+ "MaxMarketMakerLimitOrderAge": 3000000,
+ "Cqrs": {
+ "ConnectionString": "amqp://login:pwd@rabbit-mt.mt.svc.cluster.local:5672",
+ "RetryDelay": "00:00:02",
+ "EnvironmentName": "env name"
+ },
+ "SpecialLiquidation": {
+ "Enabled": true,
+ "FakePrice": 5,
+ "PriceRequestTimeoutSec": 600,
+ "RetryTimeout": "00:01:00",
+ "VolumeThreshold": 1000,
+ "VolumeThresholdCurrency": "EUR"
+ },
+ "ChaosKitty": {
+ "StateOfChaos": 0
+ },
+ "Throttling": {
+ "MarginCallThrottlingPeriodMin": 30,
+ "StopOutThrottlingPeriodMin": 1
+ },
+ "OvernightMargin": {
+ "ScheduleMarketId": "PlatformScheduleMarketId",
+ "OvernightMarginParameter": 100,
+ "WarnPeriodMinutes": 10,
+ "ActivationPeriodMinutes": 10
+ },
+ "PendingOrderRetriesThreshold": 100,
+ "RedisSettings": {
+ "Configuration": "redis conn str"
+ },
+ "DeduplicationTimestampPeriod": "00:00:01",
+ "DeduplicationCheckPeriod": "00:00:02",
+ "StartupQueuesChecker": {
+ "ConnectionString": "amqp://login:pwd@rabbit-mt.mt.svc.cluster.local:5672",
+ "OrderHistoryQueueName": "lykke.mt.orderhistory.MarginTrading.TradingHistory.OrderHistoryBroker.DefaultEnv",
+ "PositionHistoryQueueName": "lykke.mt.position.history.MarginTrading.TradingHistory.PositionHistoryBroker.DefaultEnv.PositionsHistory"
+ }
+ },
+ "MtStpExchangeConnectorClient": {
+ "ServiceUrl": "http://gavel.mt.svc.cluster.local:5019",
+ "ApiKey": "key"
+ },
+ "OrderBookServiceClient": {
+ "ServiceUrl": "http://mt-orderbook-service.mt.svc.cluster.local"
+ },
+ "SettingsServiceClient": {
+ "ServiceUrl": "http://mt-settings-service.mt.svc.cluster.local"
+ }
+}
+```
+
+#### Optional sections of MtBackend ####
+(with hardcoded default values):
+
+```json
+"OrderbookValidation": {
+ "ValidateInstrumentStatusForTradingQuotes": false,
+ "ValidateInstrumentStatusForTradingFx": false,
+ "ValidateInstrumentStatusForEodQuotes": true,
+ "ValidateInstrumentStatusForEodFx": true
+}
+```
diff --git a/src/MarginTrading.AzureRepositories/AccountAssetsPairsRepository.cs b/src/MarginTrading.AzureRepositories/AccountAssetsPairsRepository.cs
deleted file mode 100644
index 75e50e1ab..000000000
--- a/src/MarginTrading.AzureRepositories/AccountAssetsPairsRepository.cs
+++ /dev/null
@@ -1,143 +0,0 @@
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using AzureStorage;
-using MarginTrading.AzureRepositories.Contract;
-using MarginTrading.Backend.Core;
-using MarginTrading.Backend.Core.Settings;
-using MarginTrading.Backend.Core.TradingConditions;
-using Microsoft.WindowsAzure.Storage.Table;
-
-namespace MarginTrading.AzureRepositories
-{
- public class AccountAssetPairEntity : TableEntity, IAccountAssetPair
- {
- public string TradingConditionId { get; set; }
- public string BaseAssetId { get; set; }
- public string Instrument => RowKey;
- public int LeverageInit { get; set; }
- public int LeverageMaintenance { get; set; }
- decimal IAccountAssetPair.SwapLong => (decimal) SwapLong;
- public double SwapLong { get; set; }
- decimal IAccountAssetPair.SwapShort => (decimal) SwapShort;
- public double SwapShort { get; set; }
- decimal IAccountAssetPair.OvernightSwapLong => (decimal) OvernightSwapLong;
- public double OvernightSwapLong { get; set; }
- decimal IAccountAssetPair.OvernightSwapShort => (decimal) OvernightSwapShort;
- public double OvernightSwapShort { get; set; }
- decimal IAccountAssetPair.CommissionLong => (decimal) CommissionLong;
- public double CommissionLong { get; set; }
- decimal IAccountAssetPair.CommissionShort => (decimal) CommissionShort;
- public double CommissionShort { get; set; }
- decimal IAccountAssetPair.CommissionLot => (decimal) CommissionLot;
- public double CommissionLot { get; set; }
- decimal IAccountAssetPair.DeltaBid => (decimal) DeltaBid;
- public double DeltaBid { get; set; }
- decimal IAccountAssetPair.DeltaAsk => (decimal) DeltaAsk;
- public double DeltaAsk { get; set; }
- decimal IAccountAssetPair.DealLimit => (decimal) DealLimit;
- public double DealLimit { get; set; }
- decimal IAccountAssetPair.PositionLimit => (decimal) PositionLimit;
- public double PositionLimit { get; set; }
-
- public static string GeneratePartitionKey(string tradingConditionId, string baseAssetId)
- {
- return $"{tradingConditionId}_{baseAssetId}";
- }
-
- public static string GenerateRowKey(string instrument)
- {
- return instrument;
- }
-
- public static AccountAssetPairEntity Create(IAccountAssetPair src)
- {
- return new AccountAssetPairEntity
- {
- PartitionKey = GeneratePartitionKey(src.TradingConditionId, src.BaseAssetId),
- RowKey = GenerateRowKey(src.Instrument),
- TradingConditionId = src.TradingConditionId,
- BaseAssetId = src.BaseAssetId,
- LeverageInit = src.LeverageInit,
- LeverageMaintenance = src.LeverageMaintenance,
- SwapLong = (double) src.SwapLong,
- SwapShort = (double) src.SwapShort,
- OvernightSwapLong = (double) src.OvernightSwapLong,
- OvernightSwapShort = (double) src.OvernightSwapShort,
- CommissionLong = (double) src.CommissionLong,
- CommissionShort = (double) src.CommissionShort,
- CommissionLot = (double) src.CommissionLot,
- DeltaBid = (double) src.DeltaBid,
- DeltaAsk = (double) src.DeltaAsk,
- DealLimit = (double) src.DealLimit,
- PositionLimit = (double) src.PositionLimit
- };
- }
- }
-
- public class AccountAssetsPairsRepository : IAccountAssetPairsRepository
- {
- private readonly INoSQLTableStorage _tableStorage;
-
- public AccountAssetsPairsRepository(INoSQLTableStorage tableStorage)
- {
- _tableStorage = tableStorage;
- }
-
- public async Task AddOrReplaceAsync(IAccountAssetPair accountAssetPair)
- {
- await _tableStorage.InsertOrReplaceAsync(AccountAssetPairEntity.Create(accountAssetPair));
- }
-
- public async Task GetAsync(string tradingConditionId, string baseAssetId, string assetPairId)
- {
- return await _tableStorage.GetDataAsync(AccountAssetPairEntity.GeneratePartitionKey(tradingConditionId, baseAssetId),
- AccountAssetPairEntity.GenerateRowKey(assetPairId));
- }
-
- public async Task> GetAllAsync(string tradingConditionId, string baseAssetId)
- {
- return await _tableStorage.GetDataAsync(AccountAssetPairEntity.GeneratePartitionKey(tradingConditionId, baseAssetId));
- }
-
- public async Task> GetAllAsync()
- {
- return await _tableStorage.GetDataAsync();
- }
-
- public async Task Remove(string tradingConditionId, string baseAssetId, string assetPairId)
- {
- await _tableStorage.DeleteAsync(
- AccountAssetPairEntity.GeneratePartitionKey(tradingConditionId, baseAssetId),
- AccountAssetPairEntity.GenerateRowKey(assetPairId));
- }
-
- public async Task> AddAssetPairs(string tradingConditionId, string baseAssetId,
- IEnumerable assetPairsIds, AccountAssetsSettings defaults)
- {
- var entitiesToAdd = assetPairsIds.Select(x => AccountAssetPairEntity.Create(
- new AccountAssetPair
- {
- BaseAssetId = baseAssetId,
- TradingConditionId = tradingConditionId,
- Instrument = x,
- CommissionLong = defaults.CommissionLong,
- CommissionLot = defaults.CommissionLot,
- CommissionShort = defaults.CommissionShort,
- DealLimit = defaults.DealLimit,
- DeltaAsk = defaults.DeltaAsk,
- DeltaBid = defaults.DeltaBid,
- LeverageInit = defaults.LeverageInit,
- LeverageMaintenance = defaults.LeverageMaintenance,
- PositionLimit = defaults.PositionLimit,
- SwapLong = defaults.SwapLong,
- SwapShort = defaults.SwapShort,
- OvernightSwapLong = defaults.OvernightSwapLong,
- OvernightSwapShort = defaults.OvernightSwapShort
- })).ToArray();
- await _tableStorage.InsertAsync(entitiesToAdd);
-
- return entitiesToAdd;
- }
- }
-}
diff --git a/src/MarginTrading.AzureRepositories/AccountGroupRepository.cs b/src/MarginTrading.AzureRepositories/AccountGroupRepository.cs
deleted file mode 100644
index 0ab6aae1f..000000000
--- a/src/MarginTrading.AzureRepositories/AccountGroupRepository.cs
+++ /dev/null
@@ -1,74 +0,0 @@
-using System.Collections.Generic;
-using System.Threading.Tasks;
-using AzureStorage;
-using MarginTrading.AzureRepositories.Contract;
-using MarginTrading.Backend.Core.TradingConditions;
-using Microsoft.WindowsAzure.Storage.Table;
-
-namespace MarginTrading.AzureRepositories
-{
- public class AccountGroupEntity : TableEntity, IAccountGroup
- {
- public string TradingConditionId => PartitionKey;
- public string BaseAssetId => RowKey;
-
- decimal IAccountGroup.MarginCall => (decimal) MarginCall;
- public double MarginCall { get; set; }
- decimal IAccountGroup.StopOut => (decimal) StopOut;
- public double StopOut { get; set; }
- decimal IAccountGroup.DepositTransferLimit => (decimal) DepositTransferLimit;
- public double DepositTransferLimit { get; set; }
- decimal IAccountGroup.ProfitWithdrawalLimit => (decimal) ProfitWithdrawalLimit;
- public double ProfitWithdrawalLimit { get; set; }
-
-
- public static string GeneratePartitionKey(string tradingConditionId)
- {
- return tradingConditionId;
- }
-
- public static string GenerateRowKey(string baseAssetid)
- {
- return baseAssetid;
- }
-
- public static AccountGroupEntity Create(IAccountGroup src)
- {
- return new AccountGroupEntity
- {
- PartitionKey = GeneratePartitionKey(src.TradingConditionId),
- RowKey = GenerateRowKey(src.BaseAssetId),
- MarginCall = (double) src.MarginCall,
- StopOut = (double) src.StopOut,
- DepositTransferLimit = (double) src.DepositTransferLimit,
- ProfitWithdrawalLimit = (double) src.ProfitWithdrawalLimit
- };
- }
- }
-
- public class AccountGroupRepository : IAccountGroupRepository
- {
- private readonly INoSQLTableStorage _tableStorage;
-
- public AccountGroupRepository(INoSQLTableStorage tableStorage)
- {
- _tableStorage = tableStorage;
- }
-
- public async Task AddOrReplaceAsync(IAccountGroup group)
- {
- await _tableStorage.InsertOrReplaceAsync(AccountGroupEntity.Create(group));
- }
-
- public async Task GetAsync(string tradingConditionId, string baseAssetId)
- {
- return await _tableStorage.GetDataAsync(AccountGroupEntity.GeneratePartitionKey(tradingConditionId),
- AccountGroupEntity.GenerateRowKey(baseAssetId));
- }
-
- public async Task> GetAllAsync()
- {
- return await _tableStorage.GetDataAsync();
- }
- }
-}
diff --git a/src/MarginTrading.AzureRepositories/AccountStatRepository.cs b/src/MarginTrading.AzureRepositories/AccountStatRepository.cs
new file mode 100644
index 000000000..ab6723f86
--- /dev/null
+++ b/src/MarginTrading.AzureRepositories/AccountStatRepository.cs
@@ -0,0 +1,44 @@
+// Copyright (c) 2019 Lykke Corp.
+// See the LICENSE file in the project root for more information.
+
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using AzureStorage;
+using AzureStorage.Tables;
+using Common.Log;
+using Lykke.SettingsReader;
+using MarginTrading.AzureRepositories.Entities;
+using MarginTrading.Backend.Core;
+using MarginTrading.Backend.Core.Repositories;
+using MarginTrading.Common.Services;
+
+namespace MarginTrading.AzureRepositories
+{
+ public class AccountStatRepository : IAccountStatRepository
+ {
+ private readonly INoSQLTableStorage _tableStorage;
+ private readonly IDateService _dateService;
+
+ public AccountStatRepository(IReloadingManager connectionStringManager,
+ ILog log,
+ IDateService dateService)
+ {
+ _tableStorage = AzureTableStorage.Create(
+ connectionStringManager,
+ "AccountStatDump",
+ log);
+ _dateService = dateService;
+ }
+
+ public async Task Dump(IEnumerable accounts)
+ {
+ var reportTime = _dateService.Now();
+ var entities = accounts.Select(x => AccountStatEntity.Create(x, reportTime));
+
+ await _tableStorage.DeleteAsync();
+ await _tableStorage.CreateTableIfNotExistsAsync();
+ await _tableStorage.InsertAsync(entities);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/MarginTrading.AzureRepositories/AssetPairsRepository.cs b/src/MarginTrading.AzureRepositories/AssetPairsRepository.cs
deleted file mode 100644
index 965761bcb..000000000
--- a/src/MarginTrading.AzureRepositories/AssetPairsRepository.cs
+++ /dev/null
@@ -1,100 +0,0 @@
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using AutoMapper;
-using AzureStorage;
-using Lykke.AzureStorage.Tables;
-using MarginTrading.AzureRepositories.Contract;
-using MarginTrading.Backend.Core;
-using MarginTrading.Backend.Core.MatchingEngines;
-using MarginTrading.Common.Services;
-
-namespace MarginTrading.AzureRepositories
-{
- internal class AssetPairsRepository : IAssetPairsRepository
- {
- private readonly INoSQLTableStorage _tableStorage;
- private readonly IConvertService _convertService;
-
- public AssetPairsRepository(INoSQLTableStorage tableStorage,
- IConvertService convertService)
- {
- _tableStorage = tableStorage;
- _convertService = convertService;
- }
-
- public async Task> GetAsync()
- {
- return Convert(await _tableStorage.GetDataAsync());
- }
-
- public Task InsertAsync(IAssetPair settings)
- {
- return _tableStorage.InsertAsync(Convert(settings));
- }
-
- public Task ReplaceAsync(IAssetPair settings)
- {
- return _tableStorage.ReplaceAsync(Convert(settings));
- }
-
- public async Task DeleteAsync(string assetPairId)
- {
- return Convert(await _tableStorage.DeleteAsync(AssetPairEntity.GeneratePartitionKey(),
- AssetPairEntity.GenerateRowKey(assetPairId)));
- }
-
- public async Task GetAsync(string assetPairId)
- {
- return Convert(await _tableStorage.GetDataAsync(AssetPairEntity.GeneratePartitionKey(),
- AssetPairEntity.GenerateRowKey(assetPairId)));
- }
-
- private static IReadOnlyList Convert(
- IEnumerable accountAssetPairEntities)
- {
- return accountAssetPairEntities.ToList();
- }
-
- private AssetPairEntity Convert(IAssetPair accountAssetPair)
- {
- return _convertService.Convert(accountAssetPair,
- o => o.ConfigureMap(MemberList.Source).ForMember(e => e.ETag, e => e.UseValue("*")));
- }
-
- internal class AssetPairEntity : AzureTableEntity, IAssetPair
- {
- public AssetPairEntity()
- {
- PartitionKey = GeneratePartitionKey();
- }
-
- public string Id
- {
- get => RowKey;
- set => RowKey = value;
- }
-
- public string Name { get; set; }
- public string BaseAssetId { get; set; }
- public string QuoteAssetId { get; set; }
- public int Accuracy { get; set; }
-
- public string LegalEntity { get; set; }
- public string BasePairId { get; set; }
- public MatchingEngineMode MatchingEngineMode { get; set; }
- public decimal StpMultiplierMarkupBid { get; set; }
- public decimal StpMultiplierMarkupAsk { get; set; }
-
- public static string GeneratePartitionKey()
- {
- return "AssetPairs";
- }
-
- public static string GenerateRowKey(string assetPairId)
- {
- return assetPairId;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/MarginTrading.AzureRepositories/AzureIdentityGenerator.cs b/src/MarginTrading.AzureRepositories/AzureIdentityGenerator.cs
index 7f9706f5a..6b081e6a8 100644
--- a/src/MarginTrading.AzureRepositories/AzureIdentityGenerator.cs
+++ b/src/MarginTrading.AzureRepositories/AzureIdentityGenerator.cs
@@ -1,4 +1,7 @@
-using System;
+// Copyright (c) 2019 Lykke Corp.
+// See the LICENSE file in the project root for more information.
+
+using System;
using System.Threading.Tasks;
using AzureStorage;
using MarginTrading.AzureRepositories.Entities;
@@ -37,5 +40,15 @@ public async Task GenerateIdAsync(string entityType)
return id;
}
+
+ public string GenerateAlphanumericId()
+ {
+ return Guid.NewGuid().ToString("N");
+ }
+
+ public string GenerateGuid()
+ {
+ return Guid.NewGuid().ToString("N");
+ }
}
}
\ No newline at end of file
diff --git a/src/MarginTrading.AzureRepositories/AzureRepoFactories.cs b/src/MarginTrading.AzureRepositories/AzureRepoFactories.cs
index 3079c259d..39cd54756 100644
--- a/src/MarginTrading.AzureRepositories/AzureRepoFactories.cs
+++ b/src/MarginTrading.AzureRepositories/AzureRepoFactories.cs
@@ -1,10 +1,10 @@
-using AzureStorage.Tables;
+// Copyright (c) 2019 Lykke Corp.
+// See the LICENSE file in the project root for more information.
+
+using AzureStorage.Tables;
using Common.Log;
using Lykke.SettingsReader;
-using MarginTrading.AzureRepositories.Contract;
-using MarginTrading.AzureRepositories.Entities;
using MarginTrading.AzureRepositories.Logs;
-using MarginTrading.Backend.Core;
using MarginTrading.Common.Services;
namespace MarginTrading.AzureRepositories
@@ -13,35 +13,6 @@ public class AzureRepoFactories
{
public static class MarginTrading
{
- public static TradingConditionsRepository CreateTradingConditionsRepository(IReloadingManager connString, ILog log)
- {
- return new TradingConditionsRepository(AzureTableStorage.Create(connString,
- "MarginTradingConditions", log));
- }
-
- public static AccountGroupRepository CreateAccountGroupRepository(IReloadingManager connString, ILog log)
- {
- return new AccountGroupRepository(AzureTableStorage.Create(connString,
- "MarginTradingAccountGroups", log));
- }
-
- public static AccountAssetsPairsRepository CreateAccountAssetsRepository(IReloadingManager connString, ILog log)
- {
- return new AccountAssetsPairsRepository(AzureTableStorage.Create(connString,
- "MarginTradingAccountAssets", log));
- }
-
- public static MarginTradingOrdersHistoryRepository CreateOrdersHistoryRepository(IReloadingManager connString, ILog log)
- {
- return new MarginTradingOrdersHistoryRepository(AzureTableStorage.Create(connString,
- "MarginTradingOrdersHistory", log));
- }
-
- public static MarginTradingOrdersRejectedRepository CreateOrdersRejectedRepository(IReloadingManager connString, ILog log)
- {
- return new MarginTradingOrdersRejectedRepository(AzureTableStorage.Create(connString,
- "MarginTradingOrdersRejected", log));
- }
public static MarginTradingAccountHistoryRepository CreateAccountHistoryRepository(IReloadingManager connString, ILog log)
{
@@ -49,12 +20,6 @@ public static MarginTradingAccountHistoryRepository CreateAccountHistoryReposito
"AccountsHistory", log));
}
- public static MarginTradingAccountsRepository CreateAccountsRepository(IReloadingManager connString, ILog log)
- {
- return new MarginTradingAccountsRepository(AzureTableStorage.Create(connString,
- "MarginTradingAccounts", log));
- }
-
public static MarginTradingAccountStatsRepository CreateAccountStatsRepository(IReloadingManager connString, ILog log)
{
return new MarginTradingAccountStatsRepository(AzureTableStorage.Create(connString,
@@ -66,42 +31,11 @@ public static MarginTradingBlobRepository CreateBlobRepository(IReloadingManager
return new MarginTradingBlobRepository(connString);
}
- public static MatchingEngineRoutesRepository CreateMatchingEngineRoutesRepository(IReloadingManager connString, ILog log)
- {
- return new MatchingEngineRoutesRepository(AzureTableStorage.Create(connString,
- "MatchingEngineRoutes", log));
- }
-
public static RiskSystemCommandsLogRepository CreateRiskSystemCommandsLogRepository(IReloadingManager connString, ILog log)
{
return new RiskSystemCommandsLogRepository(AzureTableStorage.Create(connString,
"RiskSystemCommandsLog", log));
}
-
- public static OvernightSwapStateRepository CreateOvernightSwapStateRepository(IReloadingManager connString, ILog log)
- {
- return new OvernightSwapStateRepository(AzureTableStorage.Create(connString,
- "OvernightSwapState", log));
- }
-
- public static OvernightSwapHistoryRepository CreateOvernightSwapHistoryRepository(IReloadingManager connString, ILog log)
- {
- return new OvernightSwapHistoryRepository(AzureTableStorage.Create(connString,
- "OvernightSwapHistory", log));
- }
-
- public static IDayOffSettingsRepository CreateDayOffSettingsRepository(IReloadingManager connString)
- {
- return new DayOffSettingsRepository(new MarginTradingBlobRepository(connString));
- }
-
- public static IAssetPairsRepository CreateAssetPairSettingsRepository(IReloadingManager connString,
- ILog log, IConvertService convertService)
- {
- return new AssetPairsRepository(
- AzureTableStorage.Create(connString,
- "AssetPairs", log), convertService);
- }
}
}
}
\ No newline at end of file
diff --git a/src/MarginTrading.AzureRepositories/Contract/IAccountAssetPairsRepository.cs b/src/MarginTrading.AzureRepositories/Contract/IAccountAssetPairsRepository.cs
deleted file mode 100644
index f6364e658..000000000
--- a/src/MarginTrading.AzureRepositories/Contract/IAccountAssetPairsRepository.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using System.Collections.Generic;
-using System.Threading.Tasks;
-using MarginTrading.Backend.Core;
-using MarginTrading.Backend.Core.Settings;
-using MarginTrading.Backend.Core.TradingConditions;
-
-namespace MarginTrading.AzureRepositories.Contract
-{
- public interface IAccountAssetPairsRepository
- {
- Task AddOrReplaceAsync(IAccountAssetPair accountAssetPair);
- Task GetAsync(string tradingConditionId, string baseAssetId, string assetPairId);
- Task> GetAllAsync(string tradingConditionId, string baseAssetId);
- Task> GetAllAsync();
- Task> AddAssetPairs(string tradingConditionId, string baseAssetId, IEnumerable assetPairsIds,
- AccountAssetsSettings defaults);
- Task Remove(string tradingConditionId, string baseAssetId, string assetPairId);
- }
-}
\ No newline at end of file
diff --git a/src/MarginTrading.AzureRepositories/Contract/IAccountGroupRepository.cs b/src/MarginTrading.AzureRepositories/Contract/IAccountGroupRepository.cs
deleted file mode 100644
index 0d298e7ed..000000000
--- a/src/MarginTrading.AzureRepositories/Contract/IAccountGroupRepository.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System.Collections.Generic;
-using System.Threading.Tasks;
-using MarginTrading.Backend.Core.TradingConditions;
-
-namespace MarginTrading.AzureRepositories.Contract
-{
- public interface IAccountGroupRepository
- {
- Task AddOrReplaceAsync(IAccountGroup group);
- Task GetAsync(string tradingConditionId, string baseAssetId);
- Task> GetAllAsync();
- }
-}
diff --git a/src/MarginTrading.AzureRepositories/Contract/IAssetPairsRepository.cs b/src/MarginTrading.AzureRepositories/Contract/IAssetPairsRepository.cs
deleted file mode 100644
index fc8535a55..000000000
--- a/src/MarginTrading.AzureRepositories/Contract/IAssetPairsRepository.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System.Collections.Generic;
-using System.Threading.Tasks;
-using MarginTrading.Backend.Core;
-
-namespace MarginTrading.AzureRepositories.Contract
-{
- public interface IAssetPairsRepository
- {
- Task> GetAsync();
- Task InsertAsync(IAssetPair settings);
- Task ReplaceAsync(IAssetPair settings);
- Task DeleteAsync(string assetPairId);
- Task GetAsync(string assetPairId);
- }
-}
\ No newline at end of file
diff --git a/src/MarginTrading.AzureRepositories/Contract/ITradingConditionRepository.cs b/src/MarginTrading.AzureRepositories/Contract/ITradingConditionRepository.cs
deleted file mode 100644
index a1998603e..000000000
--- a/src/MarginTrading.AzureRepositories/Contract/ITradingConditionRepository.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System.Collections.Generic;
-using System.Threading.Tasks;
-using MarginTrading.Backend.Core;
-using MarginTrading.Backend.Core.TradingConditions;
-
-namespace MarginTrading.AzureRepositories.Contract
-{
- public interface ITradingConditionRepository
- {
- Task AddOrReplaceAsync(ITradingCondition condition);
- Task GetAsync(string tradingConditionId);
- Task> GetAllAsync();
- }
-}
diff --git a/src/MarginTrading.AzureRepositories/DayOffSettingsRepository.cs b/src/MarginTrading.AzureRepositories/DayOffSettingsRepository.cs
deleted file mode 100644
index 37cd8c1a9..000000000
--- a/src/MarginTrading.AzureRepositories/DayOffSettingsRepository.cs
+++ /dev/null
@@ -1,102 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.Immutable;
-using MarginTrading.Backend.Core;
-using MarginTrading.Backend.Core.DayOffSettings;
-
-namespace MarginTrading.AzureRepositories
-{
- internal class DayOffSettingsRepository : IDayOffSettingsRepository
- {
- private const string BlobContainer = "mt-dayoff-settings";
- private const string Key = "DayOffSettingsRoot";
- private readonly IMarginTradingBlobRepository _blobRepository;
-
- public DayOffSettingsRepository(IMarginTradingBlobRepository blobRepository)
- {
- _blobRepository = blobRepository;
- }
-
- public DayOffSettingsRoot Read()
- {
- return Convert(_blobRepository.Read(BlobContainer, Key));
- }
-
- public void Write(DayOffSettingsRoot settings)
- {
- _blobRepository.Write(BlobContainer, Key, Convert(settings));
- }
-
- private static DayOffSettingsRootStorageModel Convert(DayOffSettingsRoot settingsRoot)
- {
- return new DayOffSettingsRootStorageModel
- {
- Exclusions = settingsRoot.Exclusions.ToImmutableDictionary(d => d.Key, d =>
- new DayOffExclusionStorageModel
- {
- AssetPairRegex = d.Value.AssetPairRegex,
- Id = d.Value.Id,
- Start = d.Value.Start,
- End = d.Value.End,
- IsTradeEnabled = d.Value.IsTradeEnabled,
- }),
- ScheduleSettings = new ScheduleSettingsStorageModel
- {
- AssetPairsWithoutDayOff = settingsRoot.ScheduleSettings.AssetPairsWithoutDayOff,
- DayOffEndDay = settingsRoot.ScheduleSettings.DayOffEndDay,
- DayOffEndTime = settingsRoot.ScheduleSettings.DayOffEndTime,
- DayOffStartDay = settingsRoot.ScheduleSettings.DayOffStartDay,
- DayOffStartTime = settingsRoot.ScheduleSettings.DayOffStartTime,
- PendingOrdersCutOff = settingsRoot.ScheduleSettings.PendingOrdersCutOff,
- }
- };
- }
-
- private static DayOffSettingsRoot Convert(DayOffSettingsRootStorageModel settings)
- {
- if (settings == null)
- return null;
-
- return new DayOffSettingsRoot(
- settings.Exclusions.ToImmutableDictionary(s => s.Key, s =>
- new DayOffExclusion(
- id: s.Value.Id,
- assetPairRegex: s.Value.AssetPairRegex,
- start: s.Value.Start,
- end: s.Value.End,
- isTradeEnabled: s.Value.IsTradeEnabled)),
- new ScheduleSettings(
- dayOffStartDay: settings.ScheduleSettings.DayOffStartDay,
- dayOffStartTime: settings.ScheduleSettings.DayOffStartTime,
- dayOffEndDay: settings.ScheduleSettings.DayOffEndDay,
- dayOffEndTime: settings.ScheduleSettings.DayOffEndTime,
- assetPairsWithoutDayOff: settings.ScheduleSettings.AssetPairsWithoutDayOff,
- pendingOrdersCutOff: settings.ScheduleSettings.PendingOrdersCutOff));
- }
-
- public class DayOffSettingsRootStorageModel
- {
- public ImmutableDictionary Exclusions { get; set; }
- public ScheduleSettingsStorageModel ScheduleSettings { get; set; }
- }
-
- public class DayOffExclusionStorageModel
- {
- public Guid Id { get; set; }
- public string AssetPairRegex { get; set; }
- public DateTime Start { get; set; }
- public DateTime End { get; set; }
- public bool IsTradeEnabled { get; set; }
- }
-
- public class ScheduleSettingsStorageModel
- {
- public DayOfWeek DayOffStartDay { get; set; }
- public TimeSpan DayOffStartTime { get; set; }
- public DayOfWeek DayOffEndDay { get; set; }
- public TimeSpan DayOffEndTime { get; set; }
- public HashSet AssetPairsWithoutDayOff { get; set; }
- public TimeSpan PendingOrdersCutOff { get; set; }
- }
- }
-}
\ No newline at end of file
diff --git a/src/MarginTrading.AzureRepositories/Entities/AccountStatEntity.cs b/src/MarginTrading.AzureRepositories/Entities/AccountStatEntity.cs
new file mode 100644
index 000000000..99531b272
--- /dev/null
+++ b/src/MarginTrading.AzureRepositories/Entities/AccountStatEntity.cs
@@ -0,0 +1,48 @@
+// Copyright (c) 2019 Lykke Corp.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using Lykke.AzureStorage.Tables;
+using MarginTrading.Backend.Core;
+
+namespace MarginTrading.AzureRepositories.Entities
+{
+ public class AccountStatEntity : AzureTableEntity
+ {
+ public string Id => RowKey;
+
+ public decimal PnL { get; set; }
+ public decimal UnrealizedDailyPnl { get; set; }
+ public decimal UsedMargin { get; set; }
+ public decimal MarginInit { get; set; }
+ public int OpenPositionsCount { get; set; }
+ public decimal MarginCall1Level { get; set; }
+ public decimal MarginCall2Level { get; set; }
+ public decimal StopoutLevel { get; set; }
+
+ public decimal WithdrawalFrozenMargin { get; set; }
+ public decimal UnconfirmedMargin { get; set; }
+
+ public DateTime HistoryTimestamp { get; set; }
+
+ public static AccountStatEntity Create(MarginTradingAccount account, DateTime now)
+ {
+ return new AccountStatEntity
+ {
+ PartitionKey = "AccountStats",
+ RowKey = account.Id,
+ PnL = account.GetPnl(),
+ UnrealizedDailyPnl = account.GetUnrealizedDailyPnl(),
+ UsedMargin = account.GetUsedMargin(),
+ MarginInit = account.GetMarginInit(),
+ OpenPositionsCount = account.GetOpenPositionsCount(),
+ MarginCall1Level = account.GetMarginCall1Level(),
+ MarginCall2Level = account.GetMarginCall2Level(),
+ StopoutLevel = account.GetStopOutLevel(),
+ WithdrawalFrozenMargin = account.GetFrozenMargin(),
+ UnconfirmedMargin = account.GetUnconfirmedMargin(),
+ HistoryTimestamp = now,
+ };
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/MarginTrading.AzureRepositories/Entities/IdentityEntity.cs b/src/MarginTrading.AzureRepositories/Entities/IdentityEntity.cs
index f36e8cf75..e073e94b1 100644
--- a/src/MarginTrading.AzureRepositories/Entities/IdentityEntity.cs
+++ b/src/MarginTrading.AzureRepositories/Entities/IdentityEntity.cs
@@ -1,4 +1,7 @@
-using Microsoft.WindowsAzure.Storage.Table;
+// Copyright (c) 2019 Lykke Corp.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.WindowsAzure.Storage.Table;
namespace MarginTrading.AzureRepositories.Entities
{
diff --git a/src/MarginTrading.AzureRepositories/Entities/OpenPositionEntity.cs b/src/MarginTrading.AzureRepositories/Entities/OpenPositionEntity.cs
new file mode 100644
index 000000000..86c1c6678
--- /dev/null
+++ b/src/MarginTrading.AzureRepositories/Entities/OpenPositionEntity.cs
@@ -0,0 +1,105 @@
+// Copyright (c) 2019 Lykke Corp.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Collections.Generic;
+using AzureStorage.Tables;
+using Common;
+using Lykke.AzureStorage.Tables;
+using MarginTrading.Backend.Core;
+using MarginTrading.Backend.Core.Orders;
+
+namespace MarginTrading.AzureRepositories.Entities
+{
+ public class OpenPositionEntity : AzureTableEntity
+ {
+ public string Id => RowKey;
+ public long Code { get; set; }
+ public string AssetPairId { get; set; }
+ public string Direction { get; set; }
+ public decimal Volume { get; set; }
+ public string AccountId { get; set; }
+ public string TradingConditionId { get; set; }
+ public string AccountAssetId { get; set; }
+ public decimal? ExpectedOpenPrice { get; set; }
+ public string OpenMatchingEngineId { get; set; }
+ public DateTime OpenDate { get; set; }
+ public string OpenTradeId { get; set; }
+ public decimal OpenPrice { get; set; }
+ public decimal OpenFxPrice { get; set; }
+ public string EquivalentAsset { get; set; }
+ public decimal OpenPriceEquivalent { get; set; }
+ public string LegalEntity { get; set; }
+ public string OpenOriginator { get; set; }
+ public string ExternalProviderId { get; set; }
+ public decimal SwapCommissionRate { get; set; }
+ public decimal OpenCommissionRate { get; set; }
+ public decimal CloseCommissionRate { get; set; }
+ public decimal CommissionLot { get; set; }
+ public string CloseMatchingEngineId { get; set; }
+ public decimal ClosePrice { get; set; }
+ public decimal CloseFxPrice { get; set; }
+ public decimal ClosePriceEquivalent { get; set; }
+ public DateTime? StartClosingDate { get; set; }
+ public DateTime? CloseDate { get; set; }
+ public string CloseOriginator { get; set; }
+ public string CloseReason { get; set; }
+ public string CloseComment { get; set; }
+ public string CloseTrades { get; set; }
+ public DateTime? LastModified { get; set; }
+ public decimal TotalPnL { get; set; }
+ public decimal ChargedPnL { get; set; }
+ public decimal Margin { get; set; }
+
+ public string RelatedOrders { get; set; }
+
+ public DateTime HistoryTimestamp { get; set; }
+
+ public static OpenPositionEntity Create(Position position, DateTime now)
+ {
+ return new OpenPositionEntity
+ {
+ PartitionKey = "OpenPositions",
+ RowKey = position.Id,
+ AccountAssetId = position.AccountAssetId,
+ AccountId = position.AccountId,
+ AssetPairId = position.AssetPairId,
+ CloseComment = position.CloseComment,
+ CloseCommissionRate = position.CloseCommissionRate,
+ CloseDate = position.CloseDate,
+ CloseFxPrice = position.CloseFxPrice,
+ CloseMatchingEngineId = position.CloseMatchingEngineId,
+ CloseOriginator = position.CloseOriginator?.ToString(),
+ ClosePrice = position.ClosePrice,
+ ClosePriceEquivalent = position.ClosePriceEquivalent,
+ CloseReason = position.CloseReason.ToString(),
+ CloseTrades = position.CloseTrades.ToJson(),
+ Code = position.Code,
+ CommissionLot = position.CommissionLot,
+ Direction = position.Direction.ToString(),
+ EquivalentAsset = position.EquivalentAsset,
+ ExpectedOpenPrice = position.ExpectedOpenPrice,
+ ExternalProviderId = position.ExternalProviderId,
+ LastModified = position.LastModified,
+ LegalEntity = position.LegalEntity,
+ OpenCommissionRate = position.OpenCommissionRate,
+ OpenDate = position.OpenDate,
+ OpenFxPrice = position.OpenFxPrice,
+ OpenMatchingEngineId = position.OpenMatchingEngineId,
+ OpenOriginator = position.OpenOriginator.ToString(),
+ OpenPrice = position.OpenPrice,
+ OpenPriceEquivalent = position.OpenPriceEquivalent,
+ OpenTradeId = position.OpenTradeId,
+ RelatedOrders = position.RelatedOrders.ToJson(),
+ StartClosingDate = position.CloseDate,
+ SwapCommissionRate = position.SwapCommissionRate,
+ TotalPnL = position.GetFpl(),
+ ChargedPnL = position.ChargedPnL,
+ Margin = position.GetMarginMaintenance(),
+ TradingConditionId = position.TradingConditionId,
+ Volume = position.Volume,
+ HistoryTimestamp = now,
+ };
+ }
+ }
+}
diff --git a/src/MarginTrading.AzureRepositories/Entities/OperationExecutionInfoEntity.cs b/src/MarginTrading.AzureRepositories/Entities/OperationExecutionInfoEntity.cs
new file mode 100644
index 000000000..363ae2877
--- /dev/null
+++ b/src/MarginTrading.AzureRepositories/Entities/OperationExecutionInfoEntity.cs
@@ -0,0 +1,40 @@
+// Copyright (c) 2019 Lykke Corp.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using Lykke.AzureStorage.Tables;
+using MarginTrading.Backend.Core;
+using Newtonsoft.Json;
+
+namespace MarginTrading.AzureRepositories.Entities
+{
+ public class OperationExecutionInfoEntity : AzureTableEntity, IOperationExecutionInfo