Initial Commit
This commit is contained in:
335
MarketData/MarketDataLib/MarketDataModel/OptionsModel.cs
Executable file
335
MarketData/MarketDataLib/MarketDataModel/OptionsModel.cs
Executable file
@@ -0,0 +1,335 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user