Repository: jazzonaut/IntelliTrader
Branch: master
Commit: 146e198c16d2
Files: 247
Total size: 929.6 KB
Directory structure:
gitextract_1xkwb3jz/
├── .gitignore
├── .gitmodules
├── Disclaimer.txt
├── IntelliTrader/
│ ├── Help.url
│ ├── IntelliTrader.Web.deps.json
│ ├── IntelliTrader.csproj
│ ├── IntelliTrader.sh
│ ├── Program.cs
│ ├── Properties/
│ │ └── PublishProfiles/
│ │ └── FolderProfile.pubxml
│ ├── config/
│ │ ├── backtesting.json
│ │ ├── core.json
│ │ ├── exchange.json
│ │ ├── logging.json
│ │ ├── notification.json
│ │ ├── paths.json
│ │ ├── rules.json
│ │ ├── signals.json
│ │ ├── trading.json
│ │ └── web.json
│ └── data/
│ ├── encrypt-keys.bat
│ └── encrypt-keys.sh
├── IntelliTrader.Backtesting/
│ ├── AppModule.cs
│ ├── Config/
│ │ └── BacktestingConfig.cs
│ ├── IntelliTrader.Backtesting.csproj
│ ├── Model/
│ │ ├── SignalData.cs
│ │ └── TickerData.cs
│ ├── Services/
│ │ ├── BacktestingExchangeService.cs
│ │ ├── BacktestingService.cs
│ │ └── BacktestingSignalsService.cs
│ └── TimedTasks/
│ ├── BacktestingLoadSnapshotsTimedTask.cs
│ └── BacktestingSaveSnapshotsTimedTask.cs
├── IntelliTrader.Core/
│ ├── AppModule.cs
│ ├── Application.cs
│ ├── IntelliTrader.Core.csproj
│ ├── Interfaces/
│ │ ├── Configs/
│ │ │ ├── IBacktestingConfig.cs
│ │ │ ├── IConfigProvider.cs
│ │ │ ├── ICoreConfig.cs
│ │ │ ├── ILoggingConfig.cs
│ │ │ ├── INotificationConfig.cs
│ │ │ ├── IRulesConfig.cs
│ │ │ ├── ISignalsConfig.cs
│ │ │ ├── ITradingConfig.cs
│ │ │ └── IWebConfig.cs
│ │ ├── Exchange/
│ │ │ └── ITicker.cs
│ │ ├── IHealthCheck.cs
│ │ ├── Rules/
│ │ │ ├── IModuleRules.cs
│ │ │ ├── IRule.cs
│ │ │ ├── IRuleCondition.cs
│ │ │ ├── IRuleTrailing.cs
│ │ │ ├── ISignalRulesConfig.cs
│ │ │ └── RuleProcessingMode.cs
│ │ ├── Services/
│ │ │ ├── Base/
│ │ │ │ ├── IConfigurableService.cs
│ │ │ │ └── INamedService.cs
│ │ │ ├── IBacktestingService.cs
│ │ │ ├── ICoreService.cs
│ │ │ ├── IExchangeService.cs
│ │ │ ├── IHealthCheckService.cs
│ │ │ ├── ILoggingService.cs
│ │ │ ├── INotificationService.cs
│ │ │ ├── IOrderingService.cs
│ │ │ ├── IRulesService.cs
│ │ │ ├── ISignalsService.cs
│ │ │ ├── ITasksService.cs
│ │ │ ├── ITradingService.cs
│ │ │ └── IWebService.cs
│ │ ├── Signals/
│ │ │ ├── ISignal.cs
│ │ │ ├── ISignalDefinition.cs
│ │ │ └── ISignalTrailingInfo.cs
│ │ ├── Tasks/
│ │ │ └── ITimedTask.cs
│ │ └── Trading/
│ │ ├── IBuyConfig.cs
│ │ ├── IBuyDCAConfig.cs
│ │ ├── IOrder.cs
│ │ ├── IOrderDetails.cs
│ │ ├── IPairConfig.cs
│ │ ├── ISellConfig.cs
│ │ ├── ISellDCAConfig.cs
│ │ ├── ITradeResult.cs
│ │ ├── ITradingAccount.cs
│ │ └── ITradingPair.cs
│ ├── Models/
│ │ ├── Config/
│ │ │ ├── ConfigProvider.cs
│ │ │ ├── CoreConfig.cs
│ │ │ ├── LoggingConfig.cs
│ │ │ └── NotificationConfig.cs
│ │ ├── Constants.cs
│ │ ├── HealthCheck.cs
│ │ ├── Logging/
│ │ │ ├── MemorySink.cs
│ │ │ └── MemorySinkExtensions.cs
│ │ ├── Tasks/
│ │ │ ├── EqualResolutionTimedTask.cs
│ │ │ ├── HighResolutionTimedTask.cs
│ │ │ └── LowResolutionTimedTask.cs
│ │ ├── Trading/
│ │ │ ├── Arbitrage.cs
│ │ │ ├── ArbitrageMarket.cs
│ │ │ ├── ArbitrageOptions.cs
│ │ │ ├── ArbitrageType.cs
│ │ │ ├── BuyOptions.cs
│ │ │ ├── BuyTrailingStopAction.cs
│ │ │ ├── DCALevel.cs
│ │ │ ├── OrderMetadata.cs
│ │ │ ├── OrderResult.cs
│ │ │ ├── OrderSide.cs
│ │ │ ├── OrderType.cs
│ │ │ ├── RuleAction.cs
│ │ │ ├── SellOptions.cs
│ │ │ ├── SellTrailingStopAction.cs
│ │ │ ├── SwapOptions.cs
│ │ │ ├── TradePriceType.cs
│ │ │ └── TradeResult.cs
│ │ └── Utils.cs
│ ├── Serialization/
│ │ └── DecimalFormatJsonConverter.cs
│ ├── Services/
│ │ ├── ConfigurableServiceBase.cs
│ │ ├── CoreService.cs
│ │ ├── HealthCheckService.cs
│ │ ├── LoggingService.cs
│ │ ├── NotificationService.cs
│ │ └── TasksService.cs
│ └── TimedTasks/
│ └── HealthCheckTimedTask.cs
├── IntelliTrader.Exchange.Base/
│ ├── AppModule.cs
│ ├── IntelliTrader.Exchange.Base.csproj
│ ├── Models/
│ │ ├── BuyOrder.cs
│ │ ├── Config/
│ │ │ └── ExchangeConfig.cs
│ │ ├── Order.cs
│ │ ├── OrderDetails.cs
│ │ ├── SellOrder.cs
│ │ └── Ticker.cs
│ ├── Services/
│ │ └── ExchangeService.cs
│ └── TimedTasks/
│ └── TickersMonitorTimedTask.cs
├── IntelliTrader.Exchange.Binance/
│ ├── AppModule.cs
│ ├── BinanceExchangeService.cs
│ └── IntelliTrader.Exchange.Binance.csproj
├── IntelliTrader.Launcher/
│ ├── IntelliTrader.Launcher.csproj
│ ├── Program.cs
│ └── Properties/
│ └── AssemblyInfo.cs
├── IntelliTrader.Rules/
│ ├── AppModule.cs
│ ├── Config/
│ │ └── RulesConfig.cs
│ ├── IntelliTrader.Rules.csproj
│ ├── Models/
│ │ ├── ModuleRules.cs
│ │ ├── Rule.cs
│ │ ├── RuleCondition.cs
│ │ └── RuleTrailing.cs
│ └── Services/
│ └── RulesService.cs
├── IntelliTrader.Signals.Base/
│ ├── AppModule.cs
│ ├── IntelliTrader.Signals.Base.csproj
│ ├── Interfaces/
│ │ └── ISignaReceiver.cs
│ ├── Models/
│ │ ├── Config/
│ │ │ └── SignalsConfig.cs
│ │ ├── Signal.cs
│ │ ├── SignalDefinition.cs
│ │ ├── SignalRuleModifiers.cs
│ │ ├── SignalRulesConfig.cs
│ │ └── SignalTrailingInfo.cs
│ ├── Services/
│ │ └── SignalsService.cs
│ └── TimedTasks/
│ └── SignalRulesTimedTask.cs
├── IntelliTrader.Signals.TradingView/
│ ├── AppModule.cs
│ ├── IntelliTrader.Signals.TradingView.csproj
│ ├── Models/
│ │ ├── Config/
│ │ │ └── TradingViewCryptoSignalReceiverConfig.cs
│ │ └── TradingViewCryptoSignalConverter.cs
│ ├── Receivers/
│ │ └── TradingViewCryptoSignalReceiver.cs
│ └── TimedTasks/
│ └── TradingViewCryptoSignalPollingTimedTask.cs
├── IntelliTrader.Trading/
│ ├── AppModule.cs
│ ├── IntelliTrader.Trading.csproj
│ ├── Models/
│ │ ├── Accounts/
│ │ │ ├── ExchangeAccount.cs
│ │ │ ├── TradingAccountBase.cs
│ │ │ ├── TradingAccountData.cs
│ │ │ └── VirtualAccount.cs
│ │ ├── BuyTrailingInfo.cs
│ │ ├── Config/
│ │ │ └── TradingConfig.cs
│ │ ├── PairConfig.cs
│ │ ├── SellTrailingInfo.cs
│ │ ├── TradingPair.cs
│ │ ├── TradingRuleModifiers.cs
│ │ ├── TradingRulesConfig.cs
│ │ └── TrailingInfo.cs
│ ├── Services/
│ │ ├── OrderingService.cs
│ │ └── TradingService.cs
│ └── TimedTasks/
│ ├── AccountRefreshTimedTask.cs
│ ├── TradingRulesTimedTask.cs
│ └── TradingTimedTask.cs
├── IntelliTrader.Web/
│ ├── AppModule.cs
│ ├── Controllers/
│ │ └── HomeController.cs
│ ├── IntelliTrader.Web.csproj
│ ├── Misc/
│ │ └── Utils.cs
│ ├── Models/
│ │ ├── BaseViewModel.cs
│ │ ├── Config/
│ │ │ └── WebConfig.cs
│ │ ├── DashboardViewModel.cs
│ │ ├── HelpViewModel.cs
│ │ ├── LogViewModel.cs
│ │ ├── LoginViewModel.cs
│ │ ├── MarketViewModel.cs
│ │ ├── RulesViewModel.cs
│ │ ├── SettingsViewModel.cs
│ │ ├── StatsViewModel.cs
│ │ └── TradesViewModel.cs
│ ├── Properties/
│ │ └── PublishProfiles/
│ │ └── FolderProfile.pubxml
│ ├── Services/
│ │ └── WebService.cs
│ ├── Startup.cs
│ ├── Static/
│ │ ├── Help/
│ │ │ ├── config.json
│ │ │ ├── index.md
│ │ │ └── navigation.md
│ │ ├── Scripts/
│ │ │ ├── Vendor/
│ │ │ │ └── mdwiki.js
│ │ │ ├── Views/
│ │ │ │ ├── dashboard.js
│ │ │ │ ├── market.js
│ │ │ │ ├── rules.js
│ │ │ │ ├── settings.js
│ │ │ │ ├── stats.js
│ │ │ │ └── trades.js
│ │ │ └── intellitrader.js
│ │ └── Styles/
│ │ ├── Views/
│ │ │ ├── dashboard.css
│ │ │ ├── help.css
│ │ │ ├── market.css
│ │ │ ├── rules.css
│ │ │ ├── settings.css
│ │ │ ├── stats.css
│ │ │ └── trades.css
│ │ └── intellitrader.css
│ └── Views/
│ ├── Home/
│ │ ├── Dashboard.cshtml
│ │ ├── Help.cshtml
│ │ ├── Log.cshtml
│ │ ├── Login.cshtml
│ │ ├── Market.cshtml
│ │ ├── Rules.cshtml
│ │ ├── Settings.cshtml
│ │ ├── Stats.cshtml
│ │ └── Trades.cshtml
│ ├── Shared/
│ │ └── _Layout.cshtml
│ ├── _ViewImports.cshtml
│ └── _ViewStart.cshtml
├── IntelliTrader.sln
├── License.txt
├── Publish/
│ ├── Disclaimer.txt
│ ├── Help.url
│ ├── IntelliTrader.sh
│ ├── License.txt
│ ├── config/
│ │ ├── backtesting.json
│ │ ├── core.json
│ │ ├── exchange.json
│ │ ├── logging.json
│ │ ├── notification.json
│ │ ├── paths.json
│ │ ├── rules.json
│ │ ├── signals.json
│ │ ├── trading.json
│ │ └── web.json
│ └── data/
│ ├── encrypt-keys.bat
│ ├── encrypt-keys.sh
│ └── pm2.IntelliTrader.json
├── Publish.bat
├── Publish.sh
└── README.md
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
## Custom
Tests/
Cache/
Submodules/
keys.bin
virtual-account.json
exchange-account.json
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
**/Properties/launchSettings.json
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
#*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# VScode
*vscode*
.DS_Store
================================================
FILE: .gitmodules
================================================
[submodule "Submodules/ExchangeSharp"]
path = Submodules/ExchangeSharp
url = https://github.com/jazzonaut/ExchangeSharp
branch = master
================================================
FILE: Disclaimer.txt
================================================
By using, or simply downloading IntelliTrader (the Software), you understand and accept the following:
Licensing
The Software is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International licence. Full terms of the licence can be found by following this link:
https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode
A full copy of the license is also included with the download.
Limitation Of Liability
In no event shall liability be accepted for any indirect, incidental, special, consequential or punitive damages, including, without limitation, loss of profits, funds, data, use, goodwill, or other tangible and intangible losses, resulting from:
(i) your access to, or use of, or inability to access or use the Software;
(ii) any content of any third party used with the Software;
(iii) any content obtained from the Software; and
(iv) unauthorized access, use or alteration of your transmissions or content, whether based on warranty, contract, tort (including negligence) or any other legal theory, whether or not we have been informed of the possibility of such damage, and even if a remedy set forth herein is found to have failed of its essential purpose.
We do not refund losses.
Disclaimer
Your use of the Software is at your sole risk. The Software is provided on an “AS IS” and “AS AVAILABLE” basis. The Software is provided without warranties of any kind, whether expressed or implied, including, but not limited to, implied warranties of merchantability, fitness for a particular purpose, non-infringement or course of performance.
No warranty of any kind is expressed or implied, that:
a) the Software will function, be secure or operate on any nominated platform;
b) any errors or defects will be corrected;
c) the Software is free of viruses or other harmful components; or
d) the results of using the Software will meet your requirements.
If you do not agree with any of the above, please do not download or use the Software.
================================================
FILE: IntelliTrader/Help.url
================================================
[InternetShortcut]
URL=https://github.com/jazzonaut/IntelliTrader/wiki
IconFile=https://assets-cdn.github.com/favicon.ico
IconIndex=1
================================================
FILE: IntelliTrader/IntelliTrader.Web.deps.json
================================================
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v2.1",
"signature": "53477019973cf406227ea0f01f2112897f901df8"
},
"compilationOptions": {
"defines": [
"TRACE",
"RELEASE",
"NETCOREAPP",
"NETCOREAPP2_1"
],
"languageVersion": "",
"platform": "",
"allowUnsafe": false,
"warningsAsErrors": false,
"optimize": true,
"keyFile": "",
"emitEntryPoint": false,
"xmlDoc": false,
"debugType": "portable"
},
"targets": {
".NETCoreApp,Version=v2.1": {
"IntelliTrader.Web/1.0.0": {
"dependencies": {
"IntelliTrader.Core": "1.0.0",
"Microsoft.AspNetCore.Authentication": "2.1.1",
"Microsoft.AspNetCore.Authentication.Cookies": "2.1.1",
"Microsoft.AspNetCore.Diagnostics": "2.1.1",
"Microsoft.AspNetCore.Mvc": "2.1.1",
"Microsoft.AspNetCore.Server.Kestrel": "2.1.2",
"Microsoft.AspNetCore.StaticFiles": "2.1.1",
"Microsoft.NETCore.App": "2.1.0"
},
"runtime": {
"IntelliTrader.Web.dll": {}
},
"compile": {
"IntelliTrader.Web.dll": {}
}
},
"Autofac/4.8.1": {
"dependencies": {
"NETStandard.Library": "2.0.3",
"System.ComponentModel": "4.0.1"
},
"runtime": {
"lib/netstandard1.1/Autofac.dll": {
"assemblyVersion": "4.8.1.0",
"fileVersion": "4.8.1.0"
}
},
"compile": {
"lib/netstandard1.1/Autofac.dll": {}
}
},
"Microsoft.AspNetCore.Antiforgery/2.1.1": {
"dependencies": {
"Microsoft.AspNetCore.DataProtection": "2.1.1",
"Microsoft.AspNetCore.Http.Abstractions": "2.1.1",
"Microsoft.AspNetCore.Http.Extensions": "2.1.1",
"Microsoft.AspNetCore.WebUtilities": "2.1.1",
"Microsoft.Extensions.ObjectPool": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Antiforgery.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Antiforgery.dll": {}
}
},
"Microsoft.AspNetCore.Authentication/2.1.1": {
"dependencies": {
"Microsoft.AspNetCore.Authentication.Core": "2.1.1",
"Microsoft.AspNetCore.DataProtection": "2.1.1",
"Microsoft.AspNetCore.Http": "2.1.1",
"Microsoft.AspNetCore.Http.Extensions": "2.1.1",
"Microsoft.Extensions.Logging.Abstractions": "2.1.1",
"Microsoft.Extensions.Options": "2.1.1",
"Microsoft.Extensions.WebEncoders": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Authentication.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Authentication.dll": {}
}
},
"Microsoft.AspNetCore.Authentication.Abstractions/2.1.1": {
"dependencies": {
"Microsoft.AspNetCore.Http.Abstractions": "2.1.1",
"Microsoft.Extensions.Logging.Abstractions": "2.1.1",
"Microsoft.Extensions.Options": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Authentication.Abstractions.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Authentication.Abstractions.dll": {}
}
},
"Microsoft.AspNetCore.Authentication.Cookies/2.1.1": {
"dependencies": {
"Microsoft.AspNetCore.Authentication": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Authentication.Cookies.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Authentication.Cookies.dll": {}
}
},
"Microsoft.AspNetCore.Authentication.Core/2.1.1": {
"dependencies": {
"Microsoft.AspNetCore.Authentication.Abstractions": "2.1.1",
"Microsoft.AspNetCore.Http": "2.1.1",
"Microsoft.AspNetCore.Http.Extensions": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Authentication.Core.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Authentication.Core.dll": {}
}
},
"Microsoft.AspNetCore.Authorization/2.1.1": {
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "2.1.1",
"Microsoft.Extensions.Options": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Authorization.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Authorization.dll": {}
}
},
"Microsoft.AspNetCore.Authorization.Policy/2.1.1": {
"dependencies": {
"Microsoft.AspNetCore.Authentication.Abstractions": "2.1.1",
"Microsoft.AspNetCore.Authorization": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Authorization.Policy.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Authorization.Policy.dll": {}
}
},
"Microsoft.AspNetCore.Connections.Abstractions/2.1.2": {
"dependencies": {
"Microsoft.AspNetCore.Http.Features": "2.1.1",
"System.IO.Pipelines": "4.5.0"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Connections.Abstractions.dll": {
"assemblyVersion": "2.1.2.0",
"fileVersion": "2.1.2.18180"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Connections.Abstractions.dll": {}
}
},
"Microsoft.AspNetCore.Cors/2.1.1": {
"dependencies": {
"Microsoft.AspNetCore.Http.Extensions": "2.1.1",
"Microsoft.Extensions.Configuration.Abstractions": "2.1.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.1.1",
"Microsoft.Extensions.Logging.Abstractions": "2.1.1",
"Microsoft.Extensions.Options": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Cors.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Cors.dll": {}
}
},
"Microsoft.AspNetCore.Cryptography.Internal/2.1.1": {
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Cryptography.Internal.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Cryptography.Internal.dll": {}
}
},
"Microsoft.AspNetCore.DataProtection/2.1.1": {
"dependencies": {
"Microsoft.AspNetCore.Cryptography.Internal": "2.1.1",
"Microsoft.AspNetCore.DataProtection.Abstractions": "2.1.1",
"Microsoft.AspNetCore.Hosting.Abstractions": "2.1.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.1.1",
"Microsoft.Extensions.Logging.Abstractions": "2.1.1",
"Microsoft.Extensions.Options": "2.1.1",
"Microsoft.Win32.Registry": "4.5.0",
"System.Security.Cryptography.Xml": "4.5.0",
"System.Security.Principal.Windows": "4.5.0"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.DataProtection.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.DataProtection.dll": {}
}
},
"Microsoft.AspNetCore.DataProtection.Abstractions/2.1.1": {
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.DataProtection.Abstractions.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.DataProtection.Abstractions.dll": {}
}
},
"Microsoft.AspNetCore.Diagnostics/2.1.1": {
"dependencies": {
"Microsoft.AspNetCore.Diagnostics.Abstractions": "2.1.1",
"Microsoft.AspNetCore.Hosting.Abstractions": "2.1.1",
"Microsoft.AspNetCore.Http.Extensions": "2.1.1",
"Microsoft.AspNetCore.WebUtilities": "2.1.1",
"Microsoft.Extensions.FileProviders.Physical": "2.1.1",
"Microsoft.Extensions.Logging.Abstractions": "2.1.1",
"Microsoft.Extensions.Options": "2.1.1",
"System.Diagnostics.DiagnosticSource": "4.5.0",
"System.Reflection.Metadata": "1.6.0"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Diagnostics.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Diagnostics.dll": {}
}
},
"Microsoft.AspNetCore.Diagnostics.Abstractions/2.1.1": {
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Diagnostics.Abstractions.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Diagnostics.Abstractions.dll": {}
}
},
"Microsoft.AspNetCore.Hosting/2.1.1": {
"dependencies": {
"Microsoft.AspNetCore.Hosting.Abstractions": "2.1.1",
"Microsoft.AspNetCore.Http": "2.1.1",
"Microsoft.AspNetCore.Http.Extensions": "2.1.1",
"Microsoft.Extensions.Configuration": "2.1.1",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "2.1.1",
"Microsoft.Extensions.Configuration.FileExtensions": "2.1.1",
"Microsoft.Extensions.DependencyInjection": "2.1.1",
"Microsoft.Extensions.FileProviders.Physical": "2.1.1",
"Microsoft.Extensions.Hosting.Abstractions": "2.1.1",
"Microsoft.Extensions.Logging": "2.1.1",
"Microsoft.Extensions.Options": "2.1.1",
"System.Diagnostics.DiagnosticSource": "4.5.0",
"System.Reflection.Metadata": "1.6.0"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Hosting.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Hosting.dll": {}
}
},
"Microsoft.AspNetCore.Hosting.Abstractions/2.1.1": {
"dependencies": {
"Microsoft.AspNetCore.Hosting.Server.Abstractions": "2.1.1",
"Microsoft.AspNetCore.Http.Abstractions": "2.1.1",
"Microsoft.Extensions.Hosting.Abstractions": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Hosting.Abstractions.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Hosting.Abstractions.dll": {}
}
},
"Microsoft.AspNetCore.Hosting.Server.Abstractions/2.1.1": {
"dependencies": {
"Microsoft.AspNetCore.Http.Features": "2.1.1",
"Microsoft.Extensions.Configuration.Abstractions": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Hosting.Server.Abstractions.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Hosting.Server.Abstractions.dll": {}
}
},
"Microsoft.AspNetCore.Html.Abstractions/2.1.1": {
"dependencies": {
"System.Text.Encodings.Web": "4.5.0"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Html.Abstractions.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Html.Abstractions.dll": {}
}
},
"Microsoft.AspNetCore.Http/2.1.1": {
"dependencies": {
"Microsoft.AspNetCore.Http.Abstractions": "2.1.1",
"Microsoft.AspNetCore.WebUtilities": "2.1.1",
"Microsoft.Extensions.ObjectPool": "2.1.1",
"Microsoft.Extensions.Options": "2.1.1",
"Microsoft.Net.Http.Headers": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Http.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Http.dll": {}
}
},
"Microsoft.AspNetCore.Http.Abstractions/2.1.1": {
"dependencies": {
"Microsoft.AspNetCore.Http.Features": "2.1.1",
"System.Text.Encodings.Web": "4.5.0"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Http.Abstractions.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Http.Abstractions.dll": {}
}
},
"Microsoft.AspNetCore.Http.Extensions/2.1.1": {
"dependencies": {
"Microsoft.AspNetCore.Http.Abstractions": "2.1.1",
"Microsoft.Extensions.FileProviders.Abstractions": "2.1.1",
"Microsoft.Net.Http.Headers": "2.1.1",
"System.Buffers": "4.5.0"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Http.Extensions.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Http.Extensions.dll": {}
}
},
"Microsoft.AspNetCore.Http.Features/2.1.1": {
"dependencies": {
"Microsoft.Extensions.Primitives": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Http.Features.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Http.Features.dll": {}
}
},
"Microsoft.AspNetCore.JsonPatch/2.1.1": {
"dependencies": {
"Microsoft.CSharp": "4.5.0",
"Newtonsoft.Json": "11.0.2"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.JsonPatch.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.JsonPatch.dll": {}
}
},
"Microsoft.AspNetCore.Localization/2.1.1": {
"dependencies": {
"Microsoft.AspNetCore.Http.Extensions": "2.1.1",
"Microsoft.Extensions.Localization.Abstractions": "2.1.1",
"Microsoft.Extensions.Logging.Abstractions": "2.1.1",
"Microsoft.Extensions.Options": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Localization.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Localization.dll": {}
}
},
"Microsoft.AspNetCore.Mvc/2.1.1": {
"dependencies": {
"Microsoft.AspNetCore.Mvc.ApiExplorer": "2.1.1",
"Microsoft.AspNetCore.Mvc.Cors": "2.1.1",
"Microsoft.AspNetCore.Mvc.DataAnnotations": "2.1.1",
"Microsoft.AspNetCore.Mvc.Formatters.Json": "2.1.1",
"Microsoft.AspNetCore.Mvc.Localization": "2.1.1",
"Microsoft.AspNetCore.Mvc.Razor.Extensions": "2.1.1",
"Microsoft.AspNetCore.Mvc.RazorPages": "2.1.1",
"Microsoft.AspNetCore.Mvc.TagHelpers": "2.1.1",
"Microsoft.AspNetCore.Mvc.ViewFeatures": "2.1.1",
"Microsoft.AspNetCore.Razor.Design": "2.1.1",
"Microsoft.Extensions.Caching.Memory": "2.1.1",
"Microsoft.Extensions.DependencyInjection": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Mvc.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Mvc.dll": {}
}
},
"Microsoft.AspNetCore.Mvc.Abstractions/2.1.1": {
"dependencies": {
"Microsoft.AspNetCore.Routing.Abstractions": "2.1.1",
"Microsoft.Net.Http.Headers": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Mvc.Abstractions.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Mvc.Abstractions.dll": {}
}
},
"Microsoft.AspNetCore.Mvc.ApiExplorer/2.1.1": {
"dependencies": {
"Microsoft.AspNetCore.Mvc.Core": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Mvc.ApiExplorer.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Mvc.ApiExplorer.dll": {}
}
},
"Microsoft.AspNetCore.Mvc.Core/2.1.1": {
"dependencies": {
"Microsoft.AspNetCore.Authentication.Core": "2.1.1",
"Microsoft.AspNetCore.Authorization.Policy": "2.1.1",
"Microsoft.AspNetCore.Hosting.Abstractions": "2.1.1",
"Microsoft.AspNetCore.Http": "2.1.1",
"Microsoft.AspNetCore.Http.Extensions": "2.1.1",
"Microsoft.AspNetCore.Mvc.Abstractions": "2.1.1",
"Microsoft.AspNetCore.ResponseCaching.Abstractions": "2.1.1",
"Microsoft.AspNetCore.Routing": "2.1.1",
"Microsoft.Extensions.DependencyInjection": "2.1.1",
"Microsoft.Extensions.DependencyModel": "2.1.0",
"Microsoft.Extensions.FileProviders.Abstractions": "2.1.1",
"Microsoft.Extensions.Logging.Abstractions": "2.1.1",
"System.Diagnostics.DiagnosticSource": "4.5.0",
"System.Threading.Tasks.Extensions": "4.5.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Mvc.Core.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Mvc.Core.dll": {}
}
},
"Microsoft.AspNetCore.Mvc.Cors/2.1.1": {
"dependencies": {
"Microsoft.AspNetCore.Cors": "2.1.1",
"Microsoft.AspNetCore.Mvc.Core": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Mvc.Cors.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Mvc.Cors.dll": {}
}
},
"Microsoft.AspNetCore.Mvc.DataAnnotations/2.1.1": {
"dependencies": {
"Microsoft.AspNetCore.Mvc.Core": "2.1.1",
"Microsoft.Extensions.Localization": "2.1.1",
"System.ComponentModel.Annotations": "4.5.0"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Mvc.DataAnnotations.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Mvc.DataAnnotations.dll": {}
}
},
"Microsoft.AspNetCore.Mvc.Formatters.Json/2.1.1": {
"dependencies": {
"Microsoft.AspNetCore.JsonPatch": "2.1.1",
"Microsoft.AspNetCore.Mvc.Core": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Mvc.Formatters.Json.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Mvc.Formatters.Json.dll": {}
}
},
"Microsoft.AspNetCore.Mvc.Localization/2.1.1": {
"dependencies": {
"Microsoft.AspNetCore.Localization": "2.1.1",
"Microsoft.AspNetCore.Mvc.Razor": "2.1.1",
"Microsoft.Extensions.DependencyInjection": "2.1.1",
"Microsoft.Extensions.Localization": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Mvc.Localization.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Mvc.Localization.dll": {}
}
},
"Microsoft.AspNetCore.Mvc.Razor/2.1.1": {
"dependencies": {
"Microsoft.AspNetCore.Mvc.Razor.Extensions": "2.1.1",
"Microsoft.AspNetCore.Mvc.ViewFeatures": "2.1.1",
"Microsoft.AspNetCore.Razor.Runtime": "2.1.1",
"Microsoft.CodeAnalysis.CSharp": "2.8.0",
"Microsoft.CodeAnalysis.Razor": "2.1.1",
"Microsoft.Extensions.Caching.Memory": "2.1.1",
"Microsoft.Extensions.FileProviders.Composite": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Mvc.Razor.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Mvc.Razor.dll": {}
}
},
"Microsoft.AspNetCore.Mvc.Razor.Extensions/2.1.1": {
"dependencies": {
"Microsoft.AspNetCore.Razor.Language": "2.1.1",
"Microsoft.CodeAnalysis.Razor": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Mvc.Razor.Extensions.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Mvc.Razor.Extensions.dll": {}
}
},
"Microsoft.AspNetCore.Mvc.RazorPages/2.1.1": {
"dependencies": {
"Microsoft.AspNetCore.Mvc.Razor": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Mvc.RazorPages.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Mvc.RazorPages.dll": {}
}
},
"Microsoft.AspNetCore.Mvc.TagHelpers/2.1.1": {
"dependencies": {
"Microsoft.AspNetCore.Mvc.Razor": "2.1.1",
"Microsoft.AspNetCore.Razor.Runtime": "2.1.1",
"Microsoft.AspNetCore.Routing.Abstractions": "2.1.1",
"Microsoft.Extensions.Caching.Memory": "2.1.1",
"Microsoft.Extensions.FileSystemGlobbing": "2.1.1",
"Microsoft.Extensions.Primitives": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Mvc.TagHelpers.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Mvc.TagHelpers.dll": {}
}
},
"Microsoft.AspNetCore.Mvc.ViewFeatures/2.1.1": {
"dependencies": {
"Microsoft.AspNetCore.Antiforgery": "2.1.1",
"Microsoft.AspNetCore.Diagnostics.Abstractions": "2.1.1",
"Microsoft.AspNetCore.Html.Abstractions": "2.1.1",
"Microsoft.AspNetCore.Mvc.Core": "2.1.1",
"Microsoft.AspNetCore.Mvc.DataAnnotations": "2.1.1",
"Microsoft.AspNetCore.Mvc.Formatters.Json": "2.1.1",
"Microsoft.Extensions.WebEncoders": "2.1.1",
"Newtonsoft.Json.Bson": "1.0.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Mvc.ViewFeatures.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Mvc.ViewFeatures.dll": {}
}
},
"Microsoft.AspNetCore.Razor/2.1.1": {
"dependencies": {
"Microsoft.AspNetCore.Html.Abstractions": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Razor.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Razor.dll": {}
}
},
"Microsoft.AspNetCore.Razor.Design/2.1.1": {},
"Microsoft.AspNetCore.Razor.Language/2.1.1": {
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Razor.Language.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Razor.Language.dll": {}
}
},
"Microsoft.AspNetCore.Razor.Runtime/2.1.1": {
"dependencies": {
"Microsoft.AspNetCore.Html.Abstractions": "2.1.1",
"Microsoft.AspNetCore.Razor": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Razor.Runtime.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Razor.Runtime.dll": {}
}
},
"Microsoft.AspNetCore.ResponseCaching.Abstractions/2.1.1": {
"dependencies": {
"Microsoft.Extensions.Primitives": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.ResponseCaching.Abstractions.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.ResponseCaching.Abstractions.dll": {}
}
},
"Microsoft.AspNetCore.Routing/2.1.1": {
"dependencies": {
"Microsoft.AspNetCore.Http.Extensions": "2.1.1",
"Microsoft.AspNetCore.Routing.Abstractions": "2.1.1",
"Microsoft.Extensions.Logging.Abstractions": "2.1.1",
"Microsoft.Extensions.ObjectPool": "2.1.1",
"Microsoft.Extensions.Options": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Routing.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Routing.dll": {}
}
},
"Microsoft.AspNetCore.Routing.Abstractions/2.1.1": {
"dependencies": {
"Microsoft.AspNetCore.Http.Abstractions": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Routing.Abstractions.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Routing.Abstractions.dll": {}
}
},
"Microsoft.AspNetCore.Server.Kestrel/2.1.2": {
"dependencies": {
"Microsoft.AspNetCore.Hosting": "2.1.1",
"Microsoft.AspNetCore.Server.Kestrel.Core": "2.1.2",
"Microsoft.AspNetCore.Server.Kestrel.Https": "2.1.2",
"Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets": "2.1.2"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Server.Kestrel.dll": {
"assemblyVersion": "2.1.2.0",
"fileVersion": "2.1.2.18180"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Server.Kestrel.dll": {}
}
},
"Microsoft.AspNetCore.Server.Kestrel.Core/2.1.2": {
"dependencies": {
"Microsoft.AspNetCore.Hosting.Abstractions": "2.1.1",
"Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions": "2.1.2",
"Microsoft.AspNetCore.WebUtilities": "2.1.1",
"Microsoft.Extensions.Configuration.Binder": "2.1.1",
"Microsoft.Extensions.Logging.Abstractions": "2.1.1",
"Microsoft.Extensions.Options": "2.1.1",
"Microsoft.Net.Http.Headers": "2.1.1",
"System.Memory": "4.5.1",
"System.Numerics.Vectors": "4.5.0",
"System.Runtime.CompilerServices.Unsafe": "4.5.1",
"System.Security.Cryptography.Cng": "4.5.0",
"System.Threading.Tasks.Extensions": "4.5.1"
},
"runtime": {
"lib/netcoreapp2.1/Microsoft.AspNetCore.Server.Kestrel.Core.dll": {
"assemblyVersion": "2.1.2.0",
"fileVersion": "2.1.2.18180"
}
},
"compile": {
"lib/netcoreapp2.1/Microsoft.AspNetCore.Server.Kestrel.Core.dll": {}
}
},
"Microsoft.AspNetCore.Server.Kestrel.Https/2.1.2": {
"dependencies": {
"Microsoft.AspNetCore.Http.Abstractions": "2.1.1",
"Microsoft.AspNetCore.Server.Kestrel.Core": "2.1.2"
},
"runtime": {
"lib/netcoreapp2.1/Microsoft.AspNetCore.Server.Kestrel.Https.dll": {
"assemblyVersion": "2.1.2.0",
"fileVersion": "2.1.2.18180"
}
},
"compile": {
"lib/netcoreapp2.1/Microsoft.AspNetCore.Server.Kestrel.Https.dll": {}
}
},
"Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions/2.1.2": {
"dependencies": {
"Microsoft.AspNetCore.Connections.Abstractions": "2.1.2"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.dll": {
"assemblyVersion": "2.1.2.0",
"fileVersion": "2.1.2.18180"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.dll": {}
}
},
"Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets/2.1.2": {
"dependencies": {
"Microsoft.AspNetCore.Hosting.Abstractions": "2.1.1",
"Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions": "2.1.2",
"Microsoft.Extensions.Options": "2.1.1"
},
"runtime": {
"lib/netcoreapp2.1/Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.dll": {
"assemblyVersion": "2.1.2.0",
"fileVersion": "2.1.2.18180"
}
},
"compile": {
"lib/netcoreapp2.1/Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.dll": {}
}
},
"Microsoft.AspNetCore.StaticFiles/2.1.1": {
"dependencies": {
"Microsoft.AspNetCore.Hosting.Abstractions": "2.1.1",
"Microsoft.AspNetCore.Http.Extensions": "2.1.1",
"Microsoft.Extensions.FileProviders.Abstractions": "2.1.1",
"Microsoft.Extensions.Logging.Abstractions": "2.1.1",
"Microsoft.Extensions.WebEncoders": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.StaticFiles.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.StaticFiles.dll": {}
}
},
"Microsoft.AspNetCore.WebUtilities/2.1.1": {
"dependencies": {
"Microsoft.Net.Http.Headers": "2.1.1",
"System.Text.Encodings.Web": "4.5.0"
},
"runtime": {
"lib/netstandard2.0/Microsoft.AspNetCore.WebUtilities.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.AspNetCore.WebUtilities.dll": {}
}
},
"Microsoft.CodeAnalysis.Analyzers/1.1.0": {},
"Microsoft.CodeAnalysis.Common/2.8.0": {
"dependencies": {
"Microsoft.CodeAnalysis.Analyzers": "1.1.0",
"System.AppContext": "4.3.0",
"System.Collections": "4.3.0",
"System.Collections.Concurrent": "4.3.0",
"System.Collections.Immutable": "1.3.1",
"System.Console": "4.3.0",
"System.Diagnostics.Debug": "4.3.0",
"System.Diagnostics.FileVersionInfo": "4.3.0",
"System.Diagnostics.StackTrace": "4.3.0",
"System.Diagnostics.Tools": "4.3.0",
"System.Dynamic.Runtime": "4.3.0",
"System.Globalization": "4.3.0",
"System.IO.Compression": "4.3.0",
"System.IO.FileSystem": "4.3.0",
"System.IO.FileSystem.Primitives": "4.3.0",
"System.Linq": "4.3.0",
"System.Linq.Expressions": "4.3.0",
"System.Reflection": "4.3.0",
"System.Reflection.Metadata": "1.6.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Runtime.Numerics": "4.3.0",
"System.Security.Cryptography.Algorithms": "4.3.0",
"System.Security.Cryptography.Encoding": "4.3.0",
"System.Security.Cryptography.X509Certificates": "4.3.0",
"System.Text.Encoding": "4.3.0",
"System.Text.Encoding.CodePages": "4.3.0",
"System.Text.Encoding.Extensions": "4.3.0",
"System.Threading": "4.3.0",
"System.Threading.Tasks": "4.3.0",
"System.Threading.Tasks.Parallel": "4.3.0",
"System.Threading.Thread": "4.3.0",
"System.ValueTuple": "4.3.0",
"System.Xml.ReaderWriter": "4.3.0",
"System.Xml.XDocument": "4.3.0",
"System.Xml.XPath.XDocument": "4.3.0",
"System.Xml.XmlDocument": "4.3.0"
},
"runtime": {
"lib/netstandard1.3/Microsoft.CodeAnalysis.dll": {
"assemblyVersion": "2.8.0.0",
"fileVersion": "2.8.0.62830"
}
},
"compile": {
"lib/netstandard1.3/Microsoft.CodeAnalysis.dll": {}
}
},
"Microsoft.CodeAnalysis.CSharp/2.8.0": {
"dependencies": {
"Microsoft.CodeAnalysis.Common": "2.8.0"
},
"runtime": {
"lib/netstandard1.3/Microsoft.CodeAnalysis.CSharp.dll": {
"assemblyVersion": "2.8.0.0",
"fileVersion": "2.8.0.62830"
}
},
"compile": {
"lib/netstandard1.3/Microsoft.CodeAnalysis.CSharp.dll": {}
}
},
"Microsoft.CodeAnalysis.Razor/2.1.1": {
"dependencies": {
"Microsoft.AspNetCore.Razor.Language": "2.1.1",
"Microsoft.CodeAnalysis.CSharp": "2.8.0",
"Microsoft.CodeAnalysis.Common": "2.8.0"
},
"runtime": {
"lib/netstandard2.0/Microsoft.CodeAnalysis.Razor.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.CodeAnalysis.Razor.dll": {}
}
},
"Microsoft.CSharp/4.5.0": {},
"Microsoft.DotNet.PlatformAbstractions/2.1.0": {
"dependencies": {
"System.AppContext": "4.3.0",
"System.Collections": "4.3.0",
"System.IO": "4.3.0",
"System.IO.FileSystem": "4.3.0",
"System.Reflection.TypeExtensions": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Runtime.InteropServices.RuntimeInformation": "4.3.0"
},
"runtime": {
"lib/netstandard1.3/Microsoft.DotNet.PlatformAbstractions.dll": {
"assemblyVersion": "2.1.0.0",
"fileVersion": "2.1.0.0"
}
},
"compile": {
"lib/netstandard1.3/Microsoft.DotNet.PlatformAbstractions.dll": {}
}
},
"Microsoft.Extensions.Caching.Abstractions/2.1.1": {
"dependencies": {
"Microsoft.Extensions.Primitives": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.Extensions.Caching.Abstractions.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.Extensions.Caching.Abstractions.dll": {}
}
},
"Microsoft.Extensions.Caching.Memory/2.1.1": {
"dependencies": {
"Microsoft.Extensions.Caching.Abstractions": "2.1.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.1.1",
"Microsoft.Extensions.Options": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.Extensions.Caching.Memory.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.Extensions.Caching.Memory.dll": {}
}
},
"Microsoft.Extensions.Configuration/2.1.1": {
"dependencies": {
"Microsoft.Extensions.Configuration.Abstractions": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.Extensions.Configuration.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.Extensions.Configuration.dll": {}
}
},
"Microsoft.Extensions.Configuration.Abstractions/2.1.1": {
"dependencies": {
"Microsoft.Extensions.Primitives": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.Extensions.Configuration.Abstractions.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.Extensions.Configuration.Abstractions.dll": {}
}
},
"Microsoft.Extensions.Configuration.Binder/2.1.1": {
"dependencies": {
"Microsoft.Extensions.Configuration": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.Extensions.Configuration.Binder.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.Extensions.Configuration.Binder.dll": {}
}
},
"Microsoft.Extensions.Configuration.EnvironmentVariables/2.1.1": {
"dependencies": {
"Microsoft.Extensions.Configuration": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.Extensions.Configuration.EnvironmentVariables.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.Extensions.Configuration.EnvironmentVariables.dll": {}
}
},
"Microsoft.Extensions.Configuration.FileExtensions/2.1.1": {
"dependencies": {
"Microsoft.Extensions.Configuration": "2.1.1",
"Microsoft.Extensions.FileProviders.Physical": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.Extensions.Configuration.FileExtensions.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.Extensions.Configuration.FileExtensions.dll": {}
}
},
"Microsoft.Extensions.Configuration.Json/2.1.1": {
"dependencies": {
"Microsoft.Extensions.Configuration": "2.1.1",
"Microsoft.Extensions.Configuration.FileExtensions": "2.1.1",
"Newtonsoft.Json": "11.0.2"
},
"runtime": {
"lib/netstandard2.0/Microsoft.Extensions.Configuration.Json.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.Extensions.Configuration.Json.dll": {}
}
},
"Microsoft.Extensions.DependencyInjection/2.1.1": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.1.1"
},
"runtime": {
"lib/netcoreapp2.0/Microsoft.Extensions.DependencyInjection.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netcoreapp2.0/Microsoft.Extensions.DependencyInjection.dll": {}
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions/2.1.1": {
"runtime": {
"lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": {}
}
},
"Microsoft.Extensions.DependencyModel/2.1.0": {
"dependencies": {
"Microsoft.DotNet.PlatformAbstractions": "2.1.0",
"Newtonsoft.Json": "11.0.2",
"System.Diagnostics.Debug": "4.3.0",
"System.Dynamic.Runtime": "4.3.0",
"System.Linq": "4.3.0"
},
"runtime": {
"lib/netstandard1.6/Microsoft.Extensions.DependencyModel.dll": {
"assemblyVersion": "2.1.0.0",
"fileVersion": "2.1.0.0"
}
},
"compile": {
"lib/netstandard1.6/Microsoft.Extensions.DependencyModel.dll": {}
}
},
"Microsoft.Extensions.FileProviders.Abstractions/2.1.1": {
"dependencies": {
"Microsoft.Extensions.Primitives": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.Extensions.FileProviders.Abstractions.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.Extensions.FileProviders.Abstractions.dll": {}
}
},
"Microsoft.Extensions.FileProviders.Composite/2.1.1": {
"dependencies": {
"Microsoft.Extensions.FileProviders.Abstractions": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.Extensions.FileProviders.Composite.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.Extensions.FileProviders.Composite.dll": {}
}
},
"Microsoft.Extensions.FileProviders.Physical/2.1.1": {
"dependencies": {
"Microsoft.Extensions.FileProviders.Abstractions": "2.1.1",
"Microsoft.Extensions.FileSystemGlobbing": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.Extensions.FileProviders.Physical.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.Extensions.FileProviders.Physical.dll": {}
}
},
"Microsoft.Extensions.FileSystemGlobbing/2.1.1": {
"runtime": {
"lib/netstandard2.0/Microsoft.Extensions.FileSystemGlobbing.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.Extensions.FileSystemGlobbing.dll": {}
}
},
"Microsoft.Extensions.Hosting.Abstractions/2.1.1": {
"dependencies": {
"Microsoft.Extensions.Configuration.Abstractions": "2.1.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.1.1",
"Microsoft.Extensions.FileProviders.Abstractions": "2.1.1",
"Microsoft.Extensions.Logging.Abstractions": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.Extensions.Hosting.Abstractions.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.Extensions.Hosting.Abstractions.dll": {}
}
},
"Microsoft.Extensions.Localization/2.1.1": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.1.1",
"Microsoft.Extensions.Localization.Abstractions": "2.1.1",
"Microsoft.Extensions.Logging.Abstractions": "2.1.1",
"Microsoft.Extensions.Options": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.Extensions.Localization.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.Extensions.Localization.dll": {}
}
},
"Microsoft.Extensions.Localization.Abstractions/2.1.1": {
"runtime": {
"lib/netstandard2.0/Microsoft.Extensions.Localization.Abstractions.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.Extensions.Localization.Abstractions.dll": {}
}
},
"Microsoft.Extensions.Logging/2.1.1": {
"dependencies": {
"Microsoft.Extensions.Configuration.Binder": "2.1.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.1.1",
"Microsoft.Extensions.Logging.Abstractions": "2.1.1",
"Microsoft.Extensions.Options": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.Extensions.Logging.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.Extensions.Logging.dll": {}
}
},
"Microsoft.Extensions.Logging.Abstractions/2.1.1": {
"runtime": {
"lib/netstandard2.0/Microsoft.Extensions.Logging.Abstractions.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.Extensions.Logging.Abstractions.dll": {}
}
},
"Microsoft.Extensions.ObjectPool/2.1.1": {
"runtime": {
"lib/netstandard2.0/Microsoft.Extensions.ObjectPool.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.Extensions.ObjectPool.dll": {}
}
},
"Microsoft.Extensions.Options/2.1.1": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.1.1",
"Microsoft.Extensions.Primitives": "2.1.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.Extensions.Options.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.Extensions.Options.dll": {}
}
},
"Microsoft.Extensions.Primitives/2.1.1": {
"dependencies": {
"System.Memory": "4.5.1",
"System.Runtime.CompilerServices.Unsafe": "4.5.1"
},
"runtime": {
"lib/netstandard2.0/Microsoft.Extensions.Primitives.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.Extensions.Primitives.dll": {}
}
},
"Microsoft.Extensions.WebEncoders/2.1.1": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.1.1",
"Microsoft.Extensions.Options": "2.1.1",
"System.Text.Encodings.Web": "4.5.0"
},
"runtime": {
"lib/netstandard2.0/Microsoft.Extensions.WebEncoders.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.Extensions.WebEncoders.dll": {}
}
},
"Microsoft.Net.Http.Headers/2.1.1": {
"dependencies": {
"Microsoft.Extensions.Primitives": "2.1.1",
"System.Buffers": "4.5.0"
},
"runtime": {
"lib/netstandard2.0/Microsoft.Net.Http.Headers.dll": {
"assemblyVersion": "2.1.1.0",
"fileVersion": "2.1.1.18157"
}
},
"compile": {
"lib/netstandard2.0/Microsoft.Net.Http.Headers.dll": {}
}
},
"Microsoft.Win32.Registry/4.5.0": {
"dependencies": {
"System.Security.AccessControl": "4.5.0",
"System.Security.Principal.Windows": "4.5.0"
},
"runtimeTargets": {
"runtime/unix/lib/_._": {
"rid": "unix",
"assetType": "runtime"
},
"runtime/win/lib/_._": {
"rid": "win",
"assetType": "runtime"
}
},
"compile": {
"ref/netstandard2.0/Microsoft.Win32.Registry.dll": {}
}
},
"Newtonsoft.Json/11.0.2": {
"runtime": {
"lib/netstandard2.0/Newtonsoft.Json.dll": {
"assemblyVersion": "11.0.0.0",
"fileVersion": "11.0.2.21924"
}
},
"compile": {
"lib/netstandard2.0/Newtonsoft.Json.dll": {}
}
},
"Newtonsoft.Json.Bson/1.0.1": {
"dependencies": {
"NETStandard.Library": "2.0.3",
"Newtonsoft.Json": "11.0.2"
},
"runtime": {
"lib/netstandard1.3/Newtonsoft.Json.Bson.dll": {
"assemblyVersion": "1.0.0.0",
"fileVersion": "1.0.1.20722"
}
},
"compile": {
"lib/netstandard1.3/Newtonsoft.Json.Bson.dll": {}
}
},
"runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": {
"runtimeTargets": {
"runtime/debian.8-x64/native/_._": {
"rid": "debian.8-x64",
"assetType": "native"
}
}
},
"runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": {
"runtimeTargets": {
"runtime/fedora.23-x64/native/_._": {
"rid": "fedora.23-x64",
"assetType": "native"
}
}
},
"runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": {
"runtimeTargets": {
"runtime/fedora.24-x64/native/_._": {
"rid": "fedora.24-x64",
"assetType": "native"
}
}
},
"runtime.native.System/4.3.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0",
"Microsoft.NETCore.Targets": "2.1.0"
}
},
"runtime.native.System.IO.Compression/4.3.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0",
"Microsoft.NETCore.Targets": "2.1.0"
}
},
"runtime.native.System.Net.Http/4.3.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0",
"Microsoft.NETCore.Targets": "2.1.0"
}
},
"runtime.native.System.Security.Cryptography.Apple/4.3.0": {
"dependencies": {
"runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple": "4.3.0"
}
},
"runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": {
"dependencies": {
"runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0",
"runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0",
"runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0",
"runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0",
"runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0",
"runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0",
"runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0",
"runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0",
"runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0",
"runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
}
},
"runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": {
"runtimeTargets": {
"runtime/opensuse.13.2-x64/native/_._": {
"rid": "opensuse.13.2-x64",
"assetType": "native"
}
}
},
"runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": {
"runtimeTargets": {
"runtime/opensuse.42.1-x64/native/_._": {
"rid": "opensuse.42.1-x64",
"assetType": "native"
}
}
},
"runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple/4.3.0": {
"runtimeTargets": {
"runtime/osx.10.10-x64/native/_._": {
"rid": "osx.10.10-x64",
"assetType": "native"
}
}
},
"runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": {
"runtimeTargets": {
"runtime/osx.10.10-x64/native/_._": {
"rid": "osx.10.10-x64",
"assetType": "native"
}
}
},
"runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": {
"runtimeTargets": {
"runtime/rhel.7-x64/native/_._": {
"rid": "rhel.7-x64",
"assetType": "native"
}
}
},
"runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": {
"runtimeTargets": {
"runtime/ubuntu.14.04-x64/native/_._": {
"rid": "ubuntu.14.04-x64",
"assetType": "native"
}
}
},
"runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": {
"runtimeTargets": {
"runtime/ubuntu.16.04-x64/native/_._": {
"rid": "ubuntu.16.04-x64",
"assetType": "native"
}
}
},
"runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": {
"runtimeTargets": {
"runtime/ubuntu.16.10-x64/native/_._": {
"rid": "ubuntu.16.10-x64",
"assetType": "native"
}
}
},
"Serilog/2.7.1": {
"dependencies": {
"NETStandard.Library": "2.0.3",
"System.Collections.NonGeneric": "4.3.0"
},
"runtime": {
"lib/netstandard1.3/Serilog.dll": {
"assemblyVersion": "2.0.0.0",
"fileVersion": "2.7.1.0"
}
},
"compile": {
"lib/netstandard1.3/Serilog.dll": {}
}
},
"Serilog.Enrichers.Environment/2.1.2": {
"dependencies": {
"Serilog": "2.7.1"
},
"runtime": {
"lib/netstandard1.3/Serilog.Enrichers.Environment.dll": {
"assemblyVersion": "2.0.0.0",
"fileVersion": "2.1.2.0"
}
},
"compile": {
"lib/netstandard1.3/Serilog.Enrichers.Environment.dll": {}
}
},
"Serilog.Filters.Expressions/2.0.0": {
"dependencies": {
"NETStandard.Library": "2.0.3",
"Serilog": "2.7.1",
"Superpower": "2.0.0"
},
"runtime": {
"lib/netstandard1.5/Serilog.Filters.Expressions.dll": {
"assemblyVersion": "2.0.0.0",
"fileVersion": "2.0.0.0"
}
},
"compile": {
"lib/netstandard1.5/Serilog.Filters.Expressions.dll": {}
}
},
"Serilog.Settings.Configuration/2.6.1": {
"dependencies": {
"Microsoft.Extensions.Configuration.Abstractions": "2.1.1",
"Microsoft.Extensions.DependencyModel": "2.1.0",
"Serilog": "2.7.1"
},
"runtime": {
"lib/netstandard1.6/Serilog.Settings.Configuration.dll": {
"assemblyVersion": "2.6.1.0",
"fileVersion": "2.6.1.0"
}
},
"compile": {
"lib/netstandard1.6/Serilog.Settings.Configuration.dll": {}
}
},
"Serilog.Sinks.Console/3.1.1": {
"dependencies": {
"Serilog": "2.7.1",
"System.Console": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Runtime.InteropServices.RuntimeInformation": "4.3.0"
},
"runtime": {
"lib/netcoreapp1.1/Serilog.Sinks.Console.dll": {
"assemblyVersion": "3.1.1.0",
"fileVersion": "3.1.1.0"
}
},
"compile": {
"lib/netcoreapp1.1/Serilog.Sinks.Console.dll": {}
}
},
"Serilog.Sinks.File/3.2.0": {
"dependencies": {
"Serilog": "2.7.1",
"System.IO": "4.3.0",
"System.IO.FileSystem": "4.3.0",
"System.IO.FileSystem.Primitives": "4.3.0",
"System.Text.Encoding.Extensions": "4.3.0",
"System.Threading": "4.3.0",
"System.Threading.Timer": "4.0.1"
},
"runtime": {
"lib/netstandard1.3/Serilog.Sinks.File.dll": {
"assemblyVersion": "2.0.0.0",
"fileVersion": "3.2.0.0"
}
},
"compile": {
"lib/netstandard1.3/Serilog.Sinks.File.dll": {}
}
},
"Serilog.Sinks.RollingFile/3.3.0": {
"dependencies": {
"Serilog.Sinks.File": "3.2.0",
"System.IO": "4.3.0",
"System.IO.FileSystem.Primitives": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Text.Encoding.Extensions": "4.3.0"
},
"runtime": {
"lib/netstandard1.3/Serilog.Sinks.RollingFile.dll": {
"assemblyVersion": "2.0.0.0",
"fileVersion": "3.3.0.0"
}
},
"compile": {
"lib/netstandard1.3/Serilog.Sinks.RollingFile.dll": {}
}
},
"Superpower/2.0.0": {
"dependencies": {
"NETStandard.Library": "2.0.3"
},
"runtime": {
"lib/netstandard1.0/Superpower.dll": {
"assemblyVersion": "1.0.0.0",
"fileVersion": "2.0.0.0"
}
},
"compile": {
"lib/netstandard1.0/Superpower.dll": {}
}
},
"System.AppContext/4.3.0": {
"dependencies": {
"System.Runtime": "4.3.0"
}
},
"System.Buffers/4.5.0": {},
"System.Collections/4.3.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0",
"Microsoft.NETCore.Targets": "2.1.0",
"System.Runtime": "4.3.0"
}
},
"System.Collections.Concurrent/4.3.0": {
"dependencies": {
"System.Collections": "4.3.0",
"System.Diagnostics.Debug": "4.3.0",
"System.Diagnostics.Tracing": "4.3.0",
"System.Globalization": "4.3.0",
"System.Reflection": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Threading": "4.3.0",
"System.Threading.Tasks": "4.3.0"
}
},
"System.Collections.Immutable/1.3.1": {
"dependencies": {
"System.Collections": "4.3.0",
"System.Diagnostics.Debug": "4.3.0",
"System.Globalization": "4.3.0",
"System.Linq": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Threading": "4.3.0"
}
},
"System.Collections.NonGeneric/4.3.0": {
"dependencies": {
"System.Diagnostics.Debug": "4.3.0",
"System.Globalization": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Threading": "4.3.0"
}
},
"System.ComponentModel/4.0.1": {
"dependencies": {
"System.Runtime": "4.3.0"
}
},
"System.ComponentModel.Annotations/4.5.0": {},
"System.Console/4.3.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0",
"Microsoft.NETCore.Targets": "2.1.0",
"System.IO": "4.3.0",
"System.Runtime": "4.3.0",
"System.Text.Encoding": "4.3.0"
}
},
"System.Diagnostics.Debug/4.3.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0",
"Microsoft.NETCore.Targets": "2.1.0",
"System.Runtime": "4.3.0"
}
},
"System.Diagnostics.DiagnosticSource/4.5.0": {},
"System.Diagnostics.FileVersionInfo/4.3.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0",
"System.Globalization": "4.3.0",
"System.IO": "4.3.0",
"System.IO.FileSystem": "4.3.0",
"System.IO.FileSystem.Primitives": "4.3.0",
"System.Reflection.Metadata": "1.6.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.InteropServices": "4.3.0"
},
"runtimeTargets": {
"runtime/unix/lib/_._": {
"rid": "unix",
"assetType": "runtime"
},
"runtime/win/lib/_._": {
"rid": "win",
"assetType": "runtime"
}
}
},
"System.Diagnostics.StackTrace/4.3.0": {
"dependencies": {
"System.IO.FileSystem": "4.3.0",
"System.Reflection": "4.3.0",
"System.Reflection.Metadata": "1.6.0",
"System.Runtime": "4.3.0"
}
},
"System.Diagnostics.Tools/4.3.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0",
"Microsoft.NETCore.Targets": "2.1.0",
"System.Runtime": "4.3.0"
}
},
"System.Diagnostics.Tracing/4.3.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0",
"Microsoft.NETCore.Targets": "2.1.0",
"System.Runtime": "4.3.0"
}
},
"System.Dynamic.Runtime/4.3.0": {
"dependencies": {
"System.Collections": "4.3.0",
"System.Diagnostics.Debug": "4.3.0",
"System.Linq": "4.3.0",
"System.Linq.Expressions": "4.3.0",
"System.ObjectModel": "4.3.0",
"System.Reflection": "4.3.0",
"System.Reflection.Emit": "4.3.0",
"System.Reflection.Emit.ILGeneration": "4.3.0",
"System.Reflection.Primitives": "4.3.0",
"System.Reflection.TypeExtensions": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Threading": "4.3.0"
}
},
"System.Globalization/4.3.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0",
"Microsoft.NETCore.Targets": "2.1.0",
"System.Runtime": "4.3.0"
}
},
"System.Globalization.Calendars/4.3.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0",
"Microsoft.NETCore.Targets": "2.1.0",
"System.Globalization": "4.3.0",
"System.Runtime": "4.3.0"
}
},
"System.Globalization.Extensions/4.3.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0",
"System.Globalization": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.InteropServices": "4.3.0"
},
"runtimeTargets": {
"runtime/unix/lib/_._": {
"rid": "unix",
"assetType": "runtime"
},
"runtime/win/lib/_._": {
"rid": "win",
"assetType": "runtime"
}
}
},
"System.IO/4.3.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0",
"Microsoft.NETCore.Targets": "2.1.0",
"System.Runtime": "4.3.0",
"System.Text.Encoding": "4.3.0",
"System.Threading.Tasks": "4.3.0"
}
},
"System.IO.Compression/4.3.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0",
"System.Buffers": "4.5.0",
"System.Collections": "4.3.0",
"System.Diagnostics.Debug": "4.3.0",
"System.IO": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.Handles": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Text.Encoding": "4.3.0",
"System.Threading": "4.3.0",
"System.Threading.Tasks": "4.3.0",
"runtime.native.System": "4.3.0",
"runtime.native.System.IO.Compression": "4.3.0"
},
"runtimeTargets": {
"runtime/unix/lib/_._": {
"rid": "unix",
"assetType": "runtime"
},
"runtime/win/lib/_._": {
"rid": "win",
"assetType": "runtime"
}
}
},
"System.IO.FileSystem/4.3.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0",
"Microsoft.NETCore.Targets": "2.1.0",
"System.IO": "4.3.0",
"System.IO.FileSystem.Primitives": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Handles": "4.3.0",
"System.Text.Encoding": "4.3.0",
"System.Threading.Tasks": "4.3.0"
}
},
"System.IO.FileSystem.Primitives/4.3.0": {
"dependencies": {
"System.Runtime": "4.3.0"
}
},
"System.IO.Pipelines/4.5.0": {
"runtime": {
"lib/netcoreapp2.1/System.IO.Pipelines.dll": {
"assemblyVersion": "4.0.0.0",
"fileVersion": "4.6.26515.6"
}
},
"compile": {
"ref/netstandard1.3/System.IO.Pipelines.dll": {}
}
},
"System.Linq/4.3.0": {
"dependencies": {
"System.Collections": "4.3.0",
"System.Diagnostics.Debug": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0"
}
},
"System.Linq.Expressions/4.3.0": {
"dependencies": {
"System.Collections": "4.3.0",
"System.Diagnostics.Debug": "4.3.0",
"System.Globalization": "4.3.0",
"System.IO": "4.3.0",
"System.Linq": "4.3.0",
"System.ObjectModel": "4.3.0",
"System.Reflection": "4.3.0",
"System.Reflection.Emit": "4.3.0",
"System.Reflection.Emit.ILGeneration": "4.3.0",
"System.Reflection.Emit.Lightweight": "4.3.0",
"System.Reflection.Extensions": "4.3.0",
"System.Reflection.Primitives": "4.3.0",
"System.Reflection.TypeExtensions": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Threading": "4.3.0"
}
},
"System.Memory/4.5.1": {},
"System.Net.Http/4.3.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0",
"System.Collections": "4.3.0",
"System.Diagnostics.Debug": "4.3.0",
"System.Diagnostics.DiagnosticSource": "4.5.0",
"System.Diagnostics.Tracing": "4.3.0",
"System.Globalization": "4.3.0",
"System.Globalization.Extensions": "4.3.0",
"System.IO": "4.3.0",
"System.IO.FileSystem": "4.3.0",
"System.Net.Primitives": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.Handles": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Security.Cryptography.Algorithms": "4.3.0",
"System.Security.Cryptography.Encoding": "4.3.0",
"System.Security.Cryptography.OpenSsl": "4.3.0",
"System.Security.Cryptography.Primitives": "4.3.0",
"System.Security.Cryptography.X509Certificates": "4.3.0",
"System.Text.Encoding": "4.3.0",
"System.Threading": "4.3.0",
"System.Threading.Tasks": "4.3.0",
"runtime.native.System": "4.3.0",
"runtime.native.System.Net.Http": "4.3.0",
"runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
},
"runtimeTargets": {
"runtime/unix/lib/_._": {
"rid": "unix",
"assetType": "runtime"
},
"runtime/win/lib/_._": {
"rid": "win",
"assetType": "runtime"
}
}
},
"System.Net.Primitives/4.3.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0",
"Microsoft.NETCore.Targets": "2.1.0",
"System.Runtime": "4.3.0",
"System.Runtime.Handles": "4.3.0"
}
},
"System.Net.Requests/4.3.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0",
"System.Collections": "4.3.0",
"System.Diagnostics.Debug": "4.3.0",
"System.Diagnostics.Tracing": "4.3.0",
"System.Globalization": "4.3.0",
"System.IO": "4.3.0",
"System.Net.Http": "4.3.0",
"System.Net.Primitives": "4.3.0",
"System.Net.WebHeaderCollection": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Threading": "4.3.0",
"System.Threading.Tasks": "4.3.0"
},
"runtimeTargets": {
"runtime/unix/lib/_._": {
"rid": "unix",
"assetType": "runtime"
},
"runtime/win/lib/_._": {
"rid": "win",
"assetType": "runtime"
}
}
},
"System.Net.WebHeaderCollection/4.3.0": {
"dependencies": {
"System.Collections": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0"
}
},
"System.Numerics.Vectors/4.5.0": {},
"System.ObjectModel/4.3.0": {
"dependencies": {
"System.Collections": "4.3.0",
"System.Diagnostics.Debug": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Threading": "4.3.0"
}
},
"System.Reflection/4.3.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0",
"Microsoft.NETCore.Targets": "2.1.0",
"System.IO": "4.3.0",
"System.Reflection.Primitives": "4.3.0",
"System.Runtime": "4.3.0"
}
},
"System.Reflection.Emit/4.3.0": {
"dependencies": {
"System.IO": "4.3.0",
"System.Reflection": "4.3.0",
"System.Reflection.Emit.ILGeneration": "4.3.0",
"System.Reflection.Primitives": "4.3.0",
"System.Runtime": "4.3.0"
}
},
"System.Reflection.Emit.ILGeneration/4.3.0": {
"dependencies": {
"System.Reflection": "4.3.0",
"System.Reflection.Primitives": "4.3.0",
"System.Runtime": "4.3.0"
}
},
"System.Reflection.Emit.Lightweight/4.3.0": {
"dependencies": {
"System.Reflection": "4.3.0",
"System.Reflection.Emit.ILGeneration": "4.3.0",
"System.Reflection.Primitives": "4.3.0",
"System.Runtime": "4.3.0"
}
},
"System.Reflection.Extensions/4.3.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0",
"Microsoft.NETCore.Targets": "2.1.0",
"System.Reflection": "4.3.0",
"System.Runtime": "4.3.0"
}
},
"System.Reflection.Metadata/1.6.0": {},
"System.Reflection.Primitives/4.3.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0",
"Microsoft.NETCore.Targets": "2.1.0",
"System.Runtime": "4.3.0"
}
},
"System.Reflection.TypeExtensions/4.3.0": {
"dependencies": {
"System.Reflection": "4.3.0",
"System.Runtime": "4.3.0"
}
},
"System.Resources.ResourceManager/4.3.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0",
"Microsoft.NETCore.Targets": "2.1.0",
"System.Globalization": "4.3.0",
"System.Reflection": "4.3.0",
"System.Runtime": "4.3.0"
}
},
"System.Runtime/4.3.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0",
"Microsoft.NETCore.Targets": "2.1.0"
}
},
"System.Runtime.CompilerServices.Unsafe/4.5.1": {
"runtime": {
"lib/netcoreapp2.0/System.Runtime.CompilerServices.Unsafe.dll": {
"assemblyVersion": "4.0.4.0",
"fileVersion": "0.0.0.0"
}
},
"compile": {
"ref/netstandard2.0/System.Runtime.CompilerServices.Unsafe.dll": {}
}
},
"System.Runtime.Extensions/4.3.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0",
"Microsoft.NETCore.Targets": "2.1.0",
"System.Runtime": "4.3.0"
}
},
"System.Runtime.Handles/4.3.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0",
"Microsoft.NETCore.Targets": "2.1.0",
"System.Runtime": "4.3.0"
}
},
"System.Runtime.InteropServices/4.3.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0",
"Microsoft.NETCore.Targets": "2.1.0",
"System.Reflection": "4.3.0",
"System.Reflection.Primitives": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Handles": "4.3.0"
}
},
"System.Runtime.InteropServices.RuntimeInformation/4.3.0": {
"dependencies": {
"System.Reflection": "4.3.0",
"System.Reflection.Extensions": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Threading": "4.3.0",
"runtime.native.System": "4.3.0"
},
"runtimeTargets": {
"runtime/unix/lib/_._": {
"rid": "unix",
"assetType": "runtime"
},
"runtime/win/lib/_._": {
"rid": "win",
"assetType": "runtime"
}
}
},
"System.Runtime.Numerics/4.3.0": {
"dependencies": {
"System.Globalization": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0"
}
},
"System.Security.AccessControl/4.5.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0",
"System.Security.Principal.Windows": "4.5.0"
},
"runtimeTargets": {
"runtime/win/lib/_._": {
"rid": "win",
"assetType": "runtime"
}
},
"compile": {
"ref/netstandard2.0/System.Security.AccessControl.dll": {}
}
},
"System.Security.Cryptography.Algorithms/4.3.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0",
"System.Collections": "4.3.0",
"System.IO": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.Handles": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Runtime.Numerics": "4.3.0",
"System.Security.Cryptography.Encoding": "4.3.0",
"System.Security.Cryptography.Primitives": "4.3.0",
"System.Text.Encoding": "4.3.0",
"runtime.native.System.Security.Cryptography.Apple": "4.3.0",
"runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
},
"runtimeTargets": {
"runtime/osx/lib/_._": {
"rid": "osx",
"assetType": "runtime"
},
"runtime/unix/lib/_._": {
"rid": "unix",
"assetType": "runtime"
},
"runtime/win/lib/_._": {
"rid": "win",
"assetType": "runtime"
}
}
},
"System.Security.Cryptography.Cng/4.5.0": {
"runtimeTargets": {
"runtime/win/lib/_._": {
"rid": "win",
"assetType": "runtime"
}
},
"compile": {
"ref/netcoreapp2.1/System.Security.Cryptography.Cng.dll": {}
}
},
"System.Security.Cryptography.Csp/4.3.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0",
"System.IO": "4.3.0",
"System.Reflection": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.Handles": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Security.Cryptography.Algorithms": "4.3.0",
"System.Security.Cryptography.Encoding": "4.3.0",
"System.Security.Cryptography.Primitives": "4.3.0",
"System.Text.Encoding": "4.3.0",
"System.Threading": "4.3.0"
},
"runtimeTargets": {
"runtime/unix/lib/_._": {
"rid": "unix",
"assetType": "runtime"
},
"runtime/win/lib/_._": {
"rid": "win",
"assetType": "runtime"
}
}
},
"System.Security.Cryptography.Encoding/4.3.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0",
"System.Collections": "4.3.0",
"System.Collections.Concurrent": "4.3.0",
"System.Linq": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.Handles": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Security.Cryptography.Primitives": "4.3.0",
"System.Text.Encoding": "4.3.0",
"runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
},
"runtimeTargets": {
"runtime/unix/lib/_._": {
"rid": "unix",
"assetType": "runtime"
},
"runtime/win/lib/_._": {
"rid": "win",
"assetType": "runtime"
}
}
},
"System.Security.Cryptography.OpenSsl/4.3.0": {
"dependencies": {
"System.Collections": "4.3.0",
"System.IO": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.Handles": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Runtime.Numerics": "4.3.0",
"System.Security.Cryptography.Algorithms": "4.3.0",
"System.Security.Cryptography.Encoding": "4.3.0",
"System.Security.Cryptography.Primitives": "4.3.0",
"System.Text.Encoding": "4.3.0",
"runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
},
"runtimeTargets": {
"runtime/unix/lib/_._": {
"rid": "unix",
"assetType": "runtime"
}
}
},
"System.Security.Cryptography.Pkcs/4.5.0": {
"dependencies": {
"System.Security.Cryptography.Cng": "4.5.0"
},
"runtime": {
"lib/netcoreapp2.1/System.Security.Cryptography.Pkcs.dll": {
"assemblyVersion": "4.0.3.0",
"fileVersion": "4.6.26515.6"
}
},
"runtimeTargets": {
"runtimes/win/lib/netcoreapp2.1/System.Security.Cryptography.Pkcs.dll": {
"rid": "win",
"assetType": "runtime",
"assemblyVersion": "4.0.3.0",
"fileVersion": "4.6.26515.6"
}
}
},
"System.Security.Cryptography.Primitives/4.3.0": {
"dependencies": {
"System.Diagnostics.Debug": "4.3.0",
"System.Globalization": "4.3.0",
"System.IO": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Threading": "4.3.0",
"System.Threading.Tasks": "4.3.0"
}
},
"System.Security.Cryptography.X509Certificates/4.3.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0",
"System.Collections": "4.3.0",
"System.Diagnostics.Debug": "4.3.0",
"System.Globalization": "4.3.0",
"System.Globalization.Calendars": "4.3.0",
"System.IO": "4.3.0",
"System.IO.FileSystem": "4.3.0",
"System.IO.FileSystem.Primitives": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.Handles": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Runtime.Numerics": "4.3.0",
"System.Security.Cryptography.Algorithms": "4.3.0",
"System.Security.Cryptography.Cng": "4.5.0",
"System.Security.Cryptography.Csp": "4.3.0",
"System.Security.Cryptography.Encoding": "4.3.0",
"System.Security.Cryptography.OpenSsl": "4.3.0",
"System.Security.Cryptography.Primitives": "4.3.0",
"System.Text.Encoding": "4.3.0",
"System.Threading": "4.3.0",
"runtime.native.System": "4.3.0",
"runtime.native.System.Net.Http": "4.3.0",
"runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
},
"runtimeTargets": {
"runtime/unix/lib/_._": {
"rid": "unix",
"assetType": "runtime"
},
"runtime/win/lib/_._": {
"rid": "win",
"assetType": "runtime"
}
}
},
"System.Security.Cryptography.Xml/4.5.0": {
"dependencies": {
"System.Security.Cryptography.Pkcs": "4.5.0",
"System.Security.Permissions": "4.5.0"
},
"runtime": {
"lib/netstandard2.0/System.Security.Cryptography.Xml.dll": {
"assemblyVersion": "4.0.1.0",
"fileVersion": "4.6.26515.6"
}
},
"compile": {
"ref/netstandard2.0/System.Security.Cryptography.Xml.dll": {}
}
},
"System.Security.Permissions/4.5.0": {
"dependencies": {
"System.Security.AccessControl": "4.5.0"
},
"runtime": {
"lib/netstandard2.0/System.Security.Permissions.dll": {
"assemblyVersion": "4.0.1.0",
"fileVersion": "4.6.26515.6"
}
},
"compile": {
"ref/netstandard2.0/System.Security.Permissions.dll": {}
}
},
"System.Security.Principal.Windows/4.5.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0"
},
"runtimeTargets": {
"runtime/unix/lib/_._": {
"rid": "unix",
"assetType": "runtime"
},
"runtime/win/lib/_._": {
"rid": "win",
"assetType": "runtime"
}
},
"compile": {
"ref/netstandard2.0/System.Security.Principal.Windows.dll": {}
}
},
"System.Text.Encoding/4.3.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0",
"Microsoft.NETCore.Targets": "2.1.0",
"System.Runtime": "4.3.0"
}
},
"System.Text.Encoding.CodePages/4.3.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0",
"System.Collections": "4.3.0",
"System.Globalization": "4.3.0",
"System.IO": "4.3.0",
"System.Reflection": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.Handles": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Text.Encoding": "4.3.0",
"System.Threading": "4.3.0"
},
"runtimeTargets": {
"runtimes/unix/lib/netstandard1.3/System.Text.Encoding.CodePages.dll": {
"rid": "unix",
"assetType": "runtime",
"assemblyVersion": "4.0.2.0",
"fileVersion": "4.6.24705.1"
},
"runtimes/win/lib/netstandard1.3/System.Text.Encoding.CodePages.dll": {
"rid": "win",
"assetType": "runtime",
"assemblyVersion": "4.0.2.0",
"fileVersion": "4.6.24705.1"
}
}
},
"System.Text.Encoding.Extensions/4.3.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0",
"Microsoft.NETCore.Targets": "2.1.0",
"System.Runtime": "4.3.0",
"System.Text.Encoding": "4.3.0"
}
},
"System.Text.Encodings.Web/4.5.0": {
"runtime": {
"lib/netstandard2.0/System.Text.Encodings.Web.dll": {
"assemblyVersion": "4.0.3.0",
"fileVersion": "4.6.26515.6"
}
},
"compile": {
"lib/netstandard2.0/System.Text.Encodings.Web.dll": {}
}
},
"System.Text.RegularExpressions/4.3.0": {
"dependencies": {
"System.Runtime": "4.3.0"
}
},
"System.Threading/4.3.0": {
"dependencies": {
"System.Runtime": "4.3.0",
"System.Threading.Tasks": "4.3.0"
}
},
"System.Threading.Tasks/4.3.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0",
"Microsoft.NETCore.Targets": "2.1.0",
"System.Runtime": "4.3.0"
}
},
"System.Threading.Tasks.Extensions/4.5.1": {},
"System.Threading.Tasks.Parallel/4.3.0": {
"dependencies": {
"System.Collections.Concurrent": "4.3.0",
"System.Diagnostics.Debug": "4.3.0",
"System.Diagnostics.Tracing": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Threading": "4.3.0",
"System.Threading.Tasks": "4.3.0"
}
},
"System.Threading.Thread/4.3.0": {
"dependencies": {
"System.Runtime": "4.3.0"
}
},
"System.Threading.Timer/4.0.1": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0",
"Microsoft.NETCore.Targets": "2.1.0",
"System.Runtime": "4.3.0"
}
},
"System.ValueTuple/4.3.0": {
"dependencies": {
"System.Collections": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0"
}
},
"System.Xml.ReaderWriter/4.3.0": {
"dependencies": {
"System.Collections": "4.3.0",
"System.Diagnostics.Debug": "4.3.0",
"System.Globalization": "4.3.0",
"System.IO": "4.3.0",
"System.IO.FileSystem": "4.3.0",
"System.IO.FileSystem.Primitives": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Text.Encoding": "4.3.0",
"System.Text.Encoding.Extensions": "4.3.0",
"System.Text.RegularExpressions": "4.3.0",
"System.Threading.Tasks": "4.3.0",
"System.Threading.Tasks.Extensions": "4.5.1"
}
},
"System.Xml.XDocument/4.3.0": {
"dependencies": {
"System.Collections": "4.3.0",
"System.Diagnostics.Debug": "4.3.0",
"System.Diagnostics.Tools": "4.3.0",
"System.Globalization": "4.3.0",
"System.IO": "4.3.0",
"System.Reflection": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Text.Encoding": "4.3.0",
"System.Threading": "4.3.0",
"System.Xml.ReaderWriter": "4.3.0"
}
},
"System.Xml.XmlDocument/4.3.0": {
"dependencies": {
"System.Collections": "4.3.0",
"System.Diagnostics.Debug": "4.3.0",
"System.Globalization": "4.3.0",
"System.IO": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Text.Encoding": "4.3.0",
"System.Threading": "4.3.0",
"System.Xml.ReaderWriter": "4.3.0"
}
},
"System.Xml.XPath/4.3.0": {
"dependencies": {
"System.Collections": "4.3.0",
"System.Diagnostics.Debug": "4.3.0",
"System.Globalization": "4.3.0",
"System.IO": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Threading": "4.3.0",
"System.Xml.ReaderWriter": "4.3.0"
}
},
"System.Xml.XPath.XDocument/4.3.0": {
"dependencies": {
"System.Diagnostics.Debug": "4.3.0",
"System.Linq": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Threading": "4.3.0",
"System.Xml.ReaderWriter": "4.3.0",
"System.Xml.XDocument": "4.3.0",
"System.Xml.XPath": "4.3.0"
}
},
"Telegram.Bot/14.6.0": {
"dependencies": {
"NETStandard.Library": "2.0.3",
"Newtonsoft.Json": "11.0.2",
"System.Net.Requests": "4.3.0"
},
"runtime": {
"lib/netstandard1.1/Telegram.Bot.dll": {
"assemblyVersion": "14.6.0.0",
"fileVersion": "14.6.0.0"
}
},
"compile": {
"lib/netstandard1.1/Telegram.Bot.dll": {}
}
},
"IntelliTrader.Core/1.0.0": {
"dependencies": {
"Autofac": "4.8.1",
"Microsoft.Extensions.Configuration": "2.1.1",
"Microsoft.Extensions.Configuration.Binder": "2.1.1",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "2.1.1",
"Microsoft.Extensions.Configuration.Json": "2.1.1",
"Serilog": "2.7.1",
"Serilog.Enrichers.Environment": "2.1.2",
"Serilog.Filters.Expressions": "2.0.0",
"Serilog.Settings.Configuration": "2.6.1",
"Serilog.Sinks.Console": "3.1.1",
"Serilog.Sinks.RollingFile": "3.3.0",
"Telegram.Bot": "14.6.0"
},
"runtime": {
"IntelliTrader.Core.dll": {}
},
"compile": {
"IntelliTrader.Core.dll": {}
}
},
"Microsoft.NETCore.App/2.1.0": {
"dependencies": {
"Microsoft.NETCore.DotNetHostPolicy": "2.1.0",
"Microsoft.NETCore.Platforms": "2.1.0",
"Microsoft.NETCore.Targets": "2.1.0",
"NETStandard.Library": "2.0.3"
},
"compile": {
"ref/netcoreapp2.1/Microsoft.CSharp.dll": {},
"ref/netcoreapp2.1/Microsoft.VisualBasic.dll": {},
"ref/netcoreapp2.1/Microsoft.Win32.Primitives.dll": {},
"ref/netcoreapp2.1/System.AppContext.dll": {},
"ref/netcoreapp2.1/System.Buffers.dll": {},
"ref/netcoreapp2.1/System.Collections.Concurrent.dll": {},
"ref/netcoreapp2.1/System.Collections.Immutable.dll": {},
"ref/netcoreapp2.1/System.Collections.NonGeneric.dll": {},
"ref/netcoreapp2.1/System.Collections.Specialized.dll": {},
"ref/netcoreapp2.1/System.Collections.dll": {},
"ref/netcoreapp2.1/System.ComponentModel.Annotations.dll": {},
"ref/netcoreapp2.1/System.ComponentModel.DataAnnotations.dll": {},
"ref/netcoreapp2.1/System.ComponentModel.EventBasedAsync.dll": {},
"ref/netcoreapp2.1/System.ComponentModel.Primitives.dll": {},
"ref/netcoreapp2.1/System.ComponentModel.TypeConverter.dll": {},
"ref/netcoreapp2.1/System.ComponentModel.dll": {},
"ref/netcoreapp2.1/System.Configuration.dll": {},
"ref/netcoreapp2.1/System.Console.dll": {},
"ref/netcoreapp2.1/System.Core.dll": {},
"ref/netcoreapp2.1/System.Data.Common.dll": {},
"ref/netcoreapp2.1/System.Data.dll": {},
"ref/netcoreapp2.1/System.Diagnostics.Contracts.dll": {},
"ref/netcoreapp2.1/System.Diagnostics.Debug.dll": {},
"ref/netcoreapp2.1/System.Diagnostics.DiagnosticSource.dll": {},
"ref/netcoreapp2.1/System.Diagnostics.FileVersionInfo.dll": {},
"ref/netcoreapp2.1/System.Diagnostics.Process.dll": {},
"ref/netcoreapp2.1/System.Diagnostics.StackTrace.dll": {},
"ref/netcoreapp2.1/System.Diagnostics.TextWriterTraceListener.dll": {},
"ref/netcoreapp2.1/System.Diagnostics.Tools.dll": {},
"ref/netcoreapp2.1/System.Diagnostics.TraceSource.dll": {},
"ref/netcoreapp2.1/System.Diagnostics.Tracing.dll": {},
"ref/netcoreapp2.1/System.Drawing.Primitives.dll": {},
"ref/netcoreapp2.1/System.Drawing.dll": {},
"ref/netcoreapp2.1/System.Dynamic.Runtime.dll": {},
"ref/netcoreapp2.1/System.Globalization.Calendars.dll": {},
"ref/netcoreapp2.1/System.Globalization.Extensions.dll": {},
"ref/netcoreapp2.1/System.Globalization.dll": {},
"ref/netcoreapp2.1/System.IO.Compression.Brotli.dll": {},
"ref/netcoreapp2.1/System.IO.Compression.FileSystem.dll": {},
"ref/netcoreapp2.1/System.IO.Compression.ZipFile.dll": {},
"ref/netcoreapp2.1/System.IO.Compression.dll": {},
"ref/netcoreapp2.1/System.IO.FileSystem.DriveInfo.dll": {},
"ref/netcoreapp2.1/System.IO.FileSystem.Primitives.dll": {},
"ref/netcoreapp2.1/System.IO.FileSystem.Watcher.dll": {},
"ref/netcoreapp2.1/System.IO.FileSystem.dll": {},
"ref/netcoreapp2.1/System.IO.IsolatedStorage.dll": {},
"ref/netcoreapp2.1/System.IO.MemoryMappedFiles.dll": {},
"ref/netcoreapp2.1/System.IO.Pipes.dll": {},
"ref/netcoreapp2.1/System.IO.UnmanagedMemoryStream.dll": {},
"ref/netcoreapp2.1/System.IO.dll": {},
"ref/netcoreapp2.1/System.Linq.Expressions.dll": {},
"ref/netcoreapp2.1/System.Linq.Parallel.dll": {},
"ref/netcoreapp2.1/System.Linq.Queryable.dll": {},
"ref/netcoreapp2.1/System.Linq.dll": {},
"ref/netcoreapp2.1/System.Memory.dll": {},
"ref/netcoreapp2.1/System.Net.Http.dll": {},
"ref/netcoreapp2.1/System.Net.HttpListener.dll": {},
"ref/netcoreapp2.1/System.Net.Mail.dll": {},
"ref/netcoreapp2.1/System.Net.NameResolution.dll": {},
"ref/netcoreapp2.1/System.Net.NetworkInformation.dll": {},
"ref/netcoreapp2.1/System.Net.Ping.dll": {},
"ref/netcoreapp2.1/System.Net.Primitives.dll": {},
"ref/netcoreapp2.1/System.Net.Requests.dll": {},
"ref/netcoreapp2.1/System.Net.Security.dll": {},
"ref/netcoreapp2.1/System.Net.ServicePoint.dll": {},
"ref/netcoreapp2.1/System.Net.Sockets.dll": {},
"ref/netcoreapp2.1/System.Net.WebClient.dll": {},
"ref/netcoreapp2.1/System.Net.WebHeaderCollection.dll": {},
"ref/netcoreapp2.1/System.Net.WebProxy.dll": {},
"ref/netcoreapp2.1/System.Net.WebSockets.Client.dll": {},
"ref/netcoreapp2.1/System.Net.WebSockets.dll": {},
"ref/netcoreapp2.1/System.Net.dll": {},
"ref/netcoreapp2.1/System.Numerics.Vectors.dll": {},
"ref/netcoreapp2.1/System.Numerics.dll": {},
"ref/netcoreapp2.1/System.ObjectModel.dll": {},
"ref/netcoreapp2.1/System.Reflection.DispatchProxy.dll": {},
"ref/netcoreapp2.1/System.Reflection.Emit.ILGeneration.dll": {},
"ref/netcoreapp2.1/System.Reflection.Emit.Lightweight.dll": {},
"ref/netcoreapp2.1/System.Reflection.Emit.dll": {},
"ref/netcoreapp2.1/System.Reflection.Extensions.dll": {},
"ref/netcoreapp2.1/System.Reflection.Metadata.dll": {},
"ref/netcoreapp2.1/System.Reflection.Primitives.dll": {},
"ref/netcoreapp2.1/System.Reflection.TypeExtensions.dll": {},
"ref/netcoreapp2.1/System.Reflection.dll": {},
"ref/netcoreapp2.1/System.Resources.Reader.dll": {},
"ref/netcoreapp2.1/System.Resources.ResourceManager.dll": {},
"ref/netcoreapp2.1/System.Resources.Writer.dll": {},
"ref/netcoreapp2.1/System.Runtime.CompilerServices.VisualC.dll": {},
"ref/netcoreapp2.1/System.Runtime.Extensions.dll": {},
"ref/netcoreapp2.1/System.Runtime.Handles.dll": {},
"ref/netcoreapp2.1/System.Runtime.InteropServices.RuntimeInformation.dll": {},
"ref/netcoreapp2.1/System.Runtime.InteropServices.WindowsRuntime.dll": {},
"ref/netcoreapp2.1/System.Runtime.InteropServices.dll": {},
"ref/netcoreapp2.1/System.Runtime.Loader.dll": {},
"ref/netcoreapp2.1/System.Runtime.Numerics.dll": {},
"ref/netcoreapp2.1/System.Runtime.Serialization.Formatters.dll": {},
"ref/netcoreapp2.1/System.Runtime.Serialization.Json.dll": {},
"ref/netcoreapp2.1/System.Runtime.Serialization.Primitives.dll": {},
"ref/netcoreapp2.1/System.Runtime.Serialization.Xml.dll": {},
"ref/netcoreapp2.1/System.Runtime.Serialization.dll": {},
"ref/netcoreapp2.1/System.Runtime.dll": {},
"ref/netcoreapp2.1/System.Security.Claims.dll": {},
"ref/netcoreapp2.1/System.Security.Cryptography.Algorithms.dll": {},
"ref/netcoreapp2.1/System.Security.Cryptography.Csp.dll": {},
"ref/netcoreapp2.1/System.Security.Cryptography.Encoding.dll": {},
"ref/netcoreapp2.1/System.Security.Cryptography.Primitives.dll": {},
"ref/netcoreapp2.1/System.Security.Cryptography.X509Certificates.dll": {},
"ref/netcoreapp2.1/System.Security.Principal.dll": {},
"ref/netcoreapp2.1/System.Security.SecureString.dll": {},
"ref/netcoreapp2.1/System.Security.dll": {},
"ref/netcoreapp2.1/System.ServiceModel.Web.dll": {},
"ref/netcoreapp2.1/System.ServiceProcess.dll": {},
"ref/netcoreapp2.1/System.Text.Encoding.Extensions.dll": {},
"ref/netcoreapp2.1/System.Text.Encoding.dll": {},
"ref/netcoreapp2.1/System.Text.RegularExpressions.dll": {},
"ref/netcoreapp2.1/System.Threading.Overlapped.dll": {},
"ref/netcoreapp2.1/System.Threading.Tasks.Dataflow.dll": {},
"ref/netcoreapp2.1/System.Threading.Tasks.Extensions.dll": {},
"ref/netcoreapp2.1/System.Threading.Tasks.Parallel.dll": {},
"ref/netcoreapp2.1/System.Threading.Tasks.dll": {},
"ref/netcoreapp2.1/System.Threading.Thread.dll": {},
"ref/netcoreapp2.1/System.Threading.ThreadPool.dll": {},
"ref/netcoreapp2.1/System.Threading.Timer.dll": {},
"ref/netcoreapp2.1/System.Threading.dll": {},
"ref/netcoreapp2.1/System.Transactions.Local.dll": {},
"ref/netcoreapp2.1/System.Transactions.dll": {},
"ref/netcoreapp2.1/System.ValueTuple.dll": {},
"ref/netcoreapp2.1/System.Web.HttpUtility.dll": {},
"ref/netcoreapp2.1/System.Web.dll": {},
"ref/netcoreapp2.1/System.Windows.dll": {},
"ref/netcoreapp2.1/System.Xml.Linq.dll": {},
"ref/netcoreapp2.1/System.Xml.ReaderWriter.dll": {},
"ref/netcoreapp2.1/System.Xml.Serialization.dll": {},
"ref/netcoreapp2.1/System.Xml.XDocument.dll": {},
"ref/netcoreapp2.1/System.Xml.XPath.XDocument.dll": {},
"ref/netcoreapp2.1/System.Xml.XPath.dll": {},
"ref/netcoreapp2.1/System.Xml.XmlDocument.dll": {},
"ref/netcoreapp2.1/System.Xml.XmlSerializer.dll": {},
"ref/netcoreapp2.1/System.Xml.dll": {},
"ref/netcoreapp2.1/System.dll": {},
"ref/netcoreapp2.1/WindowsBase.dll": {},
"ref/netcoreapp2.1/mscorlib.dll": {},
"ref/netcoreapp2.1/netstandard.dll": {}
},
"compileOnly": true
},
"Microsoft.NETCore.DotNetAppHost/2.1.0": {
"compileOnly": true
},
"Microsoft.NETCore.DotNetHostPolicy/2.1.0": {
"dependencies": {
"Microsoft.NETCore.DotNetHostResolver": "2.1.0"
},
"compileOnly": true
},
"Microsoft.NETCore.DotNetHostResolver/2.1.0": {
"dependencies": {
"Microsoft.NETCore.DotNetAppHost": "2.1.0"
},
"compileOnly": true
},
"Microsoft.NETCore.Platforms/2.1.0": {
"compileOnly": true
},
"Microsoft.NETCore.Targets/2.1.0": {
"compileOnly": true
},
"NETStandard.Library/2.0.3": {
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.0"
},
"compileOnly": true
}
}
},
"libraries": {
"IntelliTrader.Web/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Autofac/4.8.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-aIT9rupCOdab5RMfxvWTBmOxGU77tLqmvSF4V89SzV6oQcJrtuKw/Xp55xy9EijSktbMka55SbroAPOyT+lziw==",
"path": "autofac/4.8.1",
"hashPath": "autofac.4.8.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Antiforgery/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-BKDp2thf1k3Q2XBSIxC0TvHLvGFOr3ga3DdsxOJNTQ2MEvCuqlNFAoBxXIXWtvP9EHNfLbmKA0+VF7nBqXTlYg==",
"path": "microsoft.aspnetcore.antiforgery/2.1.1",
"hashPath": "microsoft.aspnetcore.antiforgery.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Authentication/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-WgbDLOGoyX0/EoUdAlihMaKIpON6LwCYZ8fiPhZZe+qdCJhvl1aTBmJ/carHcv3NJGT+ETuq2ppYQr7PKLq1CQ==",
"path": "microsoft.aspnetcore.authentication/2.1.1",
"hashPath": "microsoft.aspnetcore.authentication.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Authentication.Abstractions/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-kl1yZmNeUMm9/kWtqoOvIATBavqHPwJICl0FA9rpvNqETqeTgakAbbY25TdG82wKKbjo4LpqZ0YCHwktNPaR2Q==",
"path": "microsoft.aspnetcore.authentication.abstractions/2.1.1",
"hashPath": "microsoft.aspnetcore.authentication.abstractions.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Authentication.Cookies/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-Yz9dgcZvZ+OJjJ8ZX/+DtgY0+9ZuKzNO0cHkDUdQubY4W4Ozn5e194s70lNQiiEGJjah9hd/5yuayPAePiz7DQ==",
"path": "microsoft.aspnetcore.authentication.cookies/2.1.1",
"hashPath": "microsoft.aspnetcore.authentication.cookies.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Authentication.Core/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-I7CfHtUAwVH67ayCG9ZrkRI5si0yOlttb0ltMR36dMwXfPR9CYab0o9PyWfTOfGIT9VQ+UgAEH9U9+jVoEjPeg==",
"path": "microsoft.aspnetcore.authentication.core/2.1.1",
"hashPath": "microsoft.aspnetcore.authentication.core.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Authorization/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-z/5haIkI/G2NcCMO288l6l7Jy3BDqzZjHLb2VxjCfj4NKRVv6KlsDD7nGIyAtAbDVKnbOsGBXF6xwhyo4aFGBw==",
"path": "microsoft.aspnetcore.authorization/2.1.1",
"hashPath": "microsoft.aspnetcore.authorization.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Authorization.Policy/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-ipuhLj35k90+q6GbBuJaouPDLGwaJilBUUE+y0rtGL+yncCtA1gYFrs3jZ+tRX/zNqlVtlAb1u7wXm5NJ/TkQw==",
"path": "microsoft.aspnetcore.authorization.policy/2.1.1",
"hashPath": "microsoft.aspnetcore.authorization.policy.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Connections.Abstractions/2.1.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-O/dAVpldQyJEzzrY1f6Ki+s4DeAk8qtvcSK8Pk+zJLYB9tZKdWMQ68ob+fy7CsYCdLyhbT/vro0TSBK1teit7g==",
"path": "microsoft.aspnetcore.connections.abstractions/2.1.2",
"hashPath": "microsoft.aspnetcore.connections.abstractions.2.1.2.nupkg.sha512"
},
"Microsoft.AspNetCore.Cors/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-ajz3/gjo4OYDFId5nJUrBAYJhKW3sJrK5+dLJ3ynTuVyGwY5me3QICukzMeADSKNV+JapSrPKLXIythHwDrQjA==",
"path": "microsoft.aspnetcore.cors/2.1.1",
"hashPath": "microsoft.aspnetcore.cors.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Cryptography.Internal/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-9X49e4ZTv6ipL/Yh1GvVxpgh+ghWMHi+PPE3tQI2HRgG6Jixvmt8LgT/KvAvfgYEDnjsSTRyt/arrHsekHwfMA==",
"path": "microsoft.aspnetcore.cryptography.internal/2.1.1",
"hashPath": "microsoft.aspnetcore.cryptography.internal.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.DataProtection/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-561yQw2Xu5DH05p6uv4G6dD0tfO2KeNuFz/kPREHHFzOk4PF3tdmH9LjCz2fX8eyOvgvfiLSib3atE7thRvZDQ==",
"path": "microsoft.aspnetcore.dataprotection/2.1.1",
"hashPath": "microsoft.aspnetcore.dataprotection.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.DataProtection.Abstractions/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-94UHZlJQUeCeCsrDNrEVDO7nOoFsr1KSetcHAttPA6DDe80XJ57wbWUpzxjoGRimoGG2yS95n7M0bueZCMD7ag==",
"path": "microsoft.aspnetcore.dataprotection.abstractions/2.1.1",
"hashPath": "microsoft.aspnetcore.dataprotection.abstractions.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Diagnostics/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-F9GjtKSe4HeOqZJjnnI110wDcvsY0aguALGswbr+R3iuw6X+Mzko7S/Vx7LxQXxInOCJoxnNEkd7Kf59dFFSRg==",
"path": "microsoft.aspnetcore.diagnostics/2.1.1",
"hashPath": "microsoft.aspnetcore.diagnostics.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Diagnostics.Abstractions/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-rLn97UtnaXvD1E8K2UFQg5MBZ/D6KLuMZEEt47qkIIEsEQar84yIlR3HdDDF7ovJ/Bg546EyJXHxXvi7t6G7yw==",
"path": "microsoft.aspnetcore.diagnostics.abstractions/2.1.1",
"hashPath": "microsoft.aspnetcore.diagnostics.abstractions.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Hosting/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-rO2JSJGuHJMYE68vm72bFI+PEj1e6zgv9r3izNMEMwyGtjsEDFSHALoGqffnehY63TKqpXdAKElKzPV0UYrMqA==",
"path": "microsoft.aspnetcore.hosting/2.1.1",
"hashPath": "microsoft.aspnetcore.hosting.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Hosting.Abstractions/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-FFZxJAK3sV9JxZ7YP47upycv6VZOcNvJLiLM0FXfvlrb67RC9y4AjCUX1RvI0W1n1v6GMZhWSNb3KYs+O6s26g==",
"path": "microsoft.aspnetcore.hosting.abstractions/2.1.1",
"hashPath": "microsoft.aspnetcore.hosting.abstractions.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Hosting.Server.Abstractions/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-xqfxC5t1Jk4ZOQN5xfR2Q0nqTOTN5R6FORk4LqjEzmfX8NDdEsds+Fj6d9bMYqhPWZ4ATRAi8RmaUKYPQuAWbQ==",
"path": "microsoft.aspnetcore.hosting.server.abstractions/2.1.1",
"hashPath": "microsoft.aspnetcore.hosting.server.abstractions.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Html.Abstractions/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-tPZG0aA3V8tljooIgKhAiVxu7ZnAnL7QPzz3uxQgs4v7vwwCZTigzh2PIL4QRtezlGFk1jn7PbOtxi+FsmEe0g==",
"path": "microsoft.aspnetcore.html.abstractions/2.1.1",
"hashPath": "microsoft.aspnetcore.html.abstractions.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Http/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-u8Fmky/nirrxOU1gBGh97J5gPoniWDc1QiT+J0EFuXJWcFo3BgPGiv7RLvYCi89QpLgIt5CkkPqTkPnWz0eaSA==",
"path": "microsoft.aspnetcore.http/2.1.1",
"hashPath": "microsoft.aspnetcore.http.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Http.Abstractions/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-0TPQgjRy2xJ75GcK18vvrT6/zCtSAWUEBSskSJN/lY0zuvQx2or8lzwr0TdKyMNK8A8MLP4QMLPqL9NOAxe0yg==",
"path": "microsoft.aspnetcore.http.abstractions/2.1.1",
"hashPath": "microsoft.aspnetcore.http.abstractions.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Http.Extensions/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-0dgKLajNfwElW6fLElwjo+fEyfhXdSN74QeXhOUgPam5UIbU3EBQU/+xD83MnfprAiUPDWHqueTKuB8oa/cjNQ==",
"path": "microsoft.aspnetcore.http.extensions/2.1.1",
"hashPath": "microsoft.aspnetcore.http.extensions.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Http.Features/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-cMnTXRH+8T7GLht6cXRCMmN1HaYfXti2WEUdXqMUuyJgi4oH9cmzW4nECSBkQjsCs5O06BphyDDDAsTW/zQmpg==",
"path": "microsoft.aspnetcore.http.features/2.1.1",
"hashPath": "microsoft.aspnetcore.http.features.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.JsonPatch/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-T5kx4u+0CH5bD3hB+QEozR4MmLZ7CDGdm0+OD1wxyQBJKNNA6jRSJmbvsZ8nmOEwoGtAfHdXLYM0r3/Zw6J4JQ==",
"path": "microsoft.aspnetcore.jsonpatch/2.1.1",
"hashPath": "microsoft.aspnetcore.jsonpatch.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Localization/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-oy13Ppp0iBLHAzq03R5tEBNTAfatboreqW7YEMhVA2fu6L0KLmBk3njHc0FJaFnwZwCbmPnRtr81J8A7NWqQuQ==",
"path": "microsoft.aspnetcore.localization/2.1.1",
"hashPath": "microsoft.aspnetcore.localization.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Mvc/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-3mHitdj9MClvbFThDsVhojGH2PxWWxhJNFzFwNnofSdORrnRby9bikM+HCqUOz2gvxnyYz5jsgbA88+CGkNy4A==",
"path": "microsoft.aspnetcore.mvc/2.1.1",
"hashPath": "microsoft.aspnetcore.mvc.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Mvc.Abstractions/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-/XgeeXi0LrykMlMCNMQftj2XyEua4JT5AFAt3D3xE6KChx0PydXTFiwQtDvbGpNvarPQWWdyEfq1rKlgyVGlXA==",
"path": "microsoft.aspnetcore.mvc.abstractions/2.1.1",
"hashPath": "microsoft.aspnetcore.mvc.abstractions.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Mvc.ApiExplorer/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-GGPbYZfzJvu6rigtCN0FRQD4B8ERmMO+grCyf/lfQhmqK9cTfhDcU8Zfw75SXrQ3Ity1lSvYpf26XeFVIi5Y5A==",
"path": "microsoft.aspnetcore.mvc.apiexplorer/2.1.1",
"hashPath": "microsoft.aspnetcore.mvc.apiexplorer.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Mvc.Core/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-QoYLsJHrN7LNnL1LWzSGzQm3v/1ERI5csb4LSzNYm71EcCG8SWckw76GgXNx6mjsJXfxsvoqRAovnLQKCCBtvA==",
"path": "microsoft.aspnetcore.mvc.core/2.1.1",
"hashPath": "microsoft.aspnetcore.mvc.core.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Mvc.Cors/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-a04jcvPbG6IfaugJe3CS59ZhSRAVLmwVEGDLp4wGuR4/9yW3T4mCZgqcSQz+5921j/hRGn1Jwu/b05bWkg+wBg==",
"path": "microsoft.aspnetcore.mvc.cors/2.1.1",
"hashPath": "microsoft.aspnetcore.mvc.cors.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Mvc.DataAnnotations/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-3/LdPk7u3VitfUxVu+forzb+YFa/G4tqFDQKG20mMHrAnE7ranDUhqURD7qoy8JFLRWdhvvdBhUJaATfvvmTVg==",
"path": "microsoft.aspnetcore.mvc.dataannotations/2.1.1",
"hashPath": "microsoft.aspnetcore.mvc.dataannotations.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Mvc.Formatters.Json/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-nBzpBR0Ei/4L63+ylGS6P4gP+u+/S1cIvUU4+G+4Rk+vtzNT5KsoFP9TfCvW8hGQ6ShehjT7wXMuci/D2SbCQQ==",
"path": "microsoft.aspnetcore.mvc.formatters.json/2.1.1",
"hashPath": "microsoft.aspnetcore.mvc.formatters.json.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Mvc.Localization/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-JN/d/T8JUYoF/YMBupIu92ZcP9PcYfLLQqIZWvfyJrNNftgXENAHMLn1999POEzG44RjGouWdioSH8QZJ1mTTQ==",
"path": "microsoft.aspnetcore.mvc.localization/2.1.1",
"hashPath": "microsoft.aspnetcore.mvc.localization.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Mvc.Razor/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-9WCfQX8+xZN8pzRK8ZxCJw/3lpsKsg3iQvFr6CRz4UtayLEoq/uzLKL5xvY8fj1rVJjt3wBh+YBhheB/196QSg==",
"path": "microsoft.aspnetcore.mvc.razor/2.1.1",
"hashPath": "microsoft.aspnetcore.mvc.razor.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Mvc.Razor.Extensions/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-w/4GAxZS5y9CnlIO4z04sC7I+cLVVYsvI+hC+Thh2vy5AQxNZj9ZIxmdIPtvqQfZ2JdURQ7cpBsr8pzf4YhTEA==",
"path": "microsoft.aspnetcore.mvc.razor.extensions/2.1.1",
"hashPath": "microsoft.aspnetcore.mvc.razor.extensions.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Mvc.RazorPages/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-icxhGYO1z5IQsrmJhbIJUHM2a0mTK7g1kdPR/mnB5L4r35im8ElX0449AFN3KlA0C00E6mzXVe1CCJ3wO+TUxQ==",
"path": "microsoft.aspnetcore.mvc.razorpages/2.1.1",
"hashPath": "microsoft.aspnetcore.mvc.razorpages.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Mvc.TagHelpers/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-wLHZ9TUdD9Gl2rVihrNGmRJ1LGTjiRzPM4d78efClOpFJwhMaHCnr9ktfQhnJX4XQj0w22XvPPCV0GxSrVp4Lg==",
"path": "microsoft.aspnetcore.mvc.taghelpers/2.1.1",
"hashPath": "microsoft.aspnetcore.mvc.taghelpers.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Mvc.ViewFeatures/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-4F4uu3Hh5pgQ/2XkKgG2XEfPIvzUUjpOrSPIdOpMzxloTfYM/jK6xEW6kM9DE5vYhyW9EE02sngRBh8cmU0vng==",
"path": "microsoft.aspnetcore.mvc.viewfeatures/2.1.1",
"hashPath": "microsoft.aspnetcore.mvc.viewfeatures.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Razor/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-oDxJTufrOF2Y7g+p2jU5+2xtrcsb3KX20pH/KosLW5rbsJMAqaOwprI6gJlBQCGtMCYl/MbnC45ZObPmzyI0NQ==",
"path": "microsoft.aspnetcore.razor/2.1.1",
"hashPath": "microsoft.aspnetcore.razor.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Razor.Design/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-f8PKGcxiezL1RVqmnmrazj24Mj4KCTSXqwdotl7Lc+82h8iLV7ItxEIShTJakG7M9iw0ZuCocM0J/IhYesdQrg==",
"path": "microsoft.aspnetcore.razor.design/2.1.1",
"hashPath": "microsoft.aspnetcore.razor.design.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Razor.Language/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-5HX7/SguN9F8cdJ6GBBFJauEii/k6XPuI1gHucOcOBKKetgm4nG/xrHzRGSBTxmc1rbCcVKrBl10/PYItE7JyA==",
"path": "microsoft.aspnetcore.razor.language/2.1.1",
"hashPath": "microsoft.aspnetcore.razor.language.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Razor.Runtime/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-dGublvci7Lwu8gAegh81YXATyKGupWHb5RDHPsIO/Ct++xG7Lv9/6nNbci05sqYienZgprDbTAH8G7PmBCpIKQ==",
"path": "microsoft.aspnetcore.razor.runtime/2.1.1",
"hashPath": "microsoft.aspnetcore.razor.runtime.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.ResponseCaching.Abstractions/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-F2/eDBTwGdTdQ+YPrlf7DBprzbHVZmZqnCTkHT6Jge7MQDu0xgUmDfNyBUzg9jn38RSKnDp6RWLQSJ6yqsYdIQ==",
"path": "microsoft.aspnetcore.responsecaching.abstractions/2.1.1",
"hashPath": "microsoft.aspnetcore.responsecaching.abstractions.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Routing/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-BnVEKMGIkRcZecG3zR+tl9tYGkViz1k/WzYVNRfdaAN0LeuSabNP0NlG037oz+pDPsLzzNkFeLSOh/w0AKLaig==",
"path": "microsoft.aspnetcore.routing/2.1.1",
"hashPath": "microsoft.aspnetcore.routing.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Routing.Abstractions/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-+Yxsy/ZcCthcziktuhfC6WpQ/cZzgD/IsQ96xefNKrCzIm9jXjfNK3ONsoScvyFFihNohp7zAVPiic5J6CvUDw==",
"path": "microsoft.aspnetcore.routing.abstractions/2.1.1",
"hashPath": "microsoft.aspnetcore.routing.abstractions.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.Server.Kestrel/2.1.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-ol4rQS7QpGBtfcHY39ecVnAg1Fe0MXTIZN/hm4ldJAXE2+PmH7BnLl1yJrZB5MMeXHYsU+v1N0+iSkX5jJm2uw==",
"path": "microsoft.aspnetcore.server.kestrel/2.1.2",
"hashPath": "microsoft.aspnetcore.server.kestrel.2.1.2.nupkg.sha512"
},
"Microsoft.AspNetCore.Server.Kestrel.Core/2.1.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-tig0vQgH1hvY3We458hCRBjJfu0zc+sqGZxTboXde8pT932MdsxxUzimxPCHdg3RBRRzVct1E1KtMb6c6M5Pxw==",
"path": "microsoft.aspnetcore.server.kestrel.core/2.1.2",
"hashPath": "microsoft.aspnetcore.server.kestrel.core.2.1.2.nupkg.sha512"
},
"Microsoft.AspNetCore.Server.Kestrel.Https/2.1.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-Z+GhgasOk1tr3g5NVkUmVqHpbi+ORqkTenErnBTF1DjgXileomxweijL2StNvmv1dtJhxhclZpIGePpWIKAAfA==",
"path": "microsoft.aspnetcore.server.kestrel.https/2.1.2",
"hashPath": "microsoft.aspnetcore.server.kestrel.https.2.1.2.nupkg.sha512"
},
"Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions/2.1.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-wtlxVAdrp6BsBi3/A3yeIOygZl1m2Wn2GOYBjngp5tTbhMJZm0bVO+xPcw2bOKUL1eQHUQwRsJB5kabPKphotg==",
"path": "microsoft.aspnetcore.server.kestrel.transport.abstractions/2.1.2",
"hashPath": "microsoft.aspnetcore.server.kestrel.transport.abstractions.2.1.2.nupkg.sha512"
},
"Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets/2.1.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-PHCpMsg8aSuNFkgXX9f+HIkYNpWMDj5l+hFni4Zyuv3hv2xfRdehqvEZTAsYPRbRWy5hyewCSZ3Kh/fifLQc7g==",
"path": "microsoft.aspnetcore.server.kestrel.transport.sockets/2.1.2",
"hashPath": "microsoft.aspnetcore.server.kestrel.transport.sockets.2.1.2.nupkg.sha512"
},
"Microsoft.AspNetCore.StaticFiles/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-3xumS58evfsC4cd8OXtYRafbwuVk5c37dsGQ1E1m0wZvRVUXScRWkTGdcPJcijoImlhoQK2pj6sY7NFMc5PfbQ==",
"path": "microsoft.aspnetcore.staticfiles/2.1.1",
"hashPath": "microsoft.aspnetcore.staticfiles.2.1.1.nupkg.sha512"
},
"Microsoft.AspNetCore.WebUtilities/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-gvCdObgQDLdZ9enyFQuPb3Rae6QyzZAPgHiv5JhYjORLMW1UNgWXvdqLov6iGtnyG+BBCavPooW9ScWGQCJHLg==",
"path": "microsoft.aspnetcore.webutilities/2.1.1",
"hashPath": "microsoft.aspnetcore.webutilities.2.1.1.nupkg.sha512"
},
"Microsoft.CodeAnalysis.Analyzers/1.1.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-6csv1zVOCb3tncoRbuYclgO5qksGIypQbUb3pofrcWVibbT3Bpq0rx19Xf5Vm1l1MzmY2HJiUY1JubL0YZvFNA==",
"path": "microsoft.codeanalysis.analyzers/1.1.0",
"hashPath": "microsoft.codeanalysis.analyzers.1.1.0.nupkg.sha512"
},
"Microsoft.CodeAnalysis.Common/2.8.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-lYUBqh3OD3iEQqxt9KB472VzgOnEKoUVG4Lx5Xw4oJe9dZtITkHFtct+T73jH3FOASFI1NSzzP5MBM0c9zZspA==",
"path": "microsoft.codeanalysis.common/2.8.0",
"hashPath": "microsoft.codeanalysis.common.2.8.0.nupkg.sha512"
},
"Microsoft.CodeAnalysis.CSharp/2.8.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-+4CHAwHMwLO5GRqPJ7Khv2Ny//omhukPKP3Ny/d2XDpt11bX35zb9pTziwZN0eNvxj6a46joIdHEYQ1JsekI3w==",
"path": "microsoft.codeanalysis.csharp/2.8.0",
"hashPath": "microsoft.codeanalysis.csharp.2.8.0.nupkg.sha512"
},
"Microsoft.CodeAnalysis.Razor/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-D5zUSmQHsgKosYlWLQjs6uXn4n7llEdUwFhJz7EIwR16ge18q8p8BJ547out9ScnMDuwHA8MeCPe8WMwCaFAPw==",
"path": "microsoft.codeanalysis.razor/2.1.1",
"hashPath": "microsoft.codeanalysis.razor.2.1.1.nupkg.sha512"
},
"Microsoft.CSharp/4.5.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-EGoBmf3Na2ppbhPePDE9PlX81r1HuOZH5twBrq7couJZiPTjUnD3648balerQJO6EJ8Sj+43+XuRwQ7r+3tE3w==",
"path": "microsoft.csharp/4.5.0",
"hashPath": "microsoft.csharp.4.5.0.nupkg.sha512"
},
"Microsoft.DotNet.PlatformAbstractions/2.1.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-wkCXkBS0q+5hsbeikjfsHCGP3nNe1L1MrDEBPCBKm+4UH8nXqHLxDZuBrTYaVY85CGIx2y1qW90nO6b+ORAfrA==",
"path": "microsoft.dotnet.platformabstractions/2.1.0",
"hashPath": "microsoft.dotnet.platformabstractions.2.1.0.nupkg.sha512"
},
"Microsoft.Extensions.Caching.Abstractions/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-gcPRTtchou4pIEdLYhh9xoBDjwCaCLiTHJaFN2IWJCP+TGJcIHQYblPMftw6fajHER9ZrvPO5RYZUyLmH1eNIA==",
"path": "microsoft.extensions.caching.abstractions/2.1.1",
"hashPath": "microsoft.extensions.caching.abstractions.2.1.1.nupkg.sha512"
},
"Microsoft.Extensions.Caching.Memory/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-KV2w9nelcxgl1Y028qmexCcgBK+CtZ18fE2eIypB1lUtLOGBrzP+XhcJTxBYwXPnYPkxazqdzcOfIRxz/Bq2uQ==",
"path": "microsoft.extensions.caching.memory/2.1.1",
"hashPath": "microsoft.extensions.caching.memory.2.1.1.nupkg.sha512"
},
"Microsoft.Extensions.Configuration/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-1JaydycXzbfAExlsD7XIWykzVnU/wZM86KzrHyGlXuxqnqzcWSXLJn4Ejn8bDnq07CEJNZ+GjsxWKlJ8kFfnvQ==",
"path": "microsoft.extensions.configuration/2.1.1",
"hashPath": "microsoft.extensions.configuration.2.1.1.nupkg.sha512"
},
"Microsoft.Extensions.Configuration.Abstractions/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-9EMhOWU2eOQOtMIJ+vfwKJpnLRc1Wl3vXu8qXeevA91cSY4j3WvArmF7ApGtJwa7yKewJTvlQlBSn9OSnLFg6Q==",
"path": "microsoft.extensions.configuration.abstractions/2.1.1",
"hashPath": "microsoft.extensions.configuration.abstractions.2.1.1.nupkg.sha512"
},
"Microsoft.Extensions.Configuration.Binder/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-t7KFAv6AxyUsZj9QN8FAbusg+X5baCELl+XtscyuP1IGUv5UctyY7/rNZLyiKaV7HhAcDQ1zC5ZQNQQFn6JpAA==",
"path": "microsoft.extensions.configuration.binder/2.1.1",
"hashPath": "microsoft.extensions.configuration.binder.2.1.1.nupkg.sha512"
},
"Microsoft.Extensions.Configuration.EnvironmentVariables/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-rDFRChBvs6sPGC+JjshKsP4kWRvsG8Y9MQKduDu60RWnJpFiIpQ7HK2K9sPrCL1MaYEk894PUkiZ5Xdsm9cPvg==",
"path": "microsoft.extensions.configuration.environmentvariables/2.1.1",
"hashPath": "microsoft.extensions.configuration.environmentvariables.2.1.1.nupkg.sha512"
},
"Microsoft.Extensions.Configuration.FileExtensions/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-JnhKotPCs1+X4CPSsHOk8CpxmBeIS/vIXYewsoM8XflXNhpzMe1gfIckQyuRKyORlGaNFEBr4WrPjpZ159bS/Q==",
"path": "microsoft.extensions.configuration.fileextensions/2.1.1",
"hashPath": "microsoft.extensions.configuration.fileextensions.2.1.1.nupkg.sha512"
},
"Microsoft.Extensions.Configuration.Json/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-f6KcI9v0GVA4YL/ExoxrEfeQv9La3hyQnySfgxGkFtMeDJIUun0ANoMjspbdpXXnuaScwgbQ2mFE3lJHt9lpJw==",
"path": "microsoft.extensions.configuration.json/2.1.1",
"hashPath": "microsoft.extensions.configuration.json.2.1.1.nupkg.sha512"
},
"Microsoft.Extensions.DependencyInjection/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-2nshYaLTn73Ie+/yTkb7EZIXwQeFIXsYCBy/jSY9bMayYykGNjdWa25frayhuPAGVbZpEgfgp3d4JRVEuVyEqQ==",
"path": "microsoft.extensions.dependencyinjection/2.1.1",
"hashPath": "microsoft.extensions.dependencyinjection.2.1.1.nupkg.sha512"
},
"Microsoft.Extensions.DependencyInjection.Abstractions/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-PW1596sF97gpIc1JuUuYvTmeLfeqC5whbWPsWgJhN0fdwz683him3b/HB0dqhFesVssOjnnA0fEz4+S0gUeBqA==",
"path": "microsoft.extensions.dependencyinjection.abstractions/2.1.1",
"hashPath": "microsoft.extensions.dependencyinjection.abstractions.2.1.1.nupkg.sha512"
},
"Microsoft.Extensions.DependencyModel/2.1.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-3KPT6CLH0VEGr2um9aG1rYTmqfMVlkRuueFpN6AxeIKpcMA4OVHf4aNpgYXZ6oF+x4uh9VhK/66FgPCd1mMlnQ==",
"path": "microsoft.extensions.dependencymodel/2.1.0",
"hashPath": "microsoft.extensions.dependencymodel.2.1.0.nupkg.sha512"
},
"Microsoft.Extensions.FileProviders.Abstractions/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-qOJP+VAlXDeMQSJ6iflW62bEsN3S1NJIPHmhKFA9L37yU+jce2wbwesA7sDe9WdJ8+SoKtLnHPUxvOyQrAcRCA==",
"path": "microsoft.extensions.fileproviders.abstractions/2.1.1",
"hashPath": "microsoft.extensions.fileproviders.abstractions.2.1.1.nupkg.sha512"
},
"Microsoft.Extensions.FileProviders.Composite/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-SovLUACJ3C+iRlHo4VdZw0IDX+v7+32paTJf7v5ZyzyWqijUkDYXr81gL7tkCfCkJmBYnrc6bScoj2Eaxlrudw==",
"path": "microsoft.extensions.fileproviders.composite/2.1.1",
"hashPath": "microsoft.extensions.fileproviders.composite.2.1.1.nupkg.sha512"
},
"Microsoft.Extensions.FileProviders.Physical/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-pbT/J3B686Xgktv5WH11FbcbZXDmBQuCN3ce8IKIF+DpOk3p0RgUPrOXcYNp81TyH+K/5Cosr4VFVjYMoirNDg==",
"path": "microsoft.extensions.fileproviders.physical/2.1.1",
"hashPath": "microsoft.extensions.fileproviders.physical.2.1.1.nupkg.sha512"
},
"Microsoft.Extensions.FileSystemGlobbing/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-Pu/O8jBc7QlEmqmbDGVosuDlyzGspMuKc71rOsJigwGMF5574aWYw9uRMX+ho1dmbnL502ZYHo6PlBP3IXkm5A==",
"path": "microsoft.extensions.filesystemglobbing/2.1.1",
"hashPath": "microsoft.extensions.filesystemglobbing.2.1.1.nupkg.sha512"
},
"Microsoft.Extensions.Hosting.Abstractions/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-v7mPlJ68Dsev9gn6w5tJJZI798r6gCmwKBv0pwJ5PunLEITYjrv1+QJ/wYkp7KuRcr8VRUML8mJg/mgUjgHggA==",
"path": "microsoft.extensions.hosting.abstractions/2.1.1",
"hashPath": "microsoft.extensions.hosting.abstractions.2.1.1.nupkg.sha512"
},
"Microsoft.Extensions.Localization/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-XPVATgcnzWwo6NYXsZfiEBSSFWWOEdFMn099BIlJCgwVSTLdZD130xRFH4wGXg5sMos3xXsBLv1fffQ67Ju+qg==",
"path": "microsoft.extensions.localization/2.1.1",
"hashPath": "microsoft.extensions.localization.2.1.1.nupkg.sha512"
},
"Microsoft.Extensions.Localization.Abstractions/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-V1znqxUEDHAfnCDXLsfrbY+RmtrFkJqOFhVBOIrcqQMp6MFJvIV9QpDTMq8JzqYc++aAraIoUEAsAwoa8otlOw==",
"path": "microsoft.extensions.localization.abstractions/2.1.1",
"hashPath": "microsoft.extensions.localization.abstractions.2.1.1.nupkg.sha512"
},
"Microsoft.Extensions.Logging/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-x4/RzeReQSIi4nVpOjXEySm/xUSr6lBjuecdYnlUboWxbLSm2j3vhFV5OLGRp3gfte3cRMdysMNa/wyZN0t/Tw==",
"path": "microsoft.extensions.logging/2.1.1",
"hashPath": "microsoft.extensions.logging.2.1.1.nupkg.sha512"
},
"Microsoft.Extensions.Logging.Abstractions/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-QWFWKrdeoDSEr8nVJaBAVDMj24wnh9clGzDNmMdgHHRsOIwTUMeh4XljeZXJhIKPT00jWuzwEzn3uNxOtO4cYg==",
"path": "microsoft.extensions.logging.abstractions/2.1.1",
"hashPath": "microsoft.extensions.logging.abstractions.2.1.1.nupkg.sha512"
},
"Microsoft.Extensions.ObjectPool/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-FE4JmV6FEZdmqSKqvld5TRnvHfJfrw9QzvvZlAiTn+FCiq/1ZaQDpcYBRH7dMHFWIsYD6Z2UTsufdbCGznox8g==",
"path": "microsoft.extensions.objectpool/2.1.1",
"hashPath": "microsoft.extensions.objectpool.2.1.1.nupkg.sha512"
},
"Microsoft.Extensions.Options/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-j0zOfTt1Qm+JDW2m+6Q/aj1m4C8+onudUu4ls/fN69VxruZkMWmX1bPKkbkYIPNNxJsf4k7FOkVq5o1vEFq9pQ==",
"path": "microsoft.extensions.options/2.1.1",
"hashPath": "microsoft.extensions.options.2.1.1.nupkg.sha512"
},
"Microsoft.Extensions.Primitives/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-Svz25/egj1TsNL4118jyMqkhDiu0l8QYWq2p52P4BBN0GbqwR18ZRIctSP5TTDJy0m0EFC8aB2FOVjGtvEGWSA==",
"path": "microsoft.extensions.primitives/2.1.1",
"hashPath": "microsoft.extensions.primitives.2.1.1.nupkg.sha512"
},
"Microsoft.Extensions.WebEncoders/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-0fR5UV3qREnTpGiqUkz6p30gHzRNvZExgTpch0Gwc+lVUh7D2MBLK/2ohmsMnXp7ckYiEAHhEb9Z/NTUdajKXA==",
"path": "microsoft.extensions.webencoders/2.1.1",
"hashPath": "microsoft.extensions.webencoders.2.1.1.nupkg.sha512"
},
"Microsoft.Net.Http.Headers/2.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-tNh1YCfZ943/d3WSE6cD57O05rhvi3lmKgwoi3zFg4wc/O/oec5FNHZmBCRau4GfzRC5zS/CBdOAkRwbvtZSaQ==",
"path": "microsoft.net.http.headers/2.1.1",
"hashPath": "microsoft.net.http.headers.2.1.1.nupkg.sha512"
},
"Microsoft.Win32.Registry/4.5.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-vduxuHEqRgRrTE8wYG8Wxj/+6wwzddOmZzjKZx6rFMc/91aUBxI5etAFYxesoNaIja5NpgSTcnk6cN8BeYXf9A==",
"path": "microsoft.win32.registry/4.5.0",
"hashPath": "microsoft.win32.registry.4.5.0.nupkg.sha512"
},
"Newtonsoft.Json/11.0.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-IvJe1pj7JHEsP8B8J8DwlMEx8UInrs/x+9oVY+oCD13jpLu4JbJU2WCIsMRn5C4yW9+DgkaO8uiVE5VHKjpmdQ==",
"path": "newtonsoft.json/11.0.2",
"hashPath": "newtonsoft.json.11.0.2.nupkg.sha512"
},
"Newtonsoft.Json.Bson/1.0.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-5PYT/IqQ+UK31AmZiSS102R6EsTo+LGTSI8bp7WAUqDKaF4wHXD8U9u4WxTI1vc64tYi++8p3dk3WWNqPFgldw==",
"path": "newtonsoft.json.bson/1.0.1",
"hashPath": "newtonsoft.json.bson.1.0.1.nupkg.sha512"
},
"runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-HdSSp5MnJSsg08KMfZThpuLPJpPwE5hBXvHwoKWosyHHfe8Mh5WKT0ylEOf6yNzX6Ngjxe4Whkafh5q7Ymac4Q==",
"path": "runtime.debian.8-x64.runtime.native.system.security.cryptography.openssl/4.3.0",
"hashPath": "runtime.debian.8-x64.runtime.native.system.security.cryptography.openssl.4.3.0.nupkg.sha512"
},
"runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-+yH1a49wJMy8Zt4yx5RhJrxO/DBDByAiCzNwiETI+1S4mPdCu0OY4djdciC7Vssk0l22wQaDLrXxXkp+3+7bVA==",
"path": "runtime.fedora.23-x64.runtime.native.system.security.cryptography.openssl/4.3.0",
"hashPath": "runtime.fedora.23-x64.runtime.native.system.security.cryptography.openssl.4.3.0.nupkg.sha512"
},
"runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-c3YNH1GQJbfIPJeCnr4avseugSqPrxwIqzthYyZDN6EuOyNOzq+y2KSUfRcXauya1sF4foESTgwM5e1A8arAKw==",
"path": "runtime.fedora.24-x64.runtime.native.system.security.cryptography.openssl/4.3.0",
"hashPath": "runtime.fedora.24-x64.runtime.native.system.security.cryptography.openssl.4.3.0.nupkg.sha512"
},
"runtime.native.System/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-c/qWt2LieNZIj1jGnVNsE2Kl23Ya2aSTBuXMD6V7k9KWr6l16Tqdwq+hJScEpWER9753NWC8h96PaVNY5Ld7Jw==",
"path": "runtime.native.system/4.3.0",
"hashPath": "runtime.native.system.4.3.0.nupkg.sha512"
},
"runtime.native.System.IO.Compression/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-INBPonS5QPEgn7naufQFXJEp3zX6L4bwHgJ/ZH78aBTpeNfQMtf7C6VrAFhlq2xxWBveIOWyFzQjJ8XzHMhdOQ==",
"path": "runtime.native.system.io.compression/4.3.0",
"hashPath": "runtime.native.system.io.compression.4.3.0.nupkg.sha512"
},
"runtime.native.System.Net.Http/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-ZVuZJqnnegJhd2k/PtAbbIcZ3aZeITq3sj06oKfMBSfphW3HDmk/t4ObvbOk/JA/swGR0LNqMksAh/f7gpTROg==",
"path": "runtime.native.system.net.http/4.3.0",
"hashPath": "runtime.native.system.net.http.4.3.0.nupkg.sha512"
},
"runtime.native.System.Security.Cryptography.Apple/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-DloMk88juo0OuOWr56QG7MNchmafTLYWvABy36izkrLI5VledI0rq28KGs1i9wbpeT9NPQrx/wTf8U2vazqQ3Q==",
"path": "runtime.native.system.security.cryptography.apple/4.3.0",
"hashPath": "runtime.native.system.security.cryptography.apple.4.3.0.nupkg.sha512"
},
"runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-NS1U+700m4KFRHR5o4vo9DSlTmlCKu/u7dtE5sUHVIPB+xpXxYQvgBgA6wEIeCz6Yfn0Z52/72WYsToCEPJnrw==",
"path": "runtime.native.system.security.cryptography.openssl/4.3.0",
"hashPath": "runtime.native.system.security.cryptography.openssl.4.3.0.nupkg.sha512"
},
"runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-b3pthNgxxFcD+Pc0WSEoC0+md3MyhRS6aCEeenvNE3Fdw1HyJ18ZhRFVJJzIeR/O/jpxPboB805Ho0T3Ul7w8A==",
"path": "runtime.opensuse.13.2-x64.runtime.native.system.security.cryptography.openssl/4.3.0",
"hashPath": "runtime.opensuse.13.2-x64.runtime.native.system.security.cryptography.openssl.4.3.0.nupkg.sha512"
},
"runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-KeLz4HClKf+nFS7p/6Fi/CqyLXh81FpiGzcmuS8DGi9lUqSnZ6Es23/gv2O+1XVGfrbNmviF7CckBpavkBoIFQ==",
"path": "runtime.opensuse.42.1-x64.runtime.native.system.security.cryptography.openssl/4.3.0",
"hashPath": "runtime.opensuse.42.1-x64.runtime.native.system.security.cryptography.openssl.4.3.0.nupkg.sha512"
},
"runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-kVXCuMTrTlxq4XOOMAysuNwsXWpYeboGddNGpIgNSZmv1b6r/s/DPk0fYMB7Q5Qo4bY68o48jt4T4y5BVecbCQ==",
"path": "runtime.osx.10.10-x64.runtime.native.system.security.cryptography.apple/4.3.0",
"hashPath": "runtime.osx.10.10-x64.runtime.native.system.security.cryptography.apple.4.3.0.nupkg.sha512"
},
"runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-X7IdhILzr4ROXd8mI1BUCQMSHSQwelUlBjF1JyTKCjXaOGn2fB4EKBxQbCK2VjO3WaWIdlXZL3W6TiIVnrhX4g==",
"path": "runtime.osx.10.10-x64.runtime.native.system.security.cryptography.openssl/4.3.0",
"hashPath": "runtime.osx.10.10-x64.runtime.native.system.security.cryptography.openssl.4.3.0.nupkg.sha512"
},
"runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-nyFNiCk/r+VOiIqreLix8yN+q3Wga9+SE8BCgkf+2BwEKiNx6DyvFjCgkfV743/grxv8jHJ8gUK4XEQw7yzRYg==",
"path": "runtime.rhel.7-x64.runtime.native.system.security.cryptography.openssl/4.3.0",
"hashPath": "runtime.rhel.7-x64.runtime.native.system.security.cryptography.openssl.4.3.0.nupkg.sha512"
},
"runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-ytoewC6wGorL7KoCAvRfsgoJPJbNq+64k2SqW6JcOAebWsFUvCCYgfzQMrnpvPiEl4OrblUlhF2ji+Q1+SVLrQ==",
"path": "runtime.ubuntu.14.04-x64.runtime.native.system.security.cryptography.openssl/4.3.0",
"hashPath": "runtime.ubuntu.14.04-x64.runtime.native.system.security.cryptography.openssl.4.3.0.nupkg.sha512"
},
"runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-I8bKw2I8k58Wx7fMKQJn2R8lamboCAiHfHeV/pS65ScKWMMI0+wJkLYlEKvgW1D/XvSl/221clBoR2q9QNNM7A==",
"path": "runtime.ubuntu.16.04-x64.runtime.native.system.security.cryptography.openssl/4.3.0",
"hashPath": "runtime.ubuntu.16.04-x64.runtime.native.system.security.cryptography.openssl.4.3.0.nupkg.sha512"
},
"runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-VB5cn/7OzUfzdnC8tqAIMQciVLiq2epm2NrAm1E9OjNRyG4lVhfR61SMcLizejzQP8R8Uf/0l5qOIbUEi+RdEg==",
"path": "runtime.ubuntu.16.10-x64.runtime.native.system.security.cryptography.openssl/4.3.0",
"hashPath": "runtime.ubuntu.16.10-x64.runtime.native.system.security.cryptography.openssl.4.3.0.nupkg.sha512"
},
"Serilog/2.7.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-5eS6AD4hesOYvlwYqjntLaOonDnEiY22QiMUKueJHPrm5vm1k4tzXgOgCb2mJoMnj6l5Wt6AXV5liXzXymvarg==",
"path": "serilog/2.7.1",
"hashPath": "serilog.2.7.1.nupkg.sha512"
},
"Serilog.Enrichers.Environment/2.1.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-Uj3X4tGW8T38IIGCp/MxbHgg5vG3HN5myBQLIw2JTt87Gwv11NgZJGc4hunmFocQYny09CPVy2LRfiI6gAqQ4Q==",
"path": "serilog.enrichers.environment/2.1.2",
"hashPath": "serilog.enrichers.environment.2.1.2.nupkg.sha512"
},
"Serilog.Filters.Expressions/2.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-JhD2uV1s3ixF4L2dSB7t7jV5OKG8AEQOYtfTqSVkNm9X/g6zr1uoGH62XhDfCzEbyd5fiB9Rv4IXm+8m98Ao9Q==",
"path": "serilog.filters.expressions/2.0.0",
"hashPath": "serilog.filters.expressions.2.0.0.nupkg.sha512"
},
"Serilog.Settings.Configuration/2.6.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-d23bkPRrI/lxfe3FQ2C1KouU/3tBDhGhIHvmlW94rDeNductsu6wzEOGTI9neImD3AwzCB/WPq2BJCZAWe2R4Q==",
"path": "serilog.settings.configuration/2.6.1",
"hashPath": "serilog.settings.configuration.2.6.1.nupkg.sha512"
},
"Serilog.Sinks.Console/3.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-56mI5AqvyF/i/c2451nvV71kq370XOCE4Uu5qiaJ295sOhMb9q3BWwG7mWLOVSnmpWiq0SBT3SXfgRXGNP6vzA==",
"path": "serilog.sinks.console/3.1.1",
"hashPath": "serilog.sinks.console.3.1.1.nupkg.sha512"
},
"Serilog.Sinks.File/3.2.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-VHbo68pMg5hwSWrzLEdZv5b/rYmIgHIRhd4d5rl8GnC5/a8Fr+RShT5kWyeJOXax1el6mNJ+dmHDOVgnNUQxaw==",
"path": "serilog.sinks.file/3.2.0",
"hashPath": "serilog.sinks.file.3.2.0.nupkg.sha512"
},
"Serilog.Sinks.RollingFile/3.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-2lT5X1r3GH4P0bRWJfhA7etGl8Q2Ipw9AACvtAHWRUSpYZ42NGVyHoVs2ALBZ/cAkkS+tA4jl80Zie144eLQPg==",
"path": "serilog.sinks.rollingfile/3.3.0",
"hashPath": "serilog.sinks.rollingfile.3.3.0.nupkg.sha512"
},
"Superpower/2.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-LvsFRxO7VJuUXiaIr3agLuTQTCVYtzgmGJ4BiNe4/DKplOMZ4pibpVSg1ON5zXdCci1jYNfRgQlNEKv0d0Kcog==",
"path": "superpower/2.0.0",
"hashPath": "superpower.2.0.0.nupkg.sha512"
},
"System.AppContext/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-fKC+rmaLfeIzUhagxY17Q9siv/sPrjjKcfNg1Ic8IlQkZLipo8ljcaZQu4VtI4Jqbzjc2VTjzGLF6WmsRXAEgA==",
"path": "system.appcontext/4.3.0",
"hashPath": "system.appcontext.4.3.0.nupkg.sha512"
},
"System.Buffers/4.5.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-xpHYjjtyTEpzMwtSQBWdVc3dPjLdQtvyUg6fBlBqcLl1r2Y7gDG/W/enAYOB98nG3oD3Q153Y2FBO8JDWd+0Xw==",
"path": "system.buffers/4.5.0",
"hashPath": "system.buffers.4.5.0.nupkg.sha512"
},
"System.Collections/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-3Dcj85/TBdVpL5Zr+gEEBUuFe2icOnLalmEh9hfck1PTYbbyWuZgh4fmm2ysCLTrqLQw6t3TgTyJ+VLp+Qb+Lw==",
"path": "system.collections/4.3.0",
"hashPath": "system.collections.4.3.0.nupkg.sha512"
},
"System.Collections.Concurrent/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-ztl69Xp0Y/UXCL+3v3tEU+lIy+bvjKNUmopn1wep/a291pVPK7dxBd6T7WnlQqRog+d1a/hSsgRsmFnIBKTPLQ==",
"path": "system.collections.concurrent/4.3.0",
"hashPath": "system.collections.concurrent.4.3.0.nupkg.sha512"
},
"System.Collections.Immutable/1.3.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-n+AGX7zmiZumW9aggOkXaHzUeAS3EfeTErnkKCusyONUozbTv+kMb8VE36m+ldV6kF9g57G2c641KCdgH9E0pg==",
"path": "system.collections.immutable/1.3.1",
"hashPath": "system.collections.immutable.1.3.1.nupkg.sha512"
},
"System.Collections.NonGeneric/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-prtjIEMhGUnQq6RnPEYLpFt8AtLbp9yq2zxOSrY7KJJZrw25Fi97IzBqY7iqssbM61Ek5b8f3MG/sG1N2sN5KA==",
"path": "system.collections.nongeneric/4.3.0",
"hashPath": "system.collections.nongeneric.4.3.0.nupkg.sha512"
},
"System.ComponentModel/4.0.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-oBZFnm7seFiVfugsIyOvQCWobNZs7FzqDV/B7tx20Ep/l3UUFCPDkdTnCNaJZTU27zjeODmy2C/cP60u3D4c9w==",
"path": "system.componentmodel/4.0.1",
"hashPath": "system.componentmodel.4.0.1.nupkg.sha512"
},
"System.ComponentModel.Annotations/4.5.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-IjDa643EO77A4CL9dhxfZ6zzGu+pM8Ar0NYPRMN3TvDiga4uGDzFHOj/ArpyNxxKyO5IFT2LZ0rK3kUog7g3jA==",
"path": "system.componentmodel.annotations/4.5.0",
"hashPath": "system.componentmodel.annotations.4.5.0.nupkg.sha512"
},
"System.Console/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-DHDrIxiqk1h03m6khKWV2X8p/uvN79rgSqpilL6uzpmSfxfU5ng8VcPtW4qsDsQDHiTv6IPV9TmD5M/vElPNLg==",
"path": "system.console/4.3.0",
"hashPath": "system.console.4.3.0.nupkg.sha512"
},
"System.Diagnostics.Debug/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-ZUhUOdqmaG5Jk3Xdb8xi5kIyQYAA4PnTNlHx1mu9ZY3qv4ELIdKbnL/akbGaKi2RnNUWaZsAs31rvzFdewTj2g==",
"path": "system.diagnostics.debug/4.3.0",
"hashPath": "system.diagnostics.debug.4.3.0.nupkg.sha512"
},
"System.Diagnostics.DiagnosticSource/4.5.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-UumL3CJklk5WyEt0eImPmjeuyY1JgJ7Thmg2hAeZGKCv+9iuuAsoc2wcXjypdo3J8VNEmVCH2Bgn/kIw8NI2bA==",
"path": "system.diagnostics.diagnosticsource/4.5.0",
"hashPath": "system.diagnostics.diagnosticsource.4.5.0.nupkg.sha512"
},
"System.Diagnostics.FileVersionInfo/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-omCF64wzQ3Q2CeIqkD6lmmxeMZtGHUmzgFMPjfVaOsyqpR66p/JaZzManMw1s33osoAb5gqpncsjie67+yUPHQ==",
"path": "system.diagnostics.fileversioninfo/4.3.0",
"hashPath": "system.diagnostics.fileversioninfo.4.3.0.nupkg.sha512"
},
"System.Diagnostics.StackTrace/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-BiHg0vgtd35/DM9jvtaC1eKRpWZxr0gcQd643ABG7GnvSlf5pOkY2uyd42mMOJoOmKvnpNj0F4tuoS1pacTwYw==",
"path": "system.diagnostics.stacktrace/4.3.0",
"hashPath": "system.diagnostics.stacktrace.4.3.0.nupkg.sha512"
},
"System.Diagnostics.Tools/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-UUvkJfSYJMM6x527dJg2VyWPSRqIVB0Z7dbjHst1zmwTXz5CcXSYJFWRpuigfbO1Lf7yfZiIaEUesfnl/g5EyA==",
"path": "system.diagnostics.tools/4.3.0",
"hashPath": "system.diagnostics.tools.4.3.0.nupkg.sha512"
},
"System.Diagnostics.Tracing/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-rswfv0f/Cqkh78rA5S8eN8Neocz234+emGCtTF3lxPY96F+mmmUen6tbn0glN6PMvlKQb9bPAY5e9u7fgPTkKw==",
"path": "system.diagnostics.tracing/4.3.0",
"hashPath": "system.diagnostics.tracing.4.3.0.nupkg.sha512"
},
"System.Dynamic.Runtime/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-SNVi1E/vfWUAs/WYKhE9+qlS6KqK0YVhnlT0HQtr8pMIA8YX3lwy3uPMownDwdYISBdmAF/2holEIldVp85Wag==",
"path": "system.dynamic.runtime/4.3.0",
"hashPath": "system.dynamic.runtime.4.3.0.nupkg.sha512"
},
"System.Globalization/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-kYdVd2f2PAdFGblzFswE4hkNANJBKRmsfa2X5LG2AcWE1c7/4t0pYae1L8vfZ5xvE2nK/R9JprtToA61OSHWIg==",
"path": "system.globalization/4.3.0",
"hashPath": "system.globalization.4.3.0.nupkg.sha512"
},
"System.Globalization.Calendars/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-GUlBtdOWT4LTV3I+9/PJW+56AnnChTaOqqTLFtdmype/L500M2LIyXgmtd9X2P2VOkmJd5c67H5SaC2QcL1bFA==",
"path": "system.globalization.calendars/4.3.0",
"hashPath": "system.globalization.calendars.4.3.0.nupkg.sha512"
},
"System.Globalization.Extensions/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-FhKmdR6MPG+pxow6wGtNAWdZh7noIOpdD5TwQ3CprzgIE1bBBoim0vbR1+AWsWjQmU7zXHgQo4TWSP6lCeiWcQ==",
"path": "system.globalization.extensions/4.3.0",
"hashPath": "system.globalization.extensions.4.3.0.nupkg.sha512"
},
"System.IO/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-3qjaHvxQPDpSOYICjUoTsmoq5u6QJAFRUITgeT/4gqkF1bajbSmb1kwSxEA8AHlofqgcKJcM8udgieRNhaJ5Cg==",
"path": "system.io/4.3.0",
"hashPath": "system.io.4.3.0.nupkg.sha512"
},
"System.IO.Compression/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-YHndyoiV90iu4iKG115ibkhrG+S3jBm8Ap9OwoUAzO5oPDAWcr0SFwQFm0HjM8WkEZWo0zvLTyLmbvTkW1bXgg==",
"path": "system.io.compression/4.3.0",
"hashPath": "system.io.compression.4.3.0.nupkg.sha512"
},
"System.IO.FileSystem/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-3wEMARTnuio+ulnvi+hkRNROYwa1kylvYahhcLk4HSoVdl+xxTFVeVlYOfLwrDPImGls0mDqbMhrza8qnWPTdA==",
"path": "system.io.filesystem/4.3.0",
"hashPath": "system.io.filesystem.4.3.0.nupkg.sha512"
},
"System.IO.FileSystem.Primitives/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-6QOb2XFLch7bEc4lIcJH49nJN2HV+OC3fHDgsLVsBVBk3Y4hFAnOBGzJ2lUu7CyDDFo9IBWkSsnbkT6IBwwiMw==",
"path": "system.io.filesystem.primitives/4.3.0",
"hashPath": "system.io.filesystem.primitives.4.3.0.nupkg.sha512"
},
"System.IO.Pipelines/4.5.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-Kq9eZWVKN9khHhkatLWLLxYCs3j9qSNMZELqn2YG1YsCMv6bPmAtaN0CfA6l7vxFbiV02C996Dy7yHO8DkaJLg==",
"path": "system.io.pipelines/4.5.0",
"hashPath": "system.io.pipelines.4.5.0.nupkg.sha512"
},
"System.Linq/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-5DbqIUpsDp0dFftytzuMmc0oeMdQwjcP/EWxsksIz/w1TcFRkZ3yKKz0PqiYFMmEwPSWw+qNVqD7PJ889JzHbw==",
"path": "system.linq/4.3.0",
"hashPath": "system.linq.4.3.0.nupkg.sha512"
},
"System.Linq.Expressions/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-PGKkrd2khG4CnlyJwxwwaWWiSiWFNBGlgXvJpeO0xCXrZ89ODrQ6tjEWS/kOqZ8GwEOUATtKtzp1eRgmYNfclg==",
"path": "system.linq.expressions/4.3.0",
"hashPath": "system.linq.expressions.4.3.0.nupkg.sha512"
},
"System.Memory/4.5.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-vcG3/MbfpxznMkkkaAblJi7RHOmuP7kawQMhDgLSuA1tRpRQYsFSCTxRSINDUgn2QNn2jWeLxv8er5BXbyACkw==",
"path": "system.memory/4.5.1",
"hashPath": "system.memory.4.5.1.nupkg.sha512"
},
"System.Net.Http/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-sYg+FtILtRQuYWSIAuNOELwVuVsxVyJGWQyOnlAzhV4xvhyFnON1bAzYYC+jjRW8JREM45R0R5Dgi8MTC5sEwA==",
"path": "system.net.http/4.3.0",
"hashPath": "system.net.http.4.3.0.nupkg.sha512"
},
"System.Net.Primitives/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-qOu+hDwFwoZPbzPvwut2qATe3ygjeQBDQj91xlsaqGFQUI5i4ZnZb8yyQuLGpDGivEPIt8EJkd1BVzVoP31FXA==",
"path": "system.net.primitives/4.3.0",
"hashPath": "system.net.primitives.4.3.0.nupkg.sha512"
},
"System.Net.Requests/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-OZNUuAs0kDXUzm7U5NZ1ojVta5YFZmgT2yxBqsQ7Eseq5Ahz88LInGRuNLJ/NP2F8W1q7tse1pKDthj3reF5QA==",
"path": "system.net.requests/4.3.0",
"hashPath": "system.net.requests.4.3.0.nupkg.sha512"
},
"System.Net.WebHeaderCollection/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-XZrXYG3c7QV/GpWeoaRC02rM6LH2JJetfVYskf35wdC/w2fFDFMphec4gmVH2dkll6abtW14u9Rt96pxd9YH2A==",
"path": "system.net.webheadercollection/4.3.0",
"hashPath": "system.net.webheadercollection.4.3.0.nupkg.sha512"
},
"System.Numerics.Vectors/4.5.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-MNcaYxUJvUcoXOa+jgKl/GDw/Mh+wMrxDjW4dre7qrp35LUGTjUBNtZsNjxsWX592ocdyqt1X5hMJB+5OStoYw==",
"path": "system.numerics.vectors/4.5.0",
"hashPath": "system.numerics.vectors.4.5.0.nupkg.sha512"
},
"System.ObjectModel/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-bdX+80eKv9bN6K4N+d77OankKHGn6CH711a6fcOpMQu2Fckp/Ft4L/kW9WznHpyR0NRAvJutzOMHNNlBGvxQzQ==",
"path": "system.objectmodel/4.3.0",
"hashPath": "system.objectmodel.4.3.0.nupkg.sha512"
},
"System.Reflection/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-KMiAFoW7MfJGa9nDFNcfu+FpEdiHpWgTcS2HdMpDvt9saK3y/G4GwprPyzqjFH9NTaGPQeWNHU+iDlDILj96aQ==",
"path": "system.reflection/4.3.0",
"hashPath": "system.reflection.4.3.0.nupkg.sha512"
},
"System.Reflection.Emit/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-228FG0jLcIwTVJyz8CLFKueVqQK36ANazUManGaJHkO0icjiIypKW7YLWLIWahyIkdh5M7mV2dJepllLyA1SKg==",
"path": "system.reflection.emit/4.3.0",
"hashPath": "system.reflection.emit.4.3.0.nupkg.sha512"
},
"System.Reflection.Emit.ILGeneration/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-59tBslAk9733NXLrUJrwNZEzbMAcu8k344OYo+wfSVygcgZ9lgBdGIzH/nrg3LYhXceynyvTc8t5/GD4Ri0/ng==",
"path": "system.reflection.emit.ilgeneration/4.3.0",
"hashPath": "system.reflection.emit.ilgeneration.4.3.0.nupkg.sha512"
},
"System.Reflection.Emit.Lightweight/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-oadVHGSMsTmZsAF864QYN1t1QzZjIcuKU3l2S9cZOwDdDueNTrqq1yRj7koFfIGEnKpt6NjpL3rOzRhs4ryOgA==",
"path": "system.reflection.emit.lightweight/4.3.0",
"hashPath": "system.reflection.emit.lightweight.4.3.0.nupkg.sha512"
},
"System.Reflection.Extensions/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-rJkrJD3kBI5B712aRu4DpSIiHRtr6QlfZSQsb0hYHrDCZORXCFjQfoipo2LaMUHoT9i1B7j7MnfaEKWDFmFQNQ==",
"path": "system.reflection.extensions/4.3.0",
"hashPath": "system.reflection.extensions.4.3.0.nupkg.sha512"
},
"System.Reflection.Metadata/1.6.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-I4aWCii7N1bmn43vviRfJQYW6UAco1G/CcjJouvgGdb/sr2BRTSnddhaPMg2oxu9VHFn8T1z3dTLq0pna8zmtA==",
"path": "system.reflection.metadata/1.6.0",
"hashPath": "system.reflection.metadata.1.6.0.nupkg.sha512"
},
"System.Reflection.Primitives/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-5RXItQz5As4xN2/YUDxdpsEkMhvw3e6aNveFXUn4Hl/udNTCNhnKp8lT9fnc3MhvGKh1baak5CovpuQUXHAlIA==",
"path": "system.reflection.primitives/4.3.0",
"hashPath": "system.reflection.primitives.4.3.0.nupkg.sha512"
},
"System.Reflection.TypeExtensions/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-7u6ulLcZbyxB5Gq0nMkQttcdBTx57ibzw+4IOXEfR+sXYQoHvjW5LTLyNr8O22UIMrqYbchJQJnos4eooYzYJA==",
"path": "system.reflection.typeextensions/4.3.0",
"hashPath": "system.reflection.typeextensions.4.3.0.nupkg.sha512"
},
"System.Resources.ResourceManager/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-/zrcPkkWdZmI4F92gL/TPumP98AVDu/Wxr3CSJGQQ+XN6wbRZcyfSKVoPo17ilb3iOr0cCRqJInGwNMolqhS8A==",
"path": "system.resources.resourcemanager/4.3.0",
"hashPath": "system.resources.resourcemanager.4.3.0.nupkg.sha512"
},
"System.Runtime/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-JufQi0vPQ0xGnAczR13AUFglDyVYt4Kqnz1AZaiKZ5+GICq0/1MH/mO/eAJHt/mHW1zjKBJd7kV26SrxddAhiw==",
"path": "system.runtime/4.3.0",
"hashPath": "system.runtime.4.3.0.nupkg.sha512"
},
"System.Runtime.CompilerServices.Unsafe/4.5.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-qUJMNWhbm9oZ3XaMFiEMiYmRPszbnXIkRIi7+4b2Md2xZ6JUOepf0/kY3S85qistRohl9OdMe4PsO+RdG2kTIQ==",
"path": "system.runtime.compilerservices.unsafe/4.5.1",
"hashPath": "system.runtime.compilerservices.unsafe.4.5.1.nupkg.sha512"
},
"System.Runtime.Extensions/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-guW0uK0fn5fcJJ1tJVXYd7/1h5F+pea1r7FLSOz/f8vPEqbR2ZAknuRDvTQ8PzAilDveOxNjSfr0CHfIQfFk8g==",
"path": "system.runtime.extensions/4.3.0",
"hashPath": "system.runtime.extensions.4.3.0.nupkg.sha512"
},
"System.Runtime.Handles/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-OKiSUN7DmTWeYb3l51A7EYaeNMnvxwE249YtZz7yooT4gOZhmTjIn48KgSsw2k2lYdLgTKNJw/ZIfSElwDRVgg==",
"path": "system.runtime.handles/4.3.0",
"hashPath": "system.runtime.handles.4.3.0.nupkg.sha512"
},
"System.Runtime.InteropServices/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-uv1ynXqiMK8mp1GM3jDqPCFN66eJ5w5XNomaK2XD+TuCroNTLFGeZ+WCmBMcBDyTFKou3P6cR6J/QsaqDp7fGQ==",
"path": "system.runtime.interopservices/4.3.0",
"hashPath": "system.runtime.interopservices.4.3.0.nupkg.sha512"
},
"System.Runtime.InteropServices.RuntimeInformation/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-cbz4YJMqRDR7oLeMRbdYv7mYzc++17lNhScCX0goO2XpGWdvAt60CGN+FHdePUEHCe/Jy9jUlvNAiNdM+7jsOw==",
"path": "system.runtime.interopservices.runtimeinformation/4.3.0",
"hashPath": "system.runtime.interopservices.runtimeinformation.4.3.0.nupkg.sha512"
},
"System.Runtime.Numerics/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-yMH+MfdzHjy17l2KESnPiF2dwq7T+xLnSJar7slyimAkUh/gTrS9/UQOtv7xarskJ2/XDSNvfLGOBQPjL7PaHQ==",
"path": "system.runtime.numerics/4.3.0",
"hashPath": "system.runtime.numerics.4.3.0.nupkg.sha512"
},
"System.Security.AccessControl/4.5.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-aVjTe36YkO8FzfNhMLoPEzv3gF9rphoW9ngFhG/MH4zzEPLx07sNrgCLwMP4Wx2leI6qarMrGv21OwQXYUKLmw==",
"path": "system.security.accesscontrol/4.5.0",
"hashPath": "system.security.accesscontrol.4.5.0.nupkg.sha512"
},
"System.Security.Cryptography.Algorithms/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-W1kd2Y8mYSCgc3ULTAZ0hOP2dSdG5YauTb1089T0/kRcN2MpSAW1izOFROrJgxSlMn3ArsgHXagigyi+ibhevg==",
"path": "system.security.cryptography.algorithms/4.3.0",
"hashPath": "system.security.cryptography.algorithms.4.3.0.nupkg.sha512"
},
"System.Security.Cryptography.Cng/4.5.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-O4tqXxWCD8y1IU1VTgzbuBFwoRahrADhDUxHjwezhHCsqyFNyQ5EytjWBxu0EsZuH14b4UO2pFkG063K2h/9Ug==",
"path": "system.security.cryptography.cng/4.5.0",
"hashPath": "system.security.cryptography.cng.4.5.0.nupkg.sha512"
},
"System.Security.Cryptography.Csp/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-X4s/FCkEUnRGnwR3aSfVIkldBmtURMhmexALNTwpjklzxWU7yjMk7GHLKOZTNkgnWnE0q7+BCf9N2LVRWxewaA==",
"path": "system.security.cryptography.csp/4.3.0",
"hashPath": "system.security.cryptography.csp.4.3.0.nupkg.sha512"
},
"System.Security.Cryptography.Encoding/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-1DEWjZZly9ae9C79vFwqaO5kaOlI5q+3/55ohmq/7dpDyDfc8lYe7YVxJUZ5MF/NtbkRjwFRo14yM4OEo9EmDw==",
"path": "system.security.cryptography.encoding/4.3.0",
"hashPath": "system.security.cryptography.encoding.4.3.0.nupkg.sha512"
},
"System.Security.Cryptography.OpenSsl/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-h4CEgOgv5PKVF/HwaHzJRiVboL2THYCou97zpmhjghx5frc7fIvlkY1jL+lnIQyChrJDMNEXS6r7byGif8Cy4w==",
"path": "system.security.cryptography.openssl/4.3.0",
"hashPath": "system.security.cryptography.openssl.4.3.0.nupkg.sha512"
},
"System.Security.Cryptography.Pkcs/4.5.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-1vv2x8cok3NAolee/nb6X/6PnTx+OBKUM3kt1Rlgg04uQ+IMwjc88xFIfJdwbYcvjlOtzT7CHba1pqVAu9tj/w==",
"path": "system.security.cryptography.pkcs/4.5.0",
"hashPath": "system.security.cryptography.pkcs.4.5.0.nupkg.sha512"
},
"System.Security.Cryptography.Primitives/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-7bDIyVFNL/xKeFHjhobUAQqSpJq9YTOpbEs6mR233Et01STBMXNAc/V+BM6dwYGc95gVh/Zf+iVXWzj3mE8DWg==",
"path": "system.security.cryptography.primitives/4.3.0",
"hashPath": "system.security.cryptography.primitives.4.3.0.nupkg.sha512"
},
"System.Security.Cryptography.X509Certificates/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-t2Tmu6Y2NtJ2um0RtcuhP7ZdNNxXEgUm2JeoA/0NvlMjAhKCnM1NX07TDl3244mVp3QU6LPEhT3HTtH1uF7IYw==",
"path": "system.security.cryptography.x509certificates/4.3.0",
"hashPath": "system.security.cryptography.x509certificates.4.3.0.nupkg.sha512"
},
"System.Security.Cryptography.Xml/4.5.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-UvxfrEg7YG7U6BQO8WdQ4Nu1LFt2lqYQnoZefaK/2RDvjYdJ+norsVe4dwOqo14XiipgYY5xNUo6VhQXNbl2vg==",
"path": "system.security.cryptography.xml/4.5.0",
"hashPath": "system.security.cryptography.xml.4.5.0.nupkg.sha512"
},
"System.Security.Permissions/4.5.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-vDQ7q30Soe0a1cPhvxn+7IFmMeTG5IP+hTQrnKQDjTNpD2epqwbZSzMM2Git5TXBr4Kwwhc/0SEtJY0qPoiegA==",
"path": "system.security.permissions/4.5.0",
"hashPath": "system.security.permissions.4.5.0.nupkg.sha512"
},
"System.Security.Principal.Windows/4.5.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-WA9ETb/pY3BjnxKjBUHEgO59B7d/nnmjHFsqjJ2eDT780nD769CT1/bw2ia0Z6W7NqlcqokE6sKGKa6uw88XGA==",
"path": "system.security.principal.windows/4.5.0",
"hashPath": "system.security.principal.windows.4.5.0.nupkg.sha512"
},
"System.Text.Encoding/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-BiIg+KWaSDOITze6jGQynxg64naAPtqGHBwDrLaCtixsa5bKiR8dpPOHA7ge3C0JJQizJE+sfkz1wV+BAKAYZw==",
"path": "system.text.encoding/4.3.0",
"hashPath": "system.text.encoding.4.3.0.nupkg.sha512"
},
"System.Text.Encoding.CodePages/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-IRiEFUa5b/Gs5Egg8oqBVoywhtOeaO2KOx3j0RfcYY/raxqBuEK7NXRDgOwtYM8qbi+7S4RPXUbNt+ZxyY0/NQ==",
"path": "system.text.encoding.codepages/4.3.0",
"hashPath": "system.text.encoding.codepages.4.3.0.nupkg.sha512"
},
"System.Text.Encoding.Extensions/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-YVMK0Bt/A43RmwizJoZ22ei2nmrhobgeiYwFzC4YAN+nue8RF6djXDMog0UCn+brerQoYVyaS+ghy9P/MUVcmw==",
"path": "system.text.encoding.extensions/4.3.0",
"hashPath": "system.text.encoding.extensions.4.3.0.nupkg.sha512"
},
"System.Text.Encodings.Web/4.5.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-JF+wDdfFiRl3rz3dPMfR6aR568AW2J5CUMmhSflgHDz4zbVK4/00ax8UHnHyEMvblPewgNugjuA4oyoL8Pex2g==",
"path": "system.text.encodings.web/4.5.0",
"hashPath": "system.text.encodings.web.4.5.0.nupkg.sha512"
},
"System.Text.RegularExpressions/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-RpT2DA+L660cBt1FssIE9CAGpLFdFPuheB7pLpKpn6ZXNby7jDERe8Ua/Ne2xGiwLVG2JOqziiaVCGDon5sKFA==",
"path": "system.text.regularexpressions/4.3.0",
"hashPath": "system.text.regularexpressions.4.3.0.nupkg.sha512"
},
"System.Threading/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-VkUS0kOBcUf3Wwm0TSbrevDDZ6BlM+b/HRiapRFWjM5O0NS0LviG0glKmFK+hhPDd1XFeSdU1GmlLhb2CoVpIw==",
"path": "system.threading/4.3.0",
"hashPath": "system.threading.4.3.0.nupkg.sha512"
},
"System.Threading.Tasks/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-LbSxKEdOUhVe8BezB/9uOGGppt+nZf6e1VFyw6v3DN6lqitm0OSn2uXMOdtP0M3W4iMcqcivm2J6UgqiwwnXiA==",
"path": "system.threading.tasks/4.3.0",
"hashPath": "system.threading.tasks.4.3.0.nupkg.sha512"
},
"System.Threading.Tasks.Extensions/4.5.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-rckdhLJtzQ3EI+0BGuq7dUVtCSnerqAoAmL3S6oMRZ4VMZTL3Rq9DS8IDW57c6PYVebA4O0NbSA1BDvyE18UMA==",
"path": "system.threading.tasks.extensions/4.5.1",
"hashPath": "system.threading.tasks.extensions.4.5.1.nupkg.sha512"
},
"System.Threading.Tasks.Parallel/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-cbjBNZHf/vQCfcdhzx7knsiygoCKgxL8mZOeocXZn5gWhCdzHIq6bYNKWX0LAJCWYP7bds4yBK8p06YkP0oa0g==",
"path": "system.threading.tasks.parallel/4.3.0",
"hashPath": "system.threading.tasks.parallel.4.3.0.nupkg.sha512"
},
"System.Threading.Thread/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-OHmbT+Zz065NKII/ZHcH9XO1dEuLGI1L2k7uYss+9C1jLxTC9kTZZuzUOyXHayRk+dft9CiDf3I/QZ0t8JKyBQ==",
"path": "system.threading.thread/4.3.0",
"hashPath": "system.threading.thread.4.3.0.nupkg.sha512"
},
"System.Threading.Timer/4.0.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-saGfUV8uqVW6LeURiqxcGhZ24PzuRNaUBtbhVeuUAvky1naH395A/1nY0P2bWvrw/BreRtIB/EzTDkGBpqCwEw==",
"path": "system.threading.timer/4.0.1",
"hashPath": "system.threading.timer.4.0.1.nupkg.sha512"
},
"System.ValueTuple/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-cNLEvBX3d6MMQRZe3SMFNukVbitDAEpVZO17qa0/2FHxZ7Y7PpFRpr6m2615XYM/tYYYf0B+WyHNujqIw8Luwg==",
"path": "system.valuetuple/4.3.0",
"hashPath": "system.valuetuple.4.3.0.nupkg.sha512"
},
"System.Xml.ReaderWriter/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-GrprA+Z0RUXaR4N7/eW71j1rgMnEnEVlgii49GZyAjTH7uliMnrOU3HNFBr6fEDBCJCIdlVNq9hHbaDR621XBA==",
"path": "system.xml.readerwriter/4.3.0",
"hashPath": "system.xml.readerwriter.4.3.0.nupkg.sha512"
},
"System.Xml.XDocument/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-5zJ0XDxAIg8iy+t4aMnQAu0MqVbqyvfoUVl1yDV61xdo3Vth45oA2FoY4pPkxYAH5f8ixpmTqXeEIya95x0aCQ==",
"path": "system.xml.xdocument/4.3.0",
"hashPath": "system.xml.xdocument.4.3.0.nupkg.sha512"
},
"System.Xml.XmlDocument/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-lJ8AxvkX7GQxpC6GFCeBj8ThYVyQczx2+f/cWHJU8tjS7YfI6Cv6bon70jVEgs2CiFbmmM8b9j1oZVx0dSI2Ww==",
"path": "system.xml.xmldocument/4.3.0",
"hashPath": "system.xml.xmldocument.4.3.0.nupkg.sha512"
},
"System.Xml.XPath/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-v1JQ5SETnQusqmS3RwStF7vwQ3L02imIzl++sewmt23VGygix04pEH+FCj1yWb+z4GDzKiljr1W7Wfvrx0YwgA==",
"path": "system.xml.xpath/4.3.0",
"hashPath": "system.xml.xpath.4.3.0.nupkg.sha512"
},
"System.Xml.XPath.XDocument/4.3.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-jw9oHHEIVW53mHY9PgrQa98Xo2IZ0ZjrpdOTmtvk+Rvg4tq7dydmxdNqUvJ5YwjDqhn75mBXWttWjiKhWP53LQ==",
"path": "system.xml.xpath.xdocument/4.3.0",
"hashPath": "system.xml.xpath.xdocument.4.3.0.nupkg.sha512"
},
"Telegram.Bot/14.6.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-ZEHe1AgqMGLv8WkxeKpnBe5wgkr4AscH7Jrix2hUFRfltCo3TkSh6g6P7/m2MacMsQ/kVd2Ah8/oOe+QrVBJhA==",
"path": "telegram.bot/14.6.0",
"hashPath": "telegram.bot.14.6.0.nupkg.sha512"
},
"IntelliTrader.Core/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Microsoft.NETCore.App/2.1.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-AvT774nTFgU8cYcGO9j1EMwuayKslxqYTurg32HGpWa2hEYNuW2+XgYVVNcZe6Ndbr84QX6fwaOZfd5n+1m2OA==",
"path": "microsoft.netcore.app/2.1.0",
"hashPath": "microsoft.netcore.app.2.1.0.nupkg.sha512"
},
"Microsoft.NETCore.DotNetAppHost/2.1.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-f/47I60Wg3SrveTvnecCQhCZCAMYlUujWF15EQ/AZTqF/54qeEJjbCIAxKcZI8ToUYzSg6JdfrHggsgjCyCE9Q==",
"path": "microsoft.netcore.dotnetapphost/2.1.0",
"hashPath": "microsoft.netcore.dotnetapphost.2.1.0.nupkg.sha512"
},
"Microsoft.NETCore.DotNetHostPolicy/2.1.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-p50yZYKzhH64lmArJgoKjtvsNehECa+/sAuOQzZh5uDNBTbRKxjN8IXP1e517xdVsgrFcSNxSEVDKZIOWVjGcQ==",
"path": "microsoft.netcore.dotnethostpolicy/2.1.0",
"hashPath": "microsoft.netcore.dotnethostpolicy.2.1.0.nupkg.sha512"
},
"Microsoft.NETCore.DotNetHostResolver/2.1.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-fS9D8a+y55n6mHMbNqgHXaPGkjmpVH9h97OyrBxsCuo3Z8aQaFMJ5xIfmzji2ntUd/3truhMbSgSfIelHOkQpg==",
"path": "microsoft.netcore.dotnethostresolver/2.1.0",
"hashPath": "microsoft.netcore.dotnethostresolver.2.1.0.nupkg.sha512"
},
"Microsoft.NETCore.Platforms/2.1.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-TT+QCi9LcxGTjBssH7S7n5+8DVcwfG4DYgXX7Dk7+BfZ4oVHj8Q0CbYk9glzAlHLsSt3bYzol+fOdra2iu6GOw==",
"path": "microsoft.netcore.platforms/2.1.0",
"hashPath": "microsoft.netcore.platforms.2.1.0.nupkg.sha512"
},
"Microsoft.NETCore.Targets/2.1.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-etaYwrLZQUS+b3UWTpCnUggd6SQ/ZIkZ5pHnoR7+dIWt/wp2Rv3CvMKOZISsrt7FYCHKwCxfcepuuyEWkQxADg==",
"path": "microsoft.netcore.targets/2.1.0",
"hashPath": "microsoft.netcore.targets.2.1.0.nupkg.sha512"
},
"NETStandard.Library/2.0.3": {
"type": "package",
"serviceable": true,
"sha512": "sha512-st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==",
"path": "netstandard.library/2.0.3",
"hashPath": "netstandard.library.2.0.3.nupkg.sha512"
}
}
}
================================================
FILE: IntelliTrader/IntelliTrader.csproj
================================================
Exe
netcoreapp2.1
Never
Never
Never
Never
Never
Never
PreserveNewest
Never
================================================
FILE: IntelliTrader/IntelliTrader.sh
================================================
#!/bin/bash
dotnet bin/IntelliTrader.dll
================================================
FILE: IntelliTrader/Program.cs
================================================
using Autofac;
using ExchangeSharp;
using IntelliTrader.Core;
using System;
using System.Collections.Generic;
namespace IntelliTrader
{
class Program
{
static void Main(string[] args)
{
var parsedArgs = ParseCommandLineArgs(args);
if (parsedArgs.Count == 0)
{
PringWelcome();
StartCoreService();
}
else
{
if (parsedArgs.ContainsKey("encrypt") && parsedArgs.ContainsKey("path") &&
parsedArgs.ContainsKey("publickey") && parsedArgs.ContainsKey("privatekey"))
{
EncryptKeys(parsedArgs);
}
else
{
PrintUsage();
}
}
}
private static void StartCoreService()
{
var coreService = Application.Resolve();
coreService.Start();
Console.ReadLine();
coreService.Stop();
}
private static void PringWelcome()
{
var foregroundColorBackup = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine();
Console.WriteLine(@" _____ _ _ _ _ _____ _ ");
Console.WriteLine(@" \_ \ _ __ | |_ ___ | || |(_)/__ \ _ __ __ _ __| | ___ _ __ ");
Console.WriteLine(@" / /\/| '_ \ | __| / _ \| || || | / /\/| '__| / _` | / _` | / _ \| '__|");
Console.WriteLine(@"/\/ /_ | | | || |_ | __/| || || | / / | | | (_| || (_| || __/| | ");
Console.WriteLine(@"\____/ |_| |_| \__| \___||_||_||_| \/ |_| \__,_| \__,_| \___||_| ");
Console.WriteLine();
Console.WriteLine("Welcome to IntelliTrader, The Intelligent Cryptocurrency Trading Bot.");
Console.WriteLine("Always use Enter/Return key to exit the program to avoid corrupting the data.");
Console.WriteLine();
Console.ForegroundColor = foregroundColorBackup;
}
private static void EncryptKeys(Dictionary args)
{
var path = args["path"];
var publicKey = args["publickey"];
var privateKey = args["privatekey"];
CryptoUtility.SaveUnprotectedStringsToFile(path, new string[] { publicKey, privateKey });
Console.WriteLine("All done! Press any key to exit...");
Console.ReadKey();
}
private static void PrintUsage()
{
Console.WriteLine();
Console.WriteLine("Usage: dotnet IntelliTrader.dll --encrypt --path= --publickey= --privatekey=");
Console.WriteLine("The encrypted file is only valid for the current user and only on the computer it is created on.");
Console.WriteLine();
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
private static Dictionary ParseCommandLineArgs(string[] args)
{
var dict = new Dictionary(StringComparer.OrdinalIgnoreCase);
foreach (string a in args)
{
int idx = a.IndexOf('=');
string key = (idx < 0 ? a.TrimStart('-') : a.Substring(0, idx)).ToLowerInvariant().TrimStart('-');
string value = (idx < 0 ? string.Empty : a.Substring(idx + 1));
dict[key] = value;
}
return dict;
}
}
}
================================================
FILE: IntelliTrader/Properties/PublishProfiles/FolderProfile.pubxml
================================================
FileSystem
Release
netcoreapp2.1
..\Publish\bin
================================================
FILE: IntelliTrader/config/backtesting.json
================================================
{
"Backtesting": {
"Enabled": false,
"Replay": false,
"ReplayOutput": true,
"ReplaySpeed": 50,
"ReplayStartIndex": null,
"ReplayEndIndex": null,
"DeleteLogs": true,
"DeleteAccountData": true,
"CopyAccountDataPath": null,
"TradingSpeedEasing": 0,
"TradingRulesSpeedEasing": 0,
"SignalRulesSpeedEasing": 0,
"SnapshotsInterval": 1,
"SnapshotsPath": "data/backtesting"
}
}
================================================
FILE: IntelliTrader/config/core.json
================================================
{
"Core": {
"DebugMode": false,
"PasswordProtected": true,
"Password": "b84967c4f073b71405404f3719c788cd",
"InstanceName": "Main",
"TimezoneOffset": 1,
"HealthCheckEnabled": true,
"HealthCheckInterval": 180,
"HealthCheckSuspendTradingTimeout": 900,
"HealthCheckFailuresToRestartServices": 5
}
}
================================================
FILE: IntelliTrader/config/exchange.json
================================================
{
"Exchange": {
"KeysPath": "data/keys.bin",
"RateLimitOccurences": 40,
"RateLimitTimeframe": 10
}
}
================================================
FILE: IntelliTrader/config/logging.json
================================================
{
"Logging": {
"Enabled": true,
"MinimumLevel": {
"Default": "Verbose",
"Override": {
"System": "Warning",
"Microsoft": "Warning"
}
},
"WriteTo": [
{
"Name": "Logger",
"Args": {
"configureLogger": {
"WriteTo": [
{
"Name": "Console",
"Args": {
"outputTemplate": "{Timestamp:HH:mm:ss} [{Level:u3}] {Message}{NewLine}{Exception}",
"theme": "Serilog.Sinks.SystemConsole.Themes.SystemConsoleTheme::Literate, Serilog.Sinks.Console",
"restrictedToMinimumLevel": "Information"
}
},
{
"Name": "RollingFile",
"Args": {
"outputTemplate": "[{Timestamp:HH:mm:ss.fff}] [{Level:u3}] {Message}{NewLine}{Exception}",
"pathFormat": "log/{Date}-general.txt",
"retainedFileCountLimit": 1000
}
}
],
"Filter": [
{
"Name": "ByIncludingOnly",
"Args": {
"expression": "Trade is null"
}
}
]
}
}
},
{
"Name": "Logger",
"Args": {
"configureLogger": {
"WriteTo": [
{
"Name": "RollingFile",
"Args": {
"outputTemplate": "[{Timestamp:HH:mm:ss.fff}] {Message}{NewLine}",
"pathFormat": "log/{Date}-trades.txt",
"retainedFileCountLimit": 1000
}
}
],
"Filter": [
{
"Name": "ByIncludingOnly",
"Args": {
"expression": "Trade is not null"
}
}
]
}
}
}
]
}
}
================================================
FILE: IntelliTrader/config/notification.json
================================================
{
"Notification": {
"Enabled": false,
"TelegramEnabled": true,
"TelegramBotToken": "",
"TelegramChatId": 0,
"TelegramAlertsEnabled": true
}
}
================================================
FILE: IntelliTrader/config/paths.json
================================================
{
"Paths": {
"Core": "core.json",
"Logging": "logging.json",
"Trading": "trading.json",
"Exchange": "exchange.json",
"Signals": "signals.json",
"Rules": "rules.json",
"Notification": "notification.json",
"Web": "web.json",
"Backtesting": "backtesting.json"
}
}
================================================
FILE: IntelliTrader/config/rules.json
================================================
{
"Rules": {
"Modules": [
{
"Module": "Signals",
"Configuration": {
"ProcessingMode": "AllMatches",
"CheckInterval": 0.1
},
"Entries": [
{
"Enabled": false,
"Name": "Buy-Arbitrage",
"Action": "Arbitrage",
"Modifiers": {
"CostMultiplier": 1
},
"Conditions": [
{
"MinArbitrage": 4
}
]
},
{
"Enabled": true,
"Name": "Buy-Safe",
"Modifiers": {
"CostMultiplier": 1
},
"Conditions": [
{
"Signal": "TV-1m",
"MinVolatility": 2.5,
"MaxVolatility": 10,
"MaxPriceChange": 5
},
{
"Signal": "TV-15m",
"MinRating": 0.30,
"MaxPriceChange": 5
},
{
"Signal": "TV-1h",
"MinRating": 0.25,
"MinVolume": 100000,
"MaxPriceChange": 6
},
{
"Signal": "TV-4h",
"MinRating": 0.1,
"MinPriceChange": 1.5,
"MaxPriceChange": 12
},
{
"Signal": "TV-1d",
"MinPriceChange": 5,
"MaxPriceChange": 20
},
{
"MinGlobalRating": -0.35,
"MaxGlobalRating": 1.0,
"MaxSpread": 0.25,
"NotPairs": [
"TUSDBTC"
]
}
]
},
{
"Enabled": true,
"Name": "Buy-Bull",
"Modifiers": {
"CostMultiplier": 1
},
"Conditions": [
{
"Signal": "TV-1m",
"MinVolatility": 3,
"MaxVolatility": 12,
"MaxPriceChange": 5
},
{
"Signal": "TV-15m",
"MinRating": 0.30,
"MaxPriceChange": 5
},
{
"Signal": "TV-1h",
"MinRating": 0.25,
"MinVolume": 100000,
"MaxPriceChange": 8
},
{
"Signal": "TV-4h",
"MinRating": 0.1,
"MinPriceChange": 2,
"MaxPriceChange": 12
},
{
"Signal": "TV-1d",
"MinPriceChange": 4,
"MaxPriceChange": 20
},
{
"MinGlobalRating": 0.25,
"MaxSpread": 0.35,
"NotPairs": [
"TUSDBTC"
]
}
]
},
{
"Enabled": false,
"Name": "Buy-TUSDT",
"Modifiers": {
"CostMultiplier": 1
},
"Conditions": [
{
"Signal": "TV-1m",
"MinRating": 0.30
},
{
"Signal": "TV-5m",
"MinRating": 0.30
},
{
"Signal": "TV-15m",
"MinRating": 0.30
},
{
"MinGlobalRating": -0.28,
"MaxGlobalRating": -0.15,
"MaxSpread": 0.35,
"Pairs": [
"TUSDBTC"
]
}
]
},
{
"Enabled": true,
"Name": "Buy-Volume-Spike",
"Modifiers": {
"CostMultiplier": 1
},
"Conditions": [
{
"Signal": "TV-5m",
"MinRating": 0.4,
"MinPriceChange": 1,
"MaxPriceChange": 8,
"MinVolumeChange": 500,
"MaxVolatility": 12
},
{
"Signal": "TV-15m",
"MinRating": 0.4,
"MinPriceChange": 1.5,
"MaxPriceChange": 9,
"MinVolumeChange": 200
},
{
"Signal": "TV-1h",
"MinRating": 0.25,
"MinVolume": 200000,
"MaxPriceChange": 8
},
{
"Signal": "TV-4h",
"MinPriceChange": 1,
"MaxPriceChange": 10
},
{
"Signal": "TV-1d",
"MinPriceChange": 2,
"MaxPriceChange": 20
},
{
"MinGlobalRating": -0.10,
"MaxGlobalRating": 1.0,
"MaxSpread": 1,
"NotPairs": [
"TUSDBTC"
]
}
]
},
{
"Enabled": true,
"Name": "Buy-Pump",
"Modifiers": {
"CostMultiplier": 1
},
"Conditions": [
{
"Signal": "TV-1m",
"MinVolumeChange": 20,
"MaxVolumeChange": 200,
"MinRating": 0.30
},
{
"Signal": "TV-5m",
"MinRating": 0.30,
"MinPriceChange": 3,
"MinVolumeChange": 0,
"MaxPriceChange": 10
},
{
"Signal": "TV-15m",
"MinRating": 0.30
},
{
"Signal": "TV-1h",
"MinRating": 0.0,
"MinVolume": 100000,
"MaxPriceChange": 8
},
{
"Signal": "TV-4h",
"MinPriceChange": 3,
"MaxPriceChange": 10
},
{
"Signal": "TV-1d",
"MinPriceChange": 4,
"MaxPriceChange": 20
},
{
"MinGlobalRating": -0.30,
"MaxGlobalRating": 1.0,
"MaxSpread": 0.6
}
],
"Trailing": {
"Enabled": true,
"MinDuration": 10,
"MaxDuration": 60,
"StartConditions": [
{
"Signal": "TV-5m",
"MinVolumeChange": 200
}
]
}
},
{
"Enabled": true,
"Name": "Swap-Safe",
"Action": "Swap",
"Modifiers": {
"CostMultiplier": 1
},
"Conditions": [
{
"Signal": "TV-15m",
"MinRating": 0.20,
"MaxRating": 0.35,
"MaxPriceChange": 5
},
{
"Signal": "TV-1h",
"MinRating": 0.10,
"MaxRating": 0.25,
"MinVolume": 400000,
"MinRatingChange": 0,
"MaxPriceChange": 6
},
{
"Signal": "TV-4h",
"MinRating": 0.10,
"MaxRating": 0.25,
"MinPriceChange": 1,
"MaxPriceChange": 8
},
{
"Signal": "TV-1d",
"MinRatingChange": 0,
"MinPriceChange": 2,
"MaxPriceChange": 12
},
{
"MinGlobalRating": -0.20,
"MaxGlobalRating": 1,
"MaxSpread": 0.35,
"NotPairs": [
"TUSDBTC"
]
}
]
}
]
},
{
"Module": "Trading",
"Configuration": {
"ProcessingMode": "AllMatches",
"CheckInterval": 0.1
},
"Entries": [
{
"Enabled": true,
"Name": "TUSD-DCA",
"Modifiers": {
"BuyEnabled": true,
"BuyDCAEnabled": true,
"SellMargin": 0.20,
"SellTrailing": 0.15,
"DCALevels": [
{
"Margin": -0.40,
"BuySamePairTimeout": 0,
"BuyTrailing": -0.20,
"BuyTrailingStopMargin": 1.00,
"BuyTrailingStopAction": "Cancel",
"SellMargin": 0.20,
"SellTrailing": 0.15
},
{
"Margin": -1.25,
"BuySamePairTimeout": 180,
"BuyTrailing": -0.20,
"BuyTrailingStopMargin": 1.50,
"BuyTrailingStopAction": "Cancel",
"SellMargin": 0.15,
"SellTrailing": 0.15
},
{
"Margin": -2.50,
"BuySamePairTimeout": 300,
"BuyTrailing": -0.25,
"BuyTrailingStopMargin": 2.00,
"BuyTrailingStopAction": "Cancel",
"SellMargin": 0.10,
"SellTrailing": 0.10
},
{
"Margin": -5.50,
"BuySamePairTimeout": 1800,
"BuyTrailing": -0.25,
"BuyTrailingStopMargin": 2.00,
"BuyTrailingStopAction": "Cancel",
"SellMargin": 0.05,
"SellTrailing": 0.10
}
]
},
"Conditions": [
{
"MinGlobalRating": -1.00,
"MaxGlobalRating": -0.10,
"Pairs": [
"TUSDBTC"
]
}
]
},
{
"Enabled": true,
"Name": "Apocalypse",
"Modifiers": {
"BuyEnabled": false,
"BuyDCAEnabled": false,
"SellMargin": -0.50,
"SellTrailing": 0,
"SellDCAMargin": -0.50,
"SellDCATrailing": 0
},
"Conditions": [
{
"MinGlobalRating": -1,
"MaxGlobalRating": -0.40
}
]
},
{
"Enabled": true,
"Name": "Bear",
"Modifiers": {
"BuyDCAEnabled": false,
"BuyTrailing": -0.45,
"SellMargin": 0.40,
"SellTrailing": 0.25,
"SellTrailingStopMargin": 0.30,
"MaxPairs": 4,
"DCALevels": [
{
"Margin": -4,
"SellMargin": 0.20,
"SellTrailing": 0.25,
"SellTrailingStopMargin": 0.20,
"BuyTrailing": -0.35,
"BuySamePairTimeout": 0
},
{
"Margin": -8,
"SellMargin": 0.15,
"SellTrailing": 0.20,
"SellTrailingStopMargin": 0.10,
"BuyTrailing": -0.55,
"BuySamePairTimeout": 600
},
{
"Margin": -15,
"SellMargin": 0.10,
"SellTrailing": 0.25,
"SellTrailingStopMargin": 0.10,
"BuyTrailing": -1,
"BuySamePairTimeout": 1200
},
{
"Margin": -20,
"SellMargin": 0.10,
"SellTrailing": 0.05,
"SellTrailingStopMargin": 0.05,
"BuyTrailing": -1.5,
"BuySamePairTimeout": 2880
}
]
},
"Conditions": [
{
"MinGlobalRating": -0.40,
"MaxGlobalRating": -0.15,
"NotPairs": [
"TUSDBTC"
]
}
]
},
{
"Enabled": true,
"BuyDCAEnabled": false,
"Name": "Boring",
"Modifiers": {
"BuyTrailing": -0.35,
"SellMargin": 0.50,
"SellTrailing": 0.35,
"SellTrailingStopMargin": 0.40,
"MaxPairs": 5,
"DCALevels": [
{
"Margin": -2.5,
"SellMargin": 0.30,
"SellTrailing": 0.25,
"SellTrailingStopMargin": 0.30,
"BuyTrailing": -0.25,
"BuySamePairTimeout": 0
},
{
"Margin": -5,
"SellMargin": 0.20,
"SellTrailing": 0.20,
"SellTrailingStopMargin": 0.20,
"BuyTrailing": -0.45,
"BuySamePairTimeout": 300
},
{
"Margin": -8,
"SellMargin": 0.10,
"SellTrailing": 0.10,
"SellTrailingStopMargin": 0.10,
"BuyTrailing": -0.75,
"BuySamePairTimeout": 900
},
{
"Margin": -12,
"SellMargin": 0.10,
"SellTrailing": 0.05,
"SellTrailingStopMargin": 0.05,
"BuyTrailing": -1.5,
"BuySamePairTimeout": 1800
}
]
},
"Conditions": [
{
"MinGlobalRating": -0.15,
"MaxGlobalRating": 0.15,
"NotPairs": [
"TUSDBTC"
]
}
]
},
{
"Enabled": true,
"Name": "Bull",
"Modifiers": {
"BuyTrailing": -0.25,
"SellMargin": 0.60,
"SellTrailing": 0.45,
"SellTrailingStopMargin": 0.50,
"MaxPairs": 6,
"DCALevels": [
{
"Margin": -0.35,
"SellMargin": 0.40,
"SellTrailing": 0.35,
"SellTrailingStopMargin": 0.35,
"BuyTrailing": -0.25,
"BuySamePairTimeout": 0
},
{
"Margin": -2,
"SellMargin": 0.35,
"SellTrailing": 0.30,
"SellTrailingStopMargin": 0.30,
"BuyTrailing": -0.35,
"BuySamePairTimeout": 180
},
{
"Margin": -7,
"SellMargin": 0.15,
"SellTrailing": 0.15,
"SellTrailingStopMargin": 0.15,
"BuyTrailing": -0.55,
"BuySamePairTimeout": 600
},
{
"Margin": -12,
"SellMargin": 0.10,
"SellTrailing": 0.05,
"SellTrailingStopMargin": 0.05,
"BuyTrailing": -1.5,
"BuySamePairTimeout": 1400
}
]
},
"Conditions": [
{
"MinGlobalRating": 0.15,
"MaxGlobalRating": 1.00
}
]
},
{
"Enabled": true,
"Name": "DCA",
"Modifiers": {
"BuyDCAEnabled": false
},
"Conditions": [
{
"Signal": "TV-15m",
"MaxRating": 0.30
},
{
"NotPairs": [
"TUSDBTC"
]
}
]
},
{
"Enabled": true,
"Name": "SuperBull-HP-DCA",
"Modifiers": {
"DCALevels": [
{
"Margin": -0.25,
"SellMargin": 0.25,
"SellTrailing": 0.25,
"SellTrailingStopMargin": 0.25,
"BuyTrailing": -0.25,
"BuySamePairTimeout": 0
},
{
"Margin": -0.75,
"SellMargin": 0.20,
"SellTrailing": 0.20,
"SellTrailingStopMargin": 0.20,
"BuyTrailing": -0.45,
"BuySamePairTimeout": 300
},
{
"Margin": -1.50,
"SellMargin": 0.15,
"SellTrailing": 0.15,
"SellTrailingStopMargin": 0.15,
"BuyTrailing": -0.65,
"BuySamePairTimeout": 600
},
{
"Margin": -4.0,
"SellMargin": 0.10,
"SellTrailing": 0.05,
"SellTrailingStopMargin": 0.05,
"BuyTrailing": 2.0,
"BuySamePairTimeout": 1200
}
]
},
"Conditions": [
{
"Signal": "TV-5m",
"MaxRating": 0.40
},
{
"Signal": "TV-15m",
"MaxRating": 0.40
},
{
"Signal": "TV-1h",
"MaxRating": 0.40
},
{
"MinGlobalRating": 0.30
}
]
},
{
"Enabled": true,
"Name": "Bull-HP-DCA",
"Modifiers": {
"DCALevels": [
{
"Margin": -0.35,
"SellMargin": 0.25,
"SellTrailing": 0.25,
"SellTrailingStopMargin": 0.25,
"BuyTrailing": -0.25,
"BuySamePairTimeout": 0
},
{
"Margin": -1.5,
"SellMargin": 0.20,
"SellTrailing": 0.20,
"SellTrailingStopMargin": 0.20,
"BuyTrailing": -0.35,
"BuySamePairTimeout": 180
},
{
"Margin": -5.5,
"SellMargin": 0.15,
"SellTrailing": 0.15,
"SellTrailingStopMargin": 0.15,
"BuyTrailing": -0.55,
"BuySamePairTimeout": 300
},
{
"Margin": -10,
"SellMargin": 0.10,
"SellTrailing": 0.05,
"SellTrailingStopMargin": 0.05,
"BuyTrailing": 2.0,
"BuySamePairTimeout": 1200
}
]
},
"Conditions": [
{
"Signal": "TV-5m",
"MaxRating": 0.40
},
{
"Signal": "TV-15m",
"MaxRating": 0.40
},
{
"Signal": "TV-1h",
"MaxRating": 0.30
},
{
"MinGlobalRating": 0.20,
"MaxGlobalRating": 0.30
}
]
},
{
"Enabled": true,
"Name": "Swap-Only-Bull",
"Modifiers": {
"SwapEnabled": true,
"SwapSignalRules": [ "Buy-Safe" ],
"SwapTimeout": 1800
},
"Conditions": [
{
"Signal": "TV-5m",
"MaxRating": 0
},
{
"Signal": "TV-15m",
"MaxRating": 0
},
{
"MaxDCALevel": 2,
"MinGlobalRating": 0.30,
"MaxGlobalRating": 1.00
}
]
},
{
"Enabled": true,
"Name": "Swap-Money-Pump",
"Modifiers": {
"SwapEnabled": true,
"SwapSignalRules": [ "Buy-Pump" ],
"SwapTimeout": 300
},
"Conditions": [
{
"Signal": "TV-15m",
"MaxRating": 0
},
{
"MaxDCALevel": 0,
"MinGlobalRating": -0.20,
"MaxGlobalRating": 1.00,
"NotPairs": [
"TUSDBTC"
]
}
]
},
{
"Enabled": true,
"Name": "Swap-Small-Bag",
"Modifiers": {
"SwapEnabled": true,
"SwapSignalRules": [ "Buy-Volume-Spike", "Buy-Safe" ],
"SwapTimeout": 900
},
"Conditions": [
{
"Signal": "TV-5m",
"MaxRating": -0.30
},
{
"Signal": "TV-15m",
"MaxRating": -0.30
},
{
"Signal": "TV-1h",
"MaxRating": 0
},
{
"MaxDCALevel": 1,
"MinGlobalRating": -0.20,
"MaxGlobalRating": 1.00,
"NotPairs": [
"TUSDBTC"
]
}
]
},
{
"Enabled": true,
"Name": "Swap-Medium-Bag",
"Modifiers": {
"SwapEnabled": true,
"SwapSignalRules": [ "Buy-Safe" ],
"SwapTimeout": 3600
},
"Conditions": [
{
"Signal": "TV-5m",
"MaxRating": -0.2
},
{
"Signal": "TV-15m",
"MaxRating": -0.2
},
{
"Signal": "TV-1h",
"MaxRating": 0
},
{
"Signal": "TV-4h",
"MaxRating": 0
},
{
"MaxDCALevel": 2,
"MinGlobalRating": -0.20,
"MaxGlobalRating": 1.00,
"NotPairs": [
"TUSDBTC"
]
}
]
},
{
"Enabled": true,
"Name": "Swap-Big-Bag",
"Modifiers": {
"BuyDCAEnabled": false,
"SwapEnabled": true,
"SwapSignalRules": [ "Swap-Safe" ],
"SwapTimeout": 7200
},
"Conditions": [
{
"Signal": "TV-15m",
"MaxRating": -0.2
},
{
"Signal": "TV-1h",
"MaxRating": 0
},
{
"Signal": "TV-4h",
"MaxRating": 0
},
{
"Signal": "TV-1d",
"MaxRating": 0
},
{
"MinDCALevel": 3
},
{
"MinGlobalRating": -0.20,
"MaxGlobalRating": 1.00,
"NotPairs": [
"TUSDBTC"
]
}
]
},
{
"Enabled": true,
"Name": "Swap-Run-Forest-Run",
"Modifiers": {
"SwapEnabled": true,
"SwapSignalRules": [ "Buy-Safe", "Swap-Safe" ],
"SwapTimeout": 300
},
"Conditions": [
{
"Signal": "TV-5m",
"MaxRating": 0
},
{
"MinGlobalRating": -0.20,
"MaxGlobalRating": 1.00,
"MinMarginChange": 3,
"NotPairs": [
"TUSDBTC"
]
}
]
},
{
"Enabled": true,
"Name": "Swap-TUSDT",
"Modifiers": {
"SwapEnabled": true,
"SwapSignalRules": [ "Buy-Safe", "Buy-Volume-Spike" ],
"SwapTimeout": 300
},
"Conditions": [
{
"MinGlobalRating": -0.10,
"MaxGlobalRating": 1.00,
"Pairs": [
"TUSDBTC"
]
}
]
},
{
"Enabled": true,
"Name": "Exclude-BNB",
"Modifiers": {
"BuyEnabled": false,
"BuyDCAEnabled": false,
"SellEnabled": false
},
"Conditions": [
{
"Pairs": [
"BNBBTC"
]
}
]
},
{
"Enabled": true,
"Name": "BNB-Top-Up",
"Modifiers": {
"BuyEnabled": true,
"BuyDCAEnabled": true,
"BuyDCASamePairTimeout": 0,
"BuyMaxCost": 0.003,
"RepeatLastDCALevel": true,
"DCALevels": [
{
"Margin": 100
}
]
},
"Conditions": [
{
"Pairs": [ "BNBBTC" ],
"MaxAmount": 1
}
]
},
{
"Enabled": true,
"Name": "Exclude-Pairs",
"Modifiers": {
"BuyEnabled": false
},
"Conditions": [
{
"Pairs": [
"ADABTC",
"BCHBTC",
"ETHBTC",
"XRPBTC",
"LTCBTC",
"EOSBTC",
"XMRBTC",
"ZECBTC",
"ICXBTC",
"DASHBTC",
"XLMBTC",
"OAXBTC",
"RCNBTC",
"QSPBTC",
"SUBBTC",
"BNTBTC",
"AEBTC",
"TNBBTC",
"XEMBTC",
"TNTBTC",
"TRXBTC",
"IOTABTC",
"AMBBTC",
"DLTBTC",
"CDTBTC",
"CNDBTC",
"CHATBTC",
"REQBTC",
"CVCBTC",
"DNTBTC",
"IOTXBTC",
"RPXBTC",
"VIBBTC"
],
"MaxGlobalRating": 0.3
}
]
},
{
"Enabled": false,
"Name": "Arbitrage",
"Modifiers": {
"BuyEnabled": true,
"ArbitrageEnabled": true,
"ArbitrageMarkets": [ "ETH", "BNB" ],
"ArbitrageBuyMultiplier": 0.985,
"ArbitrageSellMultiplier": 0.985,
"ArbitrageSignalRules": [ "Buy-Arbitrage" ]
},
"Conditions": [
{
"MinArbitrage": 3
}
]
}
]
}
]
}
}
================================================
FILE: IntelliTrader/config/signals.json
================================================
{
"Signals": {
"Enabled": true,
"GlobalRatingSignals": [
"TV-5m",
"TV-15m",
"TV-1h"
],
"Definitions": [
{
"Name": "TV-1m",
"Receiver": "TradingViewCryptoSignalReceiver",
"Configuration": {
"PollingInterval": 1,
"SignalPeriod": 1,
"VolatilityPeriod": "Day",
"RequestUrl": "https://scanner.tradingview.com/crypto/scan",
"RequestData": "{\"filter\":[{\"left\":\"exchange\",\"operation\":\"equal\",\"right\":\"%EXCHANGE%\"},{\"left\":\"name\",\"operation\":\"match\",\"right\":\"%MARKET%\"}],\"columns\":[\"name\",\"close%PERIOD%\",\"change%PERIOD%\",\"volume%PERIOD%\",\"Recommend.All%PERIOD%\",\"Volatility%VOLATILITY%\"],\"options\":{\"lang\":\"en\"},\"range\":[0,500]}"
}
},
{
"Name": "TV-5m",
"Receiver": "TradingViewCryptoSignalReceiver",
"Configuration": {
"PollingInterval": 3,
"SignalPeriod": 5,
"VolatilityPeriod": "Day",
"RequestUrl": "https://scanner.tradingview.com/crypto/scan",
"RequestData": "{\"filter\":[{\"left\":\"exchange\",\"operation\":\"equal\",\"right\":\"%EXCHANGE%\"},{\"left\":\"name\",\"operation\":\"match\",\"right\":\"%MARKET%\"}],\"columns\":[\"name\",\"close%PERIOD%\",\"change%PERIOD%\",\"volume%PERIOD%\",\"Recommend.All%PERIOD%\",\"Volatility%VOLATILITY%\"],\"options\":{\"lang\":\"en\"},\"range\":[0,500]}"
}
},
{
"Name": "TV-15m",
"Receiver": "TradingViewCryptoSignalReceiver",
"Configuration": {
"PollingInterval": 5,
"SignalPeriod": 15,
"VolatilityPeriod": "Week",
"RequestUrl": "https://scanner.tradingview.com/crypto/scan",
"RequestData": "{\"filter\":[{\"left\":\"exchange\",\"operation\":\"equal\",\"right\":\"%EXCHANGE%\"},{\"left\":\"name\",\"operation\":\"match\",\"right\":\"%MARKET%\"}],\"columns\":[\"name\",\"close%PERIOD%\",\"change%PERIOD%\",\"volume%PERIOD%\",\"Recommend.All%PERIOD%\",\"Volatility%VOLATILITY%\"],\"options\":{\"lang\":\"en\"},\"range\":[0,500]}"
}
},
{
"Name": "TV-1h",
"Receiver": "TradingViewCryptoSignalReceiver",
"Configuration": {
"PollingInterval": 7,
"SignalPeriod": 60,
"VolatilityPeriod": "Month",
"RequestUrl": "https://scanner.tradingview.com/crypto/scan",
"RequestData": "{\"filter\":[{\"left\":\"exchange\",\"operation\":\"equal\",\"right\":\"%EXCHANGE%\"},{\"left\":\"name\",\"operation\":\"match\",\"right\":\"%MARKET%\"}],\"columns\":[\"name\",\"close%PERIOD%\",\"change%PERIOD%\",\"volume%PERIOD%\",\"Recommend.All%PERIOD%\",\"Volatility%VOLATILITY%\"],\"options\":{\"lang\":\"en\"},\"range\":[0,500]}"
}
},
{
"Name": "TV-4h",
"Receiver": "TradingViewCryptoSignalReceiver",
"Configuration": {
"PollingInterval": 15,
"SignalPeriod": 240,
"VolatilityPeriod": "Month",
"RequestUrl": "https://scanner.tradingview.com/crypto/scan",
"RequestData": "{\"filter\":[{\"left\":\"exchange\",\"operation\":\"equal\",\"right\":\"%EXCHANGE%\"},{\"left\":\"name\",\"operation\":\"match\",\"right\":\"%MARKET%\"}],\"columns\":[\"name\",\"close%PERIOD%\",\"change%PERIOD%\",\"volume%PERIOD%\",\"Recommend.All%PERIOD%\",\"Volatility%VOLATILITY%\"],\"options\":{\"lang\":\"en\"},\"range\":[0,500]}"
}
},
{
"Name": "TV-1d",
"Receiver": "TradingViewCryptoSignalReceiver",
"Configuration": {
"PollingInterval": 60,
"SignalPeriod": 1440,
"VolatilityPeriod": "Month",
"RequestUrl": "https://scanner.tradingview.com/crypto/scan",
"RequestData": "{\"filter\":[{\"left\":\"exchange\",\"operation\":\"equal\",\"right\":\"%EXCHANGE%\"},{\"left\":\"name\",\"operation\":\"match\",\"right\":\"%MARKET%\"}],\"columns\":[\"name\",\"close%PERIOD%\",\"change%PERIOD%\",\"volume%PERIOD%\",\"Recommend.All%PERIOD%\",\"Volatility%VOLATILITY%\"],\"options\":{\"lang\":\"en\"},\"range\":[0,500]}"
}
}
]
}
}
================================================
FILE: IntelliTrader/config/trading.json
================================================
{
"Trading": {
"Enabled": true,
"Market": "BTC",
"Exchange": "Binance",
"MaxPairs": 5,
"MinCost": 0.000999,
"TradePriceType": "Bid",
"ExcludedPairs": [],
"BuyEnabled": true,
"BuyType": "Market",
"BuyMaxCost": 0.03,
"BuyMultiplier": 1,
"BuyMinBalance": 0,
"BuySamePairTimeout": 15,
"BuyTrailing": -0.25,
"BuyTrailingStopMargin": 1.35,
"BuyTrailingStopAction": "Buy",
"BuyDCAEnabled": true,
"BuyDCAMultiplier": 1,
"BuyDCAMinBalance": 0,
"BuyDCASamePairTimeout": 180,
"BuyDCATrailing": -0.25,
"BuyDCATrailingStopMargin": 2,
"BuyDCATrailingStopAction": "Buy",
"SellEnabled": true,
"SellType": "Market",
"SellMargin": 1.0,
"SellTrailing": 0.65,
"SellTrailingStopMargin": 0.7,
"SellTrailingStopAction": "Sell",
"SellStopLossEnabled": false,
"SellStopLossAfterDCA": false,
"SellStopLossMinAge": 0,
"SellStopLossMargin": -3,
"SellDCAMargin": 0.5,
"SellDCATrailing": 0.35,
"SellDCATrailingStopMargin": 0.5,
"SellDCATrailingStopAction": "Sell",
"RepeatLastDCALevel": false,
"DCALevels": [],
"TradingCheckInterval": 0.1,
"AccountRefreshInterval": 360,
"AccountInitialBalance": 1,
"AccountInitialBalanceDate": "2018-04-08T00:00:00+00:00",
"AccountFilePath": "data/exchange-account.json",
"VirtualTrading": true,
"VirtualTradingFees": 0.0005,
"VirtualAccountInitialBalance": 1,
"VirtualAccountFilePath": "data/virtual-account.json"
}
}
================================================
FILE: IntelliTrader/config/web.json
================================================
{
"Web": {
"Enabled": true,
"DebugMode": false,
"ReadOnlyMode": false,
"Port": 7000,
"SSLEnabled": false,
"SSLCertPath": "data/cert.pfx",
"SSLCertPassword": "certpass"
}
}
================================================
FILE: IntelliTrader/data/encrypt-keys.bat
================================================
dotnet ..\bin\Debug\netcoreapp2.1\IntelliTrader.dll --encrypt --path=keys.bin --publickey=public_key --privatekey=private_key
pause
================================================
FILE: IntelliTrader/data/encrypt-keys.sh
================================================
#!/bin/bash
dotnet bin/IntelliTrader.dll --encrypt --path=keys.bin --publickey=public_key --privatekey=private_key
================================================
FILE: IntelliTrader.Backtesting/AppModule.cs
================================================
using Autofac;
using IntelliTrader.Core;
using System;
namespace IntelliTrader.Backtesting
{
public class AppModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType().As().As().Named(Constants.ServiceNames.BacktestingService).SingleInstance();
var backtestingConfig = Application.ConfigProvider.GetSection(Constants.ServiceNames.BacktestingService);
if (backtestingConfig.Enabled && backtestingConfig.Replay)
{
builder.RegisterType().Named(Constants.ServiceNames.BacktestingExchangeService).As().Named(Constants.ServiceNames.BacktestingExchangeService).SingleInstance();
builder.RegisterType().As().As().Named(Constants.ServiceNames.BacktestingSignalsService).SingleInstance();
}
}
}
}
================================================
FILE: IntelliTrader.Backtesting/Config/BacktestingConfig.cs
================================================
using IntelliTrader.Core;
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Backtesting
{
internal class BacktestingConfig : IBacktestingConfig
{
public bool Enabled { get; set; }
public bool Replay { get; set; }
public bool ReplayOutput { get; set; }
public double ReplaySpeed { get; set; }
public int? ReplayStartIndex { get; set; }
public int? ReplayEndIndex { get; set; }
public bool DeleteLogs { get; set; }
public bool DeleteAccountData { get; set; }
public string CopyAccountDataPath { get; set; }
public int TradingSpeedEasing { get; set; }
public int TradingRulesSpeedEasing { get; set; }
public int SignalRulesSpeedEasing { get; set; }
public int SnapshotsInterval { get; set; }
public string SnapshotsPath { get; set; }
}
}
================================================
FILE: IntelliTrader.Backtesting/IntelliTrader.Backtesting.csproj
================================================
netcoreapp2.1
================================================
FILE: IntelliTrader.Backtesting/Model/SignalData.cs
================================================
using IntelliTrader.Core;
using IntelliTrader.Signals.Base;
using ZeroFormatter;
namespace IntelliTrader.Backtesting
{
[ZeroFormattable]
public class SignalData : ISignal
{
[Index(0)]
public virtual string Name { get; set; }
[Index(1)]
public virtual string Pair { get; set; }
[Index(2)]
public virtual long? Volume { get; set; }
[Index(3)]
public virtual double? VolumeChange { get; set; }
[Index(4)]
public virtual decimal? Price { get; set; }
[Index(5)]
public virtual decimal? PriceChange { get; set; }
[Index(6)]
public virtual double? Rating { get; set; }
[Index(7)]
public virtual double? RatingChange { get; set; }
[Index(8)]
public virtual double? Volatility { get; set; }
public ISignal ToSignal()
{
return new Signal
{
Name = Name,
Pair = Pair,
Volume = Volume,
VolumeChange = VolumeChange,
Price = Price,
PriceChange = PriceChange,
Rating = Rating,
RatingChange = RatingChange,
Volatility = Volatility
};
}
public static SignalData FromSignal(ISignal signal)
{
return new SignalData
{
Name = signal.Name,
Pair = signal.Pair,
Volume = signal.Volume,
VolumeChange = signal.VolumeChange,
Price = signal.Price,
PriceChange = signal.PriceChange,
Rating = signal.Rating,
RatingChange = signal.RatingChange,
Volatility = signal.Volatility
};
}
}
}
================================================
FILE: IntelliTrader.Backtesting/Model/TickerData.cs
================================================
using IntelliTrader.Core;
using IntelliTrader.Exchange.Base;
using ZeroFormatter;
namespace IntelliTrader.Backtesting
{
[ZeroFormattable]
public class TickerData : ITicker
{
[Index(0)]
public virtual string Pair { get; set; }
[Index(1)]
public virtual decimal BidPrice { get; set; }
[Index(2)]
public virtual decimal AskPrice { get; set; }
[Index(3)]
public virtual decimal LastPrice { get; set; }
public ITicker ToTicker()
{
return new Ticker
{
Pair = Pair,
BidPrice = BidPrice,
AskPrice = AskPrice,
LastPrice = LastPrice
};
}
public static TickerData FromTicker(ITicker ticker)
{
return new TickerData
{
Pair = ticker.Pair,
BidPrice = ticker.BidPrice,
AskPrice = ticker.AskPrice,
LastPrice = ticker.LastPrice
};
}
}
}
================================================
FILE: IntelliTrader.Backtesting/Services/BacktestingExchangeService.cs
================================================
using ExchangeSharp;
using IntelliTrader.Core;
using IntelliTrader.Exchange.Base;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
namespace IntelliTrader.Backtesting
{
public class BacktestingExchangeService : ExchangeService
{
private readonly IBacktestingService backtestingService;
private ConcurrentBag markets;
public BacktestingExchangeService(ILoggingService loggingService, IHealthCheckService healthCheckService,
ITasksService tasksService, IBacktestingService backtestingService)
: base(loggingService, healthCheckService, tasksService)
{
this.backtestingService = backtestingService;
}
public override void Start(bool virtualTrading)
{
loggingService.Info("Start Backtesting Exchange service...");
Api = InitializeApi();
loggingService.Info("Backtesting Exchange service started");
}
public override void Stop()
{
loggingService.Info("Stop Backtesting Exchange service...");
loggingService.Info("Backtesting Exchange service stopped");
}
protected override ExchangeAPI InitializeApi()
{
return new ExchangeBinanceAPI();
}
public override IEnumerable GetMarkets()
{
if (markets == null && backtestingService.GetCurrentTickers() != null)
{
this.markets = new ConcurrentBag(backtestingService.GetCurrentTickers().Keys
.Select(pair => GetPairMarket(pair)).Distinct().ToList());
}
return markets.AsEnumerable() ?? new List();
}
public override IEnumerable GetMarketPairs(string market)
{
return backtestingService.GetCurrentTickers().Keys.Where(t => t.EndsWith(market));
}
public override decimal GetPrice(string pair, TradePriceType priceType)
{
if (backtestingService.GetCurrentTickers().TryGetValue(pair, out ITicker ticker))
{
if (priceType == TradePriceType.Ask)
{
return ticker.AskPrice;
}
else if (priceType == TradePriceType.Bid)
{
return ticker.BidPrice;
}
else
{
return ticker.LastPrice;
}
}
else
{
return 0;
}
}
public override decimal GetPriceSpread(string pair)
{
if (backtestingService.GetCurrentTickers().TryGetValue(pair, out ITicker ticker))
{
return Utils.CalculatePercentage(ticker.BidPrice, ticker.AskPrice);
}
else
{
return 0;
}
}
public override Arbitrage GetArbitrage(string pair, string tradingMarket, List arbitrageMarkets = null, ArbitrageType? arbitrageType = null)
{
if (arbitrageMarkets == null || !arbitrageMarkets.Any())
{
arbitrageMarkets = new List { ArbitrageMarket.ETH, ArbitrageMarket.BNB, ArbitrageMarket.USDT };
}
Arbitrage arbitrage = new Arbitrage
{
Market = arbitrageMarkets.First(),
Type = arbitrageType ?? ArbitrageType.Direct
};
try
{
if (tradingMarket == Constants.Markets.BTC)
{
foreach (var market in arbitrageMarkets)
{
string marketPair = ChangeMarket(pair, market.ToString());
string arbitragePair = GetArbitrageMarketPair(market);
if (marketPair != pair &&
backtestingService.GetCurrentTickers().TryGetValue(pair, out ITicker pairTicker) &&
backtestingService.GetCurrentTickers().TryGetValue(marketPair, out ITicker marketTicker) &&
backtestingService.GetCurrentTickers().TryGetValue(arbitragePair, out ITicker arbitrageTicker))
{
decimal directArbitragePercentage = 0;
decimal reverseArbitragePercentage = 0;
if (market == ArbitrageMarket.ETH)
{
directArbitragePercentage = (1 / pairTicker.AskPrice * marketTicker.BidPrice * arbitrageTicker.BidPrice - 1) * 100;
reverseArbitragePercentage = (1 / arbitrageTicker.AskPrice / marketTicker.AskPrice * pairTicker.BidPrice - 1) * 100;
}
else if (market == ArbitrageMarket.BNB)
{
directArbitragePercentage = (1 / pairTicker.AskPrice * marketTicker.BidPrice * arbitrageTicker.BidPrice - 1) * 100;
reverseArbitragePercentage = (1 / arbitrageTicker.AskPrice / marketTicker.AskPrice * pairTicker.BidPrice - 1) * 100;
}
else if (market == ArbitrageMarket.USDT)
{
directArbitragePercentage = (1 / pairTicker.AskPrice * marketTicker.BidPrice / arbitrageTicker.AskPrice - 1) * 100;
reverseArbitragePercentage = (arbitrageTicker.BidPrice / marketTicker.AskPrice * pairTicker.BidPrice - 1) * 100;
}
if ((directArbitragePercentage > arbitrage.Percentage || !arbitrage.IsAssigned) && (arbitrageType == null || arbitrageType == ArbitrageType.Direct))
{
arbitrage.IsAssigned = true;
arbitrage.Market = market;
arbitrage.Type = ArbitrageType.Direct;
arbitrage.Percentage = directArbitragePercentage;
}
if ((reverseArbitragePercentage > arbitrage.Percentage || !arbitrage.IsAssigned) && (arbitrageType == null || arbitrageType == ArbitrageType.Reverse))
{
arbitrage.IsAssigned = true;
arbitrage.Market = market;
arbitrage.Type = ArbitrageType.Reverse;
arbitrage.Percentage = reverseArbitragePercentage;
}
}
}
}
}
catch { }
return arbitrage;
}
public override string GetArbitrageMarketPair(ArbitrageMarket arbitrageMarket)
{
if (arbitrageMarket == ArbitrageMarket.ETH)
{
return Constants.Markets.ETH + Constants.Markets.BTC;
}
else if (arbitrageMarket == ArbitrageMarket.BNB)
{
return Constants.Markets.BNB + Constants.Markets.BTC;
}
else if (arbitrageMarket == ArbitrageMarket.USDT)
{
return Constants.Markets.BTC + Constants.Markets.USDT;
}
else
{
throw new NotSupportedException($"Unsupported arbitrage market: {arbitrageMarket}");
}
}
#region Not Needed For Backtesting
public override IOrderDetails PlaceOrder(IOrder order)
{
throw new NotImplementedException();
}
public override IEnumerable GetTickers()
{
throw new NotImplementedException();
}
public override Dictionary GetAvailableAmounts()
{
throw new NotImplementedException();
}
public override IEnumerable GetTrades(string pair)
{
throw new NotImplementedException();
}
#endregion Not Needed For Backtesting
}
}
================================================
FILE: IntelliTrader.Backtesting/Services/BacktestingService.cs
================================================
using IntelliTrader.Core;
using System;
using System.Linq;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using IntelliTrader.Signals.Base;
using IntelliTrader.Trading;
namespace IntelliTrader.Backtesting
{
internal class BacktestingService : ConfigrableServiceBase, IBacktestingService
{
public const string SNAPSHOT_FILE_EXTENSION = "bin";
public override string ServiceName => Constants.ServiceNames.BacktestingService;
IBacktestingConfig IBacktestingService.Config => Config;
public object SyncRoot { get; private set; } = new object();
private readonly ILoggingService loggingService;
private readonly IHealthCheckService healthCheckService;
private readonly ITasksService tasksService;
private ISignalsService signalsService;
private ITradingService tradingService;
private BacktestingLoadSnapshotsTimedTask backtestingLoadSnapshotsTimedTask;
private BacktestingSaveSnapshotsTimedTask backtestingSaveSnapshotsTimedTask;
public BacktestingService(ILoggingService loggingService, IHealthCheckService healthCheckService, ITasksService tasksService)
{
this.loggingService = loggingService;
this.healthCheckService = healthCheckService;
this.tasksService = tasksService;
}
public void Start()
{
loggingService.Info($"Start Backtesting service... (Replay: {Config.Replay})");
signalsService = Application.Resolve();
tradingService = Application.Resolve();
if (Config.Replay)
{
backtestingLoadSnapshotsTimedTask = tasksService.AddTask(
name: nameof(BacktestingLoadSnapshotsTimedTask),
task: new BacktestingLoadSnapshotsTimedTask(loggingService, healthCheckService, tradingService, this),
interval: Config.SnapshotsInterval / Config.ReplaySpeed * 1000,
startDelay: Constants.TaskDelays.HighDelay,
startTask: false,
runNow: false,
skipIteration: 0);
}
backtestingSaveSnapshotsTimedTask = tasksService.AddTask(
name: nameof(BacktestingSaveSnapshotsTimedTask),
task: new BacktestingSaveSnapshotsTimedTask(loggingService, healthCheckService, tradingService, signalsService, this),
interval: Config.SnapshotsInterval * 1000,
startDelay: Constants.TaskDelays.HighDelay,
startTask: false,
runNow: false,
skipIteration: 0);
if (Config.DeleteLogs)
{
loggingService.DeleteAllLogs();
}
string virtualAccountPath = Path.Combine(Directory.GetCurrentDirectory(), tradingService.Config.VirtualAccountFilePath);
if (File.Exists(virtualAccountPath) && (Config.DeleteAccountData || !String.IsNullOrWhiteSpace(Config.CopyAccountDataPath)))
{
File.Delete(virtualAccountPath);
}
if (!String.IsNullOrWhiteSpace(Config.CopyAccountDataPath))
{
File.Copy(Path.Combine(Directory.GetCurrentDirectory(), Config.CopyAccountDataPath), virtualAccountPath, true);
}
if (Config.Replay)
{
Application.Speed = Config.ReplaySpeed;
}
Application.Resolve().Started += OnCoreServiceStarted;
loggingService.Info("Backtesting service started");
}
public void Stop()
{
loggingService.Info("Stop Backtesting service...");
if (Config.Replay)
{
tasksService.RemoveTask(nameof(BacktestingLoadSnapshotsTimedTask), stopTask: true);
}
tasksService.RemoveTask(nameof(BacktestingSaveSnapshotsTimedTask), stopTask: true);
healthCheckService.RemoveHealthCheck(Constants.HealthChecks.BacktestingSignalsSnapshotTaken);
healthCheckService.RemoveHealthCheck(Constants.HealthChecks.BacktestingTickersSnapshotTaken);
healthCheckService.RemoveHealthCheck(Constants.HealthChecks.BacktestingSignalsSnapshotLoaded);
healthCheckService.RemoveHealthCheck(Constants.HealthChecks.BacktestingTickersSnapshotLoaded);
Application.Resolve().Started -= OnCoreServiceStarted;
loggingService.Info("Backtesting service stopped");
}
public void Complete(int skippedSignalSnapshots, int skippedTickerSnapshots)
{
loggingService.Info("Backtesting results:");
double lagAmount = 0;
foreach (var kvp in tasksService.GetAllTasks().OrderBy(t => t.Key))
{
string taskName = kvp.Key;
ITimedTask task = kvp.Value;
double averageWaitTime = Math.Round(task.TotalLagTime / task.RunCount, 3);
if (averageWaitTime > 0) lagAmount += averageWaitTime;
loggingService.Info($" [+] {taskName} Run times: {task.RunCount}, average wait time: " + averageWaitTime);
}
loggingService.Info($"Lag value: {lagAmount}. Lower the ReplaySpeed if lag value is positive.");
loggingService.Info($"Skipped signal snapshots: {skippedSignalSnapshots}");
loggingService.Info($"Skipped ticker snapshots: {skippedTickerSnapshots}");
tradingService.SuspendTrading(forced: true);
signalsService.StopTrailing();
signalsService.Stop();
}
public string GetSnapshotFilePath(string snapshotEntity)
{
var date = DateTimeOffset.UtcNow;
return Path.Combine(
Directory.GetCurrentDirectory(),
Config.SnapshotsPath,
snapshotEntity,
date.ToString("yyyy-MM-dd"),
date.ToString("HH"),
date.ToString("mm-ss-fff")
) + "." + SNAPSHOT_FILE_EXTENSION;
}
public Dictionary> GetCurrentSignals()
{
return backtestingLoadSnapshotsTimedTask.GetCurrentSignals() ?? new Dictionary>();
}
public Dictionary GetCurrentTickers()
{
return backtestingLoadSnapshotsTimedTask.GetCurrentTickers() ?? new Dictionary();
}
public int GetTotalSnapshots()
{
return backtestingLoadSnapshotsTimedTask.GetTotalSnapshots();
}
private void OnCoreServiceStarted()
{
tasksService.GetTask(nameof(TradingTimedTask)).SkipIteration = Config.TradingSpeedEasing;
tasksService.GetTask(nameof(TradingTimedTask)).LoggingEnabled = false;
tasksService.GetTask(nameof(TradingRulesTimedTask)).SkipIteration = Config.TradingRulesSpeedEasing;
tasksService.GetTask(nameof(SignalRulesTimedTask)).SkipIteration = Config.SignalRulesSpeedEasing;
tasksService.GetTask(nameof(SignalRulesTimedTask)).LoggingEnabled = false;
}
}
}
================================================
FILE: IntelliTrader.Backtesting/Services/BacktestingSignalsService.cs
================================================
using IntelliTrader.Core;
using IntelliTrader.Signals.Base;
using System;
using System.Collections.Generic;
using System.Linq;
namespace IntelliTrader.Backtesting
{
public class BacktestingSignalsService : ConfigrableServiceBase, ISignalsService
{
public override string ServiceName => Constants.ServiceNames.SignalsService;
ISignalsConfig ISignalsService.Config => Config;
public IModuleRules Rules { get; private set; }
public ISignalRulesConfig RulesConfig { get; private set; }
private readonly ILoggingService loggingService;
private readonly IHealthCheckService healthCheckService;
private readonly ITasksService tasksService;
private readonly ITradingService tradingService;
private readonly IRulesService rulesService;
private readonly IBacktestingService backtestingService;
private SignalRulesTimedTask signalRulesTimedTask;
private IEnumerable signalNames;
public BacktestingSignalsService(ILoggingService loggingService, IHealthCheckService healthCheckService, ITasksService tasksService, ITradingService tradingService, IRulesService rulesService, IBacktestingService backtestingService)
{
this.loggingService = loggingService;
this.healthCheckService = healthCheckService;
this.tasksService = tasksService;
this.tradingService = tradingService;
this.rulesService = rulesService;
this.backtestingService = backtestingService;
}
public void Start()
{
loggingService.Info("Start Backtesting Signals service...");
OnSignalRulesChanged();
rulesService.RegisterRulesChangeCallback(OnSignalRulesChanged);
signalRulesTimedTask = tasksService.AddTask(
name: nameof(SignalRulesTimedTask),
task: new SignalRulesTimedTask(loggingService, healthCheckService, tradingService, rulesService, this),
interval: RulesConfig.CheckInterval * 1000 / Application.Speed,
startDelay: Constants.TaskDelays.LowDelay,
startTask: false,
runNow: false,
skipIteration: 0);
loggingService.Info("Backtesting Signals service started");
}
public void Stop()
{
loggingService.Info("Stop Backtesting Signals service...");
tasksService.RemoveTask(nameof(SignalRulesTimedTask), stopTask: true);
rulesService.UnregisterRulesChangeCallback(OnSignalRulesChanged);
healthCheckService.RemoveHealthCheck(Constants.HealthChecks.SignalRulesProcessed);
loggingService.Info("Backtesting Signals service stopped");
}
public void ProcessPair(string pair, Dictionary signals)
{
IEnumerable enabledRules = Rules.Entries.Where(r => r.Enabled);
foreach (IRule rule in enabledRules)
{
signalRulesTimedTask.ProcessRule(rule, signals, pair, signalRulesTimedTask.GetExcludedPairs(), GetGlobalRating());
}
}
public void StopTrailing()
{
signalRulesTimedTask.StopTrailing();
}
public List GetTrailingSignals()
{
return signalRulesTimedTask.GetTrailingSignals();
}
public IEnumerable GetTrailingInfo(string pair)
{
return signalRulesTimedTask.GetTrailingInfo(pair);
}
public IEnumerable GetSignalNames()
{
if (signalNames == null)
{
signalNames = backtestingService.GetCurrentSignals().Values.SelectMany(val => val.Select(s => s.Name)).Distinct().ToList();
}
return signalNames;
}
public IEnumerable GetAllSignals()
{
return GetSignalsByName(null);
}
public IEnumerable GetSignalsByName(string signalName)
{
IEnumerable allSignals = backtestingService.GetCurrentSignals().SelectMany(s => s.Value);
if (signalName == null)
{
return allSignals;
}
else
{
return allSignals.Where(s => s.Name == signalName);
}
}
public IEnumerable GetSignalsByPair(string pair)
{
if (backtestingService.GetCurrentSignals().TryGetValue(pair, out IEnumerable signalsByPair))
{
return signalsByPair;
}
else
{
return null;
}
}
public ISignal GetSignal(string pair, string signalName)
{
return GetSignalsByName(signalName)?.FirstOrDefault(s => s.Pair == pair);
}
public double? GetRating(string pair, string signalName)
{
return GetSignalsByName(signalName)?.FirstOrDefault(s => s.Pair == pair)?.Rating;
}
public double? GetRating(string pair, IEnumerable signalNames)
{
if (signalNames != null && signalNames.Count() > 0)
{
double ratingSum = 0;
foreach (var signalName in signalNames)
{
var rating = GetSignalsByName(signalName)?.FirstOrDefault(s => s.Pair == pair)?.Rating;
if (rating != null)
{
ratingSum += rating.Value;
}
else
{
return null;
}
}
return Math.Round(ratingSum / signalNames.Count(), 8);
}
else
{
return null;
}
}
public double? GetGlobalRating()
{
try
{
double ratingSum = 0;
double ratingCount = 0;
var currentSignals = backtestingService.GetCurrentSignals();
if (currentSignals != null)
{
var signalGroups = currentSignals.Values.SelectMany(s => s).GroupBy(s => s.Name);
foreach (var signalGroup in signalGroups)
{
if (Config.GlobalRatingSignals.Contains(signalGroup.Key))
{
double? averageRating = signalGroup.Average(s => s.Rating);
if (averageRating != null)
{
ratingSum += averageRating.Value;
ratingCount++;
}
}
}
}
if (ratingCount > 0)
{
return Math.Round(ratingSum / ratingCount, 8);
}
else
{
return null;
}
}
catch (Exception ex)
{
loggingService.Error("Unable to get global rating", ex);
return null;
}
}
private void OnSignalRulesChanged()
{
Rules = rulesService.GetRules(ServiceName);
RulesConfig = Rules.GetConfiguration();
}
}
}
================================================
FILE: IntelliTrader.Backtesting/TimedTasks/BacktestingLoadSnapshotsTimedTask.cs
================================================
using IntelliTrader.Core;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using ZeroFormatter;
namespace IntelliTrader.Backtesting
{
internal class BacktestingLoadSnapshotsTimedTask : HighResolutionTimedTask
{
private readonly ILoggingService loggingService;
private readonly IHealthCheckService healthCheckService;
private readonly ITradingService tradingService;
private readonly IBacktestingService backtestingService;
private Queue allSignalSnapshotPaths;
private Queue allTickerSnapshotPaths;
private Dictionary> currentSignals;
private Dictionary currentTickers;
private Stopwatch backtestingTimer;
private int totalSignalSnapshots;
private int totalTickerSnapshots;
public int loadedSignalSnapshots;
public int loadedTickerSnapshots;
private bool isCompleted;
public object Config { get; }
public BacktestingLoadSnapshotsTimedTask(ILoggingService loggingService, IHealthCheckService healthCheckService, ITradingService tradingService, IBacktestingService backtestingService)
{
this.loggingService = loggingService;
this.healthCheckService = healthCheckService;
this.tradingService = tradingService;
this.backtestingService = backtestingService;
PopulateSnapshotPaths();
}
protected override void Run()
{
if (!isCompleted)
{
LoadNextSnapshots();
}
}
public Dictionary> GetCurrentSignals()
{
lock (backtestingService.SyncRoot)
{
return currentSignals;
}
}
public Dictionary GetCurrentTickers()
{
lock (backtestingService.SyncRoot)
{
return currentTickers;
}
}
public int GetTotalSnapshots()
{
return totalSignalSnapshots;
}
private void LoadNextSnapshots()
{
lock (backtestingService.SyncRoot)
{
if (loadedSignalSnapshots == 0 && loadedTickerSnapshots == 0)
{
loggingService.Info($"<<<--- Backtesting started. Total signals snapshots: {totalSignalSnapshots}, Total tickers snapshots: {totalTickerSnapshots} --->>>");
backtestingTimer = Stopwatch.StartNew();
}
if (allSignalSnapshotPaths.TryDequeue(out string currentSignalsSnapshotPath))
{
try
{
byte[] currentSignalsSnapshotBytes = File.ReadAllBytes(currentSignalsSnapshotPath);
IEnumerable data = ZeroFormatterSerializer.Deserialize>(currentSignalsSnapshotBytes).Select(s => s.ToSignal()).ToList();
currentSignals = data.GroupBy(s => s.Pair).ToDictionary(s => s.Key, s => s.AsEnumerable());
loadedSignalSnapshots++;
var currentSignalsSnapshotFile = currentSignalsSnapshotPath.Substring(currentSignalsSnapshotPath.Length - 27);
currentSignalsSnapshotFile = currentSignalsSnapshotFile.Replace('\\', '-').Replace('/', '-');
if (backtestingService.Config.ReplayOutput && loadedSignalSnapshots % 100 == 0)
{
loggingService.Info($"<<<--- ({loadedSignalSnapshots}/{totalSignalSnapshots}) Load signals snapshot file: {currentSignalsSnapshotFile} --->>>");
}
healthCheckService.UpdateHealthCheck(Constants.HealthChecks.BacktestingSignalsSnapshotLoaded, $"File: {currentSignalsSnapshotFile}");
}
catch (Exception ex)
{
loggingService.Error($"<<<--- Unable to load signals snapshot file: {currentSignalsSnapshotPath} --->>>", ex);
}
}
if (allTickerSnapshotPaths.TryDequeue(out string currentTickersSnapshotPath))
{
try
{
byte[] currentTickersSnapshotBytes = File.ReadAllBytes(currentTickersSnapshotPath);
IEnumerable data = ZeroFormatterSerializer.Deserialize>(currentTickersSnapshotBytes).Select(t => t.ToTicker()).ToList();
currentTickers = data.ToDictionary(t => t.Pair, t => t);
loadedTickerSnapshots++;
var currentTickersSnapshotFile = currentTickersSnapshotPath.Substring(currentTickersSnapshotPath.Length - 27);
currentTickersSnapshotFile = currentTickersSnapshotFile.Replace('\\', '-').Replace('/', '-');
if (backtestingService.Config.ReplayOutput && loadedTickerSnapshots % 100 == 0)
{
loggingService.Info($"<<<--- ({loadedTickerSnapshots}/{totalTickerSnapshots}) Load tickers snapshot file: {currentTickersSnapshotFile} --->>>");
}
healthCheckService.UpdateHealthCheck(Constants.HealthChecks.BacktestingTickersSnapshotLoaded, $"File: {currentTickersSnapshotFile}");
}
catch (Exception ex)
{
loggingService.Error($"<<<--- Unable to load tickers snapshot file: {currentTickersSnapshotPath} --->>>", ex);
}
}
if (currentSignalsSnapshotPath == null && currentTickersSnapshotPath == null)
{
isCompleted = true;
backtestingTimer.Stop();
loggingService.Info($"<<<--- Backtesting finished in {Math.Round(backtestingTimer.Elapsed.TotalSeconds)} seconds --->>>");
backtestingService.Complete(totalSignalSnapshots - loadedSignalSnapshots, totalTickerSnapshots - loadedTickerSnapshots);
}
}
}
private void PopulateSnapshotPaths()
{
var signalsSnapshotPath = Path.Combine(Directory.GetCurrentDirectory(), backtestingService.Config.SnapshotsPath, Constants.SnapshotEntities.Signals);
if (Directory.Exists(signalsSnapshotPath))
{
var files = Directory.EnumerateFiles(signalsSnapshotPath, "*." + BacktestingService.SNAPSHOT_FILE_EXTENSION, SearchOption.AllDirectories);
allSignalSnapshotPaths = new Queue(files.Take(backtestingService.Config.ReplayEndIndex ?? files.Count()).Skip(backtestingService.Config.ReplayStartIndex ?? 0));
}
else
{
allSignalSnapshotPaths = new Queue();
}
totalSignalSnapshots = allSignalSnapshotPaths.Count;
var tickersSnapshotPath = Path.Combine(Directory.GetCurrentDirectory(), backtestingService.Config.SnapshotsPath, Constants.SnapshotEntities.Tickers);
if (Directory.Exists(tickersSnapshotPath))
{
var files = Directory.EnumerateFiles(tickersSnapshotPath, "*." + BacktestingService.SNAPSHOT_FILE_EXTENSION, SearchOption.AllDirectories);
allTickerSnapshotPaths = new Queue(files.Take(backtestingService.Config.ReplayEndIndex ?? files.Count()).Skip(backtestingService.Config.ReplayStartIndex ?? 0));
}
else
{
allTickerSnapshotPaths = new Queue();
}
totalTickerSnapshots = allTickerSnapshotPaths.Count;
}
}
}
================================================
FILE: IntelliTrader.Backtesting/TimedTasks/BacktestingSaveSnapshotsTimedTask.cs
================================================
using IntelliTrader.Core;
using System.IO;
using System.Linq;
using ZeroFormatter;
namespace IntelliTrader.Backtesting
{
internal class BacktestingSaveSnapshotsTimedTask : HighResolutionTimedTask
{
private readonly ILoggingService loggingService;
private readonly IHealthCheckService healthCheckService;
private readonly ITradingService tradingService;
private readonly ISignalsService signalsService;
private readonly IBacktestingService backtestingService;
public BacktestingSaveSnapshotsTimedTask(ILoggingService loggingService, IHealthCheckService healthCheckService, ITradingService tradingService, ISignalsService signalsService, IBacktestingService backtestingService)
{
this.loggingService = loggingService;
this.healthCheckService = healthCheckService;
this.tradingService = tradingService;
this.signalsService = signalsService;
this.backtestingService = backtestingService;
}
protected override void Run()
{
if (backtestingService.Config.Enabled && !backtestingService.Config.Replay)
{
TakeSignalsSnapshot();
TakeTickersSnapshot();
}
}
private void TakeSignalsSnapshot()
{
var signals = signalsService.GetAllSignals().Select(s => SignalData.FromSignal(s));
byte[] signalBytes = ZeroFormatterSerializer.Serialize(signals);
string signalsSnapshotFilePath = backtestingService.GetSnapshotFilePath(Constants.SnapshotEntities.Signals);
var signalsSnapshotFile = new FileInfo(signalsSnapshotFilePath);
signalsSnapshotFile.Directory.Create();
File.WriteAllBytes(signalsSnapshotFilePath, signalBytes);
healthCheckService.UpdateHealthCheck(Constants.HealthChecks.BacktestingSignalsSnapshotTaken, $"Signals: {signals.Count()}");
}
private void TakeTickersSnapshot()
{
var tickers = tradingService.Exchange.GetTickers().Select(t => TickerData.FromTicker(t));
byte[] tickerBytes = ZeroFormatterSerializer.Serialize(tickers);
string tickersSnapshotFilePath = backtestingService.GetSnapshotFilePath(Constants.SnapshotEntities.Tickers);
var tickersSnapshotFile = new FileInfo(tickersSnapshotFilePath);
tickersSnapshotFile.Directory.Create();
File.WriteAllBytes(tickersSnapshotFilePath, tickerBytes);
healthCheckService.UpdateHealthCheck(Constants.HealthChecks.BacktestingTickersSnapshotTaken, $"Tickers: {tickers.Count()}");
}
}
}
================================================
FILE: IntelliTrader.Core/AppModule.cs
================================================
using Autofac;
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public class AppModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType().As().SingleInstance();
builder.RegisterType().As().SingleInstance();
builder.RegisterType().As().As().Named(Constants.ServiceNames.CoreService).SingleInstance();
builder.RegisterType().As().As().Named(Constants.ServiceNames.LoggingService).SingleInstance();
builder.RegisterType().As().As().Named(Constants.ServiceNames.NotificationService).SingleInstance();
}
}
}
================================================
FILE: IntelliTrader.Core/Application.cs
================================================
using Autofac;
using Autofac.Core;
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
namespace IntelliTrader.Core
{
public class Application
{
public readonly static IConfigProvider ConfigProvider = new ConfigProvider();
public static double Speed { get; set; } = 1;
public static ILifetimeScope Container
{
get
{
RegisterComponents();
return container;
}
}
private static IContainer container;
public static void RegisterComponents(bool repos = true, bool queries = true, bool mappers = true)
{
if (Application.container == null)
{
var builder = new ContainerBuilder();
var assemblyPattern = new Regex($"{nameof(IntelliTrader)}.*.dll");
var loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies().Where(a => assemblyPattern.IsMatch(Path.GetFileName(a.Location)));
var dynamicAssembliesPath = new Uri(Path.GetDirectoryName(Assembly.GetCallingAssembly().Location)).LocalPath;
var dynamicAssemblies = Directory.EnumerateFiles(dynamicAssembliesPath, "*.dll", SearchOption.AllDirectories)
.Where(filename => assemblyPattern.IsMatch(Path.GetFileName(filename)) &&
!loadedAssemblies.Any(a => Path.GetFileName(a.Location) == Path.GetFileName(filename)));
var allAssemblies = loadedAssemblies.Concat(dynamicAssemblies.Select(Assembly.LoadFrom)).Distinct();
builder.RegisterAssemblyModules(allAssemblies.ToArray());
Application.container = builder.Build();
}
}
public static TService Resolve(params Parameter[] parameters) where TService : class
{
return Container.Resolve(parameters);
}
public static TService ResolveNamed(string name, params Parameter[] parameters) where TService : class
{
return Container.ResolveNamed(name, parameters);
}
public static TService ResolveOptional(params Parameter[] parameters) where TService : class
{
return Container.ResolveOptional(parameters);
}
public static TService ResolveOptionalNamed(string name, params Parameter[] parameters) where TService : class
{
return Container.ResolveOptionalNamed(name, parameters);
}
}
}
================================================
FILE: IntelliTrader.Core/IntelliTrader.Core.csproj
================================================
netcoreapp2.1
1.1.0.0
1.1.0.0
================================================
FILE: IntelliTrader.Core/Interfaces/Configs/IBacktestingConfig.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface IBacktestingConfig
{
bool Enabled { get; }
bool Replay { get; }
bool ReplayOutput { get; }
double ReplaySpeed { get; }
int? ReplayStartIndex { get; }
int? ReplayEndIndex { get; }
bool DeleteLogs { get; }
bool DeleteAccountData { get; }
string CopyAccountDataPath { get; }
int TradingSpeedEasing { get; }
int TradingRulesSpeedEasing { get; }
int SignalRulesSpeedEasing { get; }
int SnapshotsInterval { get; }
string SnapshotsPath { get; }
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Configs/IConfigProvider.cs
================================================
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface IConfigProvider
{
string GetSectionJson(string sectionName);
void SetSectionJson(string sectionName, string definition);
IConfigurationSection GetSection(string sectionName, Action onChange = null);
T GetSection(string sectionName, Action onChange = null);
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Configs/ICoreConfig.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface ICoreConfig
{
bool DebugMode { get; }
bool PasswordProtected { get; }
string Password { get; }
string InstanceName { get; }
double TimezoneOffset { get; }
bool HealthCheckEnabled { get; set; }
double HealthCheckInterval { get; }
double HealthCheckSuspendTradingTimeout { get; }
int HealthCheckFailuresToRestartServices { get; }
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Configs/ILoggingConfig.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface ILoggingConfig
{
bool Enabled { get; }
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Configs/INotificationConfig.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface INotificationConfig
{
bool Enabled { get; }
bool TelegramEnabled { get; }
string TelegramBotToken { get; }
long TelegramChatId { get; }
bool TelegramAlertsEnabled { get; }
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Configs/IRulesConfig.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface IRulesConfig
{
IEnumerable Modules { get; }
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Configs/ISignalsConfig.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface ISignalsConfig
{
bool Enabled { get; }
IEnumerable GlobalRatingSignals { get; }
IEnumerable Definitions { get; }
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Configs/ITradingConfig.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface ITradingConfig : IBuyConfig, IBuyDCAConfig, ISellConfig, ISellDCAConfig
{
bool Enabled { get; }
string Market { get; }
string Exchange { get; }
int MaxPairs { get; }
decimal MinCost { get; }
List ExcludedPairs { get; }
TradePriceType TradePriceType { get; set; }
bool RepeatLastDCALevel { get; }
List DCALevels { get; }
double TradingCheckInterval { get; }
double AccountRefreshInterval { get; }
decimal AccountInitialBalance { get; }
DateTimeOffset AccountInitialBalanceDate { get; }
string AccountFilePath { get; }
bool VirtualTrading { get; }
decimal VirtualTradingFees { get; }
decimal VirtualAccountInitialBalance { get; }
string VirtualAccountFilePath { get; }
ITradingConfig Clone();
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Configs/IWebConfig.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface IWebConfig
{
bool Enabled { get; }
bool DebugMode { get; }
bool ReadOnlyMode { get; }
int Port { get; }
bool SSLEnabled { get; }
string SSLCertPath { get; set; }
string SSLCertPassword { get; set; }
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Exchange/ITicker.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface ITicker
{
string Pair { get; }
decimal BidPrice { get; }
decimal AskPrice { get; }
decimal LastPrice { get; }
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/IHealthCheck.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface IHealthCheck
{
string Name { get; }
string Message { get; }
DateTimeOffset LastUpdated { get; }
bool Failed { get; }
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Rules/IModuleRules.cs
================================================
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface IModuleRules
{
string Module { get; }
IConfigurationSection Configuration { get; }
IEnumerable Entries { get; }
T GetConfiguration();
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Rules/IRule.cs
================================================
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface IRule
{
bool Enabled { get; }
string Name { get; }
RuleAction Action { get; }
IEnumerable Conditions { get; }
IRuleTrailing Trailing { get; }
IConfigurationSection Modifiers { get; }
T GetModifiers();
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Rules/IRuleCondition.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface IRuleCondition
{
string Signal { get; }
decimal? MinPrice { get; }
decimal? MaxPrice { get; }
decimal? MinSpread { get; }
decimal? MaxSpread { get; }
long? MinVolume { get; }
long? MaxVolume { get; }
double? MinVolumeChange { get; }
double? MaxVolumeChange { get; }
decimal? MinPriceChange { get; }
decimal? MaxPriceChange { get; }
double? MinRating { get; }
double? MaxRating { get; }
double? MinRatingChange { get; }
double? MaxRatingChange { get; }
double? MinVolatility { get; }
double? MaxVolatility { get; }
double? MinGlobalRating { get; }
double? MaxGlobalRating { get; }
decimal? MinArbitrage { get; }
decimal? MaxArbitrage { get; }
ArbitrageMarket? ArbitrageMarket { get; }
ArbitrageType? ArbitrageType { get; }
List Pairs { get; }
List NotPairs { get; }
double? MinAge { get; }
double? MaxAge { get; }
double? MinLastBuyAge { get; }
double? MaxLastBuyAge { get; }
decimal? MinMargin { get; }
decimal? MaxMargin { get; }
decimal? MinMarginChange { get; }
decimal? MaxMarginChange { get; }
decimal? MinAmount { get; set; }
decimal? MaxAmount { get; set; }
decimal? MinCost { get; }
decimal? MaxCost { get; }
int? MinDCALevel { get; }
int? MaxDCALevel { get; }
List SignalRules { get; }
List NotSignalRules { get; }
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Rules/IRuleTrailing.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface IRuleTrailing
{
bool Enabled { get; }
int MinDuration { get; }
int MaxDuration { get; }
IEnumerable StartConditions { get; }
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Rules/ISignalRulesConfig.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface ISignalRulesConfig
{
RuleProcessingMode ProcessingMode { get; }
double CheckInterval { get; }
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Rules/RuleProcessingMode.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public enum RuleProcessingMode
{
FirstMatch,
AllMatches
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Services/Base/IConfigurableService.cs
================================================
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface IConfigurableService : INamedService
{
IConfigurationSection RawConfig { get; }
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Services/Base/INamedService.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface INamedService
{
string ServiceName { get; }
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Services/IBacktestingService.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface IBacktestingService : IConfigurableService
{
IBacktestingConfig Config { get; }
object SyncRoot { get; }
void Start();
void Stop();
void Complete(int skippedSignalSnapshots, int skippedTickerSnapshots);
string GetSnapshotFilePath(string snapshotEntity);
Dictionary> GetCurrentSignals();
Dictionary GetCurrentTickers();
int GetTotalSnapshots();
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Services/ICoreService.cs
================================================
using System;
using System.Collections.Concurrent;
namespace IntelliTrader.Core
{
public interface ICoreService : IConfigurableService
{
event Action Started;
ICoreConfig Config { get; }
string Version { get; }
void Start();
void Stop();
void Restart();
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Services/IExchangeService.cs
================================================
using System;
using System.Collections.Generic;
namespace IntelliTrader.Core
{
public interface IExchangeService : IConfigurableService
{
void Start(bool virtualTrading);
void Stop();
IOrderDetails PlaceOrder(IOrder order);
decimal ClampOrderAmount(string pair, decimal amount);
decimal ClampOrderPrice(string pair, decimal price);
void ConnectTickersWebsocket();
void DisconnectTickersWebsocket();
IEnumerable GetTickers();
IEnumerable GetMarkets();
IEnumerable GetMarketPairs(string market);
Dictionary GetAvailableAmounts();
IEnumerable GetTrades(string pair);
decimal GetPrice(string pair, TradePriceType priceType);
decimal GetPriceSpread(string pair);
Arbitrage GetArbitrage(string pair, string tradingMarket, List arbitrageMarkets = null, ArbitrageType? arbitrageType = null);
string GetArbitrageMarketPair(ArbitrageMarket arbitrageMarket);
string GetPairMarket(string pair);
string ChangeMarket(string pair, string market);
decimal ConvertPrice(string pair, decimal price, string market, TradePriceType priceType);
TimeSpan GetTimeElapsedSinceLastTickersUpdate();
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Services/IHealthCheckService.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface IHealthCheckService
{
void Start();
void Stop();
void UpdateHealthCheck(string name, string message = null, bool failed = false);
void RemoveHealthCheck(string name);
IEnumerable GetHealthChecks();
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Services/ILoggingService.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface ILoggingService : IConfigurableService
{
void Debug(string message, Exception exception = null);
void Debug(string message, params object[] propertyValues);
void Error(string message, Exception exception = null);
void Error(string message, params object[] propertyValues);
void Fatal(string message, Exception exception = null);
void Fatal(string message, params object[] propertyValues);
void Info(string message, Exception exception = null);
void Info(string message, params object[] propertyValues);
void Verbose(string message, Exception exception = null);
void Verbose(string message, params object[] propertyValues);
void Warning(string message, Exception exception = null);
void Warning(string message, params object[] propertyValues);
void DeleteAllLogs();
string[] GetLogEntries();
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Services/INotificationService.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface INotificationService
{
INotificationConfig Config { get; }
void Start();
void Stop();
void Notify(string message);
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Services/IOrderingService.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface IOrderingService
{
IOrderDetails PlaceBuyOrder(BuyOptions options);
IOrderDetails PlaceSellOrder(SellOptions options);
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Services/IRulesService.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface IRulesService : IConfigurableService
{
IRulesConfig Config { get; }
IModuleRules GetRules(string module);
bool CheckConditions(IEnumerable conditions, Dictionary signals, double? globalRating, string pair, ITradingPair tradingPair);
void RegisterRulesChangeCallback(Action callback);
void UnregisterRulesChangeCallback(Action callback);
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Services/ISignalsService.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface ISignalsService : IConfigurableService
{
ISignalsConfig Config { get; }
IModuleRules Rules { get; }
ISignalRulesConfig RulesConfig { get; }
void Start();
void Stop();
void ProcessPair(string pair, Dictionary signals);
void StopTrailing();
List GetTrailingSignals();
IEnumerable GetTrailingInfo(string pair);
IEnumerable GetSignalNames();
IEnumerable GetAllSignals();
IEnumerable GetSignalsByName(string signalName);
IEnumerable GetSignalsByPair(string pair);
double? GetRating(string pair, string signalName);
double? GetRating(string pair, IEnumerable signalNames);
double? GetGlobalRating();
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Services/ITasksService.cs
================================================
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface ITasksService
{
T AddTask(string name, T task, double interval, double startDelay = 0, bool startTask = true, bool runNow = false, int skipIteration = 0) where T : ITimedTask;
void RemoveTask(string name, bool stopTask = true);
void StartAllTasks();
void StopAllTasks();
void RemoveAllTasks();
ITimedTask GetTask(string name);
T GetTask(string name);
IEnumerable> GetAllTasks();
void SetUnhandledExceptionHandler(UnhandledExceptionEventHandler handler);
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Services/ITradingService.cs
================================================
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace IntelliTrader.Core
{
public interface ITradingService : IConfigurableService
{
ITradingConfig Config { get; }
IModuleRules Rules { get; }
IExchangeService Exchange { get; }
ITradingAccount Account { get; }
ConcurrentStack OrderHistory { get; }
bool IsTradingSuspended { get; }
void Start();
void Stop();
void ResumeTrading(bool forced = false);
void SuspendTrading(bool forced = false);
IPairConfig GetPairConfig(string pair);
void ReapplyTradingRules();
void Buy(BuyOptions options);
void Sell(SellOptions options);
void Swap(SwapOptions options);
void Arbitrage(ArbitrageOptions options);
bool CanBuy(BuyOptions options, out string message);
bool CanSell(SellOptions options, out string message);
bool CanSwap(SwapOptions options, out string message);
bool CanArbitrage(ArbitrageOptions options, out string message);
decimal GetPrice(string pair, TradePriceType? priceType = null, bool normalize = true);
decimal CalculateOrderFees(IOrderDetails order);
bool IsNormalizedPair(string pair);
string NormalizePair(string pair);
void LogOrder(IOrderDetails order);
List GetTrailingBuys();
List GetTrailingSells();
void StopTrailingBuy(string pair);
void StopTrailingSell(string pair);
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Services/IWebService.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface IWebService
{
IWebConfig Config { get; }
void Start();
void Stop();
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Signals/ISignal.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface ISignal
{
string Name { get; }
string Pair { get; }
long? Volume { get; }
double? VolumeChange { get; set; }
decimal? Price { get; }
decimal? PriceChange { get; }
double? Rating { get; }
double? RatingChange { get; }
double? Volatility { get; }
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Signals/ISignalDefinition.cs
================================================
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface ISignalDefinition
{
string Name { get; }
string Receiver { get; }
IConfigurationSection Configuration { get; }
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Signals/ISignalTrailingInfo.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface ISignalTrailingInfo
{
IRule Rule { get; }
DateTimeOffset StartTime { get; }
double Duration { get; }
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Tasks/ITimedTask.cs
================================================
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
namespace IntelliTrader.Core
{
public interface ITimedTask
{
event UnhandledExceptionEventHandler UnhandledException;
double StartDelay { get; set; }
double Interval { get; set; }
int SkipIteration { get; set; }
Stopwatch Stopwatch { get; set; }
bool IsRunning { get; }
long RunCount { get; }
double TotalRunTime { get; }
double TotalLagTime { get; }
void Start();
void Stop();
void Pause();
void Continue();
void RunNow();
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Trading/IBuyConfig.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface IBuyConfig
{
bool BuyEnabled { get; set; }
OrderType BuyType { get; }
decimal BuyMaxCost { get; }
decimal BuyMultiplier { get; }
decimal BuyMinBalance { get; }
double BuySamePairTimeout { get; }
decimal BuyTrailing { get; }
decimal BuyTrailingStopMargin { get; }
BuyTrailingStopAction BuyTrailingStopAction { get; }
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Trading/IBuyDCAConfig.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface IBuyDCAConfig
{
bool BuyDCAEnabled { get; set; }
decimal BuyDCAMultiplier { get; }
decimal BuyDCAMinBalance { get; }
double BuyDCASamePairTimeout { get; }
decimal BuyDCATrailing { get; }
decimal BuyDCATrailingStopMargin { get; }
BuyTrailingStopAction BuyDCATrailingStopAction { get; }
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Trading/IOrder.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface IOrder
{
OrderSide Side { get; }
OrderType Type { get; }
DateTimeOffset Date { get; }
string Pair { get; }
decimal Amount { get; }
decimal Price { get; }
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Trading/IOrderDetails.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface IOrderDetails
{
bool IsNormalized { get; }
OrderSide Side { get; }
OrderResult Result { get; }
DateTimeOffset Date { get; }
string OrderId { get; }
string Pair { get; }
string OriginalPair { get; }
string Message { get; }
decimal Amount { get; }
decimal AmountFilled { get; }
decimal Price { get; }
decimal AveragePrice { get; }
decimal Fees { get; }
string FeesCurrency { get; }
decimal Cost { get; }
OrderMetadata Metadata { get; }
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Trading/IPairConfig.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface IPairConfig : IBuyConfig, ISellConfig
{
IEnumerable Rules { get; }
int MaxPairs { get; }
bool SwapEnabled { get; }
List SwapSignalRules { get; }
int SwapTimeout { get; }
bool ArbitrageEnabled { get; }
List ArbitrageMarkets { get; }
ArbitrageType? ArbitrageType { get; }
decimal? ArbitrageBuyMultiplier { get; }
decimal? ArbitrageSellMultiplier { get; }
List ArbitrageSignalRules { get; }
decimal? CurrentDCAMargin { get; }
decimal? NextDCAMargin { get; }
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Trading/ISellConfig.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface ISellConfig
{
bool SellEnabled { get; set; }
OrderType SellType { get; }
decimal SellMargin { get; }
decimal SellTrailing { get; }
decimal SellTrailingStopMargin { get; }
SellTrailingStopAction SellTrailingStopAction { get; }
bool SellStopLossEnabled { get; }
bool SellStopLossAfterDCA { get; }
double SellStopLossMinAge { get; }
decimal SellStopLossMargin { get; }
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Trading/ISellDCAConfig.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface ISellDCAConfig
{
decimal SellDCAMargin { get; }
decimal SellDCATrailing { get; }
decimal SellDCATrailingStopMargin { get; }
SellTrailingStopAction SellDCATrailingStopAction { get; }
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Trading/ITradeResult.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface ITradeResult
{
bool IsSuccessful { get; }
bool IsSwap { get; }
bool IsArbitrage { get; }
string Pair { get; }
decimal Amount { get; }
List OrderDates { get; }
decimal AveragePrice { get; }
decimal Fees { get; }
decimal FeesTotal { get; }
decimal Cost { get; }
DateTimeOffset SellDate { get; }
decimal SellPrice { get; }
decimal SellCost { get; }
decimal BalanceOffset { get; }
decimal Profit { get; }
OrderMetadata Metadata { get; }
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Trading/ITradingAccount.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface ITradingAccount : IDisposable
{
object SyncRoot { get; }
void Refresh();
void Save();
void AddOrder(IOrderDetails order);
void AddBuyOrder(IOrderDetails order);
ITradeResult AddSellOrder(IOrderDetails order);
ITradingPair AddOrUpdatePair(IOrderDetails order, string pair, decimal feesMarketCurrency, decimal feesPairCurrency, decimal? amountOverride = null, decimal? averagePriceOverride = null);
IOrderDetails AddBlankOrder(string pair, decimal amount, bool includeFees = true);
void AddBalance(decimal balanceOffset);
decimal GetBalance();
decimal GetTotalBalance();
bool HasTradingPair(string pair, bool includeDust = false);
ITradingPair GetTradingPair(string pair, bool includeDust = false);
IEnumerable GetTradingPairs(bool includeDust = false);
}
}
================================================
FILE: IntelliTrader.Core/Interfaces/Trading/ITradingPair.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public interface ITradingPair
{
string Pair { get; }
string FormattedName { get; }
int DCALevel { get; }
List OrderIds { get; }
List OrderDates { get; }
decimal Amount { get; }
decimal AveragePrice { get; }
decimal Fees { get; }
decimal Cost { get; }
decimal? CostOverride { get; set; }
decimal CurrentCost { get; }
decimal CurrentPrice { get; }
decimal CurrentSpread { get; }
decimal CurrentMargin { get; }
double CurrentAge { get; }
double LastBuyAge { get; }
OrderMetadata Metadata { get; }
decimal GetPartialCost(decimal partialAmount);
void OverrideCost(decimal? costOverride);
void SetCurrentValues(decimal currentPrice, decimal currentSpread);
void SetMetadata(OrderMetadata metadata);
}
}
================================================
FILE: IntelliTrader.Core/Models/Config/ConfigProvider.cs
================================================
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Primitives;
using System;
using System.IO;
namespace IntelliTrader.Core
{
internal class ConfigProvider : IConfigProvider
{
private const string ROOT_CONFIG_DIR = "config";
private const string PATHS_CONFIG_PATH = "paths.json";
private const string PATHS_SECTION_NAME = "Paths";
private IConfigurationSection paths;
public ConfigProvider()
{
IConfigurationRoot pathsConfig = GetConfig(PATHS_CONFIG_PATH, changedPathsConfig =>
{
paths = changedPathsConfig.GetSection(PATHS_SECTION_NAME);
});
paths = pathsConfig.GetSection(PATHS_SECTION_NAME);
}
public string GetSectionJson(string sectionName)
{
try
{
string configPath = paths.GetValue(sectionName);
var fullConfigPath = Path.Combine(Directory.GetCurrentDirectory(), ROOT_CONFIG_DIR, configPath);
return File.ReadAllText(fullConfigPath);
}
catch (Exception ex)
{
Application.Resolve().Error($"Unable to load config section {sectionName}", ex);
return null;
}
}
public void SetSectionJson(string sectionName, string definition)
{
try
{
string configPath = paths.GetValue(sectionName);
var fullConfigPath = Path.Combine(Directory.GetCurrentDirectory(), ROOT_CONFIG_DIR, configPath);
File.WriteAllText(fullConfigPath, definition);
}
catch (Exception ex)
{
Application.Resolve().Error($"Unable to save config section {sectionName}", ex);
}
}
public T GetSection(string sectionName, Action onChange = null)
{
IConfigurationSection configSection = GetSection(sectionName, changedConfigSection =>
{
onChange?.Invoke(changedConfigSection.Get());
});
return configSection.Get();
}
public IConfigurationSection GetSection(string sectionName, Action onChange = null)
{
string configPath = paths.GetValue(sectionName);
IConfigurationRoot configRoot = GetConfig(configPath, changedConfigRoot =>
{
onChange?.Invoke(changedConfigRoot.GetSection(sectionName));
});
return configRoot.GetSection(sectionName);
}
private IConfigurationRoot GetConfig(string configPath, Action onChange)
{
var fullConfigPath = Path.Combine(Directory.GetCurrentDirectory(), ROOT_CONFIG_DIR);
var configBuilder = new ConfigurationBuilder()
.SetBasePath(fullConfigPath)
.AddJsonFile(configPath, optional: false, reloadOnChange: true)
.AddEnvironmentVariables();
var configRoot = configBuilder.Build();
ChangeToken.OnChange(configRoot.GetReloadToken, () => onChange(configRoot));
return configRoot;
}
}
}
================================================
FILE: IntelliTrader.Core/Models/Config/CoreConfig.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
internal class CoreConfig : ICoreConfig
{
public bool DebugMode { get; set; }
public bool PasswordProtected { get; set; }
public string Password { get; set; }
public string InstanceName { get; set; }
public double TimezoneOffset { get; set; }
public bool HealthCheckEnabled { get; set; } = true;
public double HealthCheckInterval { get; set; }
public double HealthCheckSuspendTradingTimeout { get; set; }
public int HealthCheckFailuresToRestartServices { get; set; }
}
}
================================================
FILE: IntelliTrader.Core/Models/Config/LoggingConfig.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
internal class LoggingConfig : ILoggingConfig
{
public bool Enabled { get; set; }
}
}
================================================
FILE: IntelliTrader.Core/Models/Config/NotificationConfig.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
internal class NotificationConfig : INotificationConfig
{
public bool Enabled { get; set; }
public bool TelegramEnabled { get; set; }
public string TelegramBotToken { get; set; }
public long TelegramChatId { get; set; }
public bool TelegramAlertsEnabled { get; set; }
}
}
================================================
FILE: IntelliTrader.Core/Models/Constants.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public static class Constants
{
public static class ServiceNames
{
public const string CoreService = "Core";
public const string CachingService = "Caching";
public const string LoggingService = "Logging";
public const string TradingService = "Trading";
public const string ExchangeService = "Exchange";
public const string SignalsService = "Signals";
public const string RulesService = "Rules";
public const string NotificationService = "Notification";
public const string WebService = "Web";
public const string BacktestingService = "Backtesting";
public const string BacktestingExchangeService = "BacktestingExchange";
public const string BacktestingSignalsService = "BacktestingSignals";
}
public static class HealthChecks
{
public const string AccountRefreshed = "Account refreshed";
public const string TickersUpdated = "Tickers updated";
public const string TradingPairsProcessed = "Trading pairs processed";
public const string TradingViewCryptoSignalsReceived = "TV Signals received";
public const string SignalRulesProcessed = "Signals rules processed";
public const string TradingRulesProcessed = "Trading rules processed";
public const string BacktestingSignalsSnapshotTaken = "Backtesting signals snapshot taken";
public const string BacktestingTickersSnapshotTaken = "Backtesting tickers snapshot taken";
public const string BacktestingSignalsSnapshotLoaded = "Backtesting signals snapshot loaded";
public const string BacktestingTickersSnapshotLoaded = "Backtesting tickers snapshot loaded";
}
public static class SnapshotEntities
{
public const string Signals = "signals";
public const string Tickers = "tickers";
}
public static class TaskDelays
{
public const int ZeroDelay = 0;
public const int LowDelay = 1200;
public const int MidDelay = 2400;
public const int NormalDelay = 3300;
public const int HighDelay = 4700;
}
public static class Markets
{
public const string BTC = "BTC";
public const string ETH = "ETH";
public const string BNB = "BNB";
public const string USDT = "USDT";
}
}
}
================================================
FILE: IntelliTrader.Core/Models/HealthCheck.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
internal class HealthCheck : IHealthCheck
{
public string Name { get; set; }
public string Message { get; set; }
public DateTimeOffset LastUpdated { get; set; }
public bool Failed { get; set; }
}
}
================================================
FILE: IntelliTrader.Core/Models/Logging/MemorySink.cs
================================================
using System;
using System.IO;
using Serilog.Core;
using Serilog.Events;
using Serilog.Formatting;
namespace IntelliTrader.Core
{
internal class MemorySink : ILogEventSink
{
readonly TextWriter textWriter;
readonly ITextFormatter textFormatter;
readonly object syncRoot = new object();
public MemorySink(System.IO.TextWriter textWriter, ITextFormatter textFormatter)
{
this.textWriter = textWriter;
this.textFormatter = textFormatter ?? throw new ArgumentNullException(nameof(textFormatter));
}
public void Emit(LogEvent logEvent)
{
if (logEvent == null) throw new ArgumentNullException(nameof(logEvent));
lock (syncRoot)
{
textFormatter.Format(logEvent, textWriter);
textWriter.Flush();
}
}
}
}
================================================
FILE: IntelliTrader.Core/Models/Logging/MemorySinkExtensions.cs
================================================
using System;
using System.IO;
using Serilog;
using Serilog.Configuration;
using Serilog.Core;
using Serilog.Events;
using Serilog.Formatting;
using Serilog.Formatting.Display;
namespace IntelliTrader.Core
{
///
/// Adds the WriteTo.Memory() extension method to .
///
public static class TextWriterLoggerConfigurationExtensions
{
const string DefaultOutputTemplate = "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}";
///
/// Write log events to the provided .
///
/// Logger sink configuration.
/// The text writer to write log events to.
/// Message template describing the output format.
/// The minimum level for
/// events passed through the sink. Ignored when is specified.
/// A switch allowing the pass-through minimum level
/// to be changed at runtime.
/// Configuration object allowing method chaining.
/// Supplies culture-specific formatting information, or null.
///
public static LoggerConfiguration Memory(
this LoggerSinkConfiguration sinkConfiguration,
TextWriter textWriter,
LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
string outputTemplate = DefaultOutputTemplate,
IFormatProvider formatProvider = null,
LoggingLevelSwitch levelSwitch = null)
{
if (textWriter == null) throw new ArgumentNullException(nameof(textWriter));
if (outputTemplate == null) throw new ArgumentNullException(nameof(outputTemplate));
var formatter = new MessageTemplateTextFormatter(outputTemplate, formatProvider);
var sink = new MemorySink(textWriter, formatter);
return sinkConfiguration.Sink(sink, restrictedToMinimumLevel, levelSwitch);
}
///
/// Write log events to the provided .
///
/// Logger sink configuration.
/// The text writer to write log events to.
/// Text formatter used by sink.
/// /// The minimum level for
/// events passed through the sink. Ignored when is specified.
/// A switch allowing the pass-through minimum level
/// to be changed at runtime.
///
public static LoggerConfiguration Memory(
this LoggerSinkConfiguration sinkConfiguration,
ITextFormatter formatter,
TextWriter textWriter,
LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
LoggingLevelSwitch levelSwitch = null)
{
if (textWriter == null) throw new ArgumentNullException(nameof(textWriter));
if (formatter == null) throw new ArgumentNullException(nameof(formatter));
var sink = new MemorySink(textWriter, formatter);
return sinkConfiguration.Sink(sink, restrictedToMinimumLevel, levelSwitch);
}
}
}
================================================
FILE: IntelliTrader.Core/Models/Tasks/EqualResolutionTimedTask.cs
================================================
using System;
using System.Diagnostics;
using System.Threading;
namespace IntelliTrader.Core
{
public abstract class EqualResolutionTimedTask : ITimedTask
{
///
/// Raised on unhandled exception
///
public event UnhandledExceptionEventHandler UnhandledException;
///
/// Delay before starting the task in milliseconds
///
public double StartDelay { get; set; } = 0;
///
/// Periodic execution interval in milliseconds
///
public double Interval { get; set; } = 1000;
///
/// How often to skip task execution (in RunCount)
///
public int SkipIteration { get; set; } = 0;
///
/// The priority of the timer thread
///
public ThreadPriority Priorty { get; set; } = ThreadPriority.Normal;
///
/// Stopwatch to use for timing the intervals
///
public Stopwatch Stopwatch { get; set; }
///
/// Indicates whether the task is currently running
///
public bool IsRunning { get; private set; }
///
/// Number of times the task has been run
///
public long RunCount { get; private set; }
///
/// Total time it took to run the task in milliseconds
///
public double TotalRunTime { get; private set; }
///
/// Total task run delay in milliseconds
///
public double TotalLagTime { get; private set; }
private Thread timerThread;
private Stopwatch runWatch;
private ManualResetEvent timingEvent;
private ManualResetEvent blockingEvent;
///
/// Start the task
///
public void Start()
{
if (!IsRunning)
{
IsRunning = true;
runWatch = new Stopwatch();
timingEvent = new ManualResetEvent(false);
blockingEvent = new ManualResetEvent(true);
timerThread = new Thread(() =>
{
if (Stopwatch == null)
{
Stopwatch = Stopwatch.StartNew();
}
else if (!Stopwatch.IsRunning)
{
Stopwatch.Restart();
}
long startTime = Stopwatch.ElapsedMilliseconds;
while (IsRunning)
{
blockingEvent.WaitOne();
long elapsedTime = Stopwatch.ElapsedMilliseconds;
double nextRunTime = RunCount * Interval + StartDelay + TotalLagTime + startTime;
double waitTime = nextRunTime - elapsedTime;
if (waitTime > 0)
{
if (timingEvent.WaitOne((int)(waitTime)))
{
break;
}
}
if (SkipIteration == 0 || RunCount % SkipIteration != 0)
{
runWatch.Restart();
SafeRun();
long runTime = runWatch.ElapsedMilliseconds;
TotalLagTime += (runTime > Interval) ? (runTime - Interval) : 0;
TotalRunTime += runTime;
}
RunCount++;
}
});
timerThread.Priority = Priorty;
timerThread.Start();
}
}
///
/// Stop the task
///
public void Stop()
{
Stop(true);
}
///
/// Stop the task
///
///
/// This function is waiting an executing thread (unless join is set to false).
///
public void Stop(bool terminateThread)
{
if (IsRunning)
{
IsRunning = false;
timingEvent.Set();
blockingEvent.Set();
runWatch.Stop();
if (!terminateThread)
{
timerThread?.Join();
timerThread = null;
}
timingEvent.Dispose();
}
}
///
/// Temporarily pause the task
///
public void Pause()
{
blockingEvent.Reset();
}
///
/// Continue running the task
///
public void Continue()
{
blockingEvent.Set();
}
///
/// Manually run the task
///
public void RunNow()
{
SafeRun();
}
///
/// This method must be implemented by the child class and must contain the code
/// to be executed periodically.
///
protected abstract void Run();
///
/// Wrap Run method in Try/Catch
///
private void SafeRun()
{
try
{
Run();
}
catch (Exception ex)
{
UnhandledException?.Invoke(this, new UnhandledExceptionEventArgs(ex, false));
}
}
}
}
================================================
FILE: IntelliTrader.Core/Models/Tasks/HighResolutionTimedTask.cs
================================================
using System;
using System.Diagnostics;
using System.Threading;
namespace IntelliTrader.Core
{
public abstract class HighResolutionTimedTask : ITimedTask
{
///
/// Raised on unhandled exception
///
public event UnhandledExceptionEventHandler UnhandledException;
///
/// Delay before starting the task in milliseconds
///
public double StartDelay { get; set; } = 0;
///
/// Periodic execution interval in milliseconds
///
public double Interval { get; set; } = 1000;
///
/// How often to skip task execution (in RunCount)
///
public int SkipIteration { get; set; } = 0;
///
/// The priority of the timer thread
///
public ThreadPriority Priorty { get; set; } = ThreadPriority.Normal;
///
/// Stopwatch to use for timing the intervals
///
public Stopwatch Stopwatch { get; set; }
///
/// Indicates whether the task is currently running
///
public bool IsRunning { get; private set; }
///
/// Number of times the task has been run
///
public long RunCount { get; private set; }
///
/// Total time it took to run the task in milliseconds
///
public double TotalRunTime { get; private set; }
///
/// Total task run delay in milliseconds
///
public double TotalLagTime { get; private set; }
private Thread timerThread;
private Stopwatch runWatch;
private ManualResetEvent timingEvent;
private ManualResetEvent blockingEvent;
///
/// Start the task
///
public void Start()
{
if (!IsRunning)
{
IsRunning = true;
runWatch = new Stopwatch();
timingEvent = new ManualResetEvent(false);
blockingEvent = new ManualResetEvent(true);
timerThread = new Thread(() =>
{
if (Stopwatch == null)
{
Stopwatch = Stopwatch.StartNew();
}
else if (!Stopwatch.IsRunning)
{
Stopwatch.Restart();
}
long startTime = Stopwatch.ElapsedMilliseconds;
double nextRunTime = StartDelay + Interval;
while (IsRunning)
{
blockingEvent.WaitOne();
long elapsedTime = Stopwatch.ElapsedMilliseconds;
long runningTime = elapsedTime - startTime;
if (nextRunTime < runningTime) nextRunTime = runningTime;
double waitTime = nextRunTime - runningTime;
if (waitTime > 0)
{
if (timingEvent.WaitOne((int)(waitTime)))
{
break;
}
}
if (SkipIteration == 0 || RunCount % SkipIteration != 0)
{
runWatch.Restart();
SafeRun();
long runTime = runWatch.ElapsedMilliseconds;
TotalLagTime += runTime - Interval;
TotalRunTime += runTime;
}
RunCount++;
nextRunTime += Interval;
}
});
timerThread.Priority = Priorty;
timerThread.Start();
}
}
///
/// Stop the task
///
public void Stop()
{
Stop(true);
}
///
/// Stop the task
///
///
/// This function is waiting an executing thread (unless join is set to false).
///
public void Stop(bool terminateThread)
{
if (IsRunning)
{
IsRunning = false;
timingEvent.Set();
blockingEvent.Set();
runWatch.Stop();
if (!terminateThread)
{
timerThread?.Join();
timerThread = null;
}
timingEvent.Dispose();
}
}
///
/// Temporarily pause the task
///
public void Pause()
{
blockingEvent.Reset();
}
///
/// Continue running the task
///
public void Continue()
{
blockingEvent.Set();
}
///
/// Manually run the task
///
public void RunNow()
{
SafeRun();
}
///
/// This method must be implemented by the child class and must contain the code
/// to be executed periodically.
///
protected abstract void Run();
///
/// Wrap Run method in Try/Catch
///
private void SafeRun()
{
try
{
Run();
}
catch (Exception ex)
{
UnhandledException?.Invoke(this, new UnhandledExceptionEventArgs(ex, false));
}
}
}
}
================================================
FILE: IntelliTrader.Core/Models/Tasks/LowResolutionTimedTask.cs
================================================
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Timers;
namespace IntelliTrader.Core
{
public abstract class LowResolutionTimedTask : ITimedTask
{
///
/// Raised on unhandled exception
///
#pragma warning disable CS0067
public event UnhandledExceptionEventHandler UnhandledException;
///
/// Delay before starting the task in milliseconds
///
public double StartDelay { get; set; }
///
/// Periodic execution interval in milliseconds
///
public double Interval
{
get { return timer.Interval; }
set { timer.Interval = value; }
}
///
/// How often to skip task execution (in RunCount)
///
public int SkipIteration { get; set; } = 0;
///
/// Stopwatch to use for timing the intervals
///
public Stopwatch Stopwatch { get; set; }
///
/// Indicates whether the task is currently running
///
public bool IsRunning { get; private set; }
///
/// Number of times the task has been run
///
public long RunCount { get; private set; }
///
/// Total time it took to run the task in milliseconds
///
public double TotalRunTime { get; private set; }
///
/// Total task run delay in milliseconds
///
public double TotalLagTime { get; private set; }
private readonly Timer timer = new Timer();
private readonly Stopwatch runWatch = new Stopwatch();
private readonly System.Threading.AutoResetEvent syncMutex = new System.Threading.AutoResetEvent(true);
///
/// Class constructor. It allocates the memory for the background timer and
/// initializes sync mutex.
///
public LowResolutionTimedTask()
{
this.timer.Elapsed += OnTimerElapsed;
}
///
/// Starts the background task timer that is in charge of executing the Execute method each
/// time the interval is elapsed.
///
public void Start()
{
if (!IsRunning)
{
IsRunning = true;
if (StartDelay > 0)
{
Task.Delay((int)StartDelay).ContinueWith(t =>
{
if (IsRunning)
{
timer.Start();
}
});
}
else
{
timer.Start();
}
}
}
///
/// Stops the background task timer that is in charge of executing the Execute method each
/// time the interval is elapsed. If the Execute method was executing when this method is
/// called, the caller thread will block waiting the Execute operation to finish. Later on,
/// the timer will be stopped. Otherwise, if the Execute method is not executing when this
/// method is called, the timer will be stopped without blocking the caller thread.
///
public void Stop()
{
Stop(-1);
}
///
/// Stops the background task timer that is in charge of executing the Execute method each
/// time the interval is elapsed. If the Execute method was executing when this method is
/// called, the caller thread will block waiting the Execute operation to finish. Later on,
/// the timer will be stopped. Otherwise, if the Execute method is not executing when this
/// method is called, the timer will be stopped without blocking the caller thread.
///
/// Timeout value in milliseconds to wait before killing the task
public void Stop(int timeout)
{
if (IsRunning)
{
this.syncMutex.WaitOne(timeout);
this.syncMutex.Set();
this.timer.Stop();
IsRunning = false;
}
}
///
/// Stops the periodic task executor without waiting the current task to stop.
///
public void Terminate()
{
if (IsRunning)
{
this.timer.Stop();
IsRunning = false;
}
}
///
/// This method can operate in two different ways. If the Execute method is currently executing, it will
/// block the caller thread until Execute finishes. However, if the Execute method is not being executed,
/// this method will not block and will immediately return back the control to the caller thread.
///
public void Join()
{
if (IsRunning)
{
this.syncMutex.WaitOne();
this.syncMutex.Set();
}
}
///
/// Temporarily pause the task
///
public void Pause()
{
this.timer.Enabled = false;
}
///
/// Continue running the task
///
public void Continue()
{
this.timer.Enabled = true;
}
///
/// Wraps the Execute call abstracting the child class from the thread synchronization issues.
///
/// The thimer object that is calling the event listener.
/// The arguments passed by the timer to the method.
private void OnTimerElapsed(object sender, ElapsedEventArgs e)
{
//Force other threads to wait until it's finished when calling join.
this.syncMutex.Reset();
//Avoid re-calling the method while it is still operating.
this.timer.Stop();
if (IsRunning)
{
runWatch.Restart();
this.Run();
long runTime = runWatch.ElapsedMilliseconds;
TotalLagTime += (runTime > Interval) ? (runTime - Interval) : 0;
TotalRunTime += runTime;
RunCount++;
runWatch.Stop();
//Re-Start the timer to execute the worker function endlessly.
this.timer.Start();
}
//Release threads that might be frozen in join operation.
this.syncMutex.Set();
}
///
/// Manually run the task
///
public void RunNow()
{
Run();
}
///
/// This method must be implemented by the child class and must contain the code
/// to be executed periodically.
///
protected abstract void Run();
}
}
================================================
FILE: IntelliTrader.Core/Models/Trading/Arbitrage.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public class Arbitrage
{
public bool IsAssigned { get; set; }
public ArbitrageMarket Market { get; set; }
public ArbitrageType Type { get; set; }
public decimal Percentage { get; set; }
}
}
================================================
FILE: IntelliTrader.Core/Models/Trading/ArbitrageMarket.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public enum ArbitrageMarket
{
ETH,
BNB,
USDT
}
}
================================================
FILE: IntelliTrader.Core/Models/Trading/ArbitrageOptions.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public class ArbitrageOptions
{
public string Pair { get; set; }
public Arbitrage Arbitrage { get; set; }
public bool ManualOrder { get; set; }
public OrderMetadata Metadata { get; set; }
public ArbitrageOptions(string pair, Arbitrage arbitrage, OrderMetadata newPairMetadata)
{
this.Pair = pair;
this.Arbitrage = arbitrage;
this.Metadata = newPairMetadata ?? new OrderMetadata();
}
}
}
================================================
FILE: IntelliTrader.Core/Models/Trading/ArbitrageType.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public enum ArbitrageType
{
Direct,
Reverse
}
}
================================================
FILE: IntelliTrader.Core/Models/Trading/BuyOptions.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public class BuyOptions
{
public string Pair { get; set; }
public decimal? Amount { get; set; }
public decimal? MaxCost { get; set; }
public decimal? Price { get; set; }
public bool ManualOrder { get; set; }
public bool Swap { get; set; }
public bool Arbitrage { get; set; }
public bool IgnoreExisting { get; set; }
public bool IgnoreBalance { get; set; }
public OrderMetadata Metadata { get; set; }
public BuyOptions(string pair)
{
this.Pair = pair;
this.Metadata = new OrderMetadata();
}
}
}
================================================
FILE: IntelliTrader.Core/Models/Trading/BuyTrailingStopAction.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public enum BuyTrailingStopAction
{
Buy,
Cancel
}
}
================================================
FILE: IntelliTrader.Core/Models/Trading/DCALevel.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public class DCALevel
{
public decimal Margin { get; set; }
public decimal? BuyMultiplier { get; set; }
public double? BuySamePairTimeout { get; set; }
public decimal? BuyTrailing { get; set; }
public decimal? BuyTrailingStopMargin { get; set; }
public BuyTrailingStopAction? BuyTrailingStopAction { get; set; }
public decimal? SellMargin { get; set; }
public decimal? SellTrailing { get; set; }
public decimal? SellTrailingStopMargin { get; set; }
public SellTrailingStopAction? SellTrailingStopAction { get; set; }
}
}
================================================
FILE: IntelliTrader.Core/Models/Trading/OrderMetadata.cs
================================================
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public class OrderMetadata
{
public bool? IsTransitional { get; set; }
public string OriginalPair { get; set; }
public List TradingRules { get; set; }
public string SignalRule { get; set; }
public List Signals { get; set; }
public double? BoughtRating { get; set; }
public double? CurrentRating { get; set; }
public double? BoughtGlobalRating { get; set; }
public double? CurrentGlobalRating { get; set; }
public decimal? LastBuyMargin { get; set; }
public int? AdditionalDCALevels { get; set; }
public decimal? AdditionalCosts { get; set; }
public decimal? FeesNonDeductible { get; set; }
public string SwapPair { get; set; }
public string Arbitrage { get; set; }
public decimal? ArbitragePercentage { get; set; }
public OrderMetadata MergeWith(OrderMetadata metadata)
{
return new OrderMetadata
{
IsTransitional = metadata.IsTransitional ?? IsTransitional,
OriginalPair = metadata.OriginalPair ?? OriginalPair,
TradingRules = metadata.TradingRules ?? TradingRules,
SignalRule = metadata.SignalRule ?? SignalRule,
Signals = metadata.Signals ?? Signals,
BoughtRating = metadata.BoughtRating ?? BoughtRating,
CurrentRating = metadata.CurrentRating ?? CurrentRating,
BoughtGlobalRating = metadata.BoughtGlobalRating ?? BoughtGlobalRating,
CurrentGlobalRating = metadata.CurrentGlobalRating ?? CurrentGlobalRating,
LastBuyMargin = metadata.LastBuyMargin ?? LastBuyMargin,
AdditionalDCALevels = metadata.AdditionalDCALevels ?? AdditionalDCALevels,
AdditionalCosts = metadata.AdditionalCosts ?? AdditionalCosts,
FeesNonDeductible = metadata.FeesNonDeductible ?? FeesNonDeductible,
SwapPair = metadata.SwapPair ?? SwapPair,
Arbitrage = metadata.Arbitrage ?? Arbitrage,
ArbitragePercentage = metadata.ArbitragePercentage ?? ArbitragePercentage
};
}
}
}
================================================
FILE: IntelliTrader.Core/Models/Trading/OrderResult.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public enum OrderResult
{
Unknown = 0,
Filled = 1,
FilledPartially = 2,
Pending = 3,
Error = 4,
Canceled = 5
}
}
================================================
FILE: IntelliTrader.Core/Models/Trading/OrderSide.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public enum OrderSide
{
Buy,
Sell
}
}
================================================
FILE: IntelliTrader.Core/Models/Trading/OrderType.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public enum OrderType
{
Limit,
Market
}
}
================================================
FILE: IntelliTrader.Core/Models/Trading/RuleAction.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public enum RuleAction
{
Default,
Swap,
Arbitrage
}
}
================================================
FILE: IntelliTrader.Core/Models/Trading/SellOptions.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public class SellOptions
{
public string Pair { get; set; }
public decimal? Amount { get; set; }
public decimal? Price { get; set; }
public bool ManualOrder { get; set; }
public bool Swap { get; set; }
public bool Arbitrage { get; set; }
public OrderMetadata Metadata { get; set; }
public SellOptions(string pair)
{
this.Pair = pair;
this.Metadata = new OrderMetadata();
}
}
}
================================================
FILE: IntelliTrader.Core/Models/Trading/SellTrailingStopAction.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public enum SellTrailingStopAction
{
Sell,
Cancel
}
}
================================================
FILE: IntelliTrader.Core/Models/Trading/SwapOptions.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public class SwapOptions
{
public string OldPair { get; set; }
public string NewPair { get; set; }
public bool ManualOrder { get; set; }
public OrderMetadata Metadata { get; set; }
public SwapOptions(string oldPair, string newPair, OrderMetadata newPairMetadata)
{
this.OldPair = oldPair;
this.NewPair = newPair;
this.Metadata = newPairMetadata ?? new OrderMetadata();
}
}
}
================================================
FILE: IntelliTrader.Core/Models/Trading/TradePriceType.cs
================================================
namespace IntelliTrader.Core
{
public enum TradePriceType
{
Last,
Ask,
Bid
}
}
================================================
FILE: IntelliTrader.Core/Models/Trading/TradeResult.cs
================================================
using IntelliTrader.Core;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
namespace IntelliTrader.Core
{
public class TradeResult : ITradeResult
{
public bool IsSuccessful { get; set; }
public bool IsSwap { get; set; }
public bool IsArbitrage { get; set; }
public string Pair { get; set; }
public decimal Amount { get; set; }
public List OrderDates { get; set; }
public decimal AveragePrice { get; set; }
public decimal Fees { get; set; }
public decimal FeesTotal => Fees + (Metadata?.FeesNonDeductible ?? 0);
public decimal Cost => AveragePrice * Amount;
public DateTimeOffset SellDate { get; set; }
public decimal SellPrice { get; set; }
public decimal SellCost => SellPrice * Amount;
public decimal BalanceOffset { get; set; }
public decimal Profit { get; set; }
public OrderMetadata Metadata { get; set; }
}
}
================================================
FILE: IntelliTrader.Core/Models/Utils.cs
================================================
namespace IntelliTrader.Core
{
public static class Utils
{
public static decimal CalculatePercentage(decimal oldValue, decimal newValue)
{
if (oldValue != 0)
{
return (newValue - oldValue) / oldValue * 100;
}
else
{
return 0;
}
}
}
}
================================================
FILE: IntelliTrader.Core/Serialization/DecimalFormatJsonConverter.cs
================================================
using Newtonsoft.Json;
using System;
namespace IntelliTrader.Core
{
public class DecimalFormatJsonConverter : JsonConverter
{
private readonly int _numberOfDecimals;
public DecimalFormatJsonConverter(int numberOfDecimals)
{
_numberOfDecimals = numberOfDecimals;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var d = (decimal)value;
var rounded = Math.Round(d, _numberOfDecimals, MidpointRounding.AwayFromZero);
writer.WriteValue(rounded);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
JsonSerializer serializer)
{
throw new NotImplementedException("Unnecessary because CanRead is false. The type will skip the converter.");
}
public override bool CanRead
{
get { return false; }
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof(decimal);
}
}
}
================================================
FILE: IntelliTrader.Core/Services/ConfigurableServiceBase.cs
================================================
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Primitives;
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Core
{
public abstract class ConfigrableServiceBase : IConfigurableService
where TConfig : class
{
private const double DELAY_BETWEEN_CONFIG_RELOADS_MILLISECONDS = 500;
public abstract string ServiceName { get; }
public TConfig Config
{
get
{
lock (syncRoot)
{
if (config == null)
{
config = RawConfig.Get();
PrepareConfig();
}
return config;
}
}
}
public IConfigurationSection RawConfig
{
get
{
lock (syncRoot)
{
if (rawConfig == null)
{
rawConfig = Application.ConfigProvider.GetSection(ServiceName, OnRawConfigChanged);
}
return rawConfig;
}
}
}
private TConfig config;
private IConfigurationSection rawConfig;
private DateTimeOffset lastReloadDate;
private object syncRoot = new object();
protected virtual void PrepareConfig() { }
protected virtual void OnConfigReloaded() { }
private void OnRawConfigChanged(IConfigurationSection changedRawConfig)
{
lock (syncRoot)
{
rawConfig = changedRawConfig;
config = null;
}
if ((DateTimeOffset.Now - lastReloadDate).TotalMilliseconds > DELAY_BETWEEN_CONFIG_RELOADS_MILLISECONDS)
{
lastReloadDate = DateTimeOffset.Now;
PrepareConfig();
OnConfigReloaded();
Application.Resolve().Info($"{ServiceName} configuration reloaded");
}
}
}
}
================================================
FILE: IntelliTrader.Core/Services/CoreService.cs
================================================
using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
namespace IntelliTrader.Core
{
internal class CoreService : ConfigrableServiceBase, ICoreService
{
public event Action Started;
public override string ServiceName => Constants.ServiceNames.CoreService;
ICoreConfig ICoreService.Config => Config;
public string Version { get; private set; }
public string VersionType { get; private set; } = " Beta";
private readonly ILoggingService loggingService;
private readonly ITasksService tasksService;
private readonly INotificationService notificationService;
private readonly IHealthCheckService healthCheckService;
private readonly ITradingService tradingService;
private readonly IWebService webService;
private readonly IBacktestingService backtestingService;
public CoreService(ILoggingService loggingService, ITasksService tasksService, INotificationService notificationService, IHealthCheckService healthCheckService, ITradingService tradingService, IWebService webService, IBacktestingService backtestingService)
{
this.loggingService = loggingService;
this.tasksService = tasksService;
this.notificationService = notificationService;
this.healthCheckService = healthCheckService;
this.tradingService = tradingService;
this.webService = webService;
this.backtestingService = backtestingService;
// Log unhandled exceptions
AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
tasksService.SetUnhandledExceptionHandler(OnUnhandledException);
// Set decimal separator to a dot for all cultures
var cultureInfo = new CultureInfo(CultureInfo.CurrentCulture.Name);
cultureInfo.NumberFormat.NumberDecimalSeparator = ".";
CultureInfo.DefaultThreadCurrentCulture = cultureInfo;
CultureInfo.DefaultThreadCurrentUICulture = cultureInfo;
Version = GetType().Assembly.GetCustomAttribute().Version + VersionType;
}
public void Start()
{
loggingService.Info($"Start Core service (Version: {Version})...");
if (backtestingService.Config.Enabled)
{
backtestingService.Start();
}
if (Config.HealthCheckInterval > 0 && (!backtestingService.Config.Enabled || !backtestingService.Config.Replay))
{
healthCheckService.Start();
}
if (tradingService.Config.Enabled)
{
tradingService.Start();
}
if (notificationService.Config.Enabled)
{
notificationService.Start();
}
if (webService.Config.Enabled)
{
webService.Start();
}
ThreadPool.QueueUserWorkItem((state) =>
{
Thread.Sleep(2000);
Started?.Invoke();
tasksService.StartAllTasks();
});
loggingService.Info("Core service started");
notificationService.Notify($"IntelliTrader started");
}
public void Stop()
{
notificationService.Notify("IntelliTrader stopped");
loggingService.Info("Stop Core service...");
if (tradingService.Config.Enabled)
{
tradingService.Stop();
}
if (notificationService.Config.Enabled)
{
notificationService.Stop();
}
if (webService.Config.Enabled)
{
webService.Stop();
}
if (Config.HealthCheckInterval > 0 && (!backtestingService.Config.Enabled || !backtestingService.Config.Replay))
{
healthCheckService.Stop();
}
if (backtestingService.Config.Enabled)
{
backtestingService.Stop();
}
tasksService.StopAllTasks();
tasksService.RemoveAllTasks();
loggingService.Info("Core service stopped");
}
public void Restart()
{
notificationService.Notify("IntelliTrader restarting...");
loggingService.Info("Restart Core service...");
Task.Run(() => Stop()).Wait(TimeSpan.FromSeconds(20));
Start();
}
private void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
string message = "Unhandled exception occured";
if (e.ExceptionObject != null)
{
message = $"{message} - {e.ExceptionObject}";
}
try
{
loggingService.Error(message);
notificationService.Notify(message);
} catch { }
}
}
}
================================================
FILE: IntelliTrader.Core/Services/HealthCheckService.cs
================================================
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
namespace IntelliTrader.Core
{
internal class HealthCheckService : IHealthCheckService
{
private readonly ILoggingService loggingService;
private readonly INotificationService notificationService;
private readonly ITasksService tasksService;
private readonly ConcurrentDictionary healthChecks = new ConcurrentDictionary();
private HealthCheckTimedTask healthCheckTimedTask;
public HealthCheckService(ILoggingService loggingService, INotificationService notificationService, ITasksService tasksService)
{
this.loggingService = loggingService;
this.notificationService = notificationService;
this.tasksService = tasksService;
}
public void Start()
{
loggingService.Info($"Start Health Check service...");
healthCheckTimedTask = tasksService.AddTask(
name: nameof(HealthCheckTimedTask),
task: new HealthCheckTimedTask(loggingService, notificationService, this, Application.Resolve(), Application.Resolve()),
interval: Application.Resolve().Config.HealthCheckInterval * 1000 / Application.Speed,
startDelay: Constants.TaskDelays.HighDelay,
startTask: false,
runNow: false,
skipIteration: 0);
loggingService.Info("Health Check service started");
}
public void Stop()
{
loggingService.Info($"Stop Health Check service...");
tasksService.RemoveTask(nameof(HealthCheckTimedTask), stopTask: true);
loggingService.Info("Health Check service stopped");
}
public void UpdateHealthCheck(string name, string message = null, bool failed = false)
{
if (!healthChecks.TryGetValue(name, out HealthCheck existingHealthCheck))
{
healthChecks.TryAdd(name, new HealthCheck
{
Name = name,
Message = message,
LastUpdated = DateTimeOffset.Now,
Failed = failed
});
}
else
{
healthChecks[name].Message = message;
healthChecks[name].LastUpdated = DateTimeOffset.Now;
healthChecks[name].Failed = failed;
}
}
public void RemoveHealthCheck(string name)
{
healthChecks.TryRemove(name, out HealthCheck healthCheck);
}
public IEnumerable GetHealthChecks()
{
foreach (var kvp in healthChecks)
{
yield return kvp.Value;
}
}
}
}
================================================
FILE: IntelliTrader.Core/Services/LoggingService.cs
================================================
using Microsoft.Extensions.Configuration;
using Serilog;
using Serilog.Core;
using Serilog.Events;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace IntelliTrader.Core
{
internal class LoggingService : ConfigrableServiceBase, ILoggingService
{
private int LOG_ENTRIES_MAX_LENGTH = 50000;
public override string ServiceName => Constants.ServiceNames.LoggingService;
private Logger logger;
private StringWriter writer;
private StringBuilder writerStringBuilder;
private string logsPath;
private readonly object syncRoot = new object();
public LoggingService()
{
if (Config.Enabled)
{
logger = CreateLogger();
}
}
public void Verbose(string message, Exception exception = null)
{
lock (syncRoot)
{
if (Config.Enabled)
{
logger.Verbose(exception, message);
CleanUpOldLogEntries();
}
}
}
public void Verbose(string message, params object[] propertyValues)
{
lock (syncRoot)
{
if (Config.Enabled)
{
logger.Verbose(message, propertyValues);
CleanUpOldLogEntries();
}
}
}
public void Debug(string message, Exception exception = null)
{
lock (syncRoot)
{
if (Config.Enabled)
{
logger.Debug(exception, message);
CleanUpOldLogEntries();
}
}
}
public void Debug(string message, params object[] propertyValues)
{
lock (syncRoot)
{
if (Config.Enabled)
{
logger.Debug(message, propertyValues);
CleanUpOldLogEntries();
}
}
}
public void Info(string message, Exception exception = null)
{
lock (syncRoot)
{
if (Config.Enabled)
{
logger.Information(exception, message);
CleanUpOldLogEntries();
}
}
}
public void Info(string message, params object[] propertyValues)
{
lock (syncRoot)
{
if (Config.Enabled)
{
logger.Information(message, propertyValues);
CleanUpOldLogEntries();
}
}
}
public void Warning(string message, Exception exception = null)
{
lock (syncRoot)
{
if (Config.Enabled)
{
logger.Warning(exception, message);
CleanUpOldLogEntries();
}
}
}
public void Warning(string message, params object[] propertyValues)
{
lock (syncRoot)
{
if (Config.Enabled)
{
logger.Warning(message, propertyValues);
CleanUpOldLogEntries();
}
}
}
public void Error(string message, Exception exception = null)
{
lock (syncRoot)
{
if (Config.Enabled)
{
logger.Error(exception, message);
CleanUpOldLogEntries();
}
}
}
public void Error(string message, params object[] propertyValues)
{
lock (syncRoot)
{
if (Config.Enabled)
{
logger.Error(message, propertyValues);
CleanUpOldLogEntries();
}
}
}
public void Fatal(string message, Exception exception = null)
{
lock (syncRoot)
{
if (Config.Enabled)
{
logger.Fatal(exception, message);
CleanUpOldLogEntries();
}
}
}
public void Fatal(string message, params object[] propertyValues)
{
lock (syncRoot)
{
if (Config.Enabled)
{
logger.Fatal(message, propertyValues);
CleanUpOldLogEntries();
}
}
}
public void DeleteAllLogs()
{
lock(syncRoot)
{
logger.Dispose();
Directory.Delete(Path.Combine(Directory.GetCurrentDirectory(), logsPath), true);
logger = CreateLogger();
}
}
public string[] GetLogEntries()
{
lock (syncRoot)
{
if (writer != null)
{
writer.Flush();
return writer.GetStringBuilder().ToString().Split(new string[] { writer.NewLine }, StringSplitOptions.RemoveEmptyEntries);
}
else
{
return new string[0];
}
}
}
protected override void OnConfigReloaded()
{
lock (syncRoot)
{
logger = CreateLogger();
}
}
private Logger CreateLogger()
{
lock (syncRoot)
{
string outputTemplate = GetConfigValue("outputTemplate", RawConfig.GetChildren());
string filterExpression = GetConfigValue("expression", RawConfig.GetChildren());
string pathFormat = GetConfigValue("pathFormat", RawConfig.GetChildren());
logsPath = Path.GetDirectoryName(pathFormat);
writerStringBuilder = new StringBuilder();
writer = new StringWriter(writerStringBuilder);
return new LoggerConfiguration()
.ReadFrom.ConfigurationSection(RawConfig)
.WriteTo.Logger(config => config.WriteTo.Memory(writer, LogEventLevel.Information, outputTemplate).Filter.ByIncludingOnly(filterExpression))
.CreateLogger();
}
}
private void CleanUpOldLogEntries()
{
lock (syncRoot)
{
if (writerStringBuilder.Length > LOG_ENTRIES_MAX_LENGTH)
{
writerStringBuilder.Remove(0, writerStringBuilder.Length - LOG_ENTRIES_MAX_LENGTH);
}
}
}
private string GetConfigValue(string key, IEnumerable sections)
{
foreach (var section in sections)
{
if (section.Key == key)
{
return section.Value;
}
else
{
string value = GetConfigValue(key, section.GetChildren());
if (value != null)
{
return value;
}
}
}
return null;
}
}
}
================================================
FILE: IntelliTrader.Core/Services/NotificationService.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
using Telegram.Bot;
using Telegram.Bot.Types;
using Telegram.Bot.Types.Enums;
namespace IntelliTrader.Core
{
internal class NotificationService : ConfigrableServiceBase, INotificationService
{
public override string ServiceName => Constants.ServiceNames.NotificationService;
INotificationConfig INotificationService.Config => Config;
private readonly ILoggingService loggingService;
// Telegram
private TelegramBotClient telegramBotClient;
private ChatId telegramChatId;
public NotificationService(ILoggingService loggingService)
{
this.loggingService = loggingService;
}
public void Start()
{
try
{
loggingService.Info("Start Notification service...");
if (Config.TelegramEnabled)
{
telegramBotClient = new TelegramBotClient(Config.TelegramBotToken);
var me = telegramBotClient.GetMeAsync().Result;
telegramChatId = new ChatId(Config.TelegramChatId);
}
loggingService.Info("Notification service started");
}
catch (Exception ex)
{
loggingService.Error("Unable to start Notification service", ex);
Config.Enabled = false;
}
}
public void Stop()
{
loggingService.Info("Stop Notification service...");
if (Config.TelegramEnabled)
{
telegramBotClient = null;
}
loggingService.Info("Notification service stopped");
}
public void Notify(string message)
{
if (Config.Enabled)
{
if (Config.TelegramEnabled)
{
try
{
var instanceName = Application.Resolve().Config.InstanceName;
telegramBotClient.SendTextMessageAsync(telegramChatId, $"({instanceName}) {message}", ParseMode.Default, false, !Config.TelegramAlertsEnabled);
}
catch (Exception ex)
{
loggingService.Error("Unable to send Telegram message", ex);
}
}
}
}
protected override void OnConfigReloaded()
{
Stop();
Start();
}
}
}
================================================
FILE: IntelliTrader.Core/Services/TasksService.cs
================================================
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace IntelliTrader.Core
{
internal class TasksService : ITasksService
{
private ConcurrentDictionary tasks = new ConcurrentDictionary();
private Stopwatch syncStopSwatch = new Stopwatch();
private UnhandledExceptionEventHandler exceptionHandler;
public T AddTask(string name, T task, double interval, double startDelay = 0, bool startTask = true, bool runNow = false, int skipIteration = 0)
where T : ITimedTask
{
tasks[name] = task;
task.Interval = interval;
task.StartDelay = startDelay;
task.Stopwatch = syncStopSwatch;
task.SkipIteration = skipIteration;
if (exceptionHandler != null)
{
task.UnhandledException += exceptionHandler;
}
if (startTask)
{
task.Start();
}
if (runNow)
{
task.RunNow();
}
return task;
}
public void RemoveTask(string name, bool stopTask = true)
{
if (tasks.TryRemove(name, out ITimedTask task))
{
if (stopTask)
{
task.Stop();
}
if (exceptionHandler != null)
{
task.UnhandledException -= exceptionHandler;
}
task.Stopwatch = null;
}
}
public void StartAllTasks()
{
foreach (var task in tasks.Values)
{
task.Start();
}
}
public void StopAllTasks()
{
foreach (var task in tasks.Values)
{
task.Stop();
}
syncStopSwatch.Reset();
}
public void RemoveAllTasks()
{
foreach (var taskName in tasks.Keys)
{
RemoveTask(taskName);
}
syncStopSwatch.Reset();
}
public ITimedTask GetTask(string name)
{
if (tasks.TryGetValue(name, out ITimedTask task))
{
return task;
}
else
{
return null;
}
}
public T GetTask(string name)
{
return (T)GetTask(name);
}
public IEnumerable> GetAllTasks()
{
return tasks.AsEnumerable();
}
public void SetUnhandledExceptionHandler(UnhandledExceptionEventHandler handler)
{
exceptionHandler = handler;
}
}
}
================================================
FILE: IntelliTrader.Core/TimedTasks/HealthCheckTimedTask.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
namespace IntelliTrader.Core
{
internal class HealthCheckTimedTask : HighResolutionTimedTask
{
private readonly ILoggingService loggingService;
private readonly INotificationService notificationService;
private readonly IHealthCheckService healthCheckService;
private readonly ICoreService coreService;
private readonly ITradingService tradingService;
private int healthCheckFailures = 0;
public HealthCheckTimedTask(ILoggingService loggingService, INotificationService notificationService, IHealthCheckService healthCheckService, ICoreService coreService, ITradingService tradingService)
{
this.loggingService = loggingService;
this.notificationService = notificationService;
this.healthCheckService = healthCheckService;
this.coreService = coreService;
this.tradingService = tradingService;
}
protected override void Run()
{
if (coreService.Config.HealthCheckEnabled)
{
bool healthCheckFailed = false;
loggingService.Info("Health check results:");
foreach (var healthCheck in healthCheckService.GetHealthChecks().OrderBy(c => c.Name))
{
var elapsedSinceLastUpdate = (DateTimeOffset.Now - healthCheck.LastUpdated).TotalSeconds;
bool healthCheckTimeout = coreService.Config.HealthCheckSuspendTradingTimeout > 0 && elapsedSinceLastUpdate > coreService.Config.HealthCheckSuspendTradingTimeout;
string indicator = (healthCheck.Failed || healthCheckTimeout) ? "[-]" : "[+]";
if (healthCheck.Message != null)
{
loggingService.Info($" {indicator} ({healthCheck.LastUpdated:HH:mm:ss}) {healthCheck.Name} - {healthCheck.Message}");
}
else
{
loggingService.Info($" {indicator} ({healthCheck.LastUpdated:HH:mm:ss}) {healthCheck.Name}");
}
if (healthCheck.Failed || healthCheckTimeout)
{
healthCheckFailed = true;
}
}
if (healthCheckFailed)
{
healthCheckFailures++;
}
else
{
healthCheckFailures = 0;
}
if (healthCheckFailed && coreService.Config.HealthCheckFailuresToRestartServices > 0 && healthCheckFailures >= coreService.Config.HealthCheckFailuresToRestartServices)
{
coreService.Restart();
}
else
{
if (healthCheckFailed)
{
loggingService.Info($"Health check failed ({healthCheckFailures})");
notificationService.Notify($"Health check failed ({healthCheckFailures})");
if (!tradingService.IsTradingSuspended)
{
healthCheckService.RemoveHealthCheck(Constants.HealthChecks.TradingPairsProcessed);
healthCheckService.RemoveHealthCheck(Constants.HealthChecks.TradingRulesProcessed);
healthCheckService.RemoveHealthCheck(Constants.HealthChecks.SignalRulesProcessed);
tradingService.SuspendTrading();
}
}
else if (!healthCheckFailed && tradingService.IsTradingSuspended)
{
loggingService.Info("Health check passed");
notificationService.Notify("Health check passed");
tradingService.ResumeTrading();
}
}
}
}
}
}
================================================
FILE: IntelliTrader.Exchange.Base/AppModule.cs
================================================
using Autofac;
using IntelliTrader.Core;
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Exchange.Base
{
public class AppModule : Module
{
protected override void Load(ContainerBuilder builder)
{
}
}
}
================================================
FILE: IntelliTrader.Exchange.Base/IntelliTrader.Exchange.Base.csproj
================================================
netcoreapp2.1
================================================
FILE: IntelliTrader.Exchange.Base/Models/BuyOrder.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
using IntelliTrader.Core;
namespace IntelliTrader.Exchange.Base
{
public class BuyOrder : Order
{
public override OrderSide Side => OrderSide.Buy;
}
}
================================================
FILE: IntelliTrader.Exchange.Base/Models/Config/ExchangeConfig.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Exchange.Base
{
public class ExchangeConfig
{
public string KeysPath { get; set; }
public int RateLimitOccurences { get; set; }
public int RateLimitTimeframe { get; set; }
}
}
================================================
FILE: IntelliTrader.Exchange.Base/Models/Order.cs
================================================
using IntelliTrader.Core;
using System;
using System.Collections.Generic;
namespace IntelliTrader.Exchange.Base
{
public abstract class Order : IOrder
{
public abstract OrderSide Side { get; }
public OrderType Type { get; set; }
public DateTimeOffset Date { get; set; }
public string Pair { get; set; }
public decimal Amount { get; set; }
public decimal Price { get; set; }
}
}
================================================
FILE: IntelliTrader.Exchange.Base/Models/OrderDetails.cs
================================================
using IntelliTrader.Core;
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Exchange.Base
{
public class OrderDetails : IOrderDetails
{
public bool IsNormalized { get; set; }
public OrderSide Side { get; set; }
public OrderResult Result { get; set; }
public DateTimeOffset Date { get; set; }
public string OrderId { get; set; }
public string Pair { get; set; }
public string OriginalPair { get; set; }
public string Message { get; set; }
public decimal Amount { get; set; }
public decimal AmountFilled { get; set; }
public decimal Price { get; set; }
public decimal AveragePrice { get; set; }
public decimal Fees { get; set; }
public string FeesCurrency { get; set; }
public decimal Cost => AveragePrice * AmountFilled;
public OrderMetadata Metadata { get; set; } = new OrderMetadata();
}
}
================================================
FILE: IntelliTrader.Exchange.Base/Models/SellOrder.cs
================================================
using IntelliTrader.Core;
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Exchange.Base
{
public class SellOrder : Order
{
public override OrderSide Side => OrderSide.Sell;
}
}
================================================
FILE: IntelliTrader.Exchange.Base/Models/Ticker.cs
================================================
using IntelliTrader.Core;
namespace IntelliTrader.Exchange.Base
{
public class Ticker : ITicker
{
public string Pair { get; set; }
public decimal BidPrice { get; set; }
public decimal AskPrice { get; set; }
public decimal LastPrice { get; set; }
}
}
================================================
FILE: IntelliTrader.Exchange.Base/Services/ExchangeService.cs
================================================
using ExchangeSharp;
using IntelliTrader.Core;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
namespace IntelliTrader.Exchange.Base
{
public abstract class ExchangeService : ConfigrableServiceBase, IExchangeService
{
public const int SOCKET_DISPOSE_TIMEOUT_MILLISECONDS = 10000;
public const int MAX_TICKERS_AGE_TO_RECONNECT_MILLISECONDS = 60000;
public const int INITIAL_TICKERS_TIMEOUT_MILLISECONDS = 5000;
public const int INITIAL_TICKERS_RETRY_LIMIT = 4;
public override string ServiceName => Constants.ServiceNames.ExchangeService;
protected readonly ILoggingService loggingService;
protected readonly IHealthCheckService healthCheckService;
protected readonly ITasksService tasksService;
public ExchangeAPI Api { get; set; }
public ConcurrentDictionary Tickers { get; private set; }
private IDisposable socket;
private ConcurrentBag markets;
private TickersMonitorTimedTask tickersMonitorTimedTask;
private DateTimeOffset lastTickersUpdate;
private bool tickersStarted;
public ExchangeService(ILoggingService loggingService, IHealthCheckService healthCheckService, ITasksService tasksService)
{
this.loggingService = loggingService;
this.healthCheckService = healthCheckService;
this.tasksService = tasksService;
}
public virtual void Start(bool virtualTrading)
{
loggingService.Info("Start Exchange service...");
Api = InitializeApi();
if (!virtualTrading && !String.IsNullOrWhiteSpace(Config.KeysPath))
{
if (File.Exists(Config.KeysPath))
{
loggingService.Info("Load keys from encrypted file...");
Api.LoadAPIKeys(Config.KeysPath);
}
else
{
throw new FileNotFoundException("Keys file not found");
}
}
loggingService.Info("Get initial ticker values...");
IEnumerable> exchangeTickers = null;
for (int retry = 0; retry < INITIAL_TICKERS_RETRY_LIMIT; retry++)
{
Task.Run(() => exchangeTickers = Api.GetTickers()).Wait(TimeSpan.FromMilliseconds(INITIAL_TICKERS_TIMEOUT_MILLISECONDS));
if (exchangeTickers != null) break;
}
if (exchangeTickers != null)
{
Tickers = new ConcurrentDictionary(exchangeTickers.Select(t => new KeyValuePair(t.Key, new Ticker
{
Pair = t.Key,
AskPrice = t.Value.Ask,
BidPrice = t.Value.Bid,
LastPrice = t.Value.Last
})));
markets = new ConcurrentBag(Tickers.Keys.Select(pair => GetPairMarket(pair)).Distinct().ToList());
lastTickersUpdate = DateTimeOffset.Now;
healthCheckService.UpdateHealthCheck(Constants.HealthChecks.TickersUpdated, $"Updates: {Tickers.Count}");
}
else if (Tickers != null)
{
loggingService.Error("Unable to get initial ticker values");
}
else
{
throw new Exception("Unable to get initial ticker values");
}
ConnectTickersWebsocket();
loggingService.Info("Exchange service started");
}
public virtual void Stop()
{
loggingService.Info("Stop Exchange service...");
DisconnectTickersWebsocket();
lastTickersUpdate = DateTimeOffset.MinValue;
healthCheckService.RemoveHealthCheck(Constants.HealthChecks.TickersUpdated);
loggingService.Info("Exchange service stopped");
}
protected abstract ExchangeAPI InitializeApi();
public abstract IOrderDetails PlaceOrder(IOrder order);
public virtual decimal ClampOrderAmount(string pair, decimal amount)
{
ExchangeMarket market = Api.GetExchangeMarketFromCache(pair);
return market == null ? amount : CryptoUtility.ClampDecimal(market.MinTradeSize, market.MaxTradeSize, market.QuantityStepSize, amount);
}
public virtual decimal ClampOrderPrice(string pair, decimal price)
{
ExchangeMarket market = Api.GetExchangeMarketFromCache(pair);
return market == null ? price : CryptoUtility.ClampDecimal(market.MinPrice, market.MaxPrice, market.PriceStepSize, price);
}
public void ConnectTickersWebsocket()
{
try
{
loggingService.Info("Connect to Exchange tickers...");
socket = Api.GetTickersWebSocket(OnTickersUpdated);
loggingService.Info("Connected to Exchange tickers");
tickersMonitorTimedTask = tasksService.AddTask(
name: nameof(TickersMonitorTimedTask),
task: new TickersMonitorTimedTask(loggingService, this),
interval: MAX_TICKERS_AGE_TO_RECONNECT_MILLISECONDS / 2,
startDelay: Constants.TaskDelays.ZeroDelay,
startTask: tickersStarted,
runNow: false,
skipIteration: 0);
}
catch (Exception ex)
{
loggingService.Error("Unable to connect to Exchange tickers", ex);
}
}
public void DisconnectTickersWebsocket()
{
try
{
tasksService.RemoveTask(nameof(TickersMonitorTimedTask), stopTask: true);
loggingService.Info("Disconnect from Exchange tickers...");
// Give Dispose 10 seconds to complete and then time out if not
Task.Run(() => socket.Dispose()).Wait(TimeSpan.FromMilliseconds(SOCKET_DISPOSE_TIMEOUT_MILLISECONDS));
socket = null;
loggingService.Info("Disconnected from Exchange tickers");
}
catch (Exception ex)
{
loggingService.Error("Unable to disconnect from Exchange tickers", ex);
}
}
public virtual IEnumerable GetTickers()
{
return Tickers.Values;
}
public virtual IEnumerable GetMarkets()
{
return markets.AsEnumerable();
}
public virtual IEnumerable GetMarketPairs(string market)
{
return Tickers.Keys.Where(t => t.EndsWith(market));
}
public virtual Dictionary GetAvailableAmounts()
{
return Api.GetAmountsAvailableToTradeAsync().Result;
}
public abstract IEnumerable GetTrades(string pair);
public virtual decimal GetPrice(string pair, TradePriceType priceType)
{
if (Tickers.TryGetValue(pair, out Ticker ticker))
{
if (priceType == TradePriceType.Ask)
{
return ticker.AskPrice;
}
else if (priceType == TradePriceType.Bid)
{
return ticker.BidPrice;
}
else
{
return ticker.LastPrice;
}
}
else
{
return 0;
}
}
public virtual decimal GetPriceSpread(string pair)
{
if (Tickers.TryGetValue(pair, out Ticker ticker))
{
return Utils.CalculatePercentage(ticker.BidPrice, ticker.AskPrice);
}
else
{
return 0;
}
}
public abstract Arbitrage GetArbitrage(string pair, string tradingMarket, List arbitrageMarkets = null, ArbitrageType? arbitrageType = null);
public abstract string GetArbitrageMarketPair(ArbitrageMarket arbitrageMarket);
public virtual string GetPairMarket(string pair)
{
return Api.ExchangeSymbolToGlobalSymbol(pair).Split('-')[0];
}
public virtual string ChangeMarket(string pair, string market)
{
if (!pair.StartsWith(market) && !pair.EndsWith(market))
{
string currentMarket = GetPairMarket(pair);
return pair.Substring(0, pair.Length - currentMarket.Length) + market;
}
return pair;
}
public virtual decimal ConvertPrice(string pair, decimal price, string market, TradePriceType priceType)
{
string pairMarket = GetPairMarket(pair);
if (pairMarket == Constants.Markets.USDT)
{
string marketPair = market + pairMarket;
return price / GetPrice(marketPair, priceType);
}
else
{
string marketPair = pairMarket + market;
return GetPrice(marketPair, priceType) * price;
}
}
public TimeSpan GetTimeElapsedSinceLastTickersUpdate()
{
return DateTimeOffset.Now - lastTickersUpdate;
}
private void OnTickersUpdated(IReadOnlyCollection> updatedTickers)
{
if (!tickersStarted)
{
loggingService.Info("Ticker updates are working, good!");
tickersStarted = true;
}
healthCheckService.UpdateHealthCheck(Constants.HealthChecks.TickersUpdated, $"Updates: {updatedTickers.Count}");
lastTickersUpdate = DateTimeOffset.Now;
foreach (var update in updatedTickers)
{
if (Tickers.TryGetValue(update.Key, out Ticker ticker))
{
ticker.AskPrice = update.Value.Ask;
ticker.BidPrice = update.Value.Bid;
ticker.LastPrice = update.Value.Last;
}
else
{
Tickers.TryAdd(update.Key, new Ticker
{
Pair = update.Key,
AskPrice = update.Value.Ask,
BidPrice = update.Value.Bid,
LastPrice = update.Value.Last
});
var market = GetPairMarket(update.Key);
if (!markets.Contains(market))
{
markets.Add(market);
}
}
}
}
}
}
================================================
FILE: IntelliTrader.Exchange.Base/TimedTasks/TickersMonitorTimedTask.cs
================================================
using IntelliTrader.Core;
using IntelliTrader.Exchange.Base;
namespace IntelliTrader.Exchange
{
internal class TickersMonitorTimedTask : HighResolutionTimedTask
{
private readonly ILoggingService loggingService;
private readonly IExchangeService exchangeService;
public TickersMonitorTimedTask(ILoggingService loggingService, IExchangeService exchangeService)
{
this.loggingService = loggingService;
this.exchangeService = exchangeService;
}
protected override void Run()
{
if (exchangeService.GetTimeElapsedSinceLastTickersUpdate().TotalMilliseconds > ExchangeService.MAX_TICKERS_AGE_TO_RECONNECT_MILLISECONDS)
{
loggingService.Info("Exchange max tickers age reached, reconnecting...");
exchangeService.DisconnectTickersWebsocket();
exchangeService.ConnectTickersWebsocket();
}
}
}
}
================================================
FILE: IntelliTrader.Exchange.Binance/AppModule.cs
================================================
using Autofac;
using IntelliTrader.Core;
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Exchange.Binance
{
public class AppModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType().Named("Binance").As().Named("ExchangeBinance").SingleInstance().PreserveExistingDefaults();
}
}
}
================================================
FILE: IntelliTrader.Exchange.Binance/BinanceExchangeService.cs
================================================
using ExchangeSharp;
using IntelliTrader.Core;
using IntelliTrader.Exchange.Base;
using System;
using System.Linq;
using System.Collections.Generic;
namespace IntelliTrader.Exchange.Binance
{
internal class BinanceExchangeService : ExchangeService
{
public BinanceExchangeService(ILoggingService loggingService, IHealthCheckService healthCheckService, ITasksService tasksService) :
base(loggingService, healthCheckService, tasksService)
{
}
protected override ExchangeAPI InitializeApi()
{
var binanceApi = new ExchangeBinanceAPI
{
RateLimit = new RateGate(Config.RateLimitOccurences, TimeSpan.FromSeconds(Config.RateLimitTimeframe))
};
return binanceApi;
}
public override IOrderDetails PlaceOrder(IOrder order)
{
var result = Api.PlaceOrderAsync(new ExchangeOrderRequest
{
OrderType = (ExchangeSharp.OrderType)(int)order.Type,
IsBuy = order.Side == OrderSide.Buy,
Amount = order.Amount,
Price = order.Price,
Symbol = order.Pair
}).Result;
return new OrderDetails
{
Side = result.IsBuy ? OrderSide.Buy : OrderSide.Sell,
Result = (OrderResult)(int)result.Result,
Date = result.OrderDate,
OrderId = result.OrderId,
Pair = result.Symbol,
Message = result.Message,
Amount = result.Amount,
AmountFilled = result.AmountFilled,
Price = result.Price,
AveragePrice = result.AveragePrice,
Fees = result.Fees,
FeesCurrency = result.FeesCurrency
};
}
public override IEnumerable GetTrades(string pair)
{
var myTrades = new List();
var results = ((ExchangeBinanceAPI)Api).GetMyTrades(pair);
foreach (var result in results)
{
myTrades.Add(new OrderDetails
{
Side = result.IsBuy ? OrderSide.Buy : OrderSide.Sell,
Result = (OrderResult)(int)result.Result,
Date = result.OrderDate,
OrderId = result.OrderId,
Pair = result.Symbol,
Message = result.Message,
Amount = result.Amount,
AmountFilled = result.AmountFilled,
Price = result.Price,
AveragePrice = result.AveragePrice,
Fees = result.Fees,
FeesCurrency = result.FeesCurrency
});
}
return myTrades;
}
public override Arbitrage GetArbitrage(string pair, string tradingMarket, List arbitrageMarkets = null, ArbitrageType? arbitrageType = null)
{
if (arbitrageMarkets == null || !arbitrageMarkets.Any())
{
arbitrageMarkets = new List { ArbitrageMarket.ETH, ArbitrageMarket.BNB, ArbitrageMarket.USDT };
}
Arbitrage arbitrage = new Arbitrage
{
Market = arbitrageMarkets.First(),
Type = arbitrageType ?? ArbitrageType.Direct
};
try
{
if (tradingMarket == Constants.Markets.BTC)
{
foreach (var market in arbitrageMarkets)
{
string marketPair = ChangeMarket(pair, market.ToString());
string arbitragePair = GetArbitrageMarketPair(market);
if (marketPair != pair &&
Tickers.TryGetValue(pair, out Ticker pairTicker) &&
Tickers.TryGetValue(marketPair, out Ticker marketTicker) &&
Tickers.TryGetValue(arbitragePair, out Ticker arbitrageTicker))
{
decimal directArbitragePercentage = 0;
decimal reverseArbitragePercentage = 0;
if (market == ArbitrageMarket.ETH)
{
directArbitragePercentage = (1 / pairTicker.AskPrice * marketTicker.BidPrice * arbitrageTicker.BidPrice - 1) * 100;
reverseArbitragePercentage = (1 / arbitrageTicker.AskPrice / marketTicker.AskPrice * pairTicker.BidPrice - 1) * 100;
}
else if (market == ArbitrageMarket.BNB)
{
directArbitragePercentage = (1 / pairTicker.AskPrice * marketTicker.BidPrice * arbitrageTicker.BidPrice - 1) * 100;
reverseArbitragePercentage = (1 / arbitrageTicker.AskPrice / marketTicker.AskPrice * pairTicker.BidPrice - 1) * 100;
}
else if (market == ArbitrageMarket.USDT)
{
directArbitragePercentage = (1 / pairTicker.AskPrice * marketTicker.BidPrice / arbitrageTicker.AskPrice - 1) * 100;
reverseArbitragePercentage = (arbitrageTicker.BidPrice / marketTicker.AskPrice * pairTicker.BidPrice - 1) * 100;
}
if ((directArbitragePercentage > arbitrage.Percentage || !arbitrage.IsAssigned) && (arbitrageType == null || arbitrageType == ArbitrageType.Direct))
{
arbitrage.IsAssigned = true;
arbitrage.Market = market;
arbitrage.Type = ArbitrageType.Direct;
arbitrage.Percentage = directArbitragePercentage;
}
if ((reverseArbitragePercentage > arbitrage.Percentage || !arbitrage.IsAssigned) && (arbitrageType == null || arbitrageType == ArbitrageType.Reverse))
{
arbitrage.IsAssigned = true;
arbitrage.Market = market;
arbitrage.Type = ArbitrageType.Reverse;
arbitrage.Percentage = reverseArbitragePercentage;
}
}
}
}
}
catch { }
return arbitrage;
}
public override string GetArbitrageMarketPair(ArbitrageMarket arbitrageMarket)
{
if (arbitrageMarket == ArbitrageMarket.ETH)
{
return Constants.Markets.ETH + Constants.Markets.BTC;
}
else if (arbitrageMarket == ArbitrageMarket.BNB)
{
return Constants.Markets.BNB + Constants.Markets.BTC;
}
else if (arbitrageMarket == ArbitrageMarket.USDT)
{
return Constants.Markets.BTC + Constants.Markets.USDT;
}
else
{
throw new NotSupportedException($"Unsupported arbitrage market: {arbitrageMarket}");
}
}
}
}
================================================
FILE: IntelliTrader.Exchange.Binance/IntelliTrader.Exchange.Binance.csproj
================================================
netcoreapp2.1
================================================
FILE: IntelliTrader.Launcher/IntelliTrader.Launcher.csproj
================================================
Debug
AnyCPU
{B458FDA9-0E55-40BB-86C9-711F1FA18CDF}
WinExe
IntelliTrader.Launcher
IntelliTrader
v4.0
512
Client
publish\
true
Disk
false
Foreground
7
Days
false
false
true
0
1.0.0.%2a
false
false
true
AnyCPU
false
none
false
..\IntelliTrader\
DEBUG;TRACE
prompt
4
false
AnyCPU
none
true
..\IntelliTrader\
TRACE
prompt
4
false
IntelliTrader.ico
IntelliTrader.Launcher.Program
true
False
.NET Framework 3.5 SP1
true
================================================
FILE: IntelliTrader.Launcher/Program.cs
================================================
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
namespace IntelliTrader.Launcher
{
class Program
{
const int PROCESS_WAIT_TIMEOUT = 1;
[DllImport("user32.dll")]
static extern int SetWindowText(IntPtr hWnd, string text);
static void Main(string[] args)
{
string instanceName = args.Length == 1 ? args[0] : null;
string processFileName = $"{nameof(IntelliTrader)}.dll";
string processPath = Directory.EnumerateFiles(Directory.GetCurrentDirectory(), processFileName, SearchOption.AllDirectories).FirstOrDefault();
if (!string.IsNullOrWhiteSpace(processPath))
{
Process process = new Process();
try
{
process.StartInfo.FileName = "dotnet";
process.StartInfo.Arguments = $"\"{processPath}\"";
process.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
process.Start();
Thread.Sleep(TimeSpan.FromSeconds(PROCESS_WAIT_TIMEOUT));
if (process.HasExited)
{
MessageBox.Show($"Unable to start IntelliTrader.{Environment.NewLine}{Environment.NewLine}Please make sure you have the latest .NET Core Runtime installed from{Environment.NewLine}https://www.microsoft.com/net/download", nameof(IntelliTrader));
return;
}
SpinWait.SpinUntil(() =>
{
return process.MainWindowHandle != IntPtr.Zero;
}, TimeSpan.FromSeconds(PROCESS_WAIT_TIMEOUT));
}
catch (Exception ex)
{
MessageBox.Show($"Error: {ex.Message}{Environment.NewLine}{Environment.NewLine}Please download the latest .NET Core Runtime from{Environment.NewLine}https://www.microsoft.com/net/download", nameof(IntelliTrader));
}
try
{
if (!String.IsNullOrWhiteSpace(instanceName))
{
SetWindowText(process.MainWindowHandle, $"{nameof(IntelliTrader)} - {instanceName}");
}
else
{
SetWindowText(process.MainWindowHandle, $"{nameof(IntelliTrader)}");
}
}
catch { }
}
else
{
MessageBox.Show($"{processFileName} not found", nameof(IntelliTrader));
}
}
}
}
================================================
FILE: IntelliTrader.Launcher/Properties/AssemblyInfo.cs
================================================
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("IntelliTrader.Launcher")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("IntelliTrader.Launcher")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("b458fda9-0e55-40bb-86c9-711f1fa18cdf")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
================================================
FILE: IntelliTrader.Rules/AppModule.cs
================================================
using Autofac;
using IntelliTrader.Core;
using System;
namespace IntelliTrader.Rules
{
public class AppModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType().As().As().Named(Constants.ServiceNames.RulesService).SingleInstance();
}
}
}
================================================
FILE: IntelliTrader.Rules/Config/RulesConfig.cs
================================================
using IntelliTrader.Core;
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Rules
{
internal class RulesConfig : IRulesConfig
{
public IEnumerable Modules { get; set; }
IEnumerable IRulesConfig.Modules => Modules;
}
}
================================================
FILE: IntelliTrader.Rules/IntelliTrader.Rules.csproj
================================================
netcoreapp2.1
================================================
FILE: IntelliTrader.Rules/Models/ModuleRules.cs
================================================
using IntelliTrader.Core;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Rules
{
internal class ModuleRules : IModuleRules
{
public string Module { get; set; }
public IConfigurationSection Configuration { get; set; }
public IEnumerable Entries { get; set; }
IEnumerable IModuleRules.Entries => Entries;
public T GetConfiguration()
{
return Configuration.Get();
}
}
}
================================================
FILE: IntelliTrader.Rules/Models/Rule.cs
================================================
using IntelliTrader.Core;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Rules
{
internal class Rule : IRule
{
public bool Enabled { get; set; }
public string Name { get; set; }
public RuleAction Action { get; set; }
public IEnumerable Conditions { get; set; }
public RuleTrailing Trailing { get; set; }
public IConfigurationSection Modifiers { get; set; }
IEnumerable IRule.Conditions => Conditions;
IRuleTrailing IRule.Trailing => Trailing;
private object typedModifiersCached;
public T GetModifiers()
{
if (typedModifiersCached == null)
{
typedModifiersCached = Modifiers.Get();
}
return (T)typedModifiersCached;
}
}
}
================================================
FILE: IntelliTrader.Rules/Models/RuleCondition.cs
================================================
using IntelliTrader.Core;
using System.Collections.Generic;
namespace IntelliTrader.Rules
{
internal class RuleCondition : IRuleCondition
{
public string Signal { get; set; }
public decimal? MinPrice { get; set; }
public decimal? MaxPrice { get; set; }
public decimal? MinSpread { get; set; }
public decimal? MaxSpread { get; set; }
public long? MinVolume { get; set; }
public long? MaxVolume { get; set; }
public double? MinVolumeChange { get; set; }
public double? MaxVolumeChange { get; set; }
public decimal? MinPriceChange { get; set; }
public decimal? MaxPriceChange { get; set; }
public double? MinRating { get; set; }
public double? MaxRating { get; set; }
public double? MinRatingChange { get; set; }
public double? MaxRatingChange { get; set; }
public double? MinVolatility { get; set; }
public double? MaxVolatility { get; set; }
public double? MinGlobalRating { get; set; }
public double? MaxGlobalRating { get; set; }
public decimal? MinArbitrage { get; set; }
public decimal? MaxArbitrage { get; set; }
public ArbitrageMarket? ArbitrageMarket { get; set; }
public ArbitrageType? ArbitrageType { get; set; }
public List Pairs { get; set; }
public List NotPairs { get; set; }
// Trading pair specific conditions
public double? MinAge { get; set; }
public double? MaxAge { get; set; }
public double? MinLastBuyAge { get; set; }
public double? MaxLastBuyAge { get; set; }
public decimal? MinMargin { get; set; }
public decimal? MaxMargin { get; set; }
public decimal? MinMarginChange { get; set; }
public decimal? MaxMarginChange { get; set; }
public decimal? MinAmount { get; set; }
public decimal? MaxAmount { get; set; }
public decimal? MinCost { get; set; }
public decimal? MaxCost { get; set; }
public int? MinDCALevel { get; set; }
public int? MaxDCALevel { get; set; }
public List SignalRules { get; set; }
public List NotSignalRules { get; set; }
}
}
================================================
FILE: IntelliTrader.Rules/Models/RuleTrailing.cs
================================================
using IntelliTrader.Core;
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Rules
{
internal class RuleTrailing : IRuleTrailing
{
public bool Enabled { get; set; }
public int MinDuration { get; set; }
public int MaxDuration { get; set; }
public IEnumerable StartConditions { get; set; }
IEnumerable IRuleTrailing.StartConditions => StartConditions;
}
}
================================================
FILE: IntelliTrader.Rules/Services/RulesService.cs
================================================
using IntelliTrader.Core;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
namespace IntelliTrader.Rules
{
internal class RulesService : ConfigrableServiceBase, IRulesService
{
public override string ServiceName => Constants.ServiceNames.RulesService;
IRulesConfig IRulesService.Config => Config;
private readonly ILoggingService loggingService;
private readonly ITradingService tradingService;
private readonly List rulesChangeCallbacks = new List();
public RulesService(ILoggingService loggingService, ITradingService tradingService)
{
this.loggingService = loggingService;
this.tradingService = tradingService;
}
public IModuleRules GetRules(string module)
{
IModuleRules moduleRules = Config.Modules.FirstOrDefault(m => m.Module == module);
if (moduleRules != null)
{
return moduleRules;
}
else
{
throw new Exception($"Unable to find rules for {module}");
}
}
public bool CheckConditions(IEnumerable conditions, Dictionary signals, double? globalRating, string pair, ITradingPair tradingPair)
{
if (conditions != null)
{
foreach (var condition in conditions)
{
ISignal signal = null;
if (condition.Signal != null && signals.TryGetValue(condition.Signal, out ISignal s))
{
signal = s;
}
if (condition.MinPrice != null && (tradingService.GetPrice(pair) < condition.MinPrice) ||
condition.MaxPrice != null && (tradingService.GetPrice(pair) > condition.MaxPrice) ||
condition.MinSpread != null && (tradingService.Exchange.GetPriceSpread(pair) < condition.MinSpread) ||
condition.MaxSpread != null && (tradingService.Exchange.GetPriceSpread(pair) > condition.MaxSpread) ||
condition.MinArbitrage != null && tradingService.Exchange.GetArbitrage(pair, tradingService.Config.Market,
condition.ArbitrageMarket != null ? new List { condition.ArbitrageMarket.Value } : null, condition.ArbitrageType).Percentage < condition.MinArbitrage ||
condition.MaxArbitrage != null && tradingService.Exchange.GetArbitrage(pair, tradingService.Config.Market,
condition.ArbitrageMarket != null ? new List { condition.ArbitrageMarket.Value } : null, condition.ArbitrageType).Percentage > condition.MaxArbitrage ||
condition.MinVolume != null && (signal == null || signal.Volume == null || signal.Volume < condition.MinVolume) ||
condition.MaxVolume != null && (signal == null || signal.Volume == null || signal.Volume > condition.MaxVolume) ||
condition.MinVolumeChange != null && (signal == null || signal.VolumeChange == null || signal.VolumeChange < condition.MinVolumeChange) ||
condition.MaxVolumeChange != null && (signal == null || signal.VolumeChange == null || signal.VolumeChange > condition.MaxVolumeChange) ||
condition.MinPriceChange != null && (signal == null || signal.PriceChange == null || signal.PriceChange < condition.MinPriceChange) ||
condition.MaxPriceChange != null && (signal == null || signal.PriceChange == null || signal.PriceChange > condition.MaxPriceChange) ||
condition.MinRating != null && (signal == null || signal.Rating == null || signal.Rating < condition.MinRating) ||
condition.MaxRating != null && (signal == null || signal.Rating == null || signal.Rating > condition.MaxRating) ||
condition.MinRatingChange != null && (signal == null || signal.RatingChange == null || signal.RatingChange < condition.MinRatingChange) ||
condition.MaxRatingChange != null && (signal == null || signal.RatingChange == null || signal.RatingChange > condition.MaxRatingChange) ||
condition.MinVolatility != null && (signal == null || signal.Volatility == null || signal.Volatility < condition.MinVolatility) ||
condition.MaxVolatility != null && (signal == null || signal.Volatility == null || signal.Volatility > condition.MaxVolatility) ||
condition.MinGlobalRating != null && (globalRating == null || globalRating < condition.MinGlobalRating) ||
condition.MaxGlobalRating != null && (globalRating == null || globalRating > condition.MaxGlobalRating) ||
condition.Pairs != null && (pair == null || !condition.Pairs.Contains(pair)) ||
condition.NotPairs != null && (pair == null || condition.NotPairs.Contains(pair)) ||
condition.MinAge != null && (tradingPair == null || tradingPair.CurrentAge < condition.MinAge / Application.Speed) ||
condition.MaxAge != null && (tradingPair == null || tradingPair.CurrentAge > condition.MaxAge / Application.Speed) ||
condition.MinLastBuyAge != null && (tradingPair == null || tradingPair.LastBuyAge < condition.MinLastBuyAge / Application.Speed) ||
condition.MaxLastBuyAge != null && (tradingPair == null || tradingPair.LastBuyAge > condition.MaxLastBuyAge / Application.Speed) ||
condition.MinMargin != null && (tradingPair == null || tradingPair.CurrentMargin < condition.MinMargin) ||
condition.MaxMargin != null && (tradingPair == null || tradingPair.CurrentMargin > condition.MaxMargin) ||
condition.MinMarginChange != null && (tradingPair == null || tradingPair.Metadata.LastBuyMargin == null || (tradingPair.CurrentMargin - tradingPair.Metadata.LastBuyMargin) < condition.MinMarginChange) ||
condition.MaxMarginChange != null && (tradingPair == null || tradingPair.Metadata.LastBuyMargin == null || (tradingPair.CurrentMargin - tradingPair.Metadata.LastBuyMargin) > condition.MaxMarginChange) ||
condition.MinAmount != null && (tradingPair == null || tradingPair.Amount < condition.MinAmount) ||
condition.MaxAmount != null && (tradingPair == null || tradingPair.Amount > condition.MaxAmount) ||
condition.MinCost != null && (tradingPair == null || tradingPair.CurrentCost < condition.MinCost) ||
condition.MaxCost != null && (tradingPair == null || tradingPair.CurrentCost > condition.MaxCost) ||
condition.MinDCALevel != null && (tradingPair == null || tradingPair.DCALevel < condition.MinDCALevel) ||
condition.MaxDCALevel != null && (tradingPair == null || tradingPair.DCALevel > condition.MaxDCALevel) ||
condition.SignalRules != null && (tradingPair == null || tradingPair.Metadata.SignalRule == null || !condition.SignalRules.Contains(tradingPair.Metadata.SignalRule)) ||
condition.NotSignalRules != null && (tradingPair == null || tradingPair.Metadata.SignalRule == null || condition.NotSignalRules.Contains(tradingPair.Metadata.SignalRule)))
{
return false;
}
}
}
return true;
}
public void RegisterRulesChangeCallback(Action callback)
{
rulesChangeCallbacks.Add(callback);
}
public void UnregisterRulesChangeCallback(Action callback)
{
rulesChangeCallbacks.Remove(callback);
}
protected override void OnConfigReloaded()
{
foreach (var callback in rulesChangeCallbacks)
{
callback();
}
}
}
}
================================================
FILE: IntelliTrader.Signals.Base/AppModule.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using Autofac;
using IntelliTrader.Core;
namespace IntelliTrader.Signals.Base
{
public class AppModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType().As().As().Named(Constants.ServiceNames.SignalsService).SingleInstance().PreserveExistingDefaults();
}
}
}
================================================
FILE: IntelliTrader.Signals.Base/IntelliTrader.Signals.Base.csproj
================================================
netcoreapp2.1
================================================
FILE: IntelliTrader.Signals.Base/Interfaces/ISignaReceiver.cs
================================================
using IntelliTrader.Core;
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Signals.Base
{
public interface ISignalReceiver
{
string SignalName { get; }
void Start();
void Stop();
int GetPeriod();
IEnumerable GetSignals();
double? GetAverageRating();
}
}
================================================
FILE: IntelliTrader.Signals.Base/Models/Config/SignalsConfig.cs
================================================
using IntelliTrader.Core;
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Signals.Base
{
public class SignalsConfig : ISignalsConfig
{
public bool Enabled { get; set; }
public IEnumerable GlobalRatingSignals { get; set; }
public IEnumerable Definitions { get; set; }
IEnumerable ISignalsConfig.Definitions => Definitions;
}
}
================================================
FILE: IntelliTrader.Signals.Base/Models/Signal.cs
================================================
using IntelliTrader.Core;
namespace IntelliTrader.Signals.Base
{
public class Signal : ISignal
{
public string Name { get; set; }
public string Pair { get; set; }
public long? Volume { get; set; }
public double? VolumeChange { get; set; }
public decimal? Price { get; set; }
public decimal? PriceChange { get; set; }
public double? Rating { get; set; }
public double? RatingChange { get; set; }
public double? Volatility { get; set; }
}
}
================================================
FILE: IntelliTrader.Signals.Base/Models/SignalDefinition.cs
================================================
using IntelliTrader.Core;
using Microsoft.Extensions.Configuration;
namespace IntelliTrader.Signals.Base
{
public class SignalDefinition : ISignalDefinition
{
public string Name { get; set; }
public string Receiver { get; set; }
public IConfigurationSection Configuration { get; set; }
}
}
================================================
FILE: IntelliTrader.Signals.Base/Models/SignalRuleModifiers.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Signals.Base
{
internal class SignalRuleModifiers
{
public decimal? CostMultiplier { get; set; }
}
}
================================================
FILE: IntelliTrader.Signals.Base/Models/SignalRulesConfig.cs
================================================
using IntelliTrader.Core;
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Signals.Base
{
public class SignalRulesConfig : ISignalRulesConfig
{
public RuleProcessingMode ProcessingMode { get; set; }
public double CheckInterval { get; set; }
}
}
================================================
FILE: IntelliTrader.Signals.Base/Models/SignalTrailingInfo.cs
================================================
using IntelliTrader.Core;
using System;
using System.Collections.Generic;
using System.Text;
namespace IntelliTrader.Signals.Base
{
internal class SignalTrailingInfo : ISignalTrailingInfo
{
public IRule Rule { get; set; }
public DateTimeOffset StartTime { get; set; }
public double Duration => (DateTimeOffset.Now - StartTime).TotalSeconds;
}
}
================================================
FILE: IntelliTrader.Signals.Base/Services/SignalsService.cs
================================================
using Autofac;
using IntelliTrader.Core;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
namespace IntelliTrader.Signals.Base
{
public class SignalsService : ConfigrableServiceBase, ISignalsService
{
public override string ServiceName => Constants.ServiceNames.SignalsService;
ISignalsConfig ISignalsService.Config => Config;
public IModuleRules Rules { get; private set; }
public ISignalRulesConfig RulesConfig { get; private set; }
private readonly ILoggingService loggingService;
private readonly IHealthCheckService healthCheckService;
private readonly ITasksService tasksService;
private readonly ITradingService tradingService;
private readonly IRulesService rulesService;
private ConcurrentDictionary signalReceivers = new ConcurrentDictionary();
private SignalRulesTimedTask signalRulesTimedTask;
public SignalsService(ILoggingService loggingService, IHealthCheckService healthCheckService, ITasksService tasksService, ITradingService tradingService, IRulesService rulesService)
{
this.loggingService = loggingService;
this.healthCheckService = healthCheckService;
this.tasksService = tasksService;
this.tradingService = tradingService;
this.rulesService = rulesService;
}
public void Start()
{
loggingService.Info("Start Signals service...");
OnSignalRulesChanged();
rulesService.RegisterRulesChangeCallback(OnSignalRulesChanged);
signalReceivers.Clear();
foreach (var definition in Config.Definitions)
{
var receiver = Application.ResolveOptionalNamed(definition.Receiver,
new TypedParameter(typeof(string), definition.Name),
new TypedParameter(typeof(IConfigurationSection), definition.Configuration));
if (receiver != null)
{
if (signalReceivers.TryAdd(definition.Name, receiver))
{
receiver.Start();
}
else
{
throw new Exception($"Duplicate signal definition: {definition.Name}");
}
}
else
{
throw new Exception($"Signal receiver not found: {definition.Receiver}");
}
}
signalRulesTimedTask = tasksService.AddTask(
name: nameof(SignalRulesTimedTask),
task: new SignalRulesTimedTask(loggingService, healthCheckService, tradingService, rulesService, this),
interval: RulesConfig.CheckInterval * 1000 / Application.Speed,
startDelay: Constants.TaskDelays.LowDelay,
startTask: false,
runNow: false,
skipIteration: 0);
loggingService.Info("Signals service started");
}
public void Stop()
{
loggingService.Info("Stop Signals service...");
foreach (var receiver in signalReceivers.Values)
{
receiver.Stop();
}
signalReceivers.Clear();
tasksService.RemoveTask(nameof(SignalRulesTimedTask), stopTask: true);
rulesService.UnregisterRulesChangeCallback(OnSignalRulesChanged);
healthCheckService.RemoveHealthCheck(Constants.HealthChecks.SignalRulesProcessed);
loggingService.Info("Signals service stopped");
}
public void ProcessPair(string pair, Dictionary signals)
{
IEnumerable enabledRules = Rules.Entries.Where(r => r.Enabled);
foreach (IRule rule in enabledRules)
{
signalRulesTimedTask.ProcessRule(rule, signals, pair, signalRulesTimedTask.GetExcludedPairs(), GetGlobalRating());
}
}
public void StopTrailing()
{
signalRulesTimedTask.StopTrailing();
}
public List GetTrailingSignals()
{
return signalRulesTimedTask.GetTrailingSignals();
}
public IEnumerable GetTrailingInfo(string pair)
{
return signalRulesTimedTask.GetTrailingInfo(pair);
}
public IEnumerable GetSignalNames()
{
return signalReceivers.OrderBy(r => r.Value.GetPeriod()).Select(r => r.Key);
}
public IEnumerable GetAllSignals()
{
return GetSignalsByName(null);
}
public IEnumerable GetSignalsByName(string signalName)
{
IEnumerable signals = null;
foreach (var kvp in signalReceivers.OrderBy(r => r.Value.GetPeriod()))
{
if (signalName == null || signalName == kvp.Key)
{
ISignalReceiver receiver = kvp.Value;
if (signals == null)
{
signals = receiver.GetSignals();
}
else
{
signals = signals.Concat(receiver.GetSignals());
}
}
}
return signals;
}
public IEnumerable GetSignalsByPair(string pair)
{
foreach (var receiver in signalReceivers.Values.OrderBy(r => r.GetPeriod()))
{
var signal = receiver.GetSignals().FirstOrDefault(s => s.Pair == pair);
if (signal != null)
{
yield return signal;
}
}
}
public ISignal GetSignal(string pair, string signalName)
{
return GetSignalsByName(signalName)?.FirstOrDefault(s => s.Pair == pair);
}
public double? GetRating(string pair, string signalName)
{
return GetSignalsByName(signalName)?.FirstOrDefault(s => s.Pair == pair)?.Rating;
}
public double? GetRating(string pair, IEnumerable signalNames)
{
if (signalNames != null && signalNames.Count() > 0)
{
double ratingSum = 0;
foreach (var signalName in signalNames)
{
var rating = GetSignalsByName(signalName)?.FirstOrDefault(s => s.Pair == pair)?.Rating;
if (rating != null)
{
ratingSum += rating.Value;
}
else
{
return null;
}
}
return Math.Round(ratingSum / signalNames.Count(), 8);
}
else
{
return null;
}
}
public double? GetGlobalRating()
{
try
{
double ratingSum = 0;
double ratingCount = 0;
foreach (var kvp in signalReceivers)
{
string signalName = kvp.Key;
if (Config.GlobalRatingSignals.Contains(signalName))
{
ISignalReceiver receiver = kvp.Value;
double? averageRating = receiver.GetAverageRating();
if (averageRating != null)
{
ratingSum += averageRating.Value;
ratingCount++;
}
}
}
if (ratingCount > 0)
{
return Math.Round(ratingSum / ratingCount, 8);
}
else
{
return null;
}
}
catch (Exception ex)
{
loggingService.Error("Unable to get global rating", ex);
return null;
}
}
private void OnSignalRulesChanged()
{
Rules = rulesService.GetRules(ServiceName);
RulesConfig = Rules.GetConfiguration();
}
}
}
================================================
FILE: IntelliTrader.Signals.Base/TimedTasks/SignalRulesTimedTask.cs
================================================
using IntelliTrader.Core;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
namespace IntelliTrader.Signals.Base
{
public class SignalRulesTimedTask : HighResolutionTimedTask
{
public bool LoggingEnabled { get; set; } = true;
private readonly ILoggingService loggingService;
private readonly IHealthCheckService healthCheckService;
private readonly ITradingService tradingService;
private readonly IRulesService rulesService;
private readonly ISignalsService signalsService;
private ConcurrentDictionary> trailingSignals = new ConcurrentDictionary>();
public SignalRulesTimedTask(ILoggingService loggingService, IHealthCheckService healthCheckService, ITradingService tradingService, IRulesService rulesService, ISignalsService signalsService)
{
this.loggingService = loggingService;
this.healthCheckService = healthCheckService;
this.tradingService = tradingService;
this.rulesService = rulesService;
this.signalsService = signalsService;
}
protected override void Run()
{
ProcessTrailingSignals();
ProcessAllRules();
}
public void StopTrailing()
{
trailingSignals.Clear();
}
public void StopTrailing(string pair)
{
trailingSignals.TryRemove(pair, out List