Initial Commit
This commit is contained in:
333
PortfolioManager/Models/CMPositionModelCollection.cs
Normal file
333
PortfolioManager/Models/CMPositionModelCollection.cs
Normal file
@@ -0,0 +1,333 @@
|
||||
using MarketData.MarketDataModel;
|
||||
using MarketData.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using MarketData.Generator.CMMomentum;
|
||||
using Position=MarketData.Generator.CMMomentum.Position;
|
||||
using PortfolioManager.ViewModels;
|
||||
using PortfolioManager.UIUtils;
|
||||
using Avalonia.Media;
|
||||
|
||||
namespace PortfolioManager.Models
|
||||
{
|
||||
public class CMPositionModelCollection : ObservableCollection<CMPositionModel>
|
||||
{
|
||||
public void Add(ActivePositions activePositions)
|
||||
{
|
||||
List<int> slotKeys = new List<int>(activePositions.Keys);
|
||||
for (int keyIndex = 0; keyIndex < slotKeys.Count; keyIndex++)
|
||||
{
|
||||
Positions slotPositions = activePositions[slotKeys[keyIndex]];
|
||||
foreach (Position position in slotPositions) Add(new CMPositionModel(position, keyIndex));
|
||||
}
|
||||
}
|
||||
public void Add(Positions allPositions)
|
||||
{
|
||||
foreach (Position position in allPositions) Add(new CMPositionModel(position));
|
||||
}
|
||||
public void OnCollectionChanged()
|
||||
{
|
||||
base.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset, null));
|
||||
}
|
||||
}
|
||||
// ************************************************************************************************************************************************************************************
|
||||
public class CMPositionModel : ModelBase
|
||||
{
|
||||
private Position position = new Position();
|
||||
private int slot;
|
||||
private int priceChangeDirection = 0;
|
||||
private double prevPrice = double.NaN;
|
||||
private DateTime lastUpdated = DateTime.Now;
|
||||
private double rsi3 = double.NaN;
|
||||
|
||||
public CMPositionModel()
|
||||
{
|
||||
}
|
||||
|
||||
public CMPositionModel(Position position, int slot)
|
||||
{
|
||||
Slot = slot;
|
||||
Symbol = position.Symbol;
|
||||
PurchaseDate = position.PurchaseDate;
|
||||
SellDate = position.SellDate;
|
||||
Shares = position.Shares;
|
||||
PurchasePrice = position.PurchasePrice;
|
||||
CurrentPrice = position.CurrentPrice;
|
||||
Beta = position.Beta;
|
||||
BetaMonths = position.BetaMonths;
|
||||
SharpeRatio = position.SharpeRatio;
|
||||
CNNPrediction = position.CNNPrediction;
|
||||
}
|
||||
|
||||
public CMPositionModel(Position position)
|
||||
{
|
||||
slot = -1;
|
||||
Symbol = position.Symbol;
|
||||
PurchaseDate = position.PurchaseDate;
|
||||
SellDate = position.SellDate;
|
||||
Shares = position.Shares;
|
||||
PurchasePrice = position.PurchasePrice;
|
||||
CurrentPrice = position.CurrentPrice;
|
||||
Beta = position.Beta;
|
||||
BetaMonths = position.BetaMonths;
|
||||
SharpeRatio = position.SharpeRatio;
|
||||
CNNPrediction = position.CNNPrediction;
|
||||
}
|
||||
|
||||
public Position Position
|
||||
{
|
||||
get
|
||||
{
|
||||
return position;
|
||||
}
|
||||
}
|
||||
|
||||
public String Symbol
|
||||
{
|
||||
get { return position.Symbol; }
|
||||
set { position.Symbol = value; base.OnPropertyChanged("Symbol"); }
|
||||
}
|
||||
|
||||
public DateTime PurchaseDate
|
||||
{
|
||||
get
|
||||
{
|
||||
return position.PurchaseDate;
|
||||
}
|
||||
set
|
||||
{
|
||||
position.PurchaseDate = value;
|
||||
base.OnPropertyChanged("PurchaseDate");
|
||||
}
|
||||
}
|
||||
|
||||
public IBrush PurchaseDateColor
|
||||
{
|
||||
get
|
||||
{
|
||||
DateGenerator dateGenerator=new DateGenerator();
|
||||
if(!dateGenerator.IsMarketOpen(PurchaseDate)) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
|
||||
if(!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
|
||||
public DateTime SellDate
|
||||
{
|
||||
get { return position.SellDate; }
|
||||
set { position.SellDate = value; base.OnPropertyChanged("SellDate"); }
|
||||
}
|
||||
|
||||
public IBrush SellDateColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if(Utility.IsEpoch(SellDate)) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
DateGenerator dateGenerator=new DateGenerator();
|
||||
if(!dateGenerator.IsMarketOpen(SellDate)) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
|
||||
if(!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
|
||||
public int DaysHeld
|
||||
{
|
||||
get
|
||||
{
|
||||
DateGenerator dateGenerator = new DateGenerator();
|
||||
if (Utility.IsEpoch(SellDate)) return dateGenerator.DaysBetween(PurchaseDate, DateTime.Now.Date);
|
||||
return dateGenerator.DaysBetween(PurchaseDate, SellDate);
|
||||
}
|
||||
}
|
||||
|
||||
public int Slot
|
||||
{
|
||||
get { return slot; }
|
||||
set { slot = value; base.OnPropertyChanged("Slot"); }
|
||||
}
|
||||
|
||||
public String SlotAsString
|
||||
{
|
||||
get
|
||||
{
|
||||
if (-1 == Slot) return Constants.CONST_DASHES;
|
||||
return Slot.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public double Shares
|
||||
{
|
||||
get { return position.Shares; }
|
||||
set { position.Shares = value; base.OnPropertyChanged("Shares"); base.OnPropertyChanged("Exposure"); base.OnPropertyChanged("ActiveExposure"); base.OnPropertyChanged("MarketValue"); base.OnPropertyChanged("ActiveMarketValue"); base.OnPropertyChanged("GainLoss"); base.OnPropertyChanged("GainLossPcnt"); }
|
||||
}
|
||||
|
||||
public double PurchasePrice
|
||||
{
|
||||
get { return position.PurchasePrice; }
|
||||
set { position.PurchasePrice = value; base.OnPropertyChanged("PurchasePrice"); base.OnPropertyChanged("Exposure"); base.OnPropertyChanged("ActiveExposure"); base.OnPropertyChanged("GainLoss"); base.OnPropertyChanged("GainLossPcnt"); }
|
||||
}
|
||||
|
||||
public double CurrentPrice
|
||||
{
|
||||
get { return position.CurrentPrice; }
|
||||
set
|
||||
{
|
||||
if (position.CurrentPrice == value) return;
|
||||
position.CurrentPrice = value;
|
||||
if (double.IsNaN(prevPrice)) { prevPrice = position.CurrentPrice; priceChangeDirection = 0; }
|
||||
else if (prevPrice > position.CurrentPrice) priceChangeDirection = -1;
|
||||
else if (prevPrice == position.CurrentPrice) priceChangeDirection = 0;
|
||||
else priceChangeDirection = 1;
|
||||
prevPrice = position.CurrentPrice;
|
||||
base.OnPropertyChanged("CurrentPrice");
|
||||
base.OnPropertyChanged("MarketValue");
|
||||
base.OnPropertyChanged("ActiveMarketValue");
|
||||
base.OnPropertyChanged("GainLoss");
|
||||
base.OnPropertyChanged("GainLossPcnt");
|
||||
base.OnPropertyChanged("CurrentPriceColor");
|
||||
}
|
||||
}
|
||||
|
||||
public double RSI3
|
||||
{
|
||||
get { return rsi3; }
|
||||
set
|
||||
{
|
||||
if (rsi3 == value) return;
|
||||
rsi3 = value;
|
||||
base.OnPropertyChanged("RSI3");
|
||||
base.OnPropertyChanged("RSI3Color");
|
||||
}
|
||||
}
|
||||
|
||||
public DateTime LastUpdated
|
||||
{
|
||||
get { return lastUpdated; }
|
||||
set { lastUpdated = value; base.OnPropertyChanged("LastUpdated"); }
|
||||
}
|
||||
|
||||
public IBrush CurrentPriceColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
if (priceChangeDirection > 0) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Green);
|
||||
else if (priceChangeDirection < 0) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
|
||||
else return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
|
||||
public IBrush RSI3Color
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
if (RSI3 < 10 || RSI3 > 80) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
|
||||
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
|
||||
public double Exposure
|
||||
{
|
||||
get { return Shares * PurchasePrice; }
|
||||
}
|
||||
|
||||
public double ActiveExposure
|
||||
{
|
||||
get { return IsActivePosition ? Exposure : 0.00; }
|
||||
}
|
||||
|
||||
public IBrush ActiveExposureColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
else return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
|
||||
public bool CNNPrediction
|
||||
{
|
||||
get { return position.CNNPrediction; }
|
||||
set { position.CNNPrediction = value; base.OnPropertyChanged("CNNPrediction"); }
|
||||
}
|
||||
|
||||
public double MarketValue
|
||||
{
|
||||
get { return Shares * CurrentPrice; }
|
||||
}
|
||||
|
||||
public double ActiveMarketValue
|
||||
{
|
||||
get { return IsActivePosition ? MarketValue : 0.00; }
|
||||
}
|
||||
|
||||
public IBrush ActiveMarketValueColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if(!IsActivePosition)return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
if (ActiveMarketValue > Exposure) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Green);
|
||||
else if (ActiveMarketValue < Exposure) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
|
||||
else return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
|
||||
public double GainLoss
|
||||
{
|
||||
get { return MarketValue - Exposure; }
|
||||
}
|
||||
|
||||
public IBrush GainLossColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
if (GainLoss > 0) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Green);
|
||||
else if (GainLoss < 0) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
|
||||
else return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
|
||||
public double GainLossPcnt
|
||||
{
|
||||
get { return (MarketValue - Exposure) / Exposure; }
|
||||
}
|
||||
|
||||
public IBrush GainLossPcntColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
if (GainLoss > 0) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Green);
|
||||
else if (GainLoss < 0) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
|
||||
else return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
|
||||
public double Beta
|
||||
{
|
||||
get { return position.Beta; }
|
||||
set { position.Beta = value; base.OnPropertyChanged("Beta"); }
|
||||
}
|
||||
|
||||
public int BetaMonths
|
||||
{
|
||||
get { return position.BetaMonths; }
|
||||
set { position.BetaMonths = value; base.OnPropertyChanged("BetaMonths"); }
|
||||
}
|
||||
|
||||
public double SharpeRatio
|
||||
{
|
||||
get { return position.SharpeRatio; }
|
||||
set { position.SharpeRatio = value; base.OnPropertyChanged("SharpeRatio"); }
|
||||
}
|
||||
|
||||
public bool IsActivePosition
|
||||
{
|
||||
get { return Utility.IsEpoch(SellDate) ? true : false; }
|
||||
}
|
||||
}
|
||||
}
|
||||
515
PortfolioManager/Models/CMTPositionModelCollection.cs
Normal file
515
PortfolioManager/Models/CMTPositionModelCollection.cs
Normal file
@@ -0,0 +1,515 @@
|
||||
using MarketData.Generator;
|
||||
using MarketData.MarketDataModel;
|
||||
using MarketData.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using PortfolioManager.ViewModels;
|
||||
using PortfolioManager.UIUtils;
|
||||
using System.Collections.Specialized;
|
||||
using MarketData.Generator.CMTrend;
|
||||
using MarketData;
|
||||
|
||||
using Position=MarketData.Generator.CMTrend.Position;
|
||||
using StopLimit=MarketData.MarketDataModel.StopLimit;
|
||||
|
||||
using MarketData.DataAccess;
|
||||
using PortfolioManager.Interface;
|
||||
using Avalonia.Media;
|
||||
|
||||
namespace PortfolioManager.Models
|
||||
{
|
||||
public class CMTPositionModelCollection:ObservableCollection<CMTPositionModel>
|
||||
{
|
||||
public void Add(ActivePositions activePositions)
|
||||
{
|
||||
foreach(Position position in activePositions)Add(new CMTPositionModel(position));
|
||||
}
|
||||
public void Add(Positions allPositions)
|
||||
{
|
||||
foreach(Position position in allPositions) Add(new CMTPositionModel(position));
|
||||
}
|
||||
public void OnCollectionChanged()
|
||||
{
|
||||
base.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset,null));
|
||||
}
|
||||
}
|
||||
|
||||
public class CMTPositionModel : ModelBase, IPositionModel
|
||||
{
|
||||
private Position position=new Position();
|
||||
private int priceChangeDirection=0;
|
||||
private double prevPrice=double.NaN;
|
||||
private double currentPriceLow=double.NaN;
|
||||
private DateTime lastUpdated=DateTime.Now;
|
||||
private double edgeRatio=double.NaN;
|
||||
|
||||
public CMTPositionModel()
|
||||
{
|
||||
}
|
||||
public CMTPositionModel(Position position)
|
||||
{
|
||||
Symbol=position.Symbol;
|
||||
PurchaseDate=position.PurchaseDate;
|
||||
SellDate=position.SellDate;
|
||||
Shares=position.Shares;
|
||||
PurchasePrice=position.PurchasePrice;
|
||||
CurrentPrice=position.CurrentPrice;
|
||||
PositionRiskPercentDecimal=position.PositionRiskPercentDecimal;
|
||||
InitialStopLimit=position.InitialStopLimit;
|
||||
TrailingStopLimit=position.TrailingStopLimit;
|
||||
LastStopAdjustment=position.LastStopAdjustment;
|
||||
this.position.R=position.R;
|
||||
this.position.C=position.C;
|
||||
}
|
||||
public void UpdateProperties()
|
||||
{
|
||||
base.OnPropertyChanged("CurrentPrice");
|
||||
base.OnPropertyChanged("MarketValue");
|
||||
base.OnPropertyChanged("ActiveMarketValue");
|
||||
base.OnPropertyChanged("GainLoss");
|
||||
base.OnPropertyChanged("GainLossPcnt");
|
||||
base.OnPropertyChanged("RMultiple");
|
||||
base.OnPropertyChanged("EdgeRatioAsString");
|
||||
|
||||
base.OnPropertyChanged("CurrentPriceColor");
|
||||
base.OnPropertyChanged("TrailingStopLimitColor");
|
||||
base.OnPropertyChanged("InitialStopLimitColor");
|
||||
base.OnPropertyChanged("TotalRiskExposureColor");
|
||||
base.OnPropertyChanged("ActiveMarketValueColor");
|
||||
base.OnPropertyChanged("GainLossColor");
|
||||
base.OnPropertyChanged("GainLossPcntColor");
|
||||
base.OnPropertyChanged("EdgeRatioAsStringColor");
|
||||
base.OnPropertyChanged("RMultipleColor");
|
||||
}
|
||||
public Position Position
|
||||
{
|
||||
get{return position;}
|
||||
set
|
||||
{
|
||||
Symbol=position.Symbol;
|
||||
PurchaseDate=position.PurchaseDate;
|
||||
SellDate=position.SellDate;
|
||||
Shares=position.Shares;
|
||||
PurchasePrice=position.PurchasePrice;
|
||||
CurrentPrice=position.CurrentPrice;
|
||||
PositionRiskPercentDecimal=position.PositionRiskPercentDecimal;
|
||||
InitialStopLimit=position.InitialStopLimit;
|
||||
TrailingStopLimit=position.TrailingStopLimit;
|
||||
LastStopAdjustment=position.LastStopAdjustment;
|
||||
this.position.R=position.R;
|
||||
this.position.C=position.C;
|
||||
}
|
||||
}
|
||||
|
||||
public String Symbol
|
||||
{
|
||||
get { return position.Symbol; }
|
||||
set { position.Symbol = value; base.OnPropertyChanged("Symbol"); }
|
||||
}
|
||||
|
||||
public IBrush SymbolColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
// ***
|
||||
public DateTime PurchaseDate
|
||||
{
|
||||
get { return position.PurchaseDate; }
|
||||
set { position.PurchaseDate=value; base.OnPropertyChanged("PurchaseDate"); }
|
||||
}
|
||||
|
||||
public IBrush PurchaseDateColor
|
||||
{
|
||||
get
|
||||
{
|
||||
DateGenerator dateGenerator=new DateGenerator();
|
||||
if(!dateGenerator.IsMarketOpen(PurchaseDate)) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
|
||||
if(!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
|
||||
public DateTime SellDate
|
||||
{
|
||||
get { return position.SellDate; }
|
||||
set { position.SellDate=value; base.OnPropertyChanged("SellDate"); }
|
||||
}
|
||||
|
||||
public IBrush SellDateColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if(Utility.IsEpoch(SellDate)) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
DateGenerator dateGenerator=new DateGenerator();
|
||||
if(!dateGenerator.IsMarketOpen(SellDate)) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
|
||||
if(!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
// ***
|
||||
public int DaysHeld
|
||||
{
|
||||
get
|
||||
{
|
||||
DateGenerator dateGenerator=new DateGenerator();
|
||||
if(Utility.IsEpoch(SellDate)) return dateGenerator.DaysBetween(PurchaseDate,DateTime.Now.Date);
|
||||
return dateGenerator.DaysBetween(PurchaseDate,SellDate);
|
||||
}
|
||||
}
|
||||
public IBrush DaysHeldColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if(!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
// ***
|
||||
// Here we take R as based upon our StopLimit.
|
||||
public double R
|
||||
{
|
||||
get
|
||||
{
|
||||
if(position.TrailingStopLimit>position.PurchasePrice)return 0.00; // here we are considering the current risk/share which is based on our stop limit
|
||||
return position.TrailingStopLimit>position.PurchasePrice?0.00:position.PurchasePrice-position.TrailingStopLimit;
|
||||
}
|
||||
}
|
||||
public IBrush RColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if(!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
// ***
|
||||
public double TotalRiskExposure
|
||||
{
|
||||
get{return R*position.Shares;}
|
||||
}
|
||||
public IBrush TotalRiskExposureColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if(!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
// ***
|
||||
public double EdgeRatio
|
||||
{
|
||||
get{return edgeRatio;}
|
||||
set
|
||||
{
|
||||
edgeRatio=value;
|
||||
base.OnPropertyChanged("EdgeRatio");
|
||||
base.OnPropertyChanged("EdgeRatioAsStringColor");
|
||||
}
|
||||
}
|
||||
public String EdgeRatioAsString
|
||||
{
|
||||
get{return Utility.FormatNumber(edgeRatio,2,false);}
|
||||
}
|
||||
public IBrush EdgeRatioAsStringColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if(!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
if(double.IsNaN(edgeRatio))return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
if(edgeRatio>=1.00)return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Green);
|
||||
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
|
||||
}
|
||||
}
|
||||
// ***
|
||||
|
||||
public String RMultipleAsString
|
||||
{
|
||||
get{return Utility.FormatNumber((position.CurrentPrice-position.PurchasePrice)/(position.PurchasePrice-position.InitialStopLimit),2,false)+"R";} // always based on original position risk
|
||||
}
|
||||
|
||||
public double RMultiple
|
||||
{
|
||||
get{return (position.CurrentPrice-position.PurchasePrice)/(position.PurchasePrice-position.InitialStopLimit);} // always based on original position risk
|
||||
}
|
||||
|
||||
public IBrush RMultipleColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if(!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
// ***
|
||||
public double PositionRiskPercentDecimal
|
||||
{
|
||||
get{return position.PositionRiskPercentDecimal;}
|
||||
set { position.PositionRiskPercentDecimal=value; base.OnPropertyChanged("PositionRiskPercentDecimal"); }
|
||||
}
|
||||
public double InitialStopLimit
|
||||
{
|
||||
get { return position.InitialStopLimit; }
|
||||
set
|
||||
{
|
||||
position.InitialStopLimit=value;
|
||||
base.OnPropertyChanged("InitialStopLimit");
|
||||
base.OnPropertyChanged("InitialStopLimitColor");
|
||||
}
|
||||
}
|
||||
public IBrush InitialStopLimitColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if(!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
if(!Utility.IsEpoch(position.LastStopAdjustment)) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black); // if we have a trailing stop then we are no longer using the initial stop
|
||||
StopLimit stopLimit=PortfolioDA.GetStopLimit(position.Symbol);
|
||||
if(null==stopLimit||!stopLimit.StopPrice.Equals(Math.Round(position.InitialStopLimit,2))) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Purple);
|
||||
if(currentPriceLow<=position.InitialStopLimit) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
|
||||
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
public double TrailingStopLimit
|
||||
{
|
||||
get { return position.TrailingStopLimit; }
|
||||
set
|
||||
{
|
||||
position.TrailingStopLimit=value;
|
||||
base.OnPropertyChanged("TrailingStopLimit");
|
||||
base.OnPropertyChanged("TrailingStopLimitColor");
|
||||
}
|
||||
}
|
||||
public IBrush TrailingStopLimitColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if(!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
if(currentPriceLow<=position.TrailingStopLimit)
|
||||
{
|
||||
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
|
||||
}
|
||||
StopLimit stopLimit=PortfolioDA.GetStopLimit(position.Symbol);
|
||||
if(null==stopLimit || !stopLimit.StopPrice.Equals(Math.Round(position.TrailingStopLimit,2)))
|
||||
{
|
||||
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Purple);
|
||||
}
|
||||
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
// ***
|
||||
public DateTime LastStopAdjustment
|
||||
{
|
||||
get { return position.LastStopAdjustment; }
|
||||
set { position.LastStopAdjustment=value; base.OnPropertyChanged("LastStopAdjustment"); }
|
||||
}
|
||||
public IBrush LastStopAdjustmentColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if(!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
// ***
|
||||
public int DaysSinceLastStopAdjustment
|
||||
{
|
||||
get
|
||||
{
|
||||
if(!IsActivePosition)return int.MinValue;
|
||||
DateGenerator dateGenerator=new DateGenerator();
|
||||
DateTime today=DateTime.Now;
|
||||
int daysSinceLastStopAdjustment=int.MinValue;
|
||||
if(Utility.IsEpoch(position.LastStopAdjustment)) daysSinceLastStopAdjustment=dateGenerator.DaysBetweenActual(today,position.PurchaseDate);
|
||||
else daysSinceLastStopAdjustment=dateGenerator.DaysBetweenActual(today,position.LastStopAdjustment);
|
||||
return daysSinceLastStopAdjustment;
|
||||
}
|
||||
}
|
||||
public IBrush DaysSinceLastStopAdjustmentColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if(!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
int daysSinceLastStopAdjustment=DaysSinceLastStopAdjustment;
|
||||
if(int.MinValue.Equals(daysSinceLastStopAdjustment))return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
if(daysSinceLastStopAdjustment>=90) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
|
||||
else if(daysSinceLastStopAdjustment>=60) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red); // I made them both red because yellow and purple looked horrible
|
||||
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Green);
|
||||
}
|
||||
}
|
||||
|
||||
// ***
|
||||
public double Shares
|
||||
{
|
||||
get { return position.Shares; }
|
||||
set { position.Shares=value; base.OnPropertyChanged("Shares"); base.OnPropertyChanged("Exposure"); base.OnPropertyChanged("ActiveExposure"); base.OnPropertyChanged("MarketValue"); base.OnPropertyChanged("ActiveMarketValue"); base.OnPropertyChanged("GainLoss"); base.OnPropertyChanged("GainLossPcnt"); }
|
||||
}
|
||||
public IBrush SharesColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if(!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
// ***
|
||||
public double PurchasePrice
|
||||
{
|
||||
get { return position.PurchasePrice; }
|
||||
set { position.PurchasePrice=value; base.OnPropertyChanged("PurchasePrice"); base.OnPropertyChanged("Exposure"); base.OnPropertyChanged("ActiveExposure"); base.OnPropertyChanged("GainLoss"); base.OnPropertyChanged("GainLossPcnt"); }
|
||||
}
|
||||
public IBrush PurchasePriceColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if(!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
// ***
|
||||
public double CurrentPrice
|
||||
{
|
||||
get { return position.CurrentPrice; }
|
||||
set
|
||||
{
|
||||
if(position.CurrentPrice==value) return;
|
||||
position.CurrentPrice=value;
|
||||
if(double.IsNaN(prevPrice)) { prevPrice=position.CurrentPrice; priceChangeDirection=0; }
|
||||
else if(prevPrice>position.CurrentPrice) priceChangeDirection=-1;
|
||||
else if(prevPrice==position.CurrentPrice) priceChangeDirection=0;
|
||||
else priceChangeDirection=1;
|
||||
prevPrice=position.CurrentPrice;
|
||||
UpdateProperties();
|
||||
}
|
||||
}
|
||||
public IBrush CurrentPriceColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if(!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
if(priceChangeDirection>0) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Green);
|
||||
else if(priceChangeDirection<0) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
|
||||
else return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
// ***
|
||||
|
||||
public double CurrentPriceLow
|
||||
{
|
||||
get{return currentPriceLow;}
|
||||
set
|
||||
{
|
||||
if(currentPriceLow==value)return;
|
||||
currentPriceLow=value;
|
||||
base.OnPropertyChanged("CurrentPriceLow");
|
||||
base.OnPropertyChanged("CurrentPriceLowAsString");
|
||||
base.OnPropertyChanged("TrailingStopLimitColor");
|
||||
base.OnPropertyChanged("InitialStopLimitColor");
|
||||
}
|
||||
}
|
||||
// ***
|
||||
public String CurrentPriceLowAsString
|
||||
{
|
||||
get { return Utility.FormatCurrency(currentPriceLow); }
|
||||
}
|
||||
public IBrush CurrentPriceLowAsStringColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if(!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
// ***
|
||||
public DateTime LastUpdated
|
||||
{
|
||||
get { return lastUpdated; }
|
||||
set { lastUpdated=value; base.OnPropertyChanged("LastUpdated"); }
|
||||
}
|
||||
public IBrush LastUpdatedColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if(!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
// ***
|
||||
|
||||
public double Exposure
|
||||
{
|
||||
get { return Shares*PurchasePrice; }
|
||||
}
|
||||
public double ActiveExposure
|
||||
{
|
||||
get { return IsActivePosition?Exposure:0.00; }
|
||||
}
|
||||
public IBrush ActiveExposureColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if(!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
else return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
public double MarketValue
|
||||
{
|
||||
get { return Shares*CurrentPrice; }
|
||||
}
|
||||
public double ActiveMarketValue
|
||||
{
|
||||
get { return IsActivePosition?MarketValue:0.00; }
|
||||
}
|
||||
public IBrush ActiveMarketValueColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if(!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
if(ActiveMarketValue>Exposure) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Green);
|
||||
else if(ActiveMarketValue<Exposure) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
|
||||
else return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
|
||||
public double GainLoss
|
||||
{
|
||||
get { return MarketValue - Exposure; }
|
||||
}
|
||||
|
||||
public IBrush GainLossColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
if (GainLoss > 0) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Green);
|
||||
else if (GainLoss < 0) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
|
||||
else return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
public double GainLossPcnt
|
||||
{
|
||||
get { return (MarketValue-Exposure)/Exposure; }
|
||||
}
|
||||
public IBrush GainLossPcntColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if(!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
if(GainLoss>0) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Green);
|
||||
else if(GainLoss<0) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
|
||||
else return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
public bool IsActivePosition
|
||||
{
|
||||
get { return Utility.IsEpoch(SellDate)?true:false; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
140
PortfolioManager/Models/GainLossModel.cs
Normal file
140
PortfolioManager/Models/GainLossModel.cs
Normal file
@@ -0,0 +1,140 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Eremex.AvaloniaUI.Charts;
|
||||
using MarketData.MarketDataModel;
|
||||
using MarketData.MarketDataModel.GainLoss;
|
||||
using MarketData.Numerical;
|
||||
using PortfolioManager.DataSeriesViewModels;
|
||||
|
||||
namespace PortfolioManager.Models
|
||||
{
|
||||
public class GainLossModel
|
||||
{
|
||||
private GainLossModel()
|
||||
{
|
||||
}
|
||||
|
||||
public static CompositeDataSource Empty()
|
||||
{
|
||||
CompositeDataSource compositeDataSource = new CompositeDataSource()
|
||||
{
|
||||
DataAdapter = new SortedDateTimeDataAdapter()
|
||||
};
|
||||
return compositeDataSource;
|
||||
}
|
||||
|
||||
// This is the active gain/loss as number or percent.
|
||||
public static CompositeDataSource GainLoss(ModelPerformanceSeries gainLossList, bool useGainLoss)
|
||||
{
|
||||
if (null == gainLossList) return Empty();
|
||||
SortedDateTimeDataAdapter sortedDateTimeDataAdapter = new SortedDateTimeDataAdapter();
|
||||
foreach (ModelPerformanceItem modelPerformanceItem in gainLossList)
|
||||
{
|
||||
sortedDateTimeDataAdapter.Add(modelPerformanceItem.Date, useGainLoss ? modelPerformanceItem.CumulativeGainLoss : modelPerformanceItem.CumProdMinusOne * 100.00);
|
||||
}
|
||||
CompositeDataSource compositeDataSource = new CompositeDataSource()
|
||||
{
|
||||
DataAdapter = sortedDateTimeDataAdapter
|
||||
};
|
||||
return compositeDataSource;
|
||||
}
|
||||
|
||||
// This is the active gain/loss as number or percent.
|
||||
public static CompositeDataSource GainLoss(GainLossCompoundModelCollection gainLossList, bool useGainLoss)
|
||||
{
|
||||
if (null == gainLossList) return Empty();
|
||||
GainLossCompoundModelCollection sortedCollection = new GainLossCompoundModelCollection(gainLossList.OrderBy(x => x.Date).ToList());
|
||||
SortedDateTimeDataAdapter sortedDateTimeDataAdapter = new SortedDateTimeDataAdapter();
|
||||
foreach (GainLossCompoundModel gainLossCompoundModel in sortedCollection)
|
||||
{
|
||||
sortedDateTimeDataAdapter.Add(gainLossCompoundModel.Date, useGainLoss ? gainLossCompoundModel.ActiveGainLoss : gainLossCompoundModel.ActiveGainLossPercent);
|
||||
}
|
||||
CompositeDataSource compositeDataSource = new CompositeDataSource()
|
||||
{
|
||||
DataAdapter = sortedDateTimeDataAdapter
|
||||
};
|
||||
return compositeDataSource;
|
||||
}
|
||||
|
||||
// This is the total gain loss as number or percent
|
||||
public static CompositeDataSource TotalGainLoss(GainLossCompoundModelCollection gainLossList, bool useGainLoss)
|
||||
{
|
||||
if (null == gainLossList) return Empty();
|
||||
GainLossCompoundModelCollection sortedCollection = new GainLossCompoundModelCollection(gainLossList.OrderBy(x => x.Date).ToList());
|
||||
SortedDateTimeDataAdapter sortedDateTimeDataAdapter = new SortedDateTimeDataAdapter();
|
||||
foreach (GainLossCompoundModel gainLossCompoundModel in sortedCollection)
|
||||
{
|
||||
sortedDateTimeDataAdapter.Add(gainLossCompoundModel.Date, useGainLoss ? gainLossCompoundModel.TotalGainLoss : gainLossCompoundModel.TotalGainLossPercent);
|
||||
}
|
||||
CompositeDataSource compositeDataSource = new CompositeDataSource()
|
||||
{
|
||||
DataAdapter = sortedDateTimeDataAdapter
|
||||
};
|
||||
return compositeDataSource;
|
||||
}
|
||||
|
||||
// This is the least squares composite data source based on the active gain/loss
|
||||
public static CompositeDataSource LeastSquares(GainLossCompoundModelCollection gainLossList, bool useGainLoss)
|
||||
{
|
||||
if (null == gainLossList) return Empty();
|
||||
LeastSquaresResult leastSquaresResult = LeastSquaresFit(gainLossList, useGainLoss);
|
||||
GainLossCompoundModelCollection sortedCollection = new GainLossCompoundModelCollection(gainLossList.OrderBy(x => x.Date).ToList());
|
||||
SortedDateTimeDataAdapter sortedDateTimeDataAdapter = new SortedDateTimeDataAdapter();
|
||||
|
||||
for (int index = 0; index < sortedCollection.Count; index++)
|
||||
{
|
||||
GainLossCompoundModel gainLossCompoundModel = sortedCollection[index];
|
||||
int leastSquaresIndex = (leastSquaresResult.LeastSquares.Length - 1) - index;
|
||||
sortedDateTimeDataAdapter.Add(gainLossCompoundModel.Date, leastSquaresResult.LeastSquares[leastSquaresIndex]);
|
||||
}
|
||||
CompositeDataSource compositeDataSource = new CompositeDataSource()
|
||||
{
|
||||
DataAdapter = sortedDateTimeDataAdapter
|
||||
};
|
||||
return compositeDataSource;
|
||||
}
|
||||
|
||||
// This is the least squares composite data source based on the active gain/loss
|
||||
public static CompositeDataSource TotalLeastSquares(GainLossCompoundModelCollection gainLossList, bool useGainLoss)
|
||||
{
|
||||
if (null == gainLossList) return Empty();
|
||||
LeastSquaresResult leastSquaresResult = TotalLeastSquaresFit(gainLossList, useGainLoss);
|
||||
GainLossCompoundModelCollection sortedCollection = new GainLossCompoundModelCollection(gainLossList.OrderBy(x => x.Date).ToList());
|
||||
SortedDateTimeDataAdapter sortedDateTimeDataAdapter = new SortedDateTimeDataAdapter();
|
||||
|
||||
for (int index = 0; index < sortedCollection.Count; index++)
|
||||
{
|
||||
GainLossCompoundModel gainLossCompoundModel = sortedCollection[index];
|
||||
int leastSquaresIndex = (leastSquaresResult.LeastSquares.Length - 1) - index;
|
||||
sortedDateTimeDataAdapter.Add(gainLossCompoundModel.Date, leastSquaresResult.LeastSquares[leastSquaresIndex]);
|
||||
}
|
||||
CompositeDataSource compositeDataSource = new CompositeDataSource()
|
||||
{
|
||||
DataAdapter = sortedDateTimeDataAdapter
|
||||
};
|
||||
return compositeDataSource;
|
||||
}
|
||||
|
||||
// ***************************************** C A L C U L A T O R S **********************************
|
||||
|
||||
// This is the LeastSquares fit based on the active gain/loss
|
||||
public static LeastSquaresResult LeastSquaresFit(GainLossCompoundModelCollection gainLossList, bool useGainLoss)
|
||||
{
|
||||
double[] values = null;
|
||||
if (useGainLoss) values = (from GainLossCompoundModel gainLoss in gainLossList select gainLoss.ActiveGainLoss).ToList().ToArray();
|
||||
else values = (from GainLossCompoundModel gainLoss in gainLossList select gainLoss.ActiveGainLossPercent).ToList().ToArray();
|
||||
LeastSquaresResult leastSquaresResult = Numerics.LeastSquares(values);
|
||||
return leastSquaresResult;
|
||||
}
|
||||
|
||||
// This is the LeastSquares fit based on the total gain/loss
|
||||
public static LeastSquaresResult TotalLeastSquaresFit(GainLossCompoundModelCollection gainLossList,bool useGainLoss)
|
||||
{
|
||||
double[] values=null;
|
||||
if(useGainLoss)values=(from GainLossCompoundModel gainLoss in gainLossList select gainLoss.TotalGainLoss).ToList().ToArray();
|
||||
else values=(from GainLossCompoundModel gainLoss in gainLossList select gainLoss.TotalGainLossPercent).ToList().ToArray();
|
||||
LeastSquaresResult leastSquaresResult=Numerics.LeastSquares(values);
|
||||
return leastSquaresResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
351
PortfolioManager/Models/MGPositionModelCollection.cs
Normal file
351
PortfolioManager/Models/MGPositionModelCollection.cs
Normal file
@@ -0,0 +1,351 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using Avalonia.Media;
|
||||
using MarketData.Generator.Momentum;
|
||||
using MarketData.MarketDataModel;
|
||||
using MarketData.Utils;
|
||||
using PortfolioManager.UIUtils;
|
||||
using PortfolioManager.ViewModels;
|
||||
|
||||
namespace PortfolioManager.Models
|
||||
{
|
||||
public class MGPositionModelCollection : ObservableCollection<MGPositionModel>
|
||||
{
|
||||
public void Add(ActivePositions activePositions)
|
||||
{
|
||||
List<int> slotKeys=new List<int>(activePositions.Keys);
|
||||
for(int keyIndex=0;keyIndex<slotKeys.Count;keyIndex++)
|
||||
{
|
||||
Positions slotPositions=activePositions[slotKeys[keyIndex]];
|
||||
foreach (MarketData.Generator.Momentum.Position position in slotPositions) Add(new MGPositionModel(position, keyIndex));
|
||||
}
|
||||
}
|
||||
public void Add(MarketData.Generator.Momentum.Positions allPositions)
|
||||
{
|
||||
foreach (MarketData.Generator.Momentum.Position position in allPositions) Add(new MGPositionModel(position));
|
||||
}
|
||||
public void OnCollectionChanged()
|
||||
{
|
||||
base.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset,null));
|
||||
}
|
||||
}
|
||||
public class MGPositionModel : ModelBase
|
||||
{
|
||||
private MarketData.Generator.Momentum.Position position = new MarketData.Generator.Momentum.Position();
|
||||
private int slot;
|
||||
private int priceChangeDirection=0;
|
||||
private double prevPrice=double.NaN;
|
||||
private DateTime lastUpdated=DateTime.Now;
|
||||
private double rsi3=double.NaN;
|
||||
|
||||
public MGPositionModel()
|
||||
{
|
||||
}
|
||||
public MGPositionModel(MarketData.Generator.Momentum.Position position, int slot)
|
||||
{
|
||||
Slot=slot;
|
||||
Symbol=position.Symbol;
|
||||
PurchaseDate=position.PurchaseDate;
|
||||
SellDate=position.SellDate;
|
||||
Shares=position.Shares;
|
||||
PurchasePrice=position.PurchasePrice;
|
||||
CurrentPrice=position.CurrentPrice;
|
||||
Volume=position.Volume;
|
||||
Return1D=position.Return1D;
|
||||
CumReturn252=position.CumReturn252;
|
||||
IDIndicator=position.IDIndicator;
|
||||
Score=position.Score;
|
||||
MaxDrawdown=position.MaxDrawdown;
|
||||
MaxUpside=position.MaxUpside;
|
||||
Velocity=position.Velocity;
|
||||
PE=position.PE;
|
||||
Beta=position.Beta;
|
||||
ZacksRank=position.ZacksRank;
|
||||
SharpeRatio = position.SharpeRatio;
|
||||
}
|
||||
public MGPositionModel(MarketData.Generator.Momentum.Position position)
|
||||
{
|
||||
slot=-1;
|
||||
Symbol=position.Symbol;
|
||||
PurchaseDate=position.PurchaseDate;
|
||||
SellDate=position.SellDate;
|
||||
Shares=position.Shares;
|
||||
PurchasePrice=position.PurchasePrice;
|
||||
CurrentPrice=position.CurrentPrice;
|
||||
Volume=position.Volume;
|
||||
Return1D=position.Return1D;
|
||||
CumReturn252=position.CumReturn252;
|
||||
IDIndicator=position.IDIndicator;
|
||||
Score=position.Score;
|
||||
MaxDrawdown=position.MaxDrawdown;
|
||||
MaxUpside=position.MaxUpside;
|
||||
Velocity=position.Velocity;
|
||||
PE=position.PE;
|
||||
Beta=position.Beta;
|
||||
ZacksRank=position.ZacksRank;
|
||||
SharpeRatio = position.SharpeRatio;
|
||||
}
|
||||
|
||||
public MarketData.Generator.Momentum.Position Position
|
||||
{
|
||||
get
|
||||
{
|
||||
return position;
|
||||
}
|
||||
}
|
||||
|
||||
public String Symbol
|
||||
{
|
||||
get{return position.Symbol;}
|
||||
set{position.Symbol=value;base.OnPropertyChanged("Symbol");}
|
||||
}
|
||||
public DateTime PurchaseDate
|
||||
{
|
||||
get{return position.PurchaseDate;}
|
||||
set{position.PurchaseDate=value;base.OnPropertyChanged("PurchaseDate");}
|
||||
}
|
||||
|
||||
public IBrush PurchaseDateColor
|
||||
{
|
||||
get
|
||||
{
|
||||
DateGenerator dateGenerator=new DateGenerator();
|
||||
if(!dateGenerator.IsMarketOpen(PurchaseDate)) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
|
||||
if(!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
|
||||
public IBrush SellDateColor
|
||||
{
|
||||
get
|
||||
{
|
||||
DateGenerator dateGenerator=new DateGenerator();
|
||||
if(!dateGenerator.IsMarketOpen(SellDate)) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
|
||||
if(!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
|
||||
public DateTime SellDate
|
||||
{
|
||||
get{return position.SellDate;}
|
||||
set{position.SellDate=value;base.OnPropertyChanged("SellDate");}
|
||||
}
|
||||
public int DaysHeld
|
||||
{
|
||||
get
|
||||
{
|
||||
DateGenerator dateGenerator=new DateGenerator();
|
||||
if(Utility.IsEpoch(SellDate))return dateGenerator.DaysBetween(PurchaseDate,DateTime.Now.Date);
|
||||
return dateGenerator.DaysBetween(PurchaseDate,SellDate);
|
||||
}
|
||||
}
|
||||
public int Slot
|
||||
{
|
||||
get{return slot;}
|
||||
set{slot=value;base.OnPropertyChanged("Slot");}
|
||||
}
|
||||
public String SlotAsString
|
||||
{
|
||||
get
|
||||
{
|
||||
if(-1==Slot)return Constants.CONST_DASHES;
|
||||
return Slot.ToString();
|
||||
}
|
||||
}
|
||||
public double Shares
|
||||
{
|
||||
get{return position.Shares;}
|
||||
set{position.Shares=value;base.OnPropertyChanged("Shares");base.OnPropertyChanged("Exposure");base.OnPropertyChanged("ActiveExposure");base.OnPropertyChanged("MarketValue");base.OnPropertyChanged("ActiveMarketValue");base.OnPropertyChanged("GainLoss");base.OnPropertyChanged("GainLossPcnt");}
|
||||
}
|
||||
public double PurchasePrice
|
||||
{
|
||||
get{return position.PurchasePrice;}
|
||||
set{position.PurchasePrice=value;base.OnPropertyChanged("PurchasePrice");base.OnPropertyChanged("Exposure");base.OnPropertyChanged("ActiveExposure");base.OnPropertyChanged("GainLoss");base.OnPropertyChanged("GainLossPcnt");}
|
||||
}
|
||||
public double CurrentPrice
|
||||
{
|
||||
get{return position.CurrentPrice;}
|
||||
set
|
||||
{
|
||||
if(position.CurrentPrice==value)return;
|
||||
position.CurrentPrice=value;
|
||||
if(double.IsNaN(prevPrice)){prevPrice=position.CurrentPrice;priceChangeDirection=0;}
|
||||
else if(prevPrice>position.CurrentPrice)priceChangeDirection=-1;
|
||||
else if(prevPrice==position.CurrentPrice)priceChangeDirection=0;
|
||||
else priceChangeDirection=1;
|
||||
prevPrice=position.CurrentPrice;
|
||||
base.OnPropertyChanged("CurrentPrice");
|
||||
base.OnPropertyChanged("MarketValue");
|
||||
base.OnPropertyChanged("ActiveMarketValue");
|
||||
base.OnPropertyChanged("GainLoss");
|
||||
base.OnPropertyChanged("GainLossPcnt");
|
||||
base.OnPropertyChanged("CurrentPriceColor");
|
||||
}
|
||||
}
|
||||
public double RSI3
|
||||
{
|
||||
get{return rsi3;}
|
||||
set
|
||||
{
|
||||
if(rsi3==value)return;
|
||||
rsi3=value;
|
||||
base.OnPropertyChanged("RSI3");
|
||||
base.OnPropertyChanged("RSI3Color");
|
||||
}
|
||||
}
|
||||
public DateTime LastUpdated
|
||||
{
|
||||
get{return lastUpdated;}
|
||||
set{lastUpdated=value;base.OnPropertyChanged("LastUpdated");}
|
||||
}
|
||||
public IBrush CurrentPriceColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if(!IsActivePosition)return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
if(priceChangeDirection>0)return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Green);
|
||||
else if(priceChangeDirection<0)return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
|
||||
else return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
public IBrush RSI3Color
|
||||
{
|
||||
get
|
||||
{
|
||||
if(!IsActivePosition)return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
if(RSI3<10||RSI3>80)return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
|
||||
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
public double Exposure
|
||||
{
|
||||
get{return Shares*PurchasePrice;}
|
||||
}
|
||||
public double ActiveExposure
|
||||
{
|
||||
get{return IsActivePosition?Exposure:0.00;}
|
||||
}
|
||||
public IBrush ActiveExposureColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if(!IsActivePosition)return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
else return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
public double MarketValue
|
||||
{
|
||||
get{return Shares*CurrentPrice;}
|
||||
}
|
||||
public double ActiveMarketValue
|
||||
{
|
||||
get{return IsActivePosition?MarketValue:0.00;}
|
||||
}
|
||||
public IBrush ActiveMarketValueColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if(!IsActivePosition)return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
if (ActiveMarketValue > Exposure) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Green);
|
||||
else if (ActiveMarketValue < Exposure) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
|
||||
else return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
public long Volume
|
||||
{
|
||||
get{return position.Volume;}
|
||||
set{position.Volume=value;base.OnPropertyChanged("Volume");}
|
||||
}
|
||||
public double Return1D
|
||||
{
|
||||
get{return position.Return1D;}
|
||||
set{position.Return1D=value;base.OnPropertyChanged("Return1D");}
|
||||
}
|
||||
public double GainLoss
|
||||
{
|
||||
get{return MarketValue-Exposure;}
|
||||
}
|
||||
public IBrush GainLossColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if(!IsActivePosition)return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
if(GainLoss>0)return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Green);
|
||||
else if(GainLoss<0)return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
|
||||
else return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
public double GainLossPcnt
|
||||
{
|
||||
get{return (MarketValue-Exposure)/Exposure;}
|
||||
}
|
||||
public IBrush GainLossPcntColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if(!IsActivePosition)return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
if(GainLoss>0)return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Green);
|
||||
else if(GainLoss<0)return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
|
||||
else return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
public double CumReturn252
|
||||
{
|
||||
get{return position.CumReturn252;}
|
||||
set{position.CumReturn252=value;base.OnPropertyChanged("CumReturn252");}
|
||||
}
|
||||
public double IDIndicator
|
||||
{
|
||||
get{return position.IDIndicator;}
|
||||
set{position.IDIndicator=value;base.OnPropertyChanged("IDIndicator");}
|
||||
}
|
||||
public double Score
|
||||
{
|
||||
get { return position.Score; }
|
||||
set { position.Score=value; base.OnPropertyChanged("Score"); }
|
||||
}
|
||||
public double MaxDrawdown
|
||||
{
|
||||
get{return position.MaxDrawdown;}
|
||||
set{position.MaxDrawdown=value;base.OnPropertyChanged("MaxDrawdown");}
|
||||
}
|
||||
public double MaxUpside
|
||||
{
|
||||
get{return position.MaxUpside;}
|
||||
set{position.MaxUpside=value;base.OnPropertyChanged("MaxUpside");}
|
||||
}
|
||||
public double Velocity
|
||||
{
|
||||
get{return position.Velocity;}
|
||||
set{position.Velocity=value;base.OnPropertyChanged("Velocity");}
|
||||
}
|
||||
public double PE
|
||||
{
|
||||
get{return position.PE;}
|
||||
set{position.PE=value;base.OnPropertyChanged("PE");}
|
||||
}
|
||||
public String ZacksRank
|
||||
{
|
||||
get {return position.ZacksRank;}
|
||||
set{position.ZacksRank=value;base.OnPropertyChanged("ZacksRank");}
|
||||
}
|
||||
public double Beta
|
||||
{
|
||||
get{return position.Beta;}
|
||||
set{position.Beta=value;base.OnPropertyChanged("Beta");}
|
||||
}
|
||||
public double SharpeRatio
|
||||
{
|
||||
get { return position.SharpeRatio; }
|
||||
set { position.SharpeRatio = value; base.OnPropertyChanged("SharpeRatio"); }
|
||||
}
|
||||
public bool IsActivePosition
|
||||
{
|
||||
get{return Utility.IsEpoch(SellDate)?true:false;}
|
||||
}
|
||||
}
|
||||
}
|
||||
593
PortfolioManager/Models/MGSHPositionModelCollection.cs
Normal file
593
PortfolioManager/Models/MGSHPositionModelCollection.cs
Normal file
@@ -0,0 +1,593 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using Avalonia.Media;
|
||||
using MarketData.DataAccess;
|
||||
using MarketData.Generator.MGSHMomentum;
|
||||
using MarketData.MarketDataModel;
|
||||
using MarketData.Utils;
|
||||
using PortfolioManager.Interface;
|
||||
using PortfolioManager.UIUtils;
|
||||
using PortfolioManager.ViewModels;
|
||||
|
||||
namespace PortfolioManager.Models
|
||||
{
|
||||
public class MGSHPositionModelCollection : ObservableCollection<MGSHPositionModel>
|
||||
{
|
||||
public void Add(MGSHActivePositions activePositions)
|
||||
{
|
||||
List<int> slotKeys = new List<int>(activePositions.Keys);
|
||||
for (int keyIndex = 0; keyIndex < slotKeys.Count; keyIndex++)
|
||||
{
|
||||
MGSHPositions slotPositions = activePositions[slotKeys[keyIndex]];
|
||||
foreach (MGSHPosition position in slotPositions) Add(new MGSHPositionModel(position, keyIndex));
|
||||
}
|
||||
}
|
||||
|
||||
public void Add(MGSHPositions allPositions)
|
||||
{
|
||||
foreach (MGSHPosition position in allPositions) Add(new MGSHPositionModel(position));
|
||||
}
|
||||
|
||||
public void Add(MGSHPositions hedgePositions, int slotIndex = -1)
|
||||
{
|
||||
if (null == hedgePositions) return;
|
||||
foreach (MGSHPosition position in hedgePositions) Add(new MGSHPositionModel(position, slotIndex));
|
||||
}
|
||||
|
||||
public void OnCollectionChanged()
|
||||
{
|
||||
base.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset, null));
|
||||
}
|
||||
}
|
||||
|
||||
public class MGSHPositionModel : ModelBase, IPositionModel
|
||||
{
|
||||
private MGSHPosition position = new MGSHPosition();
|
||||
private int slot;
|
||||
private int priceChangeDirection = 0;
|
||||
private double prevPrice = double.NaN;
|
||||
private DateTime lastUpdated = DateTime.Now;
|
||||
private double currentPriceLow = double.NaN;
|
||||
private double rsi3 = double.NaN;
|
||||
|
||||
public MGSHPositionModel()
|
||||
{
|
||||
}
|
||||
|
||||
public MGSHPositionModel(MGSHPosition position, int slot)
|
||||
{
|
||||
Slot = slot;
|
||||
Symbol = position.Symbol;
|
||||
PurchaseDate = position.PurchaseDate;
|
||||
SellDate = position.SellDate;
|
||||
Shares = position.Shares;
|
||||
PurchasePrice = position.PurchasePrice;
|
||||
CurrentPrice = position.CurrentPrice;
|
||||
Volume = position.Volume;
|
||||
Return1D = position.Return1D;
|
||||
CumReturn252 = position.CumReturn252;
|
||||
IDIndicator = position.IDIndicator;
|
||||
Score = position.Score;
|
||||
Velocity = position.Velocity;
|
||||
PE = position.PE;
|
||||
Beta = position.Beta;
|
||||
InitialStopLimit = position.InitialStopLimit;
|
||||
TrailingStopLimit = position.TrailingStopLimit;
|
||||
LastStopAdjustment = position.LastStopAdjustment;
|
||||
PositionRiskPercentDecimal = position.PositionRiskPercentDecimal;
|
||||
Comment = position.Comment;
|
||||
}
|
||||
public MGSHPositionModel(MGSHPosition position)
|
||||
{
|
||||
slot = -1;
|
||||
Symbol = position.Symbol;
|
||||
PurchaseDate = position.PurchaseDate;
|
||||
SellDate = position.SellDate;
|
||||
Shares = position.Shares;
|
||||
PurchasePrice = position.PurchasePrice;
|
||||
CurrentPrice = position.CurrentPrice;
|
||||
Volume = position.Volume;
|
||||
Return1D = position.Return1D;
|
||||
CumReturn252 = position.CumReturn252;
|
||||
IDIndicator = position.IDIndicator;
|
||||
Score = position.Score;
|
||||
Velocity = position.Velocity;
|
||||
PE = position.PE;
|
||||
Beta = position.Beta;
|
||||
InitialStopLimit = position.InitialStopLimit;
|
||||
TrailingStopLimit = position.TrailingStopLimit;
|
||||
LastStopAdjustment = position.LastStopAdjustment;
|
||||
PositionRiskPercentDecimal = position.PositionRiskPercentDecimal;
|
||||
Comment = position.Comment;
|
||||
}
|
||||
|
||||
public MGSHPosition Position
|
||||
{
|
||||
get { return position; }
|
||||
set
|
||||
{
|
||||
Slot = -1;
|
||||
Symbol = position.Symbol;
|
||||
PurchaseDate = position.PurchaseDate;
|
||||
SellDate = position.SellDate;
|
||||
Shares = position.Shares;
|
||||
PurchasePrice = position.PurchasePrice;
|
||||
CurrentPrice = position.CurrentPrice;
|
||||
Volume = position.Volume;
|
||||
Return1D = position.Return1D;
|
||||
CumReturn252 = position.CumReturn252;
|
||||
IDIndicator = position.IDIndicator;
|
||||
Score = position.Score;
|
||||
Velocity = position.Velocity;
|
||||
PE = position.PE;
|
||||
Beta = position.Beta;
|
||||
InitialStopLimit = position.InitialStopLimit;
|
||||
TrailingStopLimit = position.TrailingStopLimit;
|
||||
LastStopAdjustment = position.LastStopAdjustment;
|
||||
PositionRiskPercentDecimal = position.PositionRiskPercentDecimal;
|
||||
Comment = position.Comment;
|
||||
this.position.R = position.R;
|
||||
}
|
||||
}
|
||||
|
||||
public double CurrentPriceLow
|
||||
{
|
||||
get { return currentPriceLow; }
|
||||
set
|
||||
{
|
||||
if (currentPriceLow == value) return;
|
||||
currentPriceLow = value;
|
||||
base.OnPropertyChanged("CurrentPriceLow");
|
||||
base.OnPropertyChanged("TrailingStopLimitColor");
|
||||
base.OnPropertyChanged("InitialStopLimitColor");
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateProperties()
|
||||
{
|
||||
base.OnPropertyChanged("CurrentPrice");
|
||||
base.OnPropertyChanged("MarketValue");
|
||||
base.OnPropertyChanged("ActiveMarketValue");
|
||||
base.OnPropertyChanged("GainLoss");
|
||||
base.OnPropertyChanged("GainLossPcnt");
|
||||
base.OnPropertyChanged("Comment");
|
||||
base.OnPropertyChanged("PositionRiskPercentDecimal");
|
||||
base.OnPropertyChanged("R");
|
||||
base.OnPropertyChanged("TotalRiskExposure");
|
||||
base.OnPropertyChanged("RMultiple");
|
||||
|
||||
base.OnPropertyChanged("CurrentPriceColor");
|
||||
base.OnPropertyChanged("TrailingStopLimitColor");
|
||||
base.OnPropertyChanged("InitialStopLimitColor");
|
||||
base.OnPropertyChanged("ActiveMarketValueColor");
|
||||
base.OnPropertyChanged("GainLossColor");
|
||||
base.OnPropertyChanged("GainLossPcntColor");
|
||||
base.OnPropertyChanged("RColor");
|
||||
base.OnPropertyChanged("TotalRiskExposureColor");
|
||||
base.OnPropertyChanged("RMultipleColor");
|
||||
}
|
||||
|
||||
public String Symbol
|
||||
{
|
||||
get { return position.Symbol; }
|
||||
set { position.Symbol = value; base.OnPropertyChanged("Symbol"); }
|
||||
}
|
||||
|
||||
public String Comment
|
||||
{
|
||||
get { return position.Comment; }
|
||||
set { position.Comment = value; base.OnPropertyChanged("Comment"); }
|
||||
}
|
||||
|
||||
public DateTime PurchaseDate
|
||||
{
|
||||
get { return position.PurchaseDate; }
|
||||
set { position.PurchaseDate = value; base.OnPropertyChanged("PurchaseDate"); }
|
||||
}
|
||||
|
||||
public IBrush PurchaseDateColor
|
||||
{
|
||||
get
|
||||
{
|
||||
DateGenerator dateGenerator = new DateGenerator();
|
||||
if (!dateGenerator.IsMarketOpen(PurchaseDate)) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
|
||||
if (!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
|
||||
public IBrush SellDateColor
|
||||
{
|
||||
get
|
||||
{
|
||||
DateGenerator dateGenerator = new DateGenerator();
|
||||
if (!dateGenerator.IsMarketOpen(SellDate)) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
|
||||
if (!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
|
||||
public DateTime SellDate
|
||||
{
|
||||
get { return position.SellDate; }
|
||||
set { position.SellDate = value; base.OnPropertyChanged("SellDate"); }
|
||||
}
|
||||
public int DaysHeld
|
||||
{
|
||||
get
|
||||
{
|
||||
DateGenerator dateGenerator = new DateGenerator();
|
||||
if (Utility.IsEpoch(SellDate)) return dateGenerator.DaysBetween(PurchaseDate, DateTime.Now.Date);
|
||||
return dateGenerator.DaysBetween(PurchaseDate, SellDate);
|
||||
}
|
||||
}
|
||||
public int Slot
|
||||
{
|
||||
get { return slot; }
|
||||
set { slot = value; base.OnPropertyChanged("Slot"); }
|
||||
}
|
||||
public String SlotAsString
|
||||
{
|
||||
get
|
||||
{
|
||||
if (-1 == Slot) return Constants.CONST_DASHES;
|
||||
return Slot.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public double PositionRiskPercentDecimal
|
||||
{
|
||||
get
|
||||
{
|
||||
return position.PositionRiskPercentDecimal;
|
||||
}
|
||||
set
|
||||
{
|
||||
position.PositionRiskPercentDecimal = value;
|
||||
base.OnPropertyChanged("PositionRiskPercentDecimal");
|
||||
}
|
||||
}
|
||||
|
||||
// ************************************************************************************************************************************
|
||||
// ******************************************************************** R I S K *******************************************************
|
||||
// ************************************************************************************************************************************
|
||||
|
||||
public double R
|
||||
{
|
||||
get
|
||||
{
|
||||
if (position.TrailingStopLimit > position.PurchasePrice) return 0.00; // here we are considering the current risk/share which is based on our stop limit
|
||||
return position.TrailingStopLimit > position.PurchasePrice ? 0.00 : position.PurchasePrice - position.TrailingStopLimit;
|
||||
}
|
||||
}
|
||||
|
||||
public IBrush RColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
|
||||
public String RMultipleAsString
|
||||
{
|
||||
get { return Utility.FormatNumber((position.CurrentPrice - position.PurchasePrice) / (position.PurchasePrice - position.InitialStopLimit), 2, false) + "R"; } // always based on original position risk
|
||||
}
|
||||
|
||||
public double RMultiple
|
||||
{
|
||||
get { return (position.CurrentPrice - position.PurchasePrice) / (position.PurchasePrice - position.InitialStopLimit); } // always based on original position risk
|
||||
}
|
||||
|
||||
public IBrush RMultipleColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
|
||||
public double TotalRiskExposure
|
||||
{
|
||||
get { return R * position.Shares; }
|
||||
}
|
||||
|
||||
public IBrush TotalRiskExposureColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
|
||||
// ************************************************************************************************************************************
|
||||
public int DaysSinceLastStopAdjustment
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!IsActivePosition) return int.MinValue;
|
||||
DateGenerator dateGenerator = new DateGenerator();
|
||||
DateTime today = DateTime.Now;
|
||||
int daysSinceLastStopAdjustment = int.MinValue;
|
||||
if (Utility.IsEpoch(position.LastStopAdjustment)) daysSinceLastStopAdjustment = dateGenerator.DaysBetweenActual(today, position.PurchaseDate);
|
||||
else daysSinceLastStopAdjustment = dateGenerator.DaysBetweenActual(today, position.LastStopAdjustment);
|
||||
return daysSinceLastStopAdjustment;
|
||||
}
|
||||
}
|
||||
|
||||
public IBrush DaysSinceLastStopAdjustmentColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
int daysSinceLastStopAdjustment = DaysSinceLastStopAdjustment;
|
||||
if (int.MinValue.Equals(daysSinceLastStopAdjustment)) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
if (daysSinceLastStopAdjustment >= 90) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
|
||||
else if (daysSinceLastStopAdjustment >= 60) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red); // I made them both red because yellow and purple looked horrible
|
||||
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Green);
|
||||
}
|
||||
}
|
||||
|
||||
public double Shares
|
||||
{
|
||||
get { return position.Shares; }
|
||||
set { position.Shares = value; base.OnPropertyChanged("Shares"); base.OnPropertyChanged("Exposure"); base.OnPropertyChanged("ActiveExposure"); base.OnPropertyChanged("MarketValue"); base.OnPropertyChanged("ActiveMarketValue"); base.OnPropertyChanged("GainLoss"); base.OnPropertyChanged("GainLossPcnt"); }
|
||||
}
|
||||
|
||||
public double PurchasePrice
|
||||
{
|
||||
get { return position.PurchasePrice; }
|
||||
set { position.PurchasePrice = value; base.OnPropertyChanged("PurchasePrice"); base.OnPropertyChanged("Exposure"); base.OnPropertyChanged("ActiveExposure"); base.OnPropertyChanged("GainLoss"); base.OnPropertyChanged("GainLossPcnt"); }
|
||||
}
|
||||
|
||||
public double CurrentPrice
|
||||
{
|
||||
get { return position.CurrentPrice; }
|
||||
set
|
||||
{
|
||||
if (position.CurrentPrice == value) return;
|
||||
position.CurrentPrice = value;
|
||||
if (double.IsNaN(prevPrice)) { prevPrice = position.CurrentPrice; priceChangeDirection = 0; }
|
||||
else if (prevPrice > position.CurrentPrice) priceChangeDirection = -1;
|
||||
else if (prevPrice == position.CurrentPrice) priceChangeDirection = 0;
|
||||
else priceChangeDirection = 1;
|
||||
prevPrice = position.CurrentPrice;
|
||||
UpdateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
public double RSI3
|
||||
{
|
||||
get { return rsi3; }
|
||||
set
|
||||
{
|
||||
if (rsi3 == value) return;
|
||||
rsi3 = value;
|
||||
base.OnPropertyChanged("RSI3");
|
||||
base.OnPropertyChanged("RSI3Color");
|
||||
}
|
||||
}
|
||||
|
||||
public DateTime LastUpdated
|
||||
{
|
||||
get { return lastUpdated; }
|
||||
set { lastUpdated = value; base.OnPropertyChanged("LastUpdated"); }
|
||||
}
|
||||
|
||||
public IBrush CurrentPriceColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
if (priceChangeDirection > 0) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Green);
|
||||
else if (priceChangeDirection < 0) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
|
||||
else return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
|
||||
public IBrush RSI3Color
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
if (RSI3 < 10 || RSI3 > 80) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
|
||||
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
|
||||
public double Exposure
|
||||
{
|
||||
get { return Shares * PurchasePrice; }
|
||||
}
|
||||
|
||||
public double ActiveExposure
|
||||
{
|
||||
get { return IsActivePosition ? Exposure : 0.00; }
|
||||
}
|
||||
|
||||
public IBrush ActiveExposureColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
else return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
|
||||
public double MarketValue
|
||||
{
|
||||
get { return Shares * CurrentPrice; }
|
||||
}
|
||||
|
||||
public double ActiveMarketValue
|
||||
{
|
||||
get { return IsActivePosition ? MarketValue : 0.00; }
|
||||
}
|
||||
|
||||
public IBrush ActiveMarketValueColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
if (ActiveMarketValue > Exposure) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Green);
|
||||
else if (ActiveMarketValue < Exposure) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
|
||||
else return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
|
||||
public long Volume
|
||||
{
|
||||
get { return position.Volume; }
|
||||
set { position.Volume = value; base.OnPropertyChanged("Volume"); }
|
||||
}
|
||||
|
||||
public double Return1D
|
||||
{
|
||||
get { return position.Return1D; }
|
||||
set { position.Return1D = value; base.OnPropertyChanged("Return1D"); }
|
||||
}
|
||||
|
||||
public double GainLoss
|
||||
{
|
||||
get { return MarketValue - Exposure; }
|
||||
}
|
||||
|
||||
public IBrush GainLossColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
if (GainLoss > 0) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Green);
|
||||
else if (GainLoss < 0) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
|
||||
else return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
|
||||
public double GainLossPcnt
|
||||
{
|
||||
get { return (MarketValue - Exposure) / Exposure; }
|
||||
}
|
||||
|
||||
public IBrush GainLossPcntColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
if (GainLoss > 0) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Green);
|
||||
else if (GainLoss < 0) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
|
||||
else return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
|
||||
public double CumReturn252
|
||||
{
|
||||
get { return position.CumReturn252; }
|
||||
set { position.CumReturn252 = value; base.OnPropertyChanged("CumReturn252"); }
|
||||
}
|
||||
|
||||
public double IDIndicator
|
||||
{
|
||||
get { return position.IDIndicator; }
|
||||
set { position.IDIndicator = value; base.OnPropertyChanged("IDIndicator"); }
|
||||
}
|
||||
|
||||
public double Score
|
||||
{
|
||||
get { return position.Score; }
|
||||
set { position.Score = value; base.OnPropertyChanged("Score"); }
|
||||
}
|
||||
|
||||
public double Velocity
|
||||
{
|
||||
get { return position.Velocity; }
|
||||
set { position.Velocity = value; base.OnPropertyChanged("Velocity"); }
|
||||
}
|
||||
|
||||
public double PE
|
||||
{
|
||||
get { return position.PE; }
|
||||
set { position.PE = value; base.OnPropertyChanged("PE"); }
|
||||
}
|
||||
|
||||
public double Beta
|
||||
{
|
||||
get { return position.Beta; }
|
||||
set { position.Beta = value; base.OnPropertyChanged("Beta"); }
|
||||
}
|
||||
|
||||
public bool IsActivePosition
|
||||
{
|
||||
get { return Utility.IsEpoch(SellDate) ? true : false; }
|
||||
}
|
||||
|
||||
public double InitialStopLimit
|
||||
{
|
||||
get { return position.InitialStopLimit; }
|
||||
set
|
||||
{
|
||||
position.InitialStopLimit = value;
|
||||
base.OnPropertyChanged("InitialStopLimit");
|
||||
base.OnPropertyChanged("InitialStopLimitColor");
|
||||
}
|
||||
}
|
||||
|
||||
public IBrush InitialStopLimitColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
if (!Utility.IsEpoch(position.LastStopAdjustment)) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black); // if we have a trailing stop then we are no longer using the initial stop
|
||||
StopLimit stopLimit = PortfolioDA.GetStopLimit(position.Symbol);
|
||||
if (null == stopLimit || !stopLimit.StopPrice.Equals(Math.Round(position.InitialStopLimit, 2))) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Purple);
|
||||
if (currentPriceLow <= position.InitialStopLimit) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
|
||||
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
|
||||
public double TrailingStopLimit
|
||||
{
|
||||
get { return position.TrailingStopLimit; }
|
||||
set
|
||||
{
|
||||
position.TrailingStopLimit = value;
|
||||
base.OnPropertyChanged("TrailingStopLimit");
|
||||
base.OnPropertyChanged("TrailingStopLimitColor");
|
||||
}
|
||||
}
|
||||
|
||||
public IBrush TrailingStopLimitColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
if (currentPriceLow <= position.TrailingStopLimit)
|
||||
{
|
||||
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Red);
|
||||
}
|
||||
StopLimit stopLimit = PortfolioDA.GetStopLimit(position.Symbol);
|
||||
if (null == stopLimit || !stopLimit.StopPrice.Equals(Math.Round(position.TrailingStopLimit, 2))) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Purple);
|
||||
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
|
||||
public DateTime LastStopAdjustment
|
||||
{
|
||||
get { return position.LastStopAdjustment; }
|
||||
set { position.LastStopAdjustment = value; base.OnPropertyChanged("LastStopAdjustment"); }
|
||||
}
|
||||
|
||||
public IBrush LastStopAdjustmentColor
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!IsActivePosition) return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Blue);
|
||||
return BrushCollection.GetContextBrush(BrushCollection.BrushColor.Black);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
49
PortfolioManager/Models/MovingAverageModel.cs
Normal file
49
PortfolioManager/Models/MovingAverageModel.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Eremex.AvaloniaUI.Charts;
|
||||
using MarketData.MarketDataModel;
|
||||
using MarketData.MarketDataModel.GainLoss;
|
||||
using PortfolioManager.DataSeriesViewModels;
|
||||
|
||||
namespace PortfolioManager.Models
|
||||
{
|
||||
public class MovingAverageModel
|
||||
{
|
||||
private MovingAverageModel()
|
||||
{
|
||||
}
|
||||
|
||||
public static CompositeDataSource Empty()
|
||||
{
|
||||
CompositeDataSource compositeDataSource = new CompositeDataSource()
|
||||
{
|
||||
DataAdapter = new SortedDateTimeDataAdapter()
|
||||
};
|
||||
return compositeDataSource;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the moving average composite data source
|
||||
/// </summary>
|
||||
/// <param name="gainLossList"></param>
|
||||
/// <param name="useGainLoss"></param>
|
||||
/// <returns></returns>
|
||||
public static CompositeDataSource CreateCompositeDataSource(DMAValues dmaValues)
|
||||
{
|
||||
if (null == dmaValues) return Empty();
|
||||
List<DMAValue> sortedValues = new List<DMAValue>(dmaValues.OrderBy(x => x.Date));
|
||||
|
||||
SortedDateTimeDataAdapter sortedDateTimeDataAdapter = new SortedDateTimeDataAdapter();
|
||||
foreach (DMAValue dmaValue in sortedValues)
|
||||
{
|
||||
sortedDateTimeDataAdapter.Add(dmaValue.Date,dmaValue.MAValue);
|
||||
}
|
||||
CompositeDataSource compositeDataSource = new CompositeDataSource()
|
||||
{
|
||||
DataAdapter = sortedDateTimeDataAdapter
|
||||
};
|
||||
return compositeDataSource;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user