Extended Examples

Spread Options

Below we define a set of various spread options that show how one can combine vanilla options into more complex payoffs.

using Miletus, Gadfly, Colors, Dates

import Miletus: Both, Give, Contract, WhenAt, value
import Base.strip

First define parameters for use in various contract and model definitions.

expirydate = Date("2016-12-25")
startdate  = Date("2016-12-1")
interestrate = 0.05
carryrate    = 0.1
volatility   = 0.15
K₁ = 98.0USD
K₂ = 100.0USD
K₃ = 102.0USD
L  = 11 # Layers in the binomial lattice / Number of time steps

Next we define a range of prices to use for plotting payoff curves.

price = K₁-1USD:0.1USD:K₃+1USD

Then we construct example analytical, binomial, and Monte Carlo test models that will be used when valuing the various vanilla and spread options at the defined start date.

gbmm = GeomBMModel(startdate, K₂, interestrate, carryrate, volatility)
crr  = CRRModel(startdate, expirydate, L, K₂, interestrate, carryrate, volatility)
mcm  = Miletus.montecarlo(gbmm, startdate:Day(1):expirydate, 10_000)

Next let's define a function for calculating the payoff curve of each spread at expiry over a range of asset prices. This function assumes that the provided date is the expiry date of all components within the contract c.

function payoff_curve(c, d::Date, prices)
    payoff = [value(GeomBMModel(d, x, 0.0, 0.0, 0.0), c) for x in prices]
    p = [x.val for x in payoff]
    r = [x.val for x in prices]
    return r, p
end

Next we will create a set of vanilla call and put options at separate strikes that will be used for construction of the different spread options. The included plots show the payoff of the option at the middle strike, K₂.

Vanilla Call Option

call₁ = EuropeanCall(expirydate, SingleStock(), K₁)
call₂ = EuropeanCall(expirydate, SingleStock(), K₂)
call₃ = EuropeanCall(expirydate, SingleStock(), K₃)
s₁,cp₁ = payoff_curve(call₁, expirydate, price)
s₂,cp₂ = payoff_curve(call₂, expirydate, price)
s₃,cp₃ = payoff_curve(call₃, expirydate, price)
plot(x = s₂, y = cp₂, Geom.line,
     Theme(default_color=colorant"blue", line_width = 1.0mm, panel_fill=nothing),
     Guide.title("Vanilla Call Payoff Curve at Expiry"),
     Guide.xlabel("Stock Price"), Guide.ylabel("Payoff"))

value(gbmm, call₂)
1.3688351717682155USD
value(crr, call₂)
1.4034866337776404USD
value(mcm, call₂)
1.3519353356867596USD

Vanilla Put Option

put₁ = EuropeanPut(expirydate, SingleStock(), K₁)
put₂ = EuropeanPut(expirydate, SingleStock(), K₂)
put₃ = EuropeanPut(expirydate, SingleStock(), K₃)
s₁,pp₁ = payoff_curve(put₁, expirydate, price)
s₂,pp₂ = payoff_curve(put₂, expirydate, price)
s₃,pp₃ = payoff_curve(put₃, expirydate, price)
plot(x = s₂, y = pp₂, Geom.line,
     Theme(default_color=colorant"blue", line_width = 1.0mm, panel_fill=nothing),
     Guide.title("Vanilla Put Payoff Curve at Expiry"),
     Guide.xlabel("Stock Price"), Guide.ylabel("Payoff"))

value(gbmm, put₂)
1.6959851162778579USD
value(crr, put₂)
1.7306365782873316USD
value(mcm, put₂)
1.703817183528092USD

Now we will start to combine these vanilla calls and puts into various spread options.

Butterfly Call Spread

# Buy two calls at the high and low strikes
# Sell two calls at the middle strike
function butterfly_call(expiry::Date, K₁, K₂, K₃)
    @assert K₁ < K₂ < K₃
    c₁ = EuropeanCall(expiry, SingleStock(), K₁)
    c₂ = EuropeanCall(expiry, SingleStock(), K₂)
    c₃ = EuropeanCall(expiry, SingleStock(), K₃)
    Both(Both(c₁,c₃), Give(Both(c₂,c₂)))
end

bfly₁ = butterfly_call(expirydate, K₁, K₂, K₃)

