Files
Avalonia/PortfolioManager/Models/CMPositionModelCollection.cs
2025-06-10 19:03:43 -04:00

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; }
}
}
}