Work on Bollinger Bands.

This commit is contained in:
2026-02-18 18:21:28 -05:00
parent 7775d6caaf
commit cddf7202b1
3 changed files with 72 additions and 28 deletions

View File

@@ -15,16 +15,18 @@ namespace TradeBlotter.Model
private GainLossModel()
{
}
public static CompositeDataSource CreateCompositeDataSource(DateTime xSource,double ySource)
{
CompositeDataSource compositeDataSource;
var xData=new EnumerableDataSource<DateTime>(new DateTime[] { xSource });
xData.SetXMapping(x => (x.Ticks/10000000000.0));
var yData=new EnumerableDataSource<double>(new double[] { ySource });
yData.SetYMapping(y => y);
compositeDataSource=xData.Join(yData);
return compositeDataSource;
}
//public static CompositeDataSource CreateCompositeDataSource(DateTime xSource,double ySource)
//{
// CompositeDataSource compositeDataSource;
// var xData=new EnumerableDataSource<DateTime>(new DateTime[] { xSource });
// xData.SetXMapping(x => (x.Ticks/10000000000.0));
// var yData=new EnumerableDataSource<double>(new double[] { ySource });
// yData.SetYMapping(y => y);
// compositeDataSource=xData.Join(yData);
// return compositeDataSource;
//}
public static CompositeDataSource Price(Price price)
{
if (null == price) return null;

View File

@@ -14,6 +14,7 @@ namespace TradeBlotter.Model
private StopLimitCompositeModel()
{
}
public static CompositeDataSource CreateCompositeDataSource(StopLimits stopLimits)
{
if(null==stopLimits) return null;
@@ -25,5 +26,22 @@ namespace TradeBlotter.Model
compositeDataSource=xData.Join(yData);
return compositeDataSource;
}
public static CompositeDataSource CreateCompositeDataSource(DateTime xSource,StopLimits stopLimits)
{
if(null==stopLimits) return null;
CompositeDataSource compositeDataSource;
List<DateTime> stopLimitDates = new List<DateTime>();
foreach(StopLimit stopLimit in stopLimits)
{
stopLimitDates.Add(stopLimit.EffectiveDate);
}
var xData=new EnumerableDataSource<DateTime>(stopLimitDates.Select(x => x.Date));
xData.SetXMapping(x => (x.Ticks/10000000000.0));
var yData=new EnumerableDataSource<double>(stopLimits.Select(y => y.StopPrice));
yData.SetYMapping(y => y);
compositeDataSource=xData.Join(yData);
return compositeDataSource;
}
}
}

View File