s,p_bfly₁ = payoff_curve(bfly₁, expirydate, price)
blk = colorant"black"
red = colorant"red"
grn = colorant"green"
blu = colorant"blue"
plot(layer( x=s ,y=p_bfly₁,Geom.line,Theme(default_color=blk,line_width=1.5mm)),
     layer( x=s₁,y=  cp₁  ,Geom.line,Theme(default_color=red,line_width=1.0mm)),
     layer( x=s₃,y=  cp₃  ,Geom.line,Theme(default_color=grn,line_width=1.0mm)),
     layer( x=s₂,y=-2cp₂  ,Geom.line,Theme(default_color=blu,line_width=1.0mm)),
     Theme(panel_fill=nothing),
     Guide.manual_color_key("",["Butterfly Call", "call₁", "call₃", "-2call₂"],
     ["black", "red", "green", "blue"]),
     Guide.title("Butterfly Call Payoff Curve at Expiry"),
     Guide.xlabel("Stock Price"), Guide.ylabel("Payoff"))

value(gbmm, bfly₁)
0.40245573232655785USD
value(crr, bfly₁)
0.3760697909383439USD
value(mcm, bfly₁)
0.4053843551718277USD

Butterfly Put Spread

# Buy two puts at the high and low strikes
# Sell two puts at the middle strike
function butterfly_put(expiry::Date, K₁, K₂, K₃)
    @assert K₁ < K₂ < K₃
    p₁ = EuropeanPut(expiry, SingleStock(), K₁)
    p₂ = EuropeanPut(expiry, SingleStock(), K₂)
    p₃ = EuropeanPut(expiry, SingleStock(), K₃)
    Both(Both(p₁,p₃), Give(Both(p₂,p₂)))
end

bfly₂ = butterfly_put(expirydate, K₁, K₂, K₃)
s,p_bfly₂ = payoff_curve(bfly₂, expirydate, price)
blk = colorant"black"
red = colorant"red"
grn = colorant"green"
blu = colorant"blue"
plot(layer( x=s ,y=p_bfly₂,Geom.line,Theme(default_color=blk,line_width=1.5mm)),
     layer( x=s₁,y=  pp₁  ,Geom.line,Theme(default_color=red,line_width=1.0mm)),
     layer( x=s₃,y=  pp₃  ,Geom.line,Theme(default_color=grn,line_width=1.0mm)),
     layer( x=s₂,y=-2pp₂  ,Geom.line,Theme(default_color=blu,line_width=1.0mm)),
     Theme(panel_fill=nothing),
     Guide.manual_color_key("",["Butterfly Put", "put₁", "put₃", "-2put₂"],
     ["black", "red", "green", "blue"]),
     Guide.title("Butterfly Put Payoff Curve at Expiry"),
     Guide.xlabel("Stock Price"), Guide.ylabel("Payoff"))

value(gbmm, bfly₂)
0.40245573232657206USD
value(crr, bfly₂)
0.37606979093834303USD
value(mcm, bfly₂)
0.4053843551718219USD

Bear Call Spread

# Buy a call at the high strike
# Sell a call at the low strike
function bear_call(expiry::Date, K₁, K₂)
    @assert K₁ != K₂
    c₁ = EuropeanCall(expiry, SingleStock(), K₁)
    c₂ = EuropeanCall(expiry, SingleStock(), K₂)
    Both(Give(c₁), c₂)
end

bear₁ = bear_call(expirydate, K₁, K₂)
s,p_bear₁ = payoff_curve(bear₁, expirydate, price)
blk = colorant"black"
red = colorant"red"
blu = colorant"blue"
plot(layer( x=s, y=p_bear₁,Geom.line,Theme(default_color=blk,line_width=1.5mm)),
     layer( x=s₁,y=-cp₁   ,Geom.line,Theme(default_color=red,line_width=1.0mm)),
     layer( x=s₂,y= cp₂   ,Geom.line,Theme(default_color=blu,line_width=1.0mm)),
     Theme(panel_fill=nothing),
     Guide.manual_color_key("",["Bear Call", "-call₁", "call₂"],
     ["black", "red", "blue"]),
     Guide.title("Bear Call Payoff Curve at Expiry"),
     Guide.xlabel("Stock Price"), Guide.ylabel("Payoff"))

value(gbmm, bear₁)
-1.119680404537255USD
value(crr, bear₁)
-1.1071634323407784USD
value(mcm, bear₁)
-1.1174271158443008USD

Bear Put Spread

# Buy a put at the low strike
# Sell a put at the high strike
function bear_put(expiry::Date, K₁, K₂)
    @assert K₁ != K₂
    p₁ = EuropeanPut(expiry, SingleStock(), K₁)
    p₂ = EuropeanPut(expiry, SingleStock(), K₂)
    Both(p₁, Give(p₂))
