334 lines
10 KiB
C#
334 lines
10 KiB
C#
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; }
|
|
}
|
|
}
|
|
}
|