@@ -36,7 +36,7 @@ namespace TradeBlotter.ViewModels
private static readonly String BAND_MESSAGE="Generating Bollinger Band...";
private static readonly String DATA_MESSAGE="Loading Pricing Data...";
private BollingerBands bollingerBands;
private StopLimit stopLimit; // This is the stop limit that is looked up in the database and displayed (if there is one)
private StopLimits internalStopLimits; // This is the stop limit that is looked up in the database and displayed (if there is one)
private StopLimits stopLimits; // These stop limits might be passed in with the SaveParams. (i.e.) MMTRend model passes in StopLimits. If these are passsed in then they are displayed instead of stopLimit.
private String symbol;
private String companyName;
@@ -220,7 +220,7 @@ namespace TradeBlotter.ViewModels
prices=null;
portfolioTrades=null;
portfolioTradesLots=null;
stopLimit=null;
internalStopLimits=null;
}
if (eventArgs.PropertyName.Equals("SyncTradeToBand")||
@@ -238,7 +238,7 @@ namespace TradeBlotter.ViewModels
BusyContent=DATA_MESSAGE;
// DEBUG
stopLimit=StopLimitDA.GetStopLimit(symbol);
internalStopLimits=StopLimitDA.GetStopLimits(symbol);
portfolioTrades = PortfolioDA.GetTradesSymbol(symbol);
portfolioTradesLots=LotAggregator.CombineLots(portfolioTrades);
if (null != portfolioTrades && 0 != portfolioTrades.Count)
@@ -442,9 +442,9 @@ namespace TradeBlotter.ViewModels
{
compositeDataSourceStopLimit=StopLimitCompositeModel.CreateCompositeDataSource(stopLimits);
}
else if(null!=stopLimit && null!=zeroPrice)
else if(null!=internalStopLimits && null!=zeroPrice)
{
compositeDataSourceStopLimit=GainLossModel.CreateCompositeDataSource(zeroPrice.Date,stopLimit.StopPrice);
compositeDataSourceStopLimit=StopLimitCompositeModel.CreateCompositeDataSource(zeroPrice.Date,stopLimits);
}
compositeDataSourceInsiderTransactionPointDisposedSmall=InsiderTransactionModel.InsiderTransactionSummaries(new InsiderTransactionSummaries(disposedSummariesBin[2]),minClose);
@@ -784,19 +784,43 @@ namespace TradeBlotter.ViewModels
}
else
{
if(null==zeroPrice)return null;
if(null==stopLimit||null==zeroPrice||!showTradeLabels) return null;
CenteredTextMarker centerTextMarker=new CenteredTextMarker();
Price latestPrice=prices[0];
double percentOffsetFromLow=((latestPrice.Low-stopLimit.StopPrice)/stopLimit.StopPrice);
StringBuilder sb=new StringBuilder();
sb.Append(stopLimit.StopType).Append(" ");
sb.Append(Utility.FormatCurrency(stopLimit.StopPrice));
sb.Append(" (").Append(percentOffsetFromLow>0?"+":"").Append(Utility.FormatPercent(percentOffsetFromLow)).Append(")");
centerTextMarker.Text=sb.ToString();
centeredTextMarkers.Add(centerTextMarker);
centerTextMarker.VerticalShift="40";
centerTextMarker.HorizontalShift="32";
if (null == zeroPrice) return null;
if (null == internalStopLimits || null == zeroPrice || !showTradeLabels) return null;
for(int index=0;index<internalStopLimits.Count;index++)
{
StopLimit limit=internalStopLimits[index];
CenteredTextMarker centerTextMarker=new CenteredTextMarker();
StringBuilder sb=new StringBuilder();
sb.Append(limit.StopType).Append(" ");
sb.Append(Utility.FormatCurrency(limit.StopPrice));
if(index==internalStopLimits.Count-1)
{
Price latestPrice=prices[0]; // always use the most recent price when calculating the spread (in percent) from the active stop limit.
double percentOffsetFromLow=((latestPrice.Low-limit.StopPrice)/limit.StopPrice);
sb.Append(" (").Append(percentOffsetFromLow>0?"+":"").Append(Utility.FormatPercent(percentOffsetFromLow)).Append(")");
}
centerTextMarker.Text=sb.ToString();
if(0==index&&internalStopLimits.Count>1) centerTextMarker.VerticalShift="25";
else centerTextMarker.VerticalShift="40";
centerTextMarker.HorizontalShift="32";
centeredTextMarkers.Add(centerTextMarker);
}
//CenteredTextMarker centerTextMarker=new CenteredTextMarker();
//Price latestPrice=prices[0];
//double percentOffsetFromLow=((latestPrice.Low-stopLimit.StopPrice)/stopLimit.StopPrice);
//StringBuilder sb=new StringBuilder();
//sb.Append(stopLimit.StopType).Append(" ");
//sb.Append(Utility.FormatCurrency(stopLimit.StopPrice));
//sb.Append(" (").Append(percentOffsetFromLow>0?"+":"").Append(Utility.FormatPercent(percentOffsetFromLow)).Append(")");
//centerTextMarker.Text=sb.ToString();
//centeredTextMarkers.Add(centerTextMarker);
//centerTextMarker.VerticalShift="40";
//centerTextMarker.HorizontalShift="32";
}
return centeredTextMarkers.ToArray();
}