end

bear₂ = bear_put(expirydate, K₁, K₂)
r,p_bear₂ = payoff_curve(bear₂, expirydate, price)
blk = colorant"black"
red = colorant"red"
blu = colorant"blue"
plot(layer( x=s,  y=p_bear₂,Geom.line,Theme(default_color=blk,line_width=1.5mm)),
     layer( x=s₁, y= pp₁   ,Geom.line,Theme(default_color=red,line_width=1.0mm)),
     layer( x=s₂, y=-pp₂   ,Geom.line,Theme(default_color=blu,line_width=1.0mm)),
     Theme(panel_fill=nothing),
     Guide.manual_color_key("",["Bear Put", "call₁", "-call₂"],
     ["black", "red", "blue"]),
     Guide.title("Bear Put Payoff Curve at Expiry"),
     Guide.xlabel("Stock Price"), Guide.ylabel("Payoff"))

value(gbmm, bear₂)
-0.873755049943605USD
value(crr, bear₂)
-0.886272022140092USD
value(mcm, bear₂)
-0.8760083386365771USD

Bull Call Spread

# Buy a call at the low strike
# Sell a call at the high strike
function bull_call(expiry::Date, K₁, K₂)
    @assert K₁ != K₂
    c₁ = EuropeanCall(expiry, SingleStock(), K₁)
    c₂ = EuropeanCall(expiry, SingleStock(), K₂)
    Both(c₁, Give(c₂))
end

bull₁ = bull_call(expirydate, K₁, K₂)
r,p_bull₁ = payoff_curve(bull₁, expirydate, price)
blk = colorant"black"
red = colorant"red"
blu = colorant"blue"
plot(layer( x=s ,y=p_bull₁,Geom.line,Theme(default_color=blk,line_width=1.5mm)),
     layer( x=s₁,y= cp₁   ,Geom.line,Theme(default_color=red,line_width=1.0mm)),
     layer( x=s₂,y=-cp₂   ,Geom.line,Theme(default_color=blu,line_width=1.0mm)),
     Theme(panel_fill=nothing),
     Guide.manual_color_key("",["Bull Call", "call₁", "-call₂"],
     ["black", "red", "blue"]),
     Guide.title("Bull Call Payoff Curve at Expiry"),
     Guide.xlabel("Stock Price"), Guide.ylabel("Payoff"))

value(gbmm, bull₁)
1.119680404537255USD
value(crr, bull₁)
1.1071634323407784USD
value(mcm, bull₁)
1.1174271158443008USD

Bull Put Spread

# Buy a put at the high strike
# Sell a put at the low strike
function bull_put(expiry::Date, K₁, K₂)
    @assert K₁ != K₂
    p₁ = EuropeanPut(expiry, SingleStock(), K₁)
    p₂ = EuropeanPut(expiry, SingleStock(), K₂)
    Both(Give(p₁), p₂)
end

bull₂ = bull_put(expirydate, K₁, K₂)
r,p_bull₂ = payoff_curve(bull₂, expirydate, price)
blk = colorant"black"
red = colorant"red"
blu = colorant"blue"
plot(layer( x=s ,y=p_bull₂,Geom.line,Theme(default_color=blk,line_width=1.5mm)),
     layer( x=s₁,y=-pp₁   ,Geom.line,Theme(default_color=red,line_width=1.0mm)),
     layer( x=s₂,y= pp₂   ,Geom.line,Theme(default_color=blu,line_width=1.0mm)),
     Theme(panel_fill=nothing),
     Guide.manual_color_key("",["Bear Put", "-put₁", "put₂"],
     ["black", "red", "blue"]),
     Guide.title("Bear Put Payoff Curve at Expiry"),
     Guide.xlabel("Stock Price"), Guide.ylabel("Payoff"))

value(gbmm, bull₂)
0.873755049943605USD
value(crr, bull₂)
0.886272022140092USD
value(mcm, bull₂)
0.8760083386365771USD

Straddle Spread

# Buy a put and a call at the same strike
function straddle(expiry::Date, K)
    p = EuropeanPut(expiry, SingleStock(), K)
    c = EuropeanCall(expiry, SingleStock(), K)
    Both(p, c)
end

strd₁ = straddle(expirydate, K₂)
r,p_strd₁ = payoff_curve(strd₁, expirydate, price)
blk = colorant"black"
red = colorant"red"
blu = colorant"blue"
plot(layer( x=s ,y=p_strd₁,Geom.line,Theme(default_color=blk,line_width=1.5mm)),
     layer( x=s₁,y=cp₂    ,Geom.line,Theme(default_color=red,line_width=1.0mm)),
     layer( x=s₂,y=pp₂    ,Geom.line,Theme(default_color=blu,line_width=1.0mm)),
     Theme(panel_fill=nothing),
     Guide.manual_color_key("",["Straddle", "call₂", "put₂"],
     ["black", "red", "blue"]),
     Guide.title("Straddle Payoff Curve at Expiry"),
     Guide.xlabel("Stock Price"), Guide.ylabel("Payoff"))

value(gbmm, strd₁)
3.0648202880460733USD
value(crr, strd₁)
3.134123212064972USD
value(mcm, strd₁)
3.0557525192148516USD

Strip Spread

# Buy one call and two puts at the same strike
function strip(expiry::Date, K)
    p = EuropeanPut(expiry, SingleStock(), K)
    c = EuropeanCall(expiry, SingleStock(), K)
    Both(c, Both(p, p))
end

strip₁ = strip(expirydate, K₂)
r,p_strip = payoff_curve(strip₁, expirydate, price)
blk = colorant"black"
red = colorant"red"
blu = colorant"blue"
plot(layer( x=s ,y=p_strip,Geom.line,Theme(default_color=blk,line_width=1.5mm)),
     layer( x=s₁,y=cp₂    ,Geom.line,Theme(default_color=red,line_width=1.0mm)),
     layer( x=s₂,y=2pp₂   ,Geom.line,Theme(default_color=blu,line_width=1.0mm)),
     Theme(panel_fill=nothing),
     Guide.manual_color_key("",["Strip", "call₂", "2put₂"],
     ["black", "red", "blue"]),
     Guide.title("Strip Payoff Curve at Expiry"),
     Guide.xlabel("Stock Price"), Guide.ylabel("Payoff"))

value(gbmm, strip₁)
4.760805404323931USD
value(crr, strip₁)
4.864759790352304USD
value(mcm, strip₁)
4.759569702742944USD

Strap Spread

# Buy one put and two calls at the same strike
function strap(expiry::Date, K)
    p = EuropeanPut(expiry, SingleStock(), K)
    c = EuropeanCall(expiry, SingleStock(), K)
    Both(p, Both(c, c))
end

strap₁ = strap(expirydate, K₂)
r,p_strap = payoff_curve(strap₁, expirydate, price)
blk = colorant"black"
red = colorant"red"
blu = colorant"blue"
plot(layer( x=s ,y=p_strap,Geom.line,Theme(default_color=blk,line_width=1.5mm)),
     layer( x=s₁,y=2cp₂   ,Geom.line,Theme(default_color=red,line_width=1.0mm)),
     layer( x=s₂,y=pp₂    ,Geom.line,Theme(default_color=blu,line_width=1.0mm)),
     Theme(panel_fill=nothing),
     Guide.manual_color_key("",["Strap", "2call₂", "put₂"],
     ["black", "red", "blue"]),
     Guide.title("Strap Payoff Curve at Expiry"),
     Guide.xlabel("Stock Price"), Guide.ylabel("Payoff"))

value(gbmm, strap₁)
4.433655459814289USD
value(crr, strap₁)
4.537609845842613USD
value(mcm, strap₁)
4.407687854901611USD

Strangle Spread

# Buy a put at the low strike and a call at the high strike
function strangle(expiry::Date, K₁, K₂)
    p = EuropeanPut(expiry, SingleStock(), K₁)
    c = EuropeanCall(expiry, SingleStock(), K₂)
    Both(p, c)
end

strangle₁ = strangle(expirydate, K₁, K₃)
r,p_strangle = payoff_curve(strangle₁, expirydate, price)
blk = colorant"black"
red = colorant"red"
blu = colorant"blue"
plot(layer( x=s ,y=p_strangle,Geom.line,Theme(default_color=blk,line_width=1.5mm)),
     layer( x=s₁,y=cp₃       ,Geom.line,Theme(default_color=red,line_width=1.0mm)),
     layer( x=s₂,y=pp₁       ,Geom.line,Theme(default_color=blu,line_width=1.0mm)),
     Theme(panel_fill=nothing),
     Guide.manual_color_key("",["Strangle", "call₃", "put₁"],
     ["black", "red", "blue"]),
     Guide.title("Strangle Payoff Curve at Expiry"),
     Guide.xlabel("Stock Price"), Guide.ylabel("Payoff"))

value(gbmm, strangle₁)
1.4738405658917713USD
value(crr, strangle₁)
1.5167575485224454USD
value(mcm, strangle₁)
1.4677014199058014USD

Coupon Bearing Bonds

Unlike a zero coupon bond, a coupon bearing bond pays the holder a specified amount at regular intervals up to the maturity date of the bond. These coupon payments, and the interest that can accumulate on those payments must be taken into account when pricing the coupon bond. The structuring of a coupon bond with Miletus provides an example of how to construct a product with multiple observation dates.

using Miletus, BusinessDays, Dates
using Miletus.TermStructure
using Miletus.DayCounts

import Miletus: Both, Receive, Contract, When, At, value
import Miletus: YieldModel
import BusinessDays: USGovernmentBond
import Dates: today, days, Day, Year

First let's show an example of the creation of a zero coupon bond. For this type of bond a payment of the par amount occurs only on the maturity date.

zcb = When(At(today()+Day(360)), Receive(100USD))
When
 ├─{==}
 │  ├─DateObs
 │  └─2023-10-13
 └─Amount
    └─100USD

Next let's define a function for our coupon bearing bond. The definition of multiple coupon payments and the final par payment involves a nested set of Both types, with each individual payment constructed from a When of an date observation and a payment contract.

function couponbond(par,coupon,periods::Int,start::Date,expiry::Date)
    duration = expiry - start
    bond = When(At(expiry), Receive(par))
    for p = periods-1:-1:1
        coupondate = start + duration*p/periods
        bond = Both(bond,When(At(coupondate), Receive(coupon)))
    end
    return bond
end
couponbond (generic function with 1 method)

To construct an individual coupon bond, we first define necessary parameters for the par, coupon, number of periods, start date and expiry date.

par = 100USD
coupon = 1USD
periods = 12
startdate = today()
expirydate = today() + Day(360)
2023-10-13

Now we can construct an instance of a coupon bearing bond.

cpb = couponbond(par,coupon,periods,startdate,expirydate)
Both
 ├─Both
 │  ├─Both
 │  │  ├─Both
 │  │  │  ├─Both
 │  │  │  │  ├─Both
 │  │  │  │  │  ├─Both
 │  │  │  │  │  │  ├─Both
 │  │  │  │  │  │  │  ├─Both
 │  │  │  │  │  │  │  │  ├─Both
 │  │  │  │  │  │  │  │  │  ├─Both
 │  │  │  │  │  │  │  │  │  │  ├─When
 │  │  │  │  │  │  │  │  │  │  │  ├─{==}
 │  │  │  │  │  │  │  │  │  │  │  │  ├─DateObs
 │  │  │  │  │  │  │  │  │  │  │  │  └─2023-10-13
 │  │  │  │  │  │  │  │  │  │  │  └─Amount
 │  │  │  │  │  │  │  │  │  │  │     └─100USD
 │  │  │  │  │  │  │  │  │  │  └─When
 │  │  │  │  │  │  │  │  │  │     ├─{==}
 │  │  │  │  │  │  │  │  │  │     │  ├─DateObs
 │  │  │  │  │  │  │  │  │  │     │  └─2023-09-13
 │  │  │  │  │  │  │  │  │  │     └─Amount
 │  │  │  │  │  │  │  │  │  │        └─1USD
 │  │  │  │  │  │  │  │  │  └─When
 │  │  │  │  │  │  │  │  │     ├─{==}
 │  │  │  │  │  │  │  │  │     │  ├─DateObs
 │  │  │  │  │  │  │  │  │     │  └─2023-08-14
 │  │  │  │  │  │  │  │  │     └─Amount
 │  │  │  │  │  │  │  │  │        └─1USD
 │  │  │  │  │  │  │  │  └─When
 │  │  │  │  │  │  │  │     ├─{==}
 │  │  │  │  │  │  │  │     │  ├─DateObs
 │  │  │  │  │  │  │  │     │  └─2023-07-15
 │  │  │  │  │  │  │  │     └─Amount
 │  │  │  │  │  │  │  │        └─1USD
 │  │  │  │  │  │  │  └─When
 │  │  │  │  │  │  │     ├─{==}
 │  │  │  │  │  │  │     │  ├─DateObs
 │  │  │  │  │  │  │     │  └─2023-06-15
 │  │  │  │  │  │  │     └─Amount
 │  │  │  │  │  │  │        └─1USD
 │  │  │  │  │  │  └─When
 │  │  │  │  │  │     ├─{==}
 │  │  │  │  │  │     │  ├─DateObs
 │  │  │  │  │  │     │  └─2023-05-16
 │  │  │  │  │  │     └─Amount
 │  │  │  │  │  │        └─1USD
 │  │  │  │  │  └─When
 │  │  │  │  │     ├─{==}
 │  │  │  │  │     │  ├─DateObs
 │  │  │  │  │     │  └─2023-04-16
 │  │  │  │  │     └─Amount
 │  │  │  │  │        └─1USD
 │  │  │  │  └─When
 │  │  │  │     ├─{==}
 │  │  │  │     │  ├─DateObs
 │  │  │  │     │  └─2023-03-17
 │  │  │  │     └─Amount
 │  │  │  │        └─1USD
 │  │  │  └─When
 │  │  │     ├─{==}
 │  │  │     │  ├─DateObs
 │  │  │     │  └─2023-02-15
 │  │  │     └─Amount
 │  │  │        └─1USD
 │  │  └─When
 │  │     ├─{==}
 │  │     │  ├─DateObs
 │  │     │  └─2023-01-16
 │  │     └─Amount
 │  │        └─1USD
 │  └─When
 │     ├─{==}
 │     │  ├─DateObs
 │     │  └─2022-12-17
 │     └─Amount
 │        └─1USD
 └─When
    ├─{==}
    │  ├─DateObs
    │  └─2022-11-17
    └─Amount
       └─1USD

Finally we can value this bond by constructing a yield curve and associated yield model and operating on the coupon bond contract with the defined yield model.

yc = ConstantYieldCurve(Actual360(), .1, :Continuous, :NoFrequency, Dates.today())
Constant Curve with r = 0.1, T = 2022-10-18 and Continuous Compounding
ym = YieldModel(yc, ModFollowing(), USGovernmentBond())
Miletus.YieldModel{Miletus.TermStructure.ConstantYieldCurve{Float64}, Miletus.DayCounts.ModFollowing, BusinessDays.USGovernmentBond}
value(ym,cpb)
100.94930244862456USD

Asian Option pricing

Asian options are structures whose payoff depends on the average price of an underlying security over a specific period of time, not just the price of the underlying at maturity. To price an Asian option, we will make use of a Monte Carlo pricing model, as well as a contract that considers a MovingAveragePrice

using Miletus, Gadfly, Colors, Dates

d1 = Dates.today()
d2 = d1 + Dates.Day(120)
2023-02-15

Structing the model without currency units

m = GeomBMModel(d1, 100.00, 0.05, 0.0, 0.3)
mcm = montecarlo(m, d1:Day(1):d2, 100_000)
Monte Carlo Model
-----------------
100000 Simulations everyday from 2022-10-18 to 2023-02-15
Yield Constant Continuous Curve with r = 0.05, T = 2022-10-18 

We can view the underlying simulation paths used for our Geometric Brownian Motion Model using Gadfly as follows:

theme=Theme(default_color=Colors.RGBA{Float32}(0.1, 0.1, 0.7, 0.1))
p = plot([layer(x=mcm.dates,y=mcm.paths[i,:],Geom.line,theme) for i = 1:200]...,Theme(panel_fill=nothing))

Now let's value a vanilla European call option using a Geometric Brownian Motion Model.

o = EuropeanCall(d2, SingleStock(), 100.00)
value(m, o)
7.644207157741416

And value that same vanilla European call using a Monte Carlo Model

value(mcm, o)
7.605119086796078

Next we construct a fixed strike Asian Call option. Note the MovingAveragePrice embedded in the definition.

oa1 = AsianFixedStrikeCall(d2, SingleStock(), Dates.Month(1), 100.00)
When
 ├─{==}
 │  ├─DateObs
 │  └─2023-02-15
 └─Either
    ├─Both
    │  ├─MovingAveragePrice
    │  │  ├─SingleStock
    │  │  └─1 month
    │  └─Give
    │     └─Amount
    │        └─100.0
    └─Zero
value(mcm, oa1)
6.880358443017346

Similarly, we can construct a floating strike Asian Call option.

oa2 = AsianFloatingStrikeCall(d2, SingleStock(), Dates.Month(1), 100.00)
When
 ├─{==}
 │  ├─DateObs
 │  └─2023-02-15
 └─Either
    ├─Both
    │  ├─SingleStock
    │  └─Give
    │     └─MovingAveragePrice
    │        ├─SingleStock
    │        └─1 month
    └─Zero
value(mcm, oa2)
2.0888706033035986