Skip to content

Commit

Permalink
Desktop UI now interfaces via REST webservice instead of directly thr…
Browse files Browse the repository at this point in the history
…ough DLLs
  • Loading branch information
bleunguts committed Jan 29, 2024
1 parent f56a15c commit 5b847b8
Show file tree
Hide file tree
Showing 13 changed files with 2,848 additions and 50 deletions.
4 changes: 4 additions & 0 deletions ProjectX.Core/Endpoints.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,9 @@ public static class Endpoints
public const string ResultsPlotOptionBS = "PricingResults/bsPlot";
public const string FXSpotPriceStart = "FXPricing";
public const string FXSpotPriceEnd = "FXPricing";
public const string BacktestLongShortPnlMatrix = "BacktestService/ComputeLongShortPnlMatrix";
public const string BacktestLongShortPnl = "BacktestService/ComputeLongShortPnl";
public const string StockSignalMovingAverage = "StockSignal/MovingAverageSignals";
public const string StockSignalHursts = "StockSignal/Hursts";
}
}
11 changes: 5 additions & 6 deletions ProjectX.Core/Services/BacktestService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ namespace ProjectX.Core.Services
public interface IBacktestService
{
IEnumerable<StrategyPnl> ComputeLongShortPnl(IEnumerable<PriceSignal> inputSignals, double notional, double signalIn, double signalOut, TradingStrategy strategy);
IEnumerable<YearlyStrategyPnl> GetYearlyPnl(List<StrategyPnl> pnls);
IEnumerable<YearlyStrategyPnl> GetYearlyPnl(IEnumerable<StrategyPnl> pnls);
IEnumerable<MatrixStrategyPnl> ComputeLongShortPnlFull(IEnumerable<MarketPrice> inputSignals, double notional, TradingStrategy strategy);
IEnumerable<StrategyDrawdown> CalculateDrawdown(List<StrategyPnl> pnls, double notional);
IEnumerable<StrategyDrawdown> CalculateDrawdown(IEnumerable<StrategyPnl> pnls, double notional);
}

[Export(typeof(IBacktestService)), PartCreationPolicy(CreationPolicy.Shared)]
Expand Down Expand Up @@ -146,7 +146,7 @@ bool testSignal(double prevSignal_, double signalIn_, out PositionStatus positio
return (sp, spHolding);
}

public IEnumerable<YearlyStrategyPnl> GetYearlyPnl(List<StrategyPnl> pnls)
public IEnumerable<YearlyStrategyPnl> GetYearlyPnl(IEnumerable<StrategyPnl> pnls)
{
DateTime firstDate = pnls.First().Date;
DateTime lastDate = pnls.Last().Date;
Expand Down Expand Up @@ -218,16 +218,15 @@ public IEnumerable<MatrixStrategyPnl> ComputeLongShortPnlFull(IEnumerable<Market
return results;
}

public IEnumerable<StrategyDrawdown> CalculateDrawdown(List<StrategyPnl> pnls, double notional)
public IEnumerable<StrategyDrawdown> CalculateDrawdown(IEnumerable<StrategyPnl> pnls, double notional)
{
var results = new List<StrategyDrawdown>();

double max = 0; double maxHold = 0;
double min = 2.0 * notional; double minHold = 2.0 * notional;

for (int i = 0; i < pnls.Count; i++)
foreach (var current in pnls)
{
var current = pnls[i];
double pnl = current.PnLCum + notional;
double pnlHold = current.PnLCumHold + notional;
max = Math.Max(max, pnl);
Expand Down
2 changes: 1 addition & 1 deletion ProjectX.Core/Strategy/StrategyPnl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ public override string ToString()
return $"Ticker={Ticker},Date={Date.ToShortDateString()},Price={Price},Signal={Signal},Type={TradeType},NumTrades={NumTrades},DateIn={DateIn},PriceIn={PriceIn},PnlPerTrade={PnlPerTrade},PnlDaily={PnLDaily},PnlCum={PnLCum},PnlDailyHold={PnLDailyHold},PnlCumHold={PnLCumHold}";
}
}

public record StrategyDrawdown(DateTime date, double pnl, double drawdown, double drawup, double pnlHold, double drawdownHold, double drawupHold);
public record StrategyResults(IEnumerable<StrategyPnl> StrategyPnls, IEnumerable<YearlyStrategyPnl> YearlyStrategyPnls, IEnumerable<StrategyDrawdown> StrategyDrawdowns);
}
31 changes: 27 additions & 4 deletions ProjectX.GatewayAPI/Controllers/BacktestServiceController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using ProjectX.Core;
using ProjectX.Core.Services;
using ProjectX.Core.Strategy;
using System.Reflection.Metadata.Ecma335;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace ProjectX.GatewayAPI.Controllers;
Expand Down Expand Up @@ -32,23 +33,45 @@ public string Get()
return "Hello from BacktestServiceController";
}

[HttpGet("LongShortPnlStrategyChartData")]
[HttpGet("ComputeLongShortPnl")]
public async Task<ActionResult<StrategyResults>> ComputeLongShortPnl(string ticker, DateTime fromDate, DateTime toDate, double notional, int movingWindow, double signalIn, double signalOut, MovingAverageImpl movingAverageImpl)
{
var strategy = new TradingStrategy(TradingStrategyType.MeanReversion, shouldReinvest: false);

var smoothenedSignals = await _stockSignalService.GetSignalUsingMovingAverageByDefault(ticker, fromDate, toDate, movingWindow, movingAverageImpl);
var strategyPnls = _backtestService.ComputeLongShortPnl(smoothenedSignals, notional, signalIn, signalOut, strategy);
var yearlyPnls = _backtestService.GetYearlyPnl(strategyPnls);
var drawdownPnls = _backtestService.CalculateDrawdown(strategyPnls, notional);
return Ok(new StrategyResults(strategyPnls, yearlyPnls, drawdownPnls));
}

[HttpGet("ComputeLongShortPnlMatrix")]
public async Task<ActionResult<IEnumerable<MatrixStrategyPnl>>> ComputeLongShortPnlMatrix(string ticker, DateTime fromDate, DateTime toDate, double notional)
{
var strategy = new TradingStrategy(TradingStrategyType.MeanReversion, shouldReinvest: false);

var marketPrices = await _stockMarketSource.GetPrices(ticker, fromDate, toDate);
var pnls = _backtestService.ComputeLongShortPnlFull(marketPrices, notional, strategy);
return Ok(pnls);
}

[HttpGet("ComputeLongShortPnlStrategyChartData")]
public async Task<ActionResult<IEnumerable<StrategyChartData>>> ComputeLongShortPnlStrategyChartData(string ticker, DateTime fromDate, DateTime toDate, double notional, MovingAverageImpl movingAverageImpl = MovingAverageImpl.BollingerBandsImpl)
{
bool isReinvest = false;
var strategy = new TradingStrategy(TradingStrategyType.MeanReversion, shouldReinvest: false);

try
{
var marketPrices = await _stockMarketSource.GetPrices(ticker, fromDate, toDate);
var pnlRanking = _backtestService.ComputeLongShortPnlFull(marketPrices, notional, new TradingStrategy(TradingStrategyType.MeanReversion, isReinvest));
var pnlRanking = _backtestService.ComputeLongShortPnlFull(marketPrices, notional, strategy);

var maximumProfitStrategy = pnlRanking.OrderByDescending(p => p.pnlCum).First();
int movingWindow = maximumProfitStrategy.movingWindow;
double signalIn = maximumProfitStrategy.zin;
double signalOut = maximumProfitStrategy.zout;

var smoothenedSignals = await _stockSignalService.GetSignalUsingMovingAverageByDefault(ticker, fromDate, toDate, movingWindow, movingAverageImpl);
List<StrategyPnl> pnlForMaximumProfit = _backtestService.ComputeLongShortPnl(smoothenedSignals, notional, signalIn, signalOut, new TradingStrategy(TradingStrategyType.MeanReversion, isReinvest)).ToList();
List<StrategyPnl> pnlForMaximumProfit = _backtestService.ComputeLongShortPnl(smoothenedSignals, notional, signalIn, signalOut, strategy).ToList();
var data = pnlForMaximumProfit.Select(p => new StrategyChartData(p.Date.ToString("ddMMyy"), p.PnLCum, p.PnLCumHold));
return Ok(data);
}
Expand Down
38 changes: 38 additions & 0 deletions ProjectX.GatewayAPI/Controllers/StockSignalController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using Microsoft.AspNetCore.Mvc;
using ProjectX.Core;
using ProjectX.Core.Services;
using ProjectX.Core.Strategy;

namespace ProjectX.GatewayAPI.Controllers;

[ApiController]
[Route("[controller]")]
public class StockSignalController : ControllerBase
{
private readonly ILogger<StockSignalController> _logger;
private readonly IStockSignalService _stockSignalService;
private readonly IStockMarketSource _stockMarketSource;

public StockSignalController(ILogger<StockSignalController> logger, IStockSignalService stockSignalService, IStockMarketSource stockMarketSource)
{
_logger = logger;
_stockSignalService = stockSignalService;
_stockMarketSource = stockMarketSource;
}

[HttpGet("MovingAverageSignals")]
public async Task<ActionResult<IEnumerable<PriceSignal>>> MovingAverageSignalAsync(string ticker, DateTime fromDate, DateTime toDate, int movingWindow, MovingAverageImpl movingAverageImpl)
{
var signals = await _stockSignalService.GetSignalUsingMovingAverageByDefault(ticker, fromDate, toDate, movingWindow, movingAverageImpl);

return Ok(signals);
}

[HttpGet("Hursts")]
public async Task<ActionResult<IEnumerable<double?>>> Hursts(string ticker, DateTime fromDate, DateTime toDate)
{
var signals = await _stockMarketSource.GetHurst(ticker, fromDate, toDate);

return Ok(signals);
}
}
34 changes: 23 additions & 11 deletions ProjectX.GatewayAPI/ProjectX.GatewayAPI.http
Original file line number Diff line number Diff line change
Expand Up @@ -39,45 +39,57 @@ GET {{GatewayAPI_HostAddress}}/BacktestService
Accept: application/json
###

GET {{GatewayAPI_HostAddress}}/BacktestService/LongShortStrategy?ticker=AAPL&fromDate=2023-05-01&toDate=2023-09-25&notional=10000
GET {{GatewayAPI_HostAddress}}/BacktestService/ComputeLongShortPnlStrategyChartData?ticker=AAPL&fromDate=2023-05-01&toDate=2023-09-25&notional=10000
Accept: application/json
###

GET {{GatewayAPI_HostAddress}}/BacktestService/LongShortStrategy?ticker=IBM&fromDate=2023-05-01&toDate=2023-09-25&notional=10000
GET {{GatewayAPI_HostAddress}}/BacktestService/ComputeLongShortPnlStrategyChartData?ticker=IBM&fromDate=2023-05-01&toDate=2023-09-25&notional=10000
Accept: application/json
###

GET {{GatewayAPI_HostAddress}}/BacktestService/LongShortStrategy?ticker=BTCUSD&fromDate=2023-05-01&toDate=2023-09-25&notional=10000
GET {{GatewayAPI_HostAddress}}/BacktestService/ComputeLongShortPnlStrategyChartData?ticker=BTCUSD&fromDate=2023-05-01&toDate=2023-09-25&notional=10000
Accept: application/json
###
GET {{GatewayAPI_HostAddress}}/BacktestService/LongShortStrategy?ticker=CCCC&fromDate=2023-05-01&toDate=2023-09-25&notional=10000
GET {{GatewayAPI_HostAddress}}/BacktestService/ComputeLongShortPnlStrategyChartData?ticker=CCCC&fromDate=2023-05-01&toDate=2023-09-25&notional=10000
Accept: application/json
###

GET {{GatewayAPI_HostAddress}}/BacktestService/LongShortStrategy?ticker=STTK&fromDate=2023-05-01&toDate=2023-09-25&notional=10000
GET {{GatewayAPI_HostAddress}}/BacktestService/ComputeLongShortPnlStrategyChartData?ticker=STTK&fromDate=2023-05-01&toDate=2023-09-25&notional=10000
Accept: application/json
###

GET {{GatewayAPI_HostAddress}}/BacktestService/LongShortStrategy?ticker=CPLS&fromDate=2023-05-01&toDate=2023-09-25&notional=10000
GET {{GatewayAPI_HostAddress}}/BacktestService/ComputeLongShortPnlStrategyChartData?ticker=CPLS&fromDate=2023-05-01&toDate=2023-09-25&notional=10000
Accept: application/json
###

GET {{GatewayAPI_HostAddress}}/BacktestService/LongShortStrategy?ticker=SBNY&fromDate=2023-05-01&toDate=2023-09-25&notional=10000
GET {{GatewayAPI_HostAddress}}/BacktestService/ComputeLongShortPnlStrategyChartData?ticker=SBNY&fromDate=2023-05-01&toDate=2023-09-25&notional=10000
Accept: application/json
###

GET {{GatewayAPI_HostAddress}}/BacktestService/LongShortStrategy?ticker=PHUN&fromDate=2023-05-01&toDate=2023-09-25&notional=10000
GET {{GatewayAPI_HostAddress}}/BacktestService/ComputeLongShortPnlStrategyChartData?ticker=PHUN&fromDate=2023-05-01&toDate=2023-09-25&notional=10000
Accept: application/json
###

GET {{GatewayAPI_HostAddress}}/BacktestService/LongShortStrategy?ticker=SOXS&fromDate=2023-05-01&toDate=2023-09-25&notional=10000
GET {{GatewayAPI_HostAddress}}/BacktestService/ComputeLongShortPnlStrategyChartData?ticker=SOXS&fromDate=2023-05-01&toDate=2023-09-25&notional=10000
Accept: application/json
###

GET {{GatewayAPI_HostAddress}}/BacktestService/LongShortStrategy?ticker=INTC&fromDate=2023-05-01&toDate=2023-09-25&notional=10000
GET {{GatewayAPI_HostAddress}}/BacktestService/ComputeLongShortPnlStrategyChartData?ticker=INTC&fromDate=2023-05-01&toDate=2023-09-25&notional=10000
Accept: application/json
###

GET {{GatewayAPI_HostAddress}}/BacktestService/LongShortStrategy?ticker=IVP&fromDate=2023-05-01&toDate=2023-09-25&notional=10000
GET {{GatewayAPI_HostAddress}}/BacktestService/ComputeLongShortPnlStrategyChartData?ticker=IVP&fromDate=2023-05-01&toDate=2023-09-25&notional=10000
Accept: application/json
###

GET {{GatewayAPI_HostAddress}}/BacktestService/ComputeLongShortPnl?ticker=AAPL&fromDate=2023-05-01&toDate=2023-09-25&notional=10000&movingWindow=10&signalIn=0.4&signalOut=0.5&movingAverageImpl=1
Accept: application/json
###

GET {{GatewayAPI_HostAddress}}/StockSignal/MovingAverageSignals?ticker=AAPL&fromDate=2023-05-01&toDate=2023-09-25&movingWindow=10&movingAverageImpl=1
Accept: application/json
###

GET {{GatewayAPI_HostAddress}}/StockSignal/Hursts?ticker=AAPL&fromDate=2023-05-01&toDate=2023-09-25
Accept: application/json
###
4 changes: 2 additions & 2 deletions ProjectX.GatewayAPI/appsettings.Development.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
"LogLevel": {
"Default": "Debug",
"Microsoft.AspNetCore": "Information",
"Microsoft.AspNetCore.SignalR": "Information",
"Microsoft.AspNetCore.Http.Connections": "Information"
"Microsoft.AspNetCore.SignalR": "Warning",
"Microsoft.AspNetCore.Http.Connections": "Debug"
}
},
"ExternalServices": {
Expand Down
4 changes: 2 additions & 2 deletions ProjectX.GatewayAPI/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Information",
"Microsoft.AspNetCore.SignalR": "Information",
"Microsoft.AspNetCore.Http.Connections": "Debug"
"Microsoft.AspNetCore.SignalR": "Warning",
"Microsoft.AspNetCore.Http.Connections": "Information"
}
},
"AllowedHosts": "*",
Expand Down

0 comments on commit 5b847b8

Please sign in to comment.