285 lines
10 KiB
C#
285 lines
10 KiB
C#
using Microsoft.AspNetCore.Components;
|
|
using MudBlazor;
|
|
using MarketData.Service;
|
|
using Microsoft.AspNetCore.Components.Authorization;
|
|
using eNavigator.Routes;
|
|
using MarketData.Utils;
|
|
using MarketData.MarketDataModel;
|
|
using eNavigator.Models;
|
|
using System.Text;
|
|
|
|
namespace eNavigator.Pages
|
|
{
|
|
public partial class BollingerBands
|
|
{
|
|
[Inject]
|
|
private AuthenticationStateProvider authenticationStateProvider { get; set; } = default;
|
|
|
|
[Inject]
|
|
private NavigationManager NavigationManager { get; set; } = default!;
|
|
|
|
protected bool IsBusy { get; set; } = false;
|
|
protected String BusyMessage { get; set;} = "";
|
|
|
|
protected List<SelectableSymbol> AvailableSymbols { get; set;} = new List<SelectableSymbol>{new SelectableSymbol(){Index=0,Name="---"}};
|
|
protected SelectableSymbol SelectedSymbol { get; set; } = new SelectableSymbol(){Index=0,Name="---"};
|
|
|
|
protected List<BollingerBandElement> BollingerBandElements { get; set; } = new List<BollingerBandElement>();
|
|
|
|
protected List<int> AvailableDayCounts { get; set; } = new List<int>{60,90,120,180,360,720,1440};
|
|
protected int SelectedDayCount { get; set; } = 120;
|
|
|
|
protected String Heading { get; set; } = "";
|
|
|
|
protected List<ChartSeries> ChartSeriesCollection { get; set; } = new List<ChartSeries>();
|
|
protected ChartOptions ChartingOptions{ get; set; } = new ChartOptions();
|
|
|
|
protected String[] XAxisLabels { get; set; } = new String[]{""};
|
|
|
|
protected override async Task OnInitializedAsync()
|
|
{
|
|
await base.OnInitializedAsync();
|
|
AuthenticationState authenticationState = await authenticationStateProvider.GetAuthenticationStateAsync();
|
|
if(!authenticationState.User.Identity.IsAuthenticated)
|
|
{
|
|
NavigationManager.NavigateTo(PageRoute.Login);
|
|
return;
|
|
}
|
|
await LoadSymbols();
|
|
SelectedSymbol = AvailableSymbols.Count()>0 ? AvailableSymbols[0] : SelectedSymbol;
|
|
await LoadBollingerBands(SelectedSymbol.Name, SelectedDayCount);
|
|
StateHasChanged();
|
|
Task.Run(async () => await Task.Yield()).GetAwaiter();
|
|
}
|
|
|
|
private async Task LoadSymbols()
|
|
{
|
|
BusyMessage = $"Loading symbols...";
|
|
IsBusy = true;
|
|
ServiceResult serviceResult = await marketDataServiceClient.GetWatchList("Valuations");
|
|
if(!serviceResult.Success)
|
|
{
|
|
DisplayToast("Error contacting server, could not load latest headlines.");
|
|
return;
|
|
}
|
|
List<String> availableSymbolsList = (serviceResult.ContextSpecificResult as List<String>);
|
|
List<SelectableSymbol> availableSymbols = new List<SelectableSymbol>();
|
|
for(int index=0;index<availableSymbolsList.Count;index++)
|
|
{
|
|
availableSymbols.Add(new SelectableSymbol(){Name=availableSymbolsList[index],Index=index});
|
|
}
|
|
AvailableSymbols = availableSymbols; //(serviceResult.ContextSpecificResult as List<String>);
|
|
DisplayToast($"Loaded {AvailableSymbols.Count} symbols in {Utility.FormatNumber(serviceResult.ElapsedTimeMS,0,true)}(ms).");
|
|
IsBusy = false;
|
|
}
|
|
|
|
private async Task LoadBollingerBands(String symbol,int dayCount)
|
|
{
|
|
String companyName = "";
|
|
BusyMessage = $"Loading {dayCount} day bollinger bands for {symbol} ...";
|
|
IsBusy = true;
|
|
|
|
ServiceResult serviceResult = await marketDataServiceClient.GetCompanyNameForSymbol(symbol);
|
|
if(serviceResult.Success)
|
|
{
|
|
companyName = (serviceResult.ContextSpecificResult as String);
|
|
}
|
|
|
|
serviceResult = await marketDataServiceClient.GetBollingerBands(symbol,dayCount);
|
|
if(!serviceResult.Success)
|
|
{
|
|
DisplayToast("Error contacting server, could not load bollinger bands.");
|
|
return;
|
|
}
|
|
BollingerBandElements = (serviceResult.ContextSpecificResult as List<BollingerBandElement>);
|
|
// if(BollingerBandElements.Count()>0)
|
|
// {
|
|
// Heading = SelectedSymbol + " - " + companyName + "("+ BollingerBandElements[BollingerBandElements.Count()-1].Date.ToShortDateString() + " Thru " + BollingerBandElements[0].Date.ToShortDateString()+ ")";
|
|
// }
|
|
DisplayToast($"Loaded {Utility.FormatNumber(BollingerBandElements.Count*13,0,true)} data points in {Utility.FormatNumber(serviceResult.ElapsedTimeMS,0,true)}(ms).");
|
|
CreateHeading(companyName);
|
|
CreateChartSeries();
|
|
CreateChartOptions();
|
|
CreateXAxisLabels();
|
|
|
|
IsBusy = false;
|
|
}
|
|
|
|
private void DisplayToast(String message)
|
|
{
|
|
snackbarService.Add(new MarkupString($"<ul><li>{message}</li></ul>"));
|
|
}
|
|
|
|
private async Task OnSymbolChanged()
|
|
{
|
|
await LoadBollingerBands(SelectedSymbol.Name, SelectedDayCount);
|
|
}
|
|
|
|
private async Task OnDayCountChanged()
|
|
{
|
|
await LoadBollingerBands(SelectedSymbol.Name, SelectedDayCount);
|
|
}
|
|
|
|
protected async Task RefreshClicked()
|
|
{
|
|
await Task.FromResult(true);
|
|
await LoadBollingerBands(SelectedSymbol.Name,SelectedDayCount);
|
|
StateHasChanged();
|
|
Task.Run(async () => await Task.Yield()).GetAwaiter();
|
|
}
|
|
|
|
private void CreateHeading(String companyName)
|
|
{
|
|
if(0==BollingerBandElements.Count())
|
|
{
|
|
Heading = "";
|
|
return;
|
|
}
|
|
BollingerBandElement bollingerBandElementCurrent = BollingerBandElements[0];
|
|
BollingerBandElement bollingerBandElementPrev = BollingerBandElements[1];
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.Append(companyName);
|
|
sb.Append(" (");
|
|
sb.Append(SelectedSymbol );
|
|
sb.Append(") ");
|
|
sb.Append(BollingerBandElements[BollingerBandElements.Count()-1].Date.ToShortDateString());
|
|
sb.Append(" Thru ");
|
|
sb.Append(BollingerBandElements[0].Date.ToShortDateString());
|
|
|
|
if(BollingerBandElements.Count()<2)
|
|
{
|
|
Heading = sb.ToString();
|
|
return;
|
|
}
|
|
|
|
double change=double.NaN;
|
|
if(0.00!=bollingerBandElementCurrent.Close)
|
|
{
|
|
change = (bollingerBandElementCurrent.Close - bollingerBandElementPrev.Close) / bollingerBandElementCurrent.Close;
|
|
}
|
|
|
|
sb.Append(" ");
|
|
sb.Append("(");
|
|
sb.Append(Utility.FormatCurrency(bollingerBandElementCurrent.Close));
|
|
sb.Append("/");
|
|
sb.Append(Utility.FormatCurrency(bollingerBandElementCurrent.Low));
|
|
if(!double.IsNaN(change))
|
|
{
|
|
sb.Append(",");
|
|
sb.Append(change>=0.00?"+":"").Append(Utility.FormatPercent((double)change,2));
|
|
}
|
|
sb.Append(")");
|
|
|
|
Heading = sb.ToString();
|
|
}
|
|
|
|
private void CreateXAxisLabels()
|
|
{
|
|
if(0==BollingerBandElements.Count())
|
|
{
|
|
return;
|
|
}
|
|
XAxisLabels = BuildXAxisLabels(6).ToArray();
|
|
}
|
|
|
|
private List<String> BuildXAxisLabels(int labels)
|
|
{
|
|
List<String> axisLabels = new List<String>();
|
|
if(0==BollingerBandElements.Count())
|
|
{
|
|
return axisLabels;
|
|
}
|
|
long dataPoints = BollingerBandElements.Count();
|
|
int intervals = (int)( (double)dataPoints/(double)labels);
|
|
for(int index=BollingerBandElements.Count()-1;index>=0;index--)
|
|
{
|
|
if(0==(index%intervals))
|
|
{
|
|
StringBuilder sb = new StringBuilder();
|
|
DateTime date = BollingerBandElements[index].Date;
|
|
sb.Append(date.Month.ToString());
|
|
sb.Append("/");
|
|
sb.Append(date.Year.ToString());
|
|
axisLabels.Add(sb.ToString());
|
|
}
|
|
else
|
|
{
|
|
axisLabels.Add("");
|
|
}
|
|
}
|
|
return axisLabels;
|
|
}
|
|
|
|
private void CreateChartOptions()
|
|
{
|
|
ChartingOptions = new ChartOptions()
|
|
{
|
|
LineStrokeWidth = 1,
|
|
XAxisLines = true,
|
|
YAxisFormat="c2",
|
|
ChartPalette = new[]
|
|
{
|
|
"#0000FF", // High
|
|
"#FF0000", // Low
|
|
"#000000", // Close
|
|
"#800080", // SMAN
|
|
"#13A10E", // K
|
|
"#13A10E", // L
|
|
"#13A10E", // KL1
|
|
"#13A10E" // LP1
|
|
}
|
|
};
|
|
}
|
|
|
|
private void CreateChartSeries()
|
|
{
|
|
ChartSeriesCollection = new List<ChartSeries>();
|
|
|
|
if(0==BollingerBandElements.Count())
|
|
{
|
|
return;
|
|
}
|
|
|
|
double[] highData = new double[BollingerBandElements.Count()];
|
|
double[] lowData = new double[BollingerBandElements.Count()];
|
|
double[] closeData = new double[BollingerBandElements.Count()];
|
|
double[] smanData = new double[BollingerBandElements.Count()];
|
|
double[] kData = new double[BollingerBandElements.Count()];
|
|
double[] lData = new double[BollingerBandElements.Count()];
|
|
double[] kl1Data = new double[BollingerBandElements.Count()];
|
|
double[] lp1Data = new double[BollingerBandElements.Count()];
|
|
|
|
for(int index=0;index<BollingerBandElements.Count();index++)
|
|
{
|
|
BollingerBandElement bollingerBandElement = BollingerBandElements[(BollingerBandElements.Count()-index)-1];
|
|
highData[index] = bollingerBandElement.High;
|
|
lowData[index] = bollingerBandElement.Low;
|
|
closeData[index] = bollingerBandElement.Close;
|
|
smanData[index] = bollingerBandElement.SMAN;
|
|
kData[index] = bollingerBandElement.K;
|
|
lData[index] = bollingerBandElement.L;
|
|
kl1Data[index] = bollingerBandElement.KL1;
|
|
lp1Data[index] = bollingerBandElement.LP1;
|
|
}
|
|
|
|
ChartSeries highSeries = new ChartSeries(){Name="High", Data=highData};
|
|
ChartSeries lowSeries = new ChartSeries(){Name="Low", Data=lowData};
|
|
ChartSeries closeSeries = new ChartSeries(){Name="Close", Data=closeData};
|
|
ChartSeries smanSeries = new ChartSeries(){Name="SMAN", Data=smanData};
|
|
ChartSeries kSeries = new ChartSeries(){Name="K", Data=kData};
|
|
ChartSeries lSeries = new ChartSeries(){Name="L", Data=lData};
|
|
ChartSeries kl1Series = new ChartSeries(){Name="KL1", Data=kl1Data};
|
|
ChartSeries lp1Series = new ChartSeries(){Name="LP1", Data=lp1Data};
|
|
|
|
ChartSeriesCollection.Add(highSeries);
|
|
ChartSeriesCollection.Add(lowSeries);
|
|
ChartSeriesCollection.Add(closeSeries);
|
|
ChartSeriesCollection.Add(smanSeries);
|
|
ChartSeriesCollection.Add(kSeries);
|
|
ChartSeriesCollection.Add(lSeries);
|
|
ChartSeriesCollection.Add(kl1Series);
|
|
ChartSeriesCollection.Add(lp1Series);
|
|
}
|
|
}
|
|
} |