Files
2024-02-22 14:52:53 -05:00

336 lines
12 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.Threading.Tasks;
using MarketData.Utils;
namespace MarketData.MarketDataModel
{
public class EquityPriceShocks : List<EquityPriceShock>
{
public static EquityPriceShocks CreateEquityPriceShocks(Price latestPrice, OptionsParams optionsParams)
{
EquityPriceShocks equityPriceShocks = new EquityPriceShocks();
int[] shocks = { 50, 25, 15, 10, 0, -5, -10, -15, -25, -50 };
for (int index = 0; index < shocks.Length; index++)
{
EquityPriceShock equityPriceShock = new EquityPriceShock();
equityPriceShock.Rank = shocks[index];
if (equityPriceShock.Rank > 0) equityPriceShock.PriceShock = "+" + Utility.FormatNumber(equityPriceShock.Rank, 0, false).ToString() + "%";
else if (equityPriceShock.Rank < 0) equityPriceShock.PriceShock = Utility.FormatNumber(equityPriceShock.Rank, 0, false) + "%";
else equityPriceShock.PriceShock = "+-" + Utility.FormatNumber(equityPriceShock.Rank, 0, false) + "%";
equityPriceShock.Premium = optionsParams.Premium;
equityPriceShock.Rank /= 100.00;
equityPriceShock.MarketPrice = latestPrice.Close + (latestPrice.Close * equityPriceShock.Rank);
equityPriceShock.StrikePrice = optionsParams.Strike;
// We expect the option to be excercises because the strike price is more favorable than market price
// price our gain loss as if we had purchased at prevailing market price and then sold at the strike price
if (optionsParams.Strike < equityPriceShock.MarketPrice)
{
equityPriceShock.PositionGL = (equityPriceShock.StrikePrice * optionsParams.Shares) - (latestPrice.Close * optionsParams.Shares);
equityPriceShock.TransactionGL = equityPriceShock.Premium + equityPriceShock.PositionGL;
equityPriceShock.ExpectedOutcome = "Option will be assigned.";
}
else
// We expect the option to go un-excercised because the stock can be purchased in the open market more cheaply than at our strike price
// price our gain/loss as if we had purchased at prevailing market prie and then sold at the shock price
{
equityPriceShock.PositionGL = (equityPriceShock.MarketPrice * optionsParams.Shares) - (latestPrice.Close * optionsParams.Shares);
equityPriceShock.TransactionGL = equityPriceShock.Premium + equityPriceShock.PositionGL;
equityPriceShock.ExpectedOutcome = "Option will not be assigned.";
}
equityPriceShocks.Add(equityPriceShock);
}
return equityPriceShocks;
}
}
public class EquityPriceShock
{
public String PriceShock { get; set; }
public double Rank { get; set; }
public double MarketPrice { get; set; }
public double StrikePrice { get; set; }
public double Premium { get; set; }
public double PositionGL { get; set; }
public double TransactionGL { get; set; }
public String ExpectedOutcome { get; set; }
}
[Serializable]
public class OptionsParams
{
private int contracts;
private double shares;
public static int CONTRACT_SIZE = 100;
public String Symbol { get; set; }
public String CompanyName { get; set; }
public double Cashdown { get; set; }
public DateTime ExpirationDate { get; set; }
public double Bid { get; set; }
public double Strike { get; set; }
public double OpenInterest { get; set; }
public double Volume { get; set; }
public double Shares
{
get
{
return shares;
}
}
public int Contracts
{
get
{
return contracts;
}
set
{
contracts = value;
shares = contracts * 100.00;
}
}
public double MarketPrice { get; set; }
public double Premium { get; set; }
public double Volatility { get; set; }
public int VolatilityDays { get; set; }
public static String Header
{
get
{
StringBuilder sb = new StringBuilder();
sb.Append("Symbol").Append(",");
sb.Append("CompanyName").Append(",");
sb.Append("Cashdown").Append(",");
sb.Append("ExpirationDate").Append(",");
sb.Append("Bid").Append(",");
sb.Append("Strike").Append(",");
sb.Append("OpenInterest").Append(",");
sb.Append("Shares").Append(",");
sb.Append("Contracts").Append(",");
sb.Append("MarketPrice").Append(",");
sb.Append("Premium").Append(",");
sb.Append("Volatility").Append(",");
sb.Append("VolatilityDays");
return sb.ToString();
}
}
public override String ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append("\"").Append(Symbol).Append("\"").Append(",");
sb.Append("\"").Append(CompanyName).Append("\"").Append(",");
sb.Append("\"").Append(Utility.FormatCurrency(Cashdown)).Append("\"").Append(",");
sb.Append("\"").Append(Utility.DateTimeToStringMMHDDHYYYY(ExpirationDate)).Append("\"").Append(",");
sb.Append("\"").Append(Utility.FormatCurrency(Bid)).Append("\"").Append(",");
sb.Append("\"").Append(Utility.FormatCurrency(Strike)).Append("\"").Append(",");
sb.Append("\"").Append(Utility.FormatNumber(OpenInterest,0,true)).Append("\"").Append(",");
sb.Append("\"").Append(Utility.FormatNumber(Shares)).Append("\"").Append(",");
sb.Append("\"").Append(Utility.FormatNumber(Contracts,0,true)).Append("\"").Append(",");
sb.Append("\"").Append(Utility.FormatCurrency(MarketPrice)).Append("\"").Append(",");
sb.Append("\"").Append(Utility.FormatCurrency(Premium)).Append("\"").Append(",");
sb.Append("\"").Append(Utility.FormatCurrency(Volatility)).Append("\"").Append(",");
sb.Append("\"").Append(Utility.FormatNumber(VolatilityDays,0,false)).Append("\"");
return sb.ToString();
}
}
public class MoneyType
{
public enum MoneyTypeEnum { AtTheMoney, InTheMoney, OutOfTheMoney, Unset };
public MoneyTypeEnum moneyType = MoneyTypeEnum.Unset;
public MoneyType()
{
moneyType = MoneyTypeEnum.Unset;
}
public MoneyType(double currentPrice, double strikePrice)
{
SetMoney(currentPrice, strikePrice);
}
public MoneyType.MoneyTypeEnum Money
{
get { return moneyType; }
set { moneyType = value; }
}
public void SetMoney(double currentPrice, double strikePrice)
{
double upperPrice = strikePrice + .15;
double lowerPrice = strikePrice - .15;
if (currentPrice <= upperPrice && currentPrice >= lowerPrice)
{
Money = MoneyTypeEnum.AtTheMoney;
}
else if (strikePrice < currentPrice) Money = MoneyTypeEnum.InTheMoney;
else Money = MoneyTypeEnum.OutOfTheMoney;
}
public override string ToString()
{
switch (Money)
{
case MoneyTypeEnum.AtTheMoney:
return "At The Money";
case MoneyTypeEnum.InTheMoney:
return "In The Money";
case MoneyTypeEnum.OutOfTheMoney:
return "Out Of The Money";
default:
return "Unset";
}
}
}
// *******************************************************************************************************************************************************************
// ************************************************************** P U T C A L L R A T I O C A L C U L A T O R ***********************************************
// *******************************************************************************************************************************************************************
public class PutCallRatioHelper
{
protected class StrikeExpiryKey
{
public StrikeExpiryKey(double strike,DateTime expiration)
{
Expiration=expiration;
Strike=strike;
}
public DateTime Expiration{get;set;}
public double Strike{get;set;}
public override int GetHashCode()
{
StringBuilder sb=new StringBuilder();
sb.Append(Expiration.ToShortDateString()).Append(Utility.FormatCurrency(Strike));
return sb.ToString().GetHashCode();
}
public override bool Equals(object obj)
{
return Equals(obj as StrikeExpiryKey);
}
public bool Equals(StrikeExpiryKey obj)
{
return obj.ToString().Equals(ToString());
}
public override String ToString()
{
StringBuilder sb=new StringBuilder();
sb.Append(Expiration.ToShortDateString()).Append(Utility.FormatCurrency(Strike));
return sb.ToString();
}
}
private PutCallRatioHelper()
{
}
public static void CalculatePutCallRatios(Options options)
{
Dictionary<StrikeExpiryKey,Option> putOptions=new Dictionary<StrikeExpiryKey,Option>();
Dictionary<StrikeExpiryKey,Option> callOptions=new Dictionary<StrikeExpiryKey,Option>();
foreach(Option option in options)
{
StrikeExpiryKey strikeExpiryKey=new StrikeExpiryKey(option.Strike,option.Expiration);
if(option.Type.Equals(OptionTypeEnum.CallOption)&&!callOptions.ContainsKey(strikeExpiryKey))callOptions.Add(strikeExpiryKey,option);
else if(!putOptions.ContainsKey(strikeExpiryKey))putOptions.Add(strikeExpiryKey,option);
}
foreach(Option option in options)
{
if(option.Volume==0)
{
option.PutCallRatio=double.NaN;
option.CallPutRatio=double.NaN;
continue;
}
StrikeExpiryKey strikeExpiryKey=new StrikeExpiryKey(option.Strike,option.Expiration);
if(option.Type.Equals(OptionTypeEnum.PutOption)) // put options
{
Option callOption=null;
option.CallPutRatio=double.NaN;
if(!callOptions.ContainsKey(strikeExpiryKey))
{
option.PutCallRatio=double.NaN;
continue;
}
callOption=callOptions[strikeExpiryKey];
if(0==callOption.Volume)
{
option.PutCallRatio=double.NaN;
continue;
}
option.PutCallRatio=(double)option.Volume/(double)callOption.Volume;
}
else // call options
{
Option putOption=null;
option.PutCallRatio=double.NaN;
if(!putOptions.ContainsKey(strikeExpiryKey))
{
option.CallPutRatio=double.NaN;
continue;
}
putOption=putOptions[strikeExpiryKey];
if(0==putOption.Volume)
{
option.CallPutRatio=double.NaN;
continue;
}
option.CallPutRatio=(double)option.Volume/(double)putOption.Volume;
}
}
}
}
// *******************************************************************************************************************************************************************
public enum OptionTypeEnum { CallOption, PutOption };
public class Options : List<Option>
{
public Options()
{
}
public Options(List<Option> options)
{
foreach(Option option in options)Add(option);
}
}
[Serializable]
public class Option
{
private MoneyType moneyType = new MoneyType();
public DateTime Expiration { get; set; }
public String Symbol { get; set; }
public OptionTypeEnum Type { get; set; }
public double Strike { get; set; }
public double PutCallRatio{get;set;}
public double CallPutRatio{get;set;}
public Double Ratio
{
get
{
if(Type.Equals(OptionTypeEnum.CallOption))return CallPutRatio;
return PutCallRatio;
}
}
public override int GetHashCode()
{
return (Symbol+Expiration.ToShortDateString()+Utility.FormatNumber(Strike,2)+(int)Type).GetHashCode();
}
public double Last { get; set; }
public double Change { get; set; }
public double Bid { get; set; }
public double Ask { get; set; }
public long Volume { get; set; }
public double OpenInterest { get; set; }
public double OptionValue { get; set; }
public DateTime Modified { get; set; }
public MoneyType MoneyType
{
get { return moneyType; }
set { moneyType = value; }
}
public String MoneyTypeAsString { get { return MoneyType.ToString(); } }
public int DaysToExpiration
{
get
{
return new DateGenerator().DaysBetween(Expiration, DateTime.Now);
}
}
}
}