|
|
|
|
@@ -20,69 +20,136 @@ using MarketData.Numerical;
|
|
|
|
|
using MarketData;
|
|
|
|
|
using Avalonia.Controls.Platform;
|
|
|
|
|
using System.Threading;
|
|
|
|
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
|
|
|
|
|
|
|
|
namespace PortfolioManager.Renderers
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// ********************************************************************************************************************************
|
|
|
|
|
public class TextPlot
|
|
|
|
|
// public class TextPlot
|
|
|
|
|
// {
|
|
|
|
|
// public TextPlot()
|
|
|
|
|
// {
|
|
|
|
|
// }
|
|
|
|
|
// public TextPlot(String markerText,SKRect boundingRect,Pixel screenCoordinates)
|
|
|
|
|
// {
|
|
|
|
|
// BoundingRect = boundingRect;
|
|
|
|
|
// ScreenCoordinates = screenCoordinates;
|
|
|
|
|
// MarkerText = markerText;
|
|
|
|
|
// }
|
|
|
|
|
// public Pixel ScreenCoordinates { get; set; }
|
|
|
|
|
// public SKRect BoundingRect { get; set; }
|
|
|
|
|
// public String MarkerText { get; set; }
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// public class TextPlots : List<TextPlot>
|
|
|
|
|
// {
|
|
|
|
|
// public TextPlots()
|
|
|
|
|
// {
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// /// <summary>
|
|
|
|
|
// /// The coordinate system is based on (0,0) in the upper left
|
|
|
|
|
// /// </summary>
|
|
|
|
|
// /// <param name="coordinates"></param>
|
|
|
|
|
// /// <returns></returns>
|
|
|
|
|
// public bool PointInRects(String markerText,Pixel screenCoordinates,ref Pixel adjustedScreenCoordinates,float factor)
|
|
|
|
|
// {
|
|
|
|
|
// MDTrace.WriteLine(LogLevel.DEBUG,$"Searching for rectangles in X:{screenCoordinates.X}Y:{screenCoordinates.Y}");
|
|
|
|
|
// foreach(TextPlot textPlot in this)
|
|
|
|
|
// {
|
|
|
|
|
// if(Math.Round(screenCoordinates.X,2) >= Math.Round(textPlot.BoundingRect.Left,2) &&
|
|
|
|
|
// Math.Round(screenCoordinates.X,2) <= Math.Round(textPlot.BoundingRect.Right,2) &&
|
|
|
|
|
// Math.Round(screenCoordinates.Y,2) >= Math.Round(textPlot.BoundingRect.Top,2) &&
|
|
|
|
|
// Math.Round(screenCoordinates.Y,2) <= Math.Round(textPlot.BoundingRect.Bottom,2))
|
|
|
|
|
// {
|
|
|
|
|
// MDTrace.WriteLine(LogLevel.DEBUG,$"The text {markerText} at Point:X:{screenCoordinates.X}:Y:{screenCoordinates.Y} is within Rect:L({textPlot.BoundingRect.Left}),T({textPlot.BoundingRect.Top}),R({textPlot.BoundingRect.Right}),B({textPlot.BoundingRect.Bottom}) with text {textPlot.MarkerText} which is plotted at Coordinates:X:{textPlot.ScreenCoordinates.X} Y:{textPlot.ScreenCoordinates.Y}");
|
|
|
|
|
// SKRect lowestRect = FindLowestAdjacentRect(textPlot.BoundingRect);
|
|
|
|
|
// adjustedScreenCoordinates.Y = textPlot.ScreenCoordinates.Y - factor;
|
|
|
|
|
// adjustedScreenCoordinates.X = screenCoordinates.X;
|
|
|
|
|
// return true;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// return false;
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// public void Summary()
|
|
|
|
|
// {
|
|
|
|
|
// MDTrace.WriteLine(LogLevel.DEBUG,$"TextPlots:{Count}");
|
|
|
|
|
// foreach(TextPlot textPlot in this)
|
|
|
|
|
// {
|
|
|
|
|
// MDTrace.WriteLine(LogLevel.DEBUG,$"Rect:L({textPlot.BoundingRect.Left}),T({textPlot.BoundingRect.Top}),R({textPlot.BoundingRect.Right}),B({textPlot.BoundingRect.Bottom}) with text {textPlot.MarkerText} is plotted at Coordinates:X:{textPlot.ScreenCoordinates.X} Y:{textPlot.ScreenCoordinates.Y}");
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// /// <summary>
|
|
|
|
|
// /// Find the Rectangle with the highest Bottom that lies within the X-plane
|
|
|
|
|
// /// </summary>
|
|
|
|
|
// /// <returns></returns>
|
|
|
|
|
// private SKRect FindLowestAdjacentRect(SKRect rect)
|
|
|
|
|
// {
|
|
|
|
|
// List<SKRect> adjacentRects = this.Where(x=> rect.Left >= x.BoundingRect.Left && rect.Right <= x.BoundingRect.Right).Select(x=>x.BoundingRect).ToList();
|
|
|
|
|
// if(null == adjacentRects || 0==adjacentRects.Count)return new SKRect(){Left=0,Top=0,Right=0,Bottom=0};
|
|
|
|
|
// adjacentRects = adjacentRects.OrderByDescending(x=>x.Bottom).ToList();
|
|
|
|
|
// return adjacentRects[0];
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
public class MarkerItem
|
|
|
|
|
{
|
|
|
|
|
public TextPlot()
|
|
|
|
|
public MarkerItem(double markerDate, double markerPrice)
|
|
|
|
|
{
|
|
|
|
|
MarkerDate = markerDate;
|
|
|
|
|
MarkerPrice = markerPrice;
|
|
|
|
|
}
|
|
|
|
|
public TextPlot(String markerText,SKRect boundingRect,Pixel screenCoordinates)
|
|
|
|
|
{
|
|
|
|
|
BoundingRect = boundingRect;
|
|
|
|
|
ScreenCoordinates = screenCoordinates;
|
|
|
|
|
MarkerText = markerText;
|
|
|
|
|
}
|
|
|
|
|
public Pixel ScreenCoordinates { get; set; }
|
|
|
|
|
public SKRect BoundingRect { get; set; }
|
|
|
|
|
public String MarkerText { get; set; }
|
|
|
|
|
|
|
|
|
|
public double MarkerDate { get; set; }
|
|
|
|
|
|
|
|
|
|
public double MarkerPrice { get; set; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class TextPlots : List<TextPlot>
|
|
|
|
|
|
|
|
|
|
public class TextMarkerManager : List<MarkerItem>
|
|
|
|
|
{
|
|
|
|
|
public TextPlots()
|
|
|
|
|
private DateGenerator dateGenerator = new DateGenerator();
|
|
|
|
|
private const double DATE_SPREAD_PCNT = 2.0; // PERCENT
|
|
|
|
|
private const double PRICE_SPREAD_PCNT = 2.0; // PERCENT
|
|
|
|
|
|
|
|
|
|
public Coordinates GetBestMarkerLocation(double markerDate, double markerPrice,OffsetDictionary offsetDictionary,double verticalAdjustmentFactor)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The coordinate system is based on (0,0) in the upper left
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="coordinates"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public bool PointInRects(String markerText,Pixel screenCoordinates,ref Pixel adjustedScreenCoordinates,float factor)
|
|
|
|
|
{
|
|
|
|
|
foreach(TextPlot textPlot in this)
|
|
|
|
|
if(!IsOverlapped(markerDate,markerPrice,offsetDictionary))
|
|
|
|
|
{
|
|
|
|
|
if(Math.Round(screenCoordinates.X,2) >= Math.Round(textPlot.BoundingRect.Left,2) &&
|
|
|
|
|
Math.Round(screenCoordinates.X,2) <= Math.Round(textPlot.BoundingRect.Right,2) &&
|
|
|
|
|
Math.Round(screenCoordinates.Y,2) >= Math.Round(textPlot.BoundingRect.Top,2) &&
|
|
|
|
|
Math.Round(screenCoordinates.Y,2) <= Math.Round(textPlot.BoundingRect.Bottom,2))
|
|
|
|
|
{
|
|
|
|
|
MDTrace.WriteLine(LogLevel.DEBUG,$"The text {markerText} at Point:X:{screenCoordinates.X}:Y:{screenCoordinates.Y} is within Rect:L({textPlot.BoundingRect.Left}),T({textPlot.BoundingRect.Top}),R({textPlot.BoundingRect.Right}),B({textPlot.BoundingRect.Bottom}) with text {textPlot.MarkerText} which is plotted at Coordinates:X:{textPlot.ScreenCoordinates.X} Y:{textPlot.ScreenCoordinates.Y}");
|
|
|
|
|
SKRect lowestRect = FindLowestAdjacentRect(textPlot.BoundingRect);
|
|
|
|
|
adjustedScreenCoordinates.Y = textPlot.ScreenCoordinates.Y - factor;
|
|
|
|
|
adjustedScreenCoordinates.X = screenCoordinates.X;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
Add(new MarkerItem(markerDate, markerPrice));
|
|
|
|
|
return new Coordinates(){X=markerDate,Y=markerPrice};
|
|
|
|
|
}
|
|
|
|
|
Add(new MarkerItem(markerDate, markerPrice));
|
|
|
|
|
return new Coordinates(){X=markerDate,Y=markerPrice-verticalAdjustmentFactor};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private bool IsOverlapped(double markerDate, double markerPrice,OffsetDictionary offsetDictionary)
|
|
|
|
|
{
|
|
|
|
|
foreach(MarkerItem markerItem in this)
|
|
|
|
|
{
|
|
|
|
|
double markerItemDate = markerItem.MarkerDate;
|
|
|
|
|
double markerItemPrice = markerItem.MarkerPrice;
|
|
|
|
|
// double minDate = markerItemDate/(1.00+DATE_SPREAD_PCNT/100.0);
|
|
|
|
|
// double maxDate = markerItemDate*(1.00+DATE_SPREAD_PCNT/100.0);
|
|
|
|
|
// double minPrice = markerItemPrice/(1.00+PRICE_SPREAD_PCNT/100.0);
|
|
|
|
|
// double maxPrice = markerItemPrice*(1.00+PRICE_SPREAD_PCNT/100.0);
|
|
|
|
|
|
|
|
|
|
double minDate = markerItemDate - offsetDictionary.HorizontalSpread*(DATE_SPREAD_PCNT/100.0);
|
|
|
|
|
double maxDate = markerItemDate + offsetDictionary.HorizontalSpread*(DATE_SPREAD_PCNT/100.0);
|
|
|
|
|
double minPrice = markerItemPrice - offsetDictionary.VerticalSpread*(PRICE_SPREAD_PCNT/100.0);
|
|
|
|
|
double maxPrice = markerItemPrice + offsetDictionary.VerticalSpread*(PRICE_SPREAD_PCNT/100.0);
|
|
|
|
|
|
|
|
|
|
if(markerDate>=minDate && markerDate<=maxDate && markerPrice >=minPrice && markerPrice<=maxPrice)
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Find the Rectangle with the highest Bottom that lies within the X-plane
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private SKRect FindLowestAdjacentRect(SKRect rect)
|
|
|
|
|
{
|
|
|
|
|
List<SKRect> adjacentRects = this.Where(x=> rect.Left >= x.BoundingRect.Left && rect.Right <= x.BoundingRect.Right).Select(x=>x.BoundingRect).ToList();
|
|
|
|
|
if(null == adjacentRects || 0==adjacentRects.Count)return new SKRect(){Left=0,Top=0,Right=0,Bottom=0};
|
|
|
|
|
adjacentRects = adjacentRects.OrderByDescending(x=>x.Bottom).ToList();
|
|
|
|
|
return adjacentRects[0];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// *********************************************************************************************************************************************
|
|
|
|
|
|
|
|
|
|
@@ -105,7 +172,8 @@ namespace PortfolioManager.Renderers
|
|
|
|
|
private Prices prices = default;
|
|
|
|
|
private BollingerBands bollingerBands;
|
|
|
|
|
private InsiderTransactionSummaries insiderTransactionSummaries = null;
|
|
|
|
|
// private TextPlots textPlots = new TextPlots();
|
|
|
|
|
// private TextPlots textPlots = new TextPlots();
|
|
|
|
|
private TextMarkerManager textMarkerManager = new TextMarkerManager();
|
|
|
|
|
|
|
|
|
|
private OffsetDictionary offsets = new OffsetDictionary();
|
|
|
|
|
|
|
|
|
|
@@ -131,78 +199,87 @@ namespace PortfolioManager.Renderers
|
|
|
|
|
|
|
|
|
|
public void Render()
|
|
|
|
|
{
|
|
|
|
|
MDTrace.WriteLine(LogLevel.DEBUG,$"[Render] ENTER");
|
|
|
|
|
Plotter.Plot.Axes.Left.TickGenerator = new ScottPlot.TickGenerators.NumericAutomatic()
|
|
|
|
|
lock(Plotter.Plot.Sync)
|
|
|
|
|
{
|
|
|
|
|
LabelFormatter = (double value) => value.ToString("C") // "C" format specifier formats as currency
|
|
|
|
|
};
|
|
|
|
|
Plotter.Plot.Axes.DateTimeTicksBottom();
|
|
|
|
|
Plotter.Plot.Axes.AutoScale();
|
|
|
|
|
Plotter.Plot.XLabel("Date");
|
|
|
|
|
Plotter.Plot.YLabel("Price");
|
|
|
|
|
Plotter.Refresh();
|
|
|
|
|
base.OnPropertyChanged("ShowLegend");
|
|
|
|
|
MDTrace.WriteLine(LogLevel.DEBUG,$"[Render] LEAVE");
|
|
|
|
|
MDTrace.WriteLine(LogLevel.DEBUG,$"[Render] ENTER");
|
|
|
|
|
Plotter.Plot.Axes.Left.TickGenerator = new ScottPlot.TickGenerators.NumericAutomatic()
|
|
|
|
|
{
|
|
|
|
|
LabelFormatter = (double value) => value.ToString("C") // "C" format specifier formats as currency
|
|
|
|
|
};
|
|
|
|
|
Plotter.Plot.Axes.DateTimeTicksBottom();
|
|
|
|
|
Plotter.Plot.Axes.AutoScale();
|
|
|
|
|
Plotter.Plot.XLabel("Date");
|
|
|
|
|
Plotter.Plot.YLabel("Price");
|
|
|
|
|
if (!ShowLegend) Plotter.Plot.HideLegend();
|
|
|
|
|
else Plotter.Plot.ShowLegend();
|
|
|
|
|
Plotter.Refresh();
|
|
|
|
|
MDTrace.WriteLine(LogLevel.DEBUG,$"[Render] LEAVE");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void SetData(String selectedSymbol, int selectedDayCount)
|
|
|
|
|
{
|
|
|
|
|
MDTrace.WriteLine(LogLevel.DEBUG,$"[SetData] ENTER");
|
|
|
|
|
this.selectedSymbol = selectedSymbol;
|
|
|
|
|
this.selectedDayCount = selectedDayCount;
|
|
|
|
|
stopLimit = PortfolioDA.GetStopLimit(selectedSymbol);
|
|
|
|
|
portfolioTrades = PortfolioDA.GetTradesSymbol(selectedSymbol);
|
|
|
|
|
portfolioTradesLots = LotAggregator.CombineLots(portfolioTrades);
|
|
|
|
|
|
|
|
|
|
Plotter.Plot.Clear();
|
|
|
|
|
if (null != portfolioTrades && 0 != portfolioTrades.Count)
|
|
|
|
|
lock(Plotter.Plot.Sync)
|
|
|
|
|
{
|
|
|
|
|
DateGenerator dateGenerator = new DateGenerator();
|
|
|
|
|
DateTime earliestTrade = portfolioTrades[0].TradeDate;
|
|
|
|
|
earliestTrade = earliestTrade.AddDays(-30);
|
|
|
|
|
int daysBetween = dateGenerator.DaysBetween(earliestTrade, DateTime.Now);
|
|
|
|
|
if (daysBetween < selectedDayCount || !syncTradeToBand) prices = PricingDA.GetPrices(selectedSymbol, selectedDayCount);
|
|
|
|
|
else prices = PricingDA.GetPrices(selectedSymbol, earliestTrade);
|
|
|
|
|
MDTrace.WriteLine(LogLevel.DEBUG,$"[SetData] ENTER");
|
|
|
|
|
this.selectedSymbol = selectedSymbol;
|
|
|
|
|
this.selectedDayCount = selectedDayCount;
|
|
|
|
|
stopLimit = PortfolioDA.GetStopLimit(selectedSymbol);
|
|
|
|
|
portfolioTrades = PortfolioDA.GetTradesSymbol(selectedSymbol);
|
|
|
|
|
portfolioTradesLots = LotAggregator.CombineLots(portfolioTrades);
|
|
|
|
|
|
|
|
|
|
DateTime earliestInsiderTransactionDate = dateGenerator.GenerateFutureBusinessDate(prices[prices.Count - 1].Date, 30);
|
|
|
|
|
insiderTransactionSummaries = InsiderTransactionDA.GetInsiderTransactionSummaries(selectedSymbol, earliestInsiderTransactionDate);
|
|
|
|
|
|
|
|
|
|
// calculate the break even price on the open trades for this symbol
|
|
|
|
|
PortfolioTrades openTrades = portfolioTrades.GetOpenTrades();
|
|
|
|
|
DateTime latestPricingDate = PricingDA.GetLatestDate(selectedSymbol);
|
|
|
|
|
latestPrice = PricingDA.GetPrice(selectedSymbol, latestPricingDate);
|
|
|
|
|
zeroPrice = ParityGenerator.GenerateGainLossValue(openTrades, latestPrice);
|
|
|
|
|
|
|
|
|
|
if (!syncTradeToBand)
|
|
|
|
|
{
|
|
|
|
|
DateTime earliestPricingDate = prices[prices.Count - 1].Date;
|
|
|
|
|
earliestPricingDate = earliestPricingDate.AddDays(30);
|
|
|
|
|
IEnumerable<PortfolioTrade> tradesInRange = (from portfolioTrade in portfolioTradesLots where portfolioTrade.TradeDate >= earliestPricingDate select portfolioTrade);
|
|
|
|
|
portfolioTrades = new PortfolioTrades();
|
|
|
|
|
foreach (PortfolioTrade portfolioTrade in tradesInRange) portfolioTrades.Add(portfolioTrade);
|
|
|
|
|
portfolioTradesLots = portfolioTrades;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
prices = PricingDA.GetPrices(selectedSymbol, selectedDayCount);
|
|
|
|
|
if (null != prices && 0 != prices.Count)
|
|
|
|
|
Plotter.Plot.Clear();
|
|
|
|
|
if (null != portfolioTrades && 0 != portfolioTrades.Count)
|
|
|
|
|
{
|
|
|
|
|
DateGenerator dateGenerator = new DateGenerator();
|
|
|
|
|
DateTime earliestTrade = portfolioTrades[0].TradeDate;
|
|
|
|
|
earliestTrade = earliestTrade.AddDays(-30);
|
|
|
|
|
int daysBetween = dateGenerator.DaysBetween(earliestTrade, DateTime.Now);
|
|
|
|
|
if (daysBetween < selectedDayCount || !syncTradeToBand) prices = PricingDA.GetPrices(selectedSymbol, selectedDayCount);
|
|
|
|
|
else prices = PricingDA.GetPrices(selectedSymbol, earliestTrade);
|
|
|
|
|
|
|
|
|
|
DateTime earliestInsiderTransactionDate = dateGenerator.GenerateFutureBusinessDate(prices[prices.Count - 1].Date, 30);
|
|
|
|
|
insiderTransactionSummaries = InsiderTransactionDA.GetInsiderTransactionSummaries(selectedSymbol, earliestInsiderTransactionDate);
|
|
|
|
|
|
|
|
|
|
// calculate the break even price on the open trades for this symbol
|
|
|
|
|
PortfolioTrades openTrades = portfolioTrades.GetOpenTrades();
|
|
|
|
|
DateTime latestPricingDate = PricingDA.GetLatestDate(selectedSymbol);
|
|
|
|
|
latestPrice = PricingDA.GetPrice(selectedSymbol, latestPricingDate);
|
|
|
|
|
zeroPrice = ParityGenerator.GenerateGainLossValue(openTrades, latestPrice);
|
|
|
|
|
|
|
|
|
|
if (!syncTradeToBand)
|
|
|
|
|
{
|
|
|
|
|
DateTime earliestPricingDate = prices[prices.Count - 1].Date;
|
|
|
|
|
earliestPricingDate = earliestPricingDate.AddDays(30);
|
|
|
|
|
IEnumerable<PortfolioTrade> tradesInRange = (from portfolioTrade in portfolioTradesLots where portfolioTrade.TradeDate >= earliestPricingDate select portfolioTrade);
|
|
|
|
|
portfolioTrades = new PortfolioTrades();
|
|
|
|
|
foreach (PortfolioTrade portfolioTrade in tradesInRange) portfolioTrades.Add(portfolioTrade);
|
|
|
|
|
portfolioTradesLots = portfolioTrades;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
prices = PricingDA.GetPrices(selectedSymbol, selectedDayCount);
|
|
|
|
|
if (null != prices && 0 != prices.Count)
|
|
|
|
|
{
|
|
|
|
|
DateGenerator dateGenerator = new DateGenerator();
|
|
|
|
|
DateTime earliestInsiderTransactionDate = dateGenerator.GenerateFutureBusinessDate(prices[prices.Count - 1].Date, 30);
|
|
|
|
|
insiderTransactionSummaries = InsiderTransactionDA.GetInsiderTransactionSummaries(selectedSymbol, earliestInsiderTransactionDate);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
bollingerBands = BollingerBandGenerator.GenerateBollingerBands(prices);
|
|
|
|
|
// textPlots.Clear();
|
|
|
|
|
textMarkerManager.Clear();
|
|
|
|
|
CalculateOffsets();
|
|
|
|
|
GenerateBollingerBands();
|
|
|
|
|
GenerateLeastSquares();
|
|
|
|
|
GenerateInsiderTransactions();
|
|
|
|
|
GenerateStopLimits();
|
|
|
|
|
GenerateTradePoints();
|
|
|
|
|
GenerateZeroPoint(zeroPrice);
|
|
|
|
|
// textPlots.Summary();
|
|
|
|
|
MDTrace.WriteLine(LogLevel.DEBUG,$"[SetData] LEAVE");
|
|
|
|
|
}
|
|
|
|
|
bollingerBands = BollingerBandGenerator.GenerateBollingerBands(prices);
|
|
|
|
|
// textPlots.Clear();
|
|
|
|
|
CalculateOffsets();
|
|
|
|
|
GenerateBollingerBands();
|
|
|
|
|
GenerateLeastSquares();
|
|
|
|
|
GenerateInsiderTransactions();
|
|
|
|
|
GenerateStopLimits();
|
|
|
|
|
GenerateTradePoints();
|
|
|
|
|
GenerateZeroPoint(zeroPrice);
|
|
|
|
|
MDTrace.WriteLine(LogLevel.DEBUG,$"[SetData] LEAVE");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
@@ -210,29 +287,29 @@ namespace PortfolioManager.Renderers
|
|
|
|
|
/// </summary>
|
|
|
|
|
private void CalculateOffsets()
|
|
|
|
|
{
|
|
|
|
|
double maxBollingerDate = bollingerBands.Max(x => x.Date).ToOADate();
|
|
|
|
|
double minBollingerDate = bollingerBands.Min(x => x.Date).ToOADate();
|
|
|
|
|
double maxBollingerValue = bollingerBands.Max(x => x.K);
|
|
|
|
|
double minBollingerValue = bollingerBands.Min(x => x.L);
|
|
|
|
|
offsets.MaxBollingerDate = bollingerBands.Max(x => x.Date).ToOADate();
|
|
|
|
|
offsets.MinBollingerDate = bollingerBands.Min(x => x.Date).ToOADate();
|
|
|
|
|
offsets.MaxBollingerValue = bollingerBands.Max(x => x.K);
|
|
|
|
|
offsets.MinBollingerValue = bollingerBands.Min(x => x.L);
|
|
|
|
|
|
|
|
|
|
offsets.Add(OffsetDictionary.OffsetType.MaxBollingerDate,maxBollingerDate);
|
|
|
|
|
offsets.Add(OffsetDictionary.OffsetType.MinBollingerDate,minBollingerDate);
|
|
|
|
|
offsets.Add(OffsetDictionary.OffsetType.MaxBollingerValue,maxBollingerValue);
|
|
|
|
|
offsets.Add(OffsetDictionary.OffsetType.MinBollingerValue,minBollingerValue);
|
|
|
|
|
offsets.Add(OffsetDictionary.OffsetType.MaxBollingerDate,offsets.MaxBollingerDate);
|
|
|
|
|
offsets.Add(OffsetDictionary.OffsetType.MinBollingerDate,offsets.MinBollingerDate);
|
|
|
|
|
offsets.Add(OffsetDictionary.OffsetType.MaxBollingerValue,offsets.MaxBollingerValue);
|
|
|
|
|
offsets.Add(OffsetDictionary.OffsetType.MinBollingerValue,offsets.MinBollingerValue);
|
|
|
|
|
|
|
|
|
|
double spreadHorz = (maxBollingerDate - minBollingerDate);
|
|
|
|
|
double spreadVert = (maxBollingerValue - minBollingerValue);
|
|
|
|
|
offsets.Add(OffsetDictionary.OffsetType.HorizontalOffset1PC,spreadHorz * .01);
|
|
|
|
|
offsets.Add(OffsetDictionary.OffsetType.HorizontalOffset3PC,spreadHorz * .03);
|
|
|
|
|
offsets.Add(OffsetDictionary.OffsetType.HorizontalOffset5PC,spreadHorz * .05);
|
|
|
|
|
offsets.Add(OffsetDictionary.OffsetType.VerticalOffset1PC,spreadVert * .01);
|
|
|
|
|
offsets.Add(OffsetDictionary.OffsetType.VerticalOffset3PC,spreadVert *.03);
|
|
|
|
|
offsets.Add(OffsetDictionary.OffsetType.VerticalOffset5PC,spreadVert * .05);
|
|
|
|
|
offsets.Add(OffsetDictionary.OffsetType.VerticalOffset6PC,spreadVert * .06);
|
|
|
|
|
offsets.Add(OffsetDictionary.OffsetType.VerticalOffset6P5PC,spreadVert * .065);
|
|
|
|
|
offsets.Add(OffsetDictionary.OffsetType.VerticalOffset7PC,spreadVert * .07);
|
|
|
|
|
offsets.Add(OffsetDictionary.OffsetType.VerticalOffset10PC,spreadVert * .10);
|
|
|
|
|
offsets.Add(OffsetDictionary.OffsetType.VerticalOffset15PC,spreadVert * .15);
|
|
|
|
|
offsets.HorizontalSpread = (offsets.MaxBollingerDate - offsets.MinBollingerDate);
|
|
|
|
|
offsets.VerticalSpread = (offsets.MaxBollingerValue - offsets.MinBollingerValue);
|
|
|
|
|
offsets.Add(OffsetDictionary.OffsetType.HorizontalOffset1PC,offsets.HorizontalSpread * .01);
|
|
|
|
|
offsets.Add(OffsetDictionary.OffsetType.HorizontalOffset3PC,offsets.HorizontalSpread * .03);
|
|
|
|
|
offsets.Add(OffsetDictionary.OffsetType.HorizontalOffset5PC,offsets.HorizontalSpread * .05);
|
|
|
|
|
offsets.Add(OffsetDictionary.OffsetType.VerticalOffset1PC,offsets.VerticalSpread * .01);
|
|
|
|
|
offsets.Add(OffsetDictionary.OffsetType.VerticalOffset3PC,offsets.VerticalSpread *.03);
|
|
|
|
|
offsets.Add(OffsetDictionary.OffsetType.VerticalOffset5PC,offsets.VerticalSpread * .05);
|
|
|
|
|
offsets.Add(OffsetDictionary.OffsetType.VerticalOffset6PC,offsets.VerticalSpread * .06);
|
|
|
|
|
offsets.Add(OffsetDictionary.OffsetType.VerticalOffset6P5PC,offsets.VerticalSpread * .065);
|
|
|
|
|
offsets.Add(OffsetDictionary.OffsetType.VerticalOffset7PC,offsets.VerticalSpread * .07);
|
|
|
|
|
offsets.Add(OffsetDictionary.OffsetType.VerticalOffset10PC,offsets.VerticalSpread * .10);
|
|
|
|
|
offsets.Add(OffsetDictionary.OffsetType.VerticalOffset15PC,offsets.VerticalSpread * .15);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
@@ -280,6 +357,9 @@ namespace PortfolioManager.Renderers
|
|
|
|
|
image = TextMarkerImageGenerator.GenerateImage(sb.ToString(), FontFactor.FontSize);
|
|
|
|
|
coordinates = new Coordinates(dates[0].ToOADate() - offsets.Offset(OffsetDictionary.OffsetType.HorizontalOffset3PC),
|
|
|
|
|
values[0] - offsets.Offset(OffsetDictionary.OffsetType.VerticalOffset6P5PC));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
coordinates = textMarkerManager.GetBestMarkerLocation(coordinates.X, coordinates.Y, offsets, offsets.Offset(OffsetDictionary.OffsetType.VerticalOffset6P5PC));
|
|
|
|
|
|
|
|
|
|
// Pixel screenCoordinates = Plotter.Plot.GetPixel(coordinates);
|
|
|
|
|
// Pixel adjScreenCoordinates = Plotter.Plot.GetPixel(coordinates);
|
|
|
|
|
@@ -342,6 +422,7 @@ namespace PortfolioManager.Renderers
|
|
|
|
|
Coordinates coordinates = new Coordinates(limit.EffectiveDate.ToOADate(),
|
|
|
|
|
limit.StopPrice - offsets.Offset(OffsetDictionary.OffsetType.VerticalOffset6P5PC));
|
|
|
|
|
|
|
|
|
|
coordinates = textMarkerManager.GetBestMarkerLocation(coordinates.X, coordinates.Y,offsets, offsets.Offset(OffsetDictionary.OffsetType.VerticalOffset6P5PC));
|
|
|
|
|
// Pixel screenCoordinates = Plotter.Plot.GetPixel(coordinates);
|
|
|
|
|
// Pixel adjScreenCoordinates = Plotter.Plot.GetPixel(coordinates);
|
|
|
|
|
// if(textPlots.PointInRects(sb.ToString(),screenCoordinates,ref adjScreenCoordinates,(float)offsets.Offset(OffsetDictionary.OffsetType.VerticalOffset6P5PC)))
|
|
|
|
|
@@ -370,7 +451,7 @@ namespace PortfolioManager.Renderers
|
|
|
|
|
Coordinates coordinates = new Coordinates(latestPrice.Date.ToOADate() - offsets.Offset(OffsetDictionary.OffsetType.HorizontalOffset3PC),
|
|
|
|
|
stopLimit.StopPrice - offsets.Offset(OffsetDictionary.OffsetType.VerticalOffset6P5PC));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
coordinates = textMarkerManager.GetBestMarkerLocation(coordinates.X, coordinates.Y,offsets, offsets.Offset(OffsetDictionary.OffsetType.VerticalOffset6P5PC));
|
|
|
|
|
// Pixel screenCoordinates = Plotter.Plot.GetPixel(coordinates);
|
|
|
|
|
// Pixel adjScreenCoordinates = Plotter.Plot.GetPixel(coordinates);
|
|
|
|
|
// if(textPlots.PointInRects(sb.ToString(),screenCoordinates,ref adjScreenCoordinates,(float)offsets.Offset(OffsetDictionary.OffsetType.VerticalOffset6P5PC)))
|
|
|
|
|
@@ -416,6 +497,7 @@ namespace PortfolioManager.Renderers
|
|
|
|
|
Coordinates coordinates = new Coordinates(portfolioTrade.TradeDate.ToOADate(),
|
|
|
|
|
portfolioTrade.Price - offsets.Offset(OffsetDictionary.OffsetType.VerticalOffset6P5PC));
|
|
|
|
|
|
|
|
|
|
coordinates = textMarkerManager.GetBestMarkerLocation(coordinates.X, coordinates.Y,offsets, offsets.Offset(OffsetDictionary.OffsetType.VerticalOffset6P5PC));
|
|
|
|
|
// Pixel screenCoordinates = Plotter.Plot.GetPixel(coordinates);
|
|
|
|
|
// Pixel adjScreenCoordinates = Plotter.Plot.GetPixel(coordinates);
|
|
|
|
|
// if(textPlots.PointInRects(sb.ToString(),screenCoordinates,ref adjScreenCoordinates,(float)offsets.Offset(OffsetDictionary.OffsetType.VerticalOffset6P5PC)))
|
|
|
|
|
|