Add MarketDataServer
This commit is contained in:
79
.gitignore
vendored
79
.gitignore
vendored
@@ -17,3 +17,82 @@ eNavigator/eNavigatorUI/bin/**
|
||||
eNavigator/eNavigatorUI/obj/**
|
||||
eNavigator/MarketDataLib/bin/**
|
||||
eNavigator/MarketDataLib/obj/**
|
||||
MarketDataServer/bin/Debug/net8.0/appsettings.json
|
||||
MarketDataServer/bin/Debug/net8.0/Axiom.Core.dll
|
||||
MarketDataServer/bin/Debug/net8.0/Axiom.Core.pdb
|
||||
MarketDataServer/bin/Debug/net8.0/BouncyCastle.Cryptography.dll
|
||||
MarketDataServer/bin/Debug/net8.0/Google.Protobuf.dll
|
||||
MarketDataServer/bin/Debug/net8.0/HtmlAgilityPack.dll
|
||||
MarketDataServer/bin/Debug/net8.0/K4os.Compression.LZ4.dll
|
||||
MarketDataServer/bin/Debug/net8.0/K4os.Compression.LZ4.Streams.dll
|
||||
MarketDataServer/bin/Debug/net8.0/K4os.Hash.xxHash.dll
|
||||
MarketDataServer/bin/Debug/net8.0/log4net.dll
|
||||
MarketDataServer/bin/Debug/net8.0/log4net.xml
|
||||
MarketDataServer/bin/Debug/net8.0/MarketDataLib.dll
|
||||
MarketDataServer/bin/Debug/net8.0/MarketDataLib.pdb
|
||||
MarketDataServer/bin/Debug/net8.0/Microsoft.Extensions.Configuration.Abstractions.dll
|
||||
MarketDataServer/bin/Debug/net8.0/Microsoft.Extensions.Configuration.dll
|
||||
MarketDataServer/bin/Debug/net8.0/Microsoft.Extensions.Configuration.FileExtensions.dll
|
||||
MarketDataServer/bin/Debug/net8.0/Microsoft.Extensions.Configuration.Json.dll
|
||||
MarketDataServer/bin/Debug/net8.0/Microsoft.Extensions.FileProviders.Abstractions.dll
|
||||
MarketDataServer/bin/Debug/net8.0/Microsoft.Extensions.FileProviders.Physical.dll
|
||||
MarketDataServer/bin/Debug/net8.0/Microsoft.Extensions.FileSystemGlobbing.dll
|
||||
MarketDataServer/bin/Debug/net8.0/Microsoft.Extensions.Primitives.dll
|
||||
MarketDataServer/bin/Debug/net8.0/Microsoft.OpenApi.dll
|
||||
MarketDataServer/bin/Debug/net8.0/Microsoft.Win32.SystemEvents.dll
|
||||
MarketDataServer/bin/Debug/net8.0/mks
|
||||
MarketDataServer/bin/Debug/net8.0/mks.deps.json
|
||||
MarketDataServer/bin/Debug/net8.0/mks.dll
|
||||
MarketDataServer/bin/Debug/net8.0/mks.pdb
|
||||
MarketDataServer/bin/Debug/net8.0/mks.runtimeconfig.json
|
||||
MarketDataServer/bin/Debug/net8.0/MySql.Data.dll
|
||||
MarketDataServer/bin/Debug/net8.0/Newtonsoft.Json.dll
|
||||
MarketDataServer/bin/Debug/net8.0/Swashbuckle.AspNetCore.Swagger.dll
|
||||
MarketDataServer/bin/Debug/net8.0/Swashbuckle.AspNetCore.SwaggerGen.dll
|
||||
MarketDataServer/bin/Debug/net8.0/Swashbuckle.AspNetCore.SwaggerUI.dll
|
||||
MarketDataServer/bin/Debug/net8.0/System.Configuration.ConfigurationManager.dll
|
||||
MarketDataServer/bin/Debug/net8.0/System.Drawing.Common.dll
|
||||
MarketDataServer/bin/Debug/net8.0/System.IO.Pipelines.dll
|
||||
MarketDataServer/bin/Debug/net8.0/System.Private.Windows.Core.dll
|
||||
MarketDataServer/bin/Debug/net8.0/System.Security.Cryptography.ProtectedData.dll
|
||||
MarketDataServer/bin/Debug/net8.0/System.Security.Permissions.dll
|
||||
MarketDataServer/bin/Debug/net8.0/System.Text.Encodings.Web.dll
|
||||
MarketDataServer/bin/Debug/net8.0/System.Text.Json.dll
|
||||
MarketDataServer/bin/Debug/net8.0/System.Windows.Extensions.dll
|
||||
MarketDataServer/bin/Debug/net8.0/ZstdSharp.dll
|
||||
MarketDataServer/bin/Debug/net8.0/logs/marketdata_marketdataserver.log
|
||||
MarketDataServer/bin/Debug/net8.0/runtimes/browser/lib/net8.0/System.Text.Encodings.Web.dll
|
||||
MarketDataServer/bin/Debug/net8.0/runtimes/win/lib/net8.0/Microsoft.Win32.SystemEvents.dll
|
||||
MarketDataServer/bin/Debug/net8.0/runtimes/win/lib/net8.0/System.Windows.Extensions.dll
|
||||
MarketDataServer/bin/Debug/net8.0/runtimes/win-x64/native/comerr64.dll
|
||||
MarketDataServer/bin/Debug/net8.0/runtimes/win-x64/native/gssapi64.dll
|
||||
MarketDataServer/bin/Debug/net8.0/runtimes/win-x64/native/k5sprt64.dll
|
||||
MarketDataServer/bin/Debug/net8.0/runtimes/win-x64/native/krb5_64.dll
|
||||
MarketDataServer/bin/Debug/net8.0/runtimes/win-x64/native/krbcc64.dll
|
||||
MarketDataServer/obj/MarketDataServer.csproj.nuget.dgspec.json
|
||||
MarketDataServer/obj/MarketDataServer.csproj.nuget.g.props
|
||||
MarketDataServer/obj/MarketDataServer.csproj.nuget.g.targets
|
||||
MarketDataServer/obj/project.assets.json
|
||||
MarketDataServer/obj/project.nuget.cache
|
||||
MarketDataServer/obj/Debug/net8.0/.NETCoreApp,Version=v8.0.AssemblyAttributes.cs
|
||||
MarketDataServer/obj/Debug/net8.0/apphost
|
||||
MarketDataServer/obj/Debug/net8.0/MarketDa.2D592492.Up2Date
|
||||
MarketDataServer/obj/Debug/net8.0/MarketDataServer.AssemblyInfo.cs
|
||||
MarketDataServer/obj/Debug/net8.0/MarketDataServer.AssemblyInfoInputs.cache
|
||||
MarketDataServer/obj/Debug/net8.0/MarketDataServer.assets.cache
|
||||
MarketDataServer/obj/Debug/net8.0/MarketDataServer.csproj.AssemblyReference.cache
|
||||
MarketDataServer/obj/Debug/net8.0/MarketDataServer.csproj.CoreCompileInputs.cache
|
||||
MarketDataServer/obj/Debug/net8.0/MarketDataServer.csproj.FileListAbsolute.txt
|
||||
MarketDataServer/obj/Debug/net8.0/MarketDataServer.GeneratedMSBuildEditorConfig.editorconfig
|
||||
MarketDataServer/obj/Debug/net8.0/MarketDataServer.genruntimeconfig.cache
|
||||
MarketDataServer/obj/Debug/net8.0/MarketDataServer.GlobalUsings.g.cs
|
||||
MarketDataServer/obj/Debug/net8.0/mks.dll
|
||||
MarketDataServer/obj/Debug/net8.0/mks.MvcApplicationPartsAssemblyInfo.cache
|
||||
MarketDataServer/obj/Debug/net8.0/mks.MvcApplicationPartsAssemblyInfo.cs
|
||||
MarketDataServer/obj/Debug/net8.0/mks.pdb
|
||||
MarketDataServer/obj/Debug/net8.0/staticwebassets.build.json
|
||||
MarketDataServer/obj/Debug/net8.0/ref/mks.dll
|
||||
MarketDataServer/obj/Debug/net8.0/refint/mks.dll
|
||||
MarketDataServer/obj/Debug/net8.0/staticwebassets/msbuild.build.mks.props
|
||||
MarketDataServer/obj/Debug/net8.0/staticwebassets/msbuild.buildMultiTargeting.mks.props
|
||||
MarketDataServer/obj/Debug/net8.0/staticwebassets/msbuild.buildTransitive.mks.props
|
||||
|
||||
24
MarketDataServer/.vscode/launch.json
vendored
Normal file
24
MarketDataServer/.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": ".NET Core Launch (console)",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
"program": "${workspaceFolder}/bin/Debug/net8.0/mks.dll",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"console": "internalConsole",
|
||||
"stopAtEntry": false
|
||||
},
|
||||
{
|
||||
"name": ".NET Core Attach",
|
||||
"type": "coreclr",
|
||||
"request": "attach"
|
||||
}
|
||||
]
|
||||
}
|
||||
41
MarketDataServer/.vscode/tasks.json
vendored
Normal file
41
MarketDataServer/.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "build",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"build",
|
||||
"${workspaceFolder}/MarketDataServer.csproj",
|
||||
"/property:GenerateFullPaths=true",
|
||||
"/consoleloggerparameters:NoSummary;ForceNoAlign"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "publish",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"publish",
|
||||
"${workspaceFolder}/MarketDataServer.csproj",
|
||||
"/property:GenerateFullPaths=true",
|
||||
"/consoleloggerparameters:NoSummary;ForceNoAlign"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "watch",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"watch",
|
||||
"run",
|
||||
"--project",
|
||||
"${workspaceFolder}/MarketDataServer.csproj"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
}
|
||||
]
|
||||
}
|
||||
78
MarketDataServer/Authorization/Authorizations.cs
Executable file
78
MarketDataServer/Authorization/Authorizations.cs
Executable file
@@ -0,0 +1,78 @@
|
||||
using MarketData;
|
||||
using MarketData.DataAccess;
|
||||
using MarketData.Extensions;
|
||||
using MarketData.MarketDataModel.User;
|
||||
using System.Text;
|
||||
|
||||
namespace MarketDataServer.Authorization
|
||||
{
|
||||
public class Authorizations
|
||||
{
|
||||
private Dictionary<String, String> authorizationDictionary = null;
|
||||
private static Authorizations authorizations = null;
|
||||
private bool isEnabled=true;
|
||||
|
||||
private Authorizations()
|
||||
{
|
||||
authorizationDictionary=new Dictionary<String,String>();
|
||||
}
|
||||
|
||||
public static Authorizations GetInstance()
|
||||
{
|
||||
lock (typeof(Authorizations))
|
||||
{
|
||||
if (null == authorizations) authorizations = new Authorizations();
|
||||
}
|
||||
return authorizations;
|
||||
}
|
||||
|
||||
public bool IsEnabled
|
||||
{
|
||||
get{return isEnabled;}
|
||||
set{isEnabled=value;}
|
||||
}
|
||||
|
||||
public bool IsAuthorized(String token)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if(!IsEnabled)return true;
|
||||
return authorizationDictionary.ContainsKey(token);
|
||||
}
|
||||
}
|
||||
|
||||
public String GetAuthenticationToken()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
String token = Guid.NewGuid().ToString();
|
||||
authorizationDictionary.Add(token, token);
|
||||
return token;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsValidUser(String username,String password)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if(!UserDA.UserExists(username))return false;
|
||||
MDTrace.WriteLine(MarketData.LogLevel.DEBUG,String.Format("[{0:G}][User {1} exists.]",DateTime.Now ,username));
|
||||
User user = UserDA.GetUser(username);
|
||||
if(null == user)
|
||||
{
|
||||
MDTrace.WriteLine(MarketData.LogLevel.DEBUG,String.Format("[{0:G}][User {1} validation failed.]",DateTime.Now ,username));
|
||||
return false;
|
||||
}
|
||||
MDTrace.WriteLine(MarketData.LogLevel.DEBUG,String.Format("[{0:G}][User {1} is validated.]",DateTime.Now ,username));
|
||||
return user.Verify(password);
|
||||
}
|
||||
}
|
||||
|
||||
public static String Xor(String input, int magic)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
foreach (char ch in input) sb.Append((char)(ch ^ (char)magic));
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
288
MarketDataServer/Controllers/GainLossController.cs
Executable file
288
MarketDataServer/Controllers/GainLossController.cs
Executable file
@@ -0,0 +1,288 @@
|
||||
using MarketData.MarketDataModel;
|
||||
using MarketData.DataAccess;
|
||||
using MarketData.Utils;
|
||||
using MarketData.Generator.GainLoss;
|
||||
using MarketData.MarketDataModel.GainLoss;
|
||||
using MarketDataServer.Authorization;
|
||||
using MarketData.Cache;
|
||||
using MarketData.Generator;
|
||||
using MarketData;
|
||||
using LogLevel = MarketData.LogLevel;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace MarketDataServer.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("api/[controller]/[action]")]
|
||||
public class GainLossController : ControllerBase
|
||||
{
|
||||
private ActiveGainLossGenerator gainLossGenerator=new ActiveGainLossGenerator();
|
||||
|
||||
[HttpGet(Name = "GetGainLoss")]
|
||||
public IEnumerable<GainLossSummaryItem> GetGainLoss(String token, DateTime selectedDate)
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("[{0:G}][GainLossController::GetGainLoss](String token, DateTime selectedDate)", DateTime.Now));
|
||||
if (!Authorizations.GetInstance().IsAuthorized(token)) return null;
|
||||
LocalPriceCache.GetInstance().Refresh();
|
||||
PortfolioTrades portfolioTrades = PortfolioDA.GetTrades();
|
||||
PortfolioTrades tradesOnOrBefore = portfolioTrades.GetTradesOnOrBefore(selectedDate);
|
||||
GainLossSummaryItemCollection gainLossSummaryItems = new GainLossSummaryItemCollection(tradesOnOrBefore, selectedDate);
|
||||
|
||||
// **** Add an aggregate entry
|
||||
GainLossSummaryItem gainLossSummaryTotals=new GainLossSummaryItem();
|
||||
gainLossSummaryTotals.Symbol="";
|
||||
gainLossSummaryTotals.CompanyName="Account Summary";
|
||||
if(null!=gainLossSummaryItems&&gainLossSummaryItems.Count>0)
|
||||
{
|
||||
gainLossSummaryTotals.Date=gainLossSummaryItems.Min(x => x.Date);
|
||||
gainLossSummaryTotals.Change=gainLossSummaryItems.Sum(x=>x.Change);
|
||||
gainLossSummaryTotals.CurrentGainLoss=gainLossSummaryItems.Sum(x => x.CurrentGainLoss);
|
||||
gainLossSummaryTotals.PreviousGainLoss = gainLossSummaryItems.Sum(x => x.PreviousGainLoss);
|
||||
gainLossSummaryTotals.ChangePercent=((gainLossSummaryTotals.CurrentGainLoss-gainLossSummaryTotals.PreviousGainLoss)/Math.Abs(gainLossSummaryTotals.PreviousGainLoss))*100.00;
|
||||
}
|
||||
else
|
||||
{
|
||||
gainLossSummaryTotals.Date = selectedDate;
|
||||
gainLossSummaryTotals.Change = 0.00;
|
||||
gainLossSummaryTotals.CurrentGainLoss = 0.00;
|
||||
gainLossSummaryTotals.PreviousGainLoss = 0.00;
|
||||
gainLossSummaryTotals.ChangePercent = 0.00;
|
||||
}
|
||||
gainLossSummaryItems.Insert(0,gainLossSummaryTotals);
|
||||
// ****
|
||||
return gainLossSummaryItems;
|
||||
}
|
||||
|
||||
[HttpGet(Name = "GetGainLoss")]
|
||||
public IEnumerable<GainLossSummaryItem> GetGainLoss(String token, DateTime selectedDate,String account)
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("[{0:G}][GainLossController::GetGainLoss](String token, DateTime selectedDate,String account)", DateTime.Now));
|
||||
LocalPriceCache.GetInstance().Refresh();
|
||||
if (!Authorizations.GetInstance().IsAuthorized(token)) return null;
|
||||
PortfolioTrades portfolioTrades = PortfolioDA.GetTrades();
|
||||
portfolioTrades=new PortfolioTrades(portfolioTrades.Where(x=>x.Account.Equals(account)).ToList());
|
||||
PortfolioTrades tradesOnOrBefore = portfolioTrades.GetTradesOnOrBefore(selectedDate);
|
||||
GainLossSummaryItemCollection gainLossSummaryItems = new GainLossSummaryItemCollection(tradesOnOrBefore, selectedDate);
|
||||
|
||||
// **** Add an aggregate entry
|
||||
GainLossSummaryItem gainLossSummaryTotals = new GainLossSummaryItem();
|
||||
gainLossSummaryTotals.Symbol = "";
|
||||
gainLossSummaryTotals.CompanyName="Account Summary";
|
||||
if (null != gainLossSummaryItems && gainLossSummaryItems.Count > 0)
|
||||
{
|
||||
gainLossSummaryTotals.Date = gainLossSummaryItems.Min(x => x.Date);
|
||||
gainLossSummaryTotals.Change = gainLossSummaryItems.Sum(x => x.Change);
|
||||
gainLossSummaryTotals.CurrentGainLoss = gainLossSummaryItems.Sum(x => x.CurrentGainLoss);
|
||||
gainLossSummaryTotals.PreviousGainLoss = gainLossSummaryItems.Sum(x => x.PreviousGainLoss);
|
||||
gainLossSummaryTotals.ChangePercent = ((gainLossSummaryTotals.CurrentGainLoss - gainLossSummaryTotals.PreviousGainLoss) / Math.Abs(gainLossSummaryTotals.PreviousGainLoss)) * 100.00;
|
||||
}
|
||||
else
|
||||
{
|
||||
gainLossSummaryTotals.Date = selectedDate;
|
||||
gainLossSummaryTotals.Change = 0.00;
|
||||
gainLossSummaryTotals.CurrentGainLoss = 0.00;
|
||||
gainLossSummaryTotals.PreviousGainLoss = 0.00;
|
||||
gainLossSummaryTotals.ChangePercent = 0.00;
|
||||
}
|
||||
gainLossSummaryItems.Insert(0, gainLossSummaryTotals);
|
||||
// ****
|
||||
return gainLossSummaryItems;
|
||||
}
|
||||
|
||||
[HttpGet(Name = "GetGainLossWithDetail")]
|
||||
public IEnumerable<GainLossSummaryItemDetail> GetGainLossWithDetail(String token, DateTime selectedDate)
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("[{0:G}][GainLossController::GetGainLossWithDetail](String token, DateTime selectedDate)", DateTime.Now));
|
||||
if (!Authorizations.GetInstance().IsAuthorized(token)) return null;
|
||||
LocalPriceCache.GetInstance().Refresh();
|
||||
PortfolioTrades portfolioTrades = PortfolioDA.GetTrades();
|
||||
PortfolioTrades tradesOnOrBefore = portfolioTrades.GetTradesOnOrBefore(selectedDate);
|
||||
GainLossSummaryItemCollection gainLossSummaryItems = new GainLossSummaryItemCollection(tradesOnOrBefore, selectedDate);
|
||||
|
||||
List<GainLossSummaryItemDetail> gainLossSummaryItemDetailCollection = new List<GainLossSummaryItemDetail>();
|
||||
foreach (GainLossSummaryItem gainLossSummaryItem in gainLossSummaryItems)
|
||||
{
|
||||
GainLossSummaryItemDetail gainLossSummaryItemDetail = new GainLossSummaryItemDetail(gainLossSummaryItem);
|
||||
portfolioTrades = PortfolioDA.GetOpenTradesSymbol(gainLossSummaryItem.Symbol);
|
||||
double weightAdjustedDividendYield = portfolioTrades.GetWeightAdjustedDividendYield();
|
||||
DateTime currentDate = PricingDA.GetLatestDate(gainLossSummaryItem.Symbol);
|
||||
if (null == portfolioTrades || 0 == portfolioTrades.Count) continue;
|
||||
double shares = (from PortfolioTrade portfolioTrade in portfolioTrades select portfolioTrade.Shares).Sum();
|
||||
double exposure = portfolioTrades.Sum(x => x.Exposure());
|
||||
if(null==gainLossGenerator) gainLossGenerator=new ActiveGainLossGenerator();
|
||||
GainLossCollection gainLoss=gainLossGenerator.GenerateGainLoss(portfolioTrades); // gainLoss contains the gain/loss from active positions. Never includes dividends .. just positions
|
||||
GainLossItem gainLossItem = gainLoss.OrderByDescending(x => x.GainLossPercent).FirstOrDefault();
|
||||
gainLossSummaryItemDetail.Lots = portfolioTrades.Count;
|
||||
gainLossSummaryItemDetail.Shares = shares;
|
||||
gainLossSummaryItemDetail.Exposure = exposure;
|
||||
if (!double.IsNaN(weightAdjustedDividendYield))
|
||||
{
|
||||
gainLossSummaryItemDetail.DividendYield = weightAdjustedDividendYield;
|
||||
gainLossSummaryItemDetail.AnnualDividend = exposure * weightAdjustedDividendYield;
|
||||
}
|
||||
ParityElement parityElement = ParityGenerator.GenerateBreakEven(gainLossSummaryItem.Symbol);
|
||||
gainLossSummaryItemDetail.ParityElement = parityElement;
|
||||
if (null != parityElement)
|
||||
{
|
||||
gainLossSummaryItemDetail.AllTimeGainLossPercent = gainLossItem.GainLossPercent;
|
||||
gainLossSummaryItemDetail.PercentDistanceFromAllTimeGainLossPercent = parityElement.ParityOffsetPercent - (gainLossItem.GainLossPercent / 100);
|
||||
}
|
||||
DateGenerator dateGenerator = new DateGenerator();
|
||||
DateTime priorDate = dateGenerator.FindPrevBusinessDay(currentDate);
|
||||
Price p1 = PricingDA.GetPrice(gainLossSummaryItem.Symbol, currentDate);
|
||||
Price p2 = PricingDA.GetPrice(gainLossSummaryItem.Symbol, priorDate);
|
||||
if (null == p2 && null != p1)
|
||||
{
|
||||
priorDate = dateGenerator.FindPrevBusinessDay(priorDate);
|
||||
p2 = PricingDA.GetPrice(gainLossSummaryItem.Symbol, priorDate);
|
||||
}
|
||||
if (null != p1 && null != p2)
|
||||
{
|
||||
double change = (p1.Close - p2.Close) / p2.Close;
|
||||
gainLossSummaryItemDetail.LatestPrice = p1;
|
||||
gainLossSummaryItemDetail.PriceChange = change;
|
||||
}
|
||||
gainLossSummaryItemDetailCollection.Add(gainLossSummaryItemDetail);
|
||||
}
|
||||
|
||||
// **** Add an aggregate entry
|
||||
GainLossSummaryItemDetail gainLossSummaryTotals = new GainLossSummaryItemDetail();
|
||||
gainLossSummaryTotals.Symbol = "";
|
||||
gainLossSummaryTotals.CompanyName = "Account Summary";
|
||||
if (null != gainLossSummaryItemDetailCollection && gainLossSummaryItemDetailCollection.Count > 0)
|
||||
{
|
||||
gainLossSummaryTotals.Date = gainLossSummaryItemDetailCollection.Min(x => x.Date);
|
||||
gainLossSummaryTotals.Exposure = gainLossSummaryItemDetailCollection.Sum(x => x.Exposure);
|
||||
gainLossSummaryTotals.Change = gainLossSummaryItemDetailCollection.Sum(x => x.Change);
|
||||
gainLossSummaryTotals.CurrentGainLoss = gainLossSummaryItemDetailCollection.Sum(x => x.CurrentGainLoss);
|
||||
gainLossSummaryTotals.PreviousGainLoss = gainLossSummaryItemDetailCollection.Sum(x => x.PreviousGainLoss);
|
||||
gainLossSummaryTotals.ChangePercent = ((gainLossSummaryTotals.CurrentGainLoss - gainLossSummaryTotals.PreviousGainLoss) / Math.Abs(gainLossSummaryTotals.PreviousGainLoss)) * 100.00;
|
||||
gainLossSummaryTotals.LatestPrice = new Price();
|
||||
gainLossSummaryTotals.PriceChange = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
gainLossSummaryTotals.Date = selectedDate;
|
||||
gainLossSummaryTotals.Change = 0.00;
|
||||
gainLossSummaryTotals.CurrentGainLoss = 0.00;
|
||||
gainLossSummaryTotals.PreviousGainLoss = 0.00;
|
||||
gainLossSummaryTotals.ChangePercent = 0.00;
|
||||
gainLossSummaryTotals.LatestPrice = new Price();
|
||||
gainLossSummaryTotals.PriceChange = 0;
|
||||
}
|
||||
gainLossSummaryItemDetailCollection.Insert(0, gainLossSummaryTotals);
|
||||
// ****
|
||||
return gainLossSummaryItemDetailCollection;
|
||||
}
|
||||
|
||||
[HttpGet(Name = "GetGainLossWithDetail")]
|
||||
public IEnumerable<GainLossSummaryItemDetail> GetGainLossWithDetail(String token, DateTime selectedDate, String account)
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("[{0:G}][GainLossController::GetGainLossWithDetail](String token, DateTime selectedDate,String account)", DateTime.Now));
|
||||
if (!Authorizations.GetInstance().IsAuthorized(token)) return null;
|
||||
LocalPriceCache.GetInstance().Refresh();
|
||||
PortfolioTrades portfolioTrades = PortfolioDA.GetTrades();
|
||||
portfolioTrades = new PortfolioTrades(portfolioTrades.Where(x => x.Account.Equals(account)).ToList());
|
||||
PortfolioTrades tradesOnOrBefore = portfolioTrades.GetTradesOnOrBefore(selectedDate);
|
||||
GainLossSummaryItemCollection gainLossSummaryItems = new GainLossSummaryItemCollection(tradesOnOrBefore, selectedDate);
|
||||
|
||||
List<GainLossSummaryItemDetail> gainLossSummaryItemDetailCollection=new List<GainLossSummaryItemDetail>();
|
||||
foreach(GainLossSummaryItem gainLossSummaryItem in gainLossSummaryItems)
|
||||
{
|
||||
GainLossSummaryItemDetail gainLossSummaryItemDetail = new GainLossSummaryItemDetail(gainLossSummaryItem);
|
||||
portfolioTrades = PortfolioDA.GetOpenTradesSymbol(gainLossSummaryItem.Symbol);
|
||||
double weightAdjustedDividendYield = portfolioTrades.GetWeightAdjustedDividendYield();
|
||||
DateTime currentDate = PricingDA.GetLatestDate(gainLossSummaryItem.Symbol);
|
||||
if(null==portfolioTrades||0==portfolioTrades.Count)continue;
|
||||
double shares = (from PortfolioTrade portfolioTrade in portfolioTrades select portfolioTrade.Shares).Sum();
|
||||
double exposure = portfolioTrades.Sum(x => x.Exposure());
|
||||
if(null==gainLossGenerator) gainLossGenerator=new ActiveGainLossGenerator();
|
||||
GainLossCollection gainLoss = gainLossGenerator.GenerateGainLoss(portfolioTrades); // gainLoss contains the gain/loss from active positions. Never includes dividends .. just positions
|
||||
GainLossItem gainLossItem = gainLoss.OrderByDescending(x => x.GainLossPercent).FirstOrDefault();
|
||||
gainLossSummaryItemDetail.Lots=portfolioTrades.Count;
|
||||
gainLossSummaryItemDetail.Shares=shares;
|
||||
gainLossSummaryItemDetail.Exposure=exposure;
|
||||
if (!double.IsNaN(weightAdjustedDividendYield))
|
||||
{
|
||||
gainLossSummaryItemDetail.DividendYield=weightAdjustedDividendYield;
|
||||
gainLossSummaryItemDetail.AnnualDividend=exposure * weightAdjustedDividendYield;
|
||||
}
|
||||
ParityElement parityElement = ParityGenerator.GenerateBreakEven(gainLossSummaryItem.Symbol);
|
||||
gainLossSummaryItemDetail.ParityElement=parityElement;
|
||||
if (null != parityElement)
|
||||
{
|
||||
gainLossSummaryItemDetail.AllTimeGainLossPercent=gainLossItem.GainLossPercent;
|
||||
gainLossSummaryItemDetail.PercentDistanceFromAllTimeGainLossPercent=parityElement.ParityOffsetPercent - (gainLossItem.GainLossPercent / 100);
|
||||
}
|
||||
DateGenerator dateGenerator = new DateGenerator();
|
||||
DateTime priorDate = dateGenerator.FindPrevBusinessDay(currentDate);
|
||||
Price p1 = PricingDA.GetPrice(gainLossSummaryItem.Symbol, currentDate);
|
||||
Price p2 = PricingDA.GetPrice(gainLossSummaryItem.Symbol, priorDate);
|
||||
if (null == p2 && null != p1)
|
||||
{
|
||||
priorDate = dateGenerator.FindPrevBusinessDay(priorDate);
|
||||
p2 = PricingDA.GetPrice(gainLossSummaryItem.Symbol, priorDate);
|
||||
}
|
||||
if(null!=p1&&null!=p2)
|
||||
{
|
||||
double change = (p1.Close - p2.Close) / p2.Close;
|
||||
gainLossSummaryItemDetail.LatestPrice=p1;
|
||||
gainLossSummaryItemDetail.PriceChange=change;
|
||||
}
|
||||
gainLossSummaryItemDetailCollection.Add(gainLossSummaryItemDetail);
|
||||
}
|
||||
|
||||
// **** Add an aggregate entry
|
||||
GainLossSummaryItemDetail gainLossSummaryTotals = new GainLossSummaryItemDetail();
|
||||
gainLossSummaryTotals.Symbol = "";
|
||||
gainLossSummaryTotals.CompanyName = "Account Summary";
|
||||
if (null != gainLossSummaryItemDetailCollection && gainLossSummaryItemDetailCollection.Count > 0)
|
||||
{
|
||||
gainLossSummaryTotals.Date = gainLossSummaryItemDetailCollection.Min(x => x.Date);
|
||||
gainLossSummaryTotals.Exposure=gainLossSummaryItemDetailCollection.Sum(x=>x.Exposure);
|
||||
gainLossSummaryTotals.Change = gainLossSummaryItemDetailCollection.Sum(x => x.Change);
|
||||
gainLossSummaryTotals.CurrentGainLoss = gainLossSummaryItemDetailCollection.Sum(x => x.CurrentGainLoss);
|
||||
gainLossSummaryTotals.PreviousGainLoss = gainLossSummaryItemDetailCollection.Sum(x => x.PreviousGainLoss);
|
||||
gainLossSummaryTotals.ChangePercent = ((gainLossSummaryTotals.CurrentGainLoss - gainLossSummaryTotals.PreviousGainLoss) / Math.Abs(gainLossSummaryTotals.PreviousGainLoss)) * 100.00;
|
||||
gainLossSummaryTotals.LatestPrice=new Price();
|
||||
gainLossSummaryTotals.PriceChange=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
gainLossSummaryTotals.Date = selectedDate;
|
||||
gainLossSummaryTotals.Change = 0.00;
|
||||
gainLossSummaryTotals.CurrentGainLoss = 0.00;
|
||||
gainLossSummaryTotals.PreviousGainLoss = 0.00;
|
||||
gainLossSummaryTotals.ChangePercent = 0.00;
|
||||
gainLossSummaryTotals.LatestPrice = new Price();
|
||||
gainLossSummaryTotals.PriceChange = 0;
|
||||
}
|
||||
gainLossSummaryItemDetailCollection.Insert(0, gainLossSummaryTotals);
|
||||
// ****
|
||||
return gainLossSummaryItemDetailCollection;
|
||||
}
|
||||
|
||||
[HttpGet(Name = "GetCompoundGainLoss")]
|
||||
public GainLossCompoundModelCollection GetCompoundGainLoss(String token, int selectedDays, bool includeDividends)
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("[{0:G}][GainLossController::GetCompundGainLoss](String token, int days)", DateTime.Now));
|
||||
if(!Authorizations.GetInstance().IsAuthorized(token)) return null;
|
||||
LocalPriceCache.GetInstance().Refresh();
|
||||
DividendPayments dividendPayments = null;
|
||||
PortfolioTrades portfolioTrades = PortfolioDA.GetTrades();
|
||||
GainLossGenerator gainLossGenerator=new GainLossGenerator();
|
||||
if(includeDividends)dividendPayments=DividendPaymentDA.GetDividendPayments();
|
||||
ActiveGainLossGenerator activeGainLossGenerator=new ActiveGainLossGenerator();
|
||||
GainLossCollection gainLoss=activeGainLossGenerator.GenerateGainLoss(portfolioTrades); // gainLoss contains the gain/loss from active positions. Never includes dividends .. just positions
|
||||
TotalGainLossCollection totalGainLoss=null;
|
||||
if(null!=dividendPayments)totalGainLoss=gainLossGenerator.GenerateTotalGainLossWithDividends(portfolioTrades,dividendPayments);
|
||||
else totalGainLoss=gainLossGenerator.GenerateTotalGainLoss(portfolioTrades);
|
||||
GainLossCompoundModelCollection gainLossModelCollection=null;
|
||||
gainLossModelCollection=new GainLossCompoundModelCollection(gainLoss,totalGainLoss);
|
||||
if(-1==selectedDays)return gainLossModelCollection;
|
||||
int skip=gainLossModelCollection.Count-selectedDays;
|
||||
if(skip<0)return gainLossModelCollection;
|
||||
return new GainLossCompoundModelCollection(gainLossModelCollection.Skip(skip).ToList());
|
||||
}
|
||||
}
|
||||
}
|
||||
40
MarketDataServer/Controllers/HeadlinesController.cs
Executable file
40
MarketDataServer/Controllers/HeadlinesController.cs
Executable file
@@ -0,0 +1,40 @@
|
||||
using MarketData.MarketDataModel;
|
||||
using MarketData.DataAccess;
|
||||
using MarketDataServer.Authorization;
|
||||
using MarketData;
|
||||
using LogLevel = MarketData.LogLevel;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace MarketDataServer.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("api/[controller]/[action]")]
|
||||
public class HeadlinesController : ControllerBase
|
||||
{
|
||||
[HttpGet(Name = "GetLatestHeadlines")]
|
||||
public IEnumerable<Headline> GetLatestHeadlines(String token)
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("[{0:G}][HeadlinesController::GetLatestHeadlines]", DateTime.Now));
|
||||
if (!Authorizations.GetInstance().IsAuthorized(token)) return null;
|
||||
return HeadlinesDA.GetLatestHeadlines();
|
||||
}
|
||||
|
||||
[HttpGet(Name = "GetHeadlineDates")]
|
||||
public IEnumerable<String> GetHeadlineDates(String token)
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("[{0:G}][HeadlinesController::GetHeadlineDates]", DateTime.Now));
|
||||
if (!Authorizations.GetInstance().IsAuthorized(token)) return null;
|
||||
List<string> headlineDates = HeadlinesDA.GetHeadlineDates();
|
||||
if(headlineDates.Count>0)headlineDates=headlineDates.Take(252).ToList();
|
||||
return headlineDates;
|
||||
}
|
||||
|
||||
[HttpGet(Name = "GetHeadlines")]
|
||||
public IEnumerable<Headline> GetHeadlines(String token,DateTime headlineDate)
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("[{0:G}][HeadlinesController::GetHeadliness(DateTime headlineDate)]", DateTime.Now));
|
||||
if (!Authorizations.GetInstance().IsAuthorized(token)) return null;
|
||||
return HeadlinesDA.GetHeadlines(headlineDate);
|
||||
}
|
||||
}
|
||||
}
|
||||
30
MarketDataServer/Controllers/LoginController.cs
Executable file
30
MarketDataServer/Controllers/LoginController.cs
Executable file
@@ -0,0 +1,30 @@
|
||||
using MarketData;
|
||||
using MarketDataServer.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using LogLevel = MarketData.LogLevel;
|
||||
|
||||
namespace MarketDataServer.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("api/[controller]/[action]")]
|
||||
public class AuthorizationController : ControllerBase
|
||||
{
|
||||
[HttpGet(Name = "GetToken")]
|
||||
public String GetToken(String user, String password)
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("[{0:G}][AuthorizationController::Authorize]",DateTime.Now));
|
||||
if(null==user)return null;
|
||||
user=Authorizations.Xor(user,5);
|
||||
password=Authorizations.Xor(password,5);
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("[{0:G}][Login requested for user '{1}']",DateTime.Now, user));
|
||||
if(!Authorizations.GetInstance().IsValidUser(user, password))
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("[{0:G}][User '{1}' is not authorized]", DateTime.Now,user));
|
||||
return null;
|
||||
}
|
||||
String accessToken= Authorizations.GetInstance().GetAuthenticationToken();
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("[{0:G}][Access token granted for user {1} : {2}]",DateTime.Now ,user, accessToken));
|
||||
return accessToken;
|
||||
}
|
||||
}
|
||||
}
|
||||
19
MarketDataServer/Controllers/PingController.cs
Executable file
19
MarketDataServer/Controllers/PingController.cs
Executable file
@@ -0,0 +1,19 @@
|
||||
using MarketData;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using LogLevel = MarketData.LogLevel;
|
||||
|
||||
|
||||
namespace MarketDataServer.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("api/[controller]/[action]")]
|
||||
public class PingController : ControllerBase
|
||||
{
|
||||
[HttpGet(Name = "GetPing")]
|
||||
public bool GetPing()
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("[{0:G}][PingController::GetPing]", DateTime.Now));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
80
MarketDataServer/Controllers/PortfolioController.cs
Executable file
80
MarketDataServer/Controllers/PortfolioController.cs
Executable file
@@ -0,0 +1,80 @@
|
||||
using MarketData.MarketDataModel;
|
||||
using MarketData.DataAccess;
|
||||
using MarketDataServer.Authorization;
|
||||
using MarketData.Generator;
|
||||
using MarketData;
|
||||
using LogLevel = MarketData.LogLevel;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace MarketDataServer.Controllers
|
||||
{
|
||||
|
||||
//http://localhost:8000/api/Portfolio/GetTradesSymbol?&symbol=SPY
|
||||
//http://73.245.214.234:8000/api/Portfolio/GetTradesSymbol?&symbol=SPY
|
||||
namespace MarketDataServer.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("api/[controller]/[action]")]
|
||||
public class PortfolioController : ControllerBase
|
||||
{
|
||||
[HttpGet(Name = "GetOpenPositionsWithDescription")]
|
||||
public IEnumerable<PositionWithDescription> GetOpenPositionsWithDescription(String token)
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("[{0:G}][PortfolioController::GetOpenPositionsWithDescriptionAsOf]",DateTime.Now));
|
||||
if (!Authorizations.GetInstance().IsAuthorized(token)) return null;
|
||||
List<PositionWithDescription> positionsWithDescription=new List<PositionWithDescription>();
|
||||
PortfolioTrades openTrades=PortfolioDA.GetOpenTrades();
|
||||
List<Position> positions=openTrades.GetPositions(DateTime.Now);
|
||||
foreach(Position position in positions)
|
||||
{
|
||||
CompanyProfile companyProfile=CompanyProfileDA.GetCompanyProfile(position.Symbol);
|
||||
if(null==companyProfile.Description)companyProfile.Description="Description unvailable";
|
||||
positionsWithDescription.Add(new PositionWithDescription(position,companyProfile.CompanyName, companyProfile.Description));
|
||||
}
|
||||
return positionsWithDescription;
|
||||
}
|
||||
|
||||
[HttpGet(Name = "GetAccounts")]
|
||||
public IEnumerable<String> GetAccounts(String token)
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("[{0:G}][PortfolioController::GetAccounts]",DateTime.Now));
|
||||
if (!Authorizations.GetInstance().IsAuthorized(token)) return null;
|
||||
return PortfolioDA.GetAccounts();
|
||||
}
|
||||
|
||||
[HttpGet(Name = "GetAccountsWithOpenTrades")]
|
||||
public IEnumerable<String> GetAccountsWithOpenTrades(String token)
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("[{0:G}][PortfolioController::GetAccountsWithOpenTrades]", DateTime.Now));
|
||||
if (!Authorizations.GetInstance().IsAuthorized(token)) return null;
|
||||
return PortfolioDA.GetAccountsWithOpenTrades();
|
||||
}
|
||||
|
||||
[HttpGet(Name = "GetStopLimit")]
|
||||
public StopLimit GetStopLimit(String token,String symbol)
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("[{0:G}][PortfolioController::GetStopLimit]",DateTime.Now));
|
||||
if(!Authorizations.GetInstance().IsAuthorized(token)) return null;
|
||||
StopLimit stopLimit=PortfolioDA.GetStopLimit(symbol);
|
||||
return stopLimit;
|
||||
}
|
||||
|
||||
[HttpGet(Name = "GetPortfolioTradesWithParityPrice")]
|
||||
public PortfolioTradesWithParityPrice GetPortfolioTradesWithParityPrice(String token, String symbol)
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("[{0:G}][PortfolioController::GetPortfolioTradesWithParityPrice]", DateTime.Now));
|
||||
if (!Authorizations.GetInstance().IsAuthorized(token)) return null;
|
||||
Price zeroPrice=null;
|
||||
DateTime latestPricingDate=PricingDA.GetLatestDate(symbol);
|
||||
Price latestPrice = PricingDA.GetPrice(symbol, latestPricingDate);
|
||||
PortfolioTrades portfolioTrades = PortfolioDA.GetTradesSymbol(symbol);
|
||||
if (null == portfolioTrades) return null;
|
||||
portfolioTrades = portfolioTrades.GetOpenTrades();
|
||||
if (null == portfolioTrades) return null;
|
||||
PortfolioTrades portfolioTradesLots = LotAggregator.CombineLots(portfolioTrades);
|
||||
zeroPrice=ParityGenerator.GenerateGainLossValue(portfolioTrades,latestPrice);
|
||||
return new PortfolioTradesWithParityPrice(portfolioTradesLots,zeroPrice);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
40
MarketDataServer/Controllers/PreMarketController.cs
Executable file
40
MarketDataServer/Controllers/PreMarketController.cs
Executable file
@@ -0,0 +1,40 @@
|
||||
using MarketData.MarketDataModel;
|
||||
using MarketData.DataAccess;
|
||||
using MarketDataServer.Authorization;
|
||||
using MarketData;
|
||||
using LogLevel = MarketData.LogLevel;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace MarketDataServer.Controllers
|
||||
{
|
||||
//http://localhost:8000/api/PreMarket/GetAvailableMarketDates?&market=S&P
|
||||
[ApiController]
|
||||
[Route("api/[controller]/[action]")]
|
||||
public class PreMarketController: ControllerBase
|
||||
{
|
||||
[HttpGet(Name = "GetAvailableMarketDates")]
|
||||
public IEnumerable<DateTime> GetAvailableMarketDates(String token,String market)
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("[{0:G}][PreMarketController::GetAvailableMarketDates]{1}",DateTime.Now,market));
|
||||
if(!Authorizations.GetInstance().IsAuthorized(token)) return null;
|
||||
return PremarketDA.GetAvailableMarketDates(market);
|
||||
}
|
||||
|
||||
[HttpGet(Name = "GetAvailableMarkets")]
|
||||
public IEnumerable<String> GetAvailableMarkets(String token)
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("[{0:G}][PreMarketController::GetAvailableMarkets]",DateTime.Now));
|
||||
if(!Authorizations.GetInstance().IsAuthorized(token)) return null;
|
||||
return PremarketDA.GetDistinctMarkets();
|
||||
}
|
||||
|
||||
[HttpGet(Name = "GetLatestPremarketData")]
|
||||
public IEnumerable<PremarketElement> GetLatestPremarketData(String token,String market,DateTime marketDate)
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("[{0:G}][PreMarketController::GetLatestPremarketData]{1},{2}",DateTime.Now,market,marketDate.ToShortDateString()));
|
||||
if(!Authorizations.GetInstance().IsAuthorized(token)) return null;
|
||||
return PremarketDA.GetLatestPremarketData(market,marketDate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
55
MarketDataServer/Controllers/PriceController.cs
Executable file
55
MarketDataServer/Controllers/PriceController.cs
Executable file
@@ -0,0 +1,55 @@
|
||||
using MarketData.MarketDataModel;
|
||||
using MarketData.DataAccess;
|
||||
using MarketDataServer.Authorization;
|
||||
using MarketData.Generator;
|
||||
using MarketData;
|
||||
using LogLevel = MarketData.LogLevel;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace MarketDataServer.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("api/[controller]/[action]")]
|
||||
//http://localhost:8000/api/Price
|
||||
//http://localhost:8000/api/Price/GetPrices?&symbol=MIDD&days=5
|
||||
//http://73.245.214.234:8000/api/Price/GetPrices?&symbol=MIDD&days=5
|
||||
|
||||
public class PriceController : ControllerBase
|
||||
{
|
||||
[HttpGet(Name = "GetPrices")]
|
||||
public IEnumerable<Price> GetPrices(String token, String symbol, int days)
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("[{0:G}][PriceController::GetPrices]", DateTime.Now));
|
||||
if (!Authorizations.GetInstance().IsAuthorized(token)) return null;
|
||||
return PricingDA.GetPrices(symbol, days);
|
||||
}
|
||||
|
||||
[HttpGet(Name = "GetBollingerBands")]
|
||||
public BollingerBands GetBollingerBands(String token,String symbol,int dayCount)
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("[{0:G}][PriceController::GetBollingerBands]", DateTime.Now));
|
||||
if (!Authorizations.GetInstance().IsAuthorized(token)) return null;
|
||||
Prices prices=PricingDA.GetPrices(symbol,dayCount);
|
||||
BollingerBands bollingerBands=BollingerBandGenerator.GenerateBollingerBands(prices);
|
||||
return bollingerBands;
|
||||
}
|
||||
|
||||
[HttpGet(Name = "GetLatestPricingDate")]
|
||||
public DateTime GetLatestPricingDate(String token)
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("[{0:G}][PriceController::GetLatestPricingDate]", DateTime.Now));
|
||||
if (!Authorizations.GetInstance().IsAuthorized(token)) return DateTime.MinValue;
|
||||
DateTime latestPricingDate=PricingDA.GetLatestDate();
|
||||
return latestPricingDate;
|
||||
}
|
||||
|
||||
[HttpGet(Name = "GetCompanyNameForSymbol")]
|
||||
public String GetCompanyNameForSymbol(String token, String symbol)
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("[{0:G}][PortfolioController::GetCompanyNameForSymbol]", DateTime.Now));
|
||||
if (!Authorizations.GetInstance().IsAuthorized(token)) return null;
|
||||
String companyName=PricingDA.GetNameForSymbol(symbol);
|
||||
return companyName;
|
||||
}
|
||||
}
|
||||
}
|
||||
32
MarketDataServer/Controllers/PriceIndexController.cs
Executable file
32
MarketDataServer/Controllers/PriceIndexController.cs
Executable file
@@ -0,0 +1,32 @@
|
||||
using MarketData.MarketDataModel;
|
||||
using MarketData.DataAccess;
|
||||
using MarketDataServer.Authorization;
|
||||
using MarketData;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using LogLevel = MarketData.LogLevel;
|
||||
|
||||
namespace MarketDataServer.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("api/[controller]/[action]")]
|
||||
public class PriceIndexController : ControllerBase
|
||||
{
|
||||
//http://localhost:8000/api/PriceIndex/GetDistnctPriceIndices
|
||||
[HttpGet(Name = "GetDistinctPriceIndices")]
|
||||
public IEnumerable<String> GetDistinctPriceIndices(String token)
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("[{0:G}][PriceIndexController::GetDistinctPriceIndices]",DateTime.Now));
|
||||
if (!Authorizations.GetInstance().IsAuthorized(token)) return null;
|
||||
return ConsumerPriceIndexDA.GetDistinctIndices();
|
||||
}
|
||||
|
||||
[HttpGet(Name = "GetConsumerPriceIndex")]
|
||||
public IEnumerable<PriceIndex> GetConsumerPriceIndex(String token,String indexCode)
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("[{0:G}][PriceIndexController::GetOpenPositionsWithDescriptionAsOf]",DateTime.Now));
|
||||
if (!Authorizations.GetInstance().IsAuthorized(token)) return null;
|
||||
PriceIndices priceIndices=ConsumerPriceIndexDA.GetConsumerPriceIndex(indexCode);
|
||||
return priceIndices;
|
||||
}
|
||||
}
|
||||
}
|
||||
21
MarketDataServer/Controllers/WatchListController.cs
Executable file
21
MarketDataServer/Controllers/WatchListController.cs
Executable file
@@ -0,0 +1,21 @@
|
||||
using MarketData;
|
||||
using MarketData.DataAccess;
|
||||
using MarketDataServer.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using LogLevel = MarketData.LogLevel;
|
||||
|
||||
namespace MarketDataServer.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("api/[controller]/[action]")]
|
||||
public class WatchListController : ControllerBase
|
||||
{
|
||||
[HttpGet(Name = "GetWatchList")]
|
||||
public IEnumerable<String> GetWatchList(String token,String watchList)
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("[{0:G}][WatchListController::GetWatchList]", DateTime.Now));
|
||||
if (!Authorizations.GetInstance().IsAuthorized(token)) return null;
|
||||
return WatchListDA.GetWatchList(watchList);
|
||||
}
|
||||
}
|
||||
}
|
||||
26
MarketDataServer/Handlers/CustomHeaderHandler.cs
Executable file
26
MarketDataServer/Handlers/CustomHeaderHandler.cs
Executable file
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace MarketDataServer.Handlers
|
||||
{
|
||||
public class CustomHeaderHandler : DelegatingHandler
|
||||
{
|
||||
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
|
||||
{
|
||||
return base.SendAsync(request, cancellationToken)
|
||||
.ContinueWith((task) =>
|
||||
{
|
||||
HttpResponseMessage response = task.Result;
|
||||
response.Headers.Add("Access-Control-Allow-Origin", "*");
|
||||
//response.Headers.Add("Access-Control-Allow-Credentials", "true");
|
||||
//response.Headers.Add("Access-Control-Allow-Methods", "OPTIONS, GET, POST");
|
||||
//response.Headers.Add("Access-Control-Allow-Headers", "Content-Type, Depth, User-Agent, X-File-Size, X-Requested-With, If-Modified-Since, X-File-Name, Cache-Control");
|
||||
return response;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
23
MarketDataServer/MarketDataServer.csproj
Executable file
23
MarketDataServer/MarketDataServer.csproj
Executable file
@@ -0,0 +1,23 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<AssemblyName>mks</AssemblyName>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>disable</Nullable>
|
||||
<NoWarn>SYSLIB0014;CA1416;CS8769;CS0108;CS8602;CS8601;CS8620;CS8618;CS8603;CS8767;CS8625;CS8604;CS8600;CS8604</NoWarn>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\MarketData\MarketDataLib\MarketDataLib.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.3" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
|
||||
<PackageReference Include="MySql.Data" Version="9.2.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Update="appsettings.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
68
MarketDataServer/Program.cs
Executable file
68
MarketDataServer/Program.cs
Executable file
@@ -0,0 +1,68 @@
|
||||
using System.Diagnostics;
|
||||
using MarketData;
|
||||
using MarketData.Configuration;
|
||||
using MarketData.Utils;
|
||||
using MarketDataServer.Authorization;
|
||||
|
||||
namespace MarketDataServer
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
String logFileName="marketdataserver";
|
||||
Authorizations.GetInstance().IsEnabled=false;
|
||||
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// Add services to the container.
|
||||
GlobalConfig.Instance.Configuration = builder.Configuration;
|
||||
String baseAddress = GlobalConfig.Instance.Configuration["server_address"];
|
||||
CreateLogging(logFileName);
|
||||
|
||||
MDTrace.WriteLine(MarketData.LogLevel.DEBUG,$"Server Address:{baseAddress}");
|
||||
|
||||
builder.Services.AddControllers();
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
builder.Services.AddSwaggerGen( config =>
|
||||
{
|
||||
config.ResolveConflictingActions (apiDescriptions => apiDescriptions.First ());
|
||||
});
|
||||
|
||||
WebApplication webApplication = builder.Build();
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
if (webApplication.Environment.IsDevelopment()||webApplication.Environment.IsProduction() )
|
||||
{
|
||||
webApplication.UseSwagger();
|
||||
webApplication.UseSwaggerUI();
|
||||
}
|
||||
|
||||
webApplication.UseHttpsRedirection();
|
||||
webApplication.UseAuthorization();
|
||||
webApplication.MapControllers();
|
||||
webApplication.MapControllerRoute(name: "default",pattern: "api/{controller}/{action}/{id?}");
|
||||
webApplication.Run(baseAddress);
|
||||
}
|
||||
|
||||
private static bool CreateLogging(String task)
|
||||
{
|
||||
if(String.IsNullOrEmpty(task))return false;
|
||||
task=task.ToLower();
|
||||
MDTrace.LogLevel = MarketData.LogLevel.DEBUG;
|
||||
String logFolder = "/logs";
|
||||
DateTime currentDate=DateTime.Now;
|
||||
String strLogFile = "marketdata_" + task + ".log";
|
||||
String currentWorkingDirectory = Directory.GetCurrentDirectory();
|
||||
Console.WriteLine($"Current directory is {currentWorkingDirectory}");
|
||||
Utility.EnsureLogFolder(currentWorkingDirectory+logFolder);
|
||||
Utility.ExpireLogs(currentWorkingDirectory+logFolder,1);
|
||||
Trace.Listeners.Remove("Default");
|
||||
Console.WriteLine($"Adding Trace Listener :{currentWorkingDirectory+logFolder+"/"+strLogFile}");
|
||||
Trace.Listeners.Add(new TextWriterTraceListener(currentWorkingDirectory+logFolder+"/"+strLogFile));
|
||||
MDTrace.WriteLine($"Trace Listener added.");
|
||||
Utility.ShowLogs(currentWorkingDirectory + logFolder);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
17
MarketDataServer/appsettings.json
Executable file
17
MarketDataServer/appsettings.json
Executable file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"market_data" : "Database=market_data;Datasource=euporie;Username=guest;Password=guest",
|
||||
"portfolio_data" : "Database=portfolio_data;Datasource=euporie;Username=guest;Password=guest",
|
||||
"user_data" : "Database=user_data;Datasource=euporie;Username=guest;Password=guest",
|
||||
"server_address" : "http://localhost:8000/",
|
||||
"sms_smtpaddress" : "smtp.gmail.com",
|
||||
"sms_smsusername" : "skessler1964@gmail.com",
|
||||
"sms_smspassword" : "xjfo isnf gmyi zovr",
|
||||
"sms_smsrecipients" : "skessler1964@gmail.com",
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
||||
Reference in New Issue
Block a user