Writer Extendible Option [Loxx]
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © loxx

//@version=5
indicator("Writer Extendible Option [Loxx]", 
     shorttitle ="WEO [Loxx]",
     overlay = true, 
     max_lines_count = 500)

if not timeframe.isdaily
    runtime.error("Error: Invald timeframe. Indicator only works on daily timeframe.") 

import loxx/cnd/1
import loxx/cbnd/1

color darkGreenColor = #1B7E02 

string srcAPrice = "Source Asset Price" 
string manAPrice = "Manual Asset Price" 

string callString = "Call"
string putString = "Put"

string Continuous = "Continuous"
string Annual = "Annual"
string SemiAnnual = "Semi-Annual"
string Quaterly = "Quaterly"
string Monthly = "Monthly"

string rogersatch = "Roger-Satchell"
string parkinson = "Parkinson"
string c2c = "Close-to-Close"
string gkvol = "Garman-Klass"
string gkzhvol = "Garman-Klass-Yang-Zhang"
string ewmavolstr = "Exponential Weighted Moving Average"

string timtoolbar= "Time Now = Current time in UNIX format. It is the number of milliseconds that have elapsed since 00:00:00 UTC, 1 January 1970."
string timtoolnow = "Time Bar = The time function returns the UNIX time of the current bar for the specified timeframe and session or NaN if the time point is out of session."
string timetooltrade = "Trading Day = The beginning time of the trading day the current bar belongs to, in UNIX format (the number of milliseconds that have elapsed since 00:00:00 UTC, 1 January 1970)."

ewmavol(float src, int per) => 
    float lambda = (per - 1) / (per + 1)
    float temp = na
    temp := lambda * nz(temp[1], math.pow(src, 2)) + (1.0 - lambda) * math.pow(src, 2)
    out = math.sqrt(temp)
    out
    
rogerssatchel(int per) =>
    float sum = math.sum(math.log(high/ close) * math.log(high / open)
         + math.log(low / close) * math.log(low / open), per) / per
    float out = math.sqrt(sum) 
    out

closetoclose(float src, int per) => 
    float avg = ta.sma(src, per)
    array<float> sarr = array.new<float>(per, 0)
    for i = 0 to per - 1 
        array.set(sarr, i,  math.pow(nz(src[i]) - avg, 2))
    float out = math.sqrt(array.sum(sarr) / (per - 1))
    out 

parkinsonvol(int per)=>
    float volConst = 1.0 / (4.0 * per * math.log(2))
    float sum = volConst * math.sum(math.pow(math.log(high / low), 2), per)
    float out = math.sqrt(sum) 
    out

garmanKlass(int per)=>
    float hllog = math.log(high / low)
    float oplog = math.log(close / open)
    float garmult = (2 * math.log(2) - 1)
    float parkinsonsum = 1 / (2 * per) * math.sum(math.pow(hllog, 2), per)
    float garmansum = garmult / per * math.sum(math.pow(oplog, 2), per)
    float sum = parkinsonsum - garmansum
    float devpercent = math.sqrt(sum)  
    devpercent

gkyzvol(int per)=>
    float gzkylog = math.log(open / nz(close[1]))
    float pklog = math.log(high / low)
    float gklog = math.log(close / open)
    float garmult = (2 * math.log(2) - 1)
    float gkyzsum = 1 / per * math.sum(math.pow(gzkylog, 2), per)
    float parkinsonsum = 1 / (2 * per) * math.sum(math.pow(pklog, 2), per)
    float garmansum = garmult / per * math.sum(math.pow(gklog, 2), per)
    float sum = gkyzsum + parkinsonsum - garmansum
    float devpercent = math.sqrt(sum)  
    devpercent

ND(float x)=> 
    float out = math.exp(-x * x * 0.5) / math.sqrt(2 * math.pi)
    out 

// via Espen Gaarder Haug; The Complete Guide to Option Pricing Formulas
convertingToCCRate(float r, float Compoundings)=>
    float ConvertingToCCRate = 0
    if Compoundings == 0 
        ConvertingToCCRate := r
    else
        ConvertingToCCRate := Compoundings * math.log(1 + r / Compoundings)
    ConvertingToCCRate

GBlackScholes(string CallPutFlag, float S, float x, float T, float r, float b, float v)=>
    float d1 = 0
    float d2 = 0
    float gBlackScholes = 0

    d1 := (math.log(S / x) + (b + math.pow(v, 2) / 2) * T) / (v * math.sqrt(T))
    d2 := d1 - v * math.sqrt(T)

    if CallPutFlag == callString
        gBlackScholes := S * math.exp((b - r) * T) * cnd.CND1(d1) - x * math.exp(-r * T) * cnd.CND1(d2)
    else
        gBlackScholes := x * math.exp(-r * T) * cnd.CND1(-d2) - S * math.exp((b - r) * T) * cnd.CND1(-d1)
    gBlackScholes

//// Writer extendible options
ExtendibleWriter(string CallPutFlag, float S, float X1, float X2, float t1, float T2, float r, float b, float v)=>
    float ExtendibleWriter = 0
    float rho = math.sqrt(t1 / T2)
    float z1 = (math.log(S / X2) + (b + math.pow(v, 2) / 2) * T2) / (v * math.sqrt(T2))
    float z2 = (math.log(S / X1) + (b + math.pow(v, 2) / 2) * t1) / (v * math.sqrt(t1))

    if CallPutFlag == callString 
        ExtendibleWriter := GBlackScholes(CallPutFlag, S, X1, t1, r, b, v) 
             + S * math.exp((b - r) * T2) * cbnd.CBND3(z1, -z2, -rho) 
             - X2 * math.exp(-r * T2) * cbnd.CBND3(z1 - math.sqrt(math.pow(v, 2) * T2), -z2 + math.sqrt(math.pow(v, 2) * t1), -rho)
    else 
        ExtendibleWriter := GBlackScholes(CallPutFlag, S, X1, t1, r, b, v) 
             + X2 * math.exp(-r * T2) * cbnd.CBND3(-z1 + math.sqrt(math.pow(v, 2) * T2), z2 
             - math.sqrt(math.pow(v, 2) * t1), -rho) - S * math.exp((b - r) * T2) * cbnd.CBND3(-z1, z2, -rho)
    ExtendibleWriter

EExtendibleWriter(string OutPutFlag, string CallPutFlag, float S, float X1, float X2, float t1, float T2, float r, float b, float v, float dSin)=>
    float dS = dSin     
    if na(dS) 
        dS := 0.01

    float EExtendibleWriter = 0
    if OutPutFlag == "p"  // Value
        EExtendibleWriter := ExtendibleWriter(CallPutFlag, S, X1, X2, t1, T2, r, b, v)

    else if OutPutFlag == "d"  //Delta
        EExtendibleWriter := (ExtendibleWriter(CallPutFlag, S + dS, X1, X2, t1, T2, r, b, v) 
             - ExtendibleWriter(CallPutFlag, S - dS, X1, X2, t1, T2, r, b, v)) / (2 * dS)

    else if OutPutFlag == "e"  //Elasticity
        EExtendibleWriter := (ExtendibleWriter(CallPutFlag, S + dS, X1, X2, t1, T2, r, b, v) 
             - ExtendibleWriter(CallPutFlag, S - dS, X1, X2, t1, T2, r, b, v)) 
             / (2 * dS) * S / ExtendibleWriter(CallPutFlag, S, X1, X2, t1, T2, r, b, v)

    else if OutPutFlag == "g"  //Gamma
        EExtendibleWriter := (ExtendibleWriter(CallPutFlag, S + dS, X1, X2, t1, T2, r, b, v) 
             - 2 * ExtendibleWriter(CallPutFlag, S, X1, X2, t1, T2, r, b, v) 
             + ExtendibleWriter(CallPutFlag, S - dS, X1, X2, t1, T2, r, b, v)) / math.pow(dS, 2)

    else if OutPutFlag == "gv"  //DGammaDVol
        EExtendibleWriter := (ExtendibleWriter(CallPutFlag, S + dS, X1, X2, t1, T2, r, b, v + 0.01) 
             - 2 * ExtendibleWriter(CallPutFlag, S, X1, X2, t1, T2, r, b, v + 0.01) 
             + ExtendibleWriter(CallPutFlag, S - dS, X1, X2, t1, T2, r, b, v + 0.01)
             - ExtendibleWriter(CallPutFlag, S + dS, X1, X2, t1, T2, r, b, v - 0.01) 
             + 2 * ExtendibleWriter(CallPutFlag, S, X1, X2, t1, T2, r, b, v - 0.01) 
             - ExtendibleWriter(CallPutFlag, S - dS, X1, X2, t1, T2, r, b, v - 0.01)) / (2 * 0.01 * math.pow(dS, 2)) / 100

    else if OutPutFlag == "gp"  //GammaP
        EExtendibleWriter := S / 100 * (ExtendibleWriter(CallPutFlag, S + dS, X1, X2, t1, T2, r, b, v) 
             - 2 * ExtendibleWriter(CallPutFlag, S, X1, X2, t1, T2, r, b, v) 
             + ExtendibleWriter(CallPutFlag, S - dS, X1, X2, t1, T2, r, b, v)) / math.pow(dS, 2)

    else if OutPutFlag == "dddv"  //DDeltaDvol
        EExtendibleWriter := 1 / (4 * dS * 0.01) * (ExtendibleWriter(CallPutFlag, S + dS, X1, X2, t1, T2, r, b, v + 0.01) 
             - ExtendibleWriter(CallPutFlag, S + dS, X1, X2, t1, T2, r, b, v - 0.01)
             - ExtendibleWriter(CallPutFlag, S - dS, X1, X2, t1, T2, r, b, v + 0.01) 
             + ExtendibleWriter(CallPutFlag, S - dS, X1, X2, t1, T2, r, b, v - 0.01)) / 100

    else if OutPutFlag == "v"  //Vega
        EExtendibleWriter := (ExtendibleWriter(CallPutFlag, S, X1, X2, t1, T2, r, b, v + 0.01) 
             - ExtendibleWriter(CallPutFlag, S, X1, X2, t1, T2, r, b, v - 0.01)) / 2

    else if OutPutFlag == "vv"  //DvegaDvol/vomma
        EExtendibleWriter := (ExtendibleWriter(CallPutFlag, S, X1, X2, t1, T2, r, b, v + 0.01) 
             - 2 * ExtendibleWriter(CallPutFlag, S, X1, X2, t1, T2, r, b, v) 
             + ExtendibleWriter(CallPutFlag, S, X1, X2, t1, T2, r, b, v - 0.01)) / math.pow(0.01, 2)/ 10000

    else if OutPutFlag == "vp"  //VegaP
        EExtendibleWriter := v / 0.1 * (ExtendibleWriter(CallPutFlag, S, X1, X2, t1, T2, r, b, v + 0.01) 
             - ExtendibleWriter(CallPutFlag, S, X1, X2, t1, T2, r, b, v - 0.01)) / 2

    else if OutPutFlag == "dvdv"  //DvegaDvol
        EExtendibleWriter := (ExtendibleWriter(CallPutFlag, S, X1, X2, t1, T2, r, b, v + 0.01) 
             - 2 * ExtendibleWriter(CallPutFlag, S, X1, X2, t1, T2, r, b, v) 
             + ExtendibleWriter(CallPutFlag, S, X1, X2, t1, T2, r, b, v - 0.01))

    else if OutPutFlag == "t"  //Theta
        if t1 <= 1 / 365 
            EExtendibleWriter := ExtendibleWriter(CallPutFlag, S, X1, X2, 1E-05, T2 - 1 / 365, r, b, v) 
                 - ExtendibleWriter(CallPutFlag, S, X1, X2, t1, T2, r, b, v)
        else
            EExtendibleWriter := ExtendibleWriter(CallPutFlag, S, X1, X2, t1 - 1 / 365, T2 - 1 / 365, r, b, v) 
                 - ExtendibleWriter(CallPutFlag, S, X1, X2, t1, T2, r, b, v)

    else if OutPutFlag == "r"  //Rho
        EExtendibleWriter := (ExtendibleWriter(CallPutFlag, S, X1, X2, t1, T2, r + 0.01, b + 0.01, v) 
             - ExtendibleWriter(CallPutFlag, S, X1, X2, t1, T2, r - 0.01, b - 0.01, v)) / 2

    else if OutPutFlag == "fr"  //Futures options rho
        EExtendibleWriter := (ExtendibleWriter(CallPutFlag, S, X1, X2, t1, T2, r + 0.01, b, v) 
             - ExtendibleWriter(CallPutFlag, S, X1, X2, t1, T2, r - 0.01, b, v)) / 2

    else if OutPutFlag == "f"  //Rho2
        EExtendibleWriter := (ExtendibleWriter(CallPutFlag, S, X1, X2, t1, T2, r, b - 0.01, v) 
             - ExtendibleWriter(CallPutFlag, S, X1, X2, t1, T2, r, b + 0.01, v)) / 2

    else if OutPutFlag == "b"  //Carry
        EExtendibleWriter := (ExtendibleWriter(CallPutFlag, S, X1, X2, t1, T2, r, b + 0.01, v) 
             - ExtendibleWriter(CallPutFlag, S, X1, X2, t1, T2, r, b - 0.01, v)) / 2

    else if OutPutFlag == "s"  //Speed
        EExtendibleWriter := 1 / math.pow(dS, 3) * (ExtendibleWriter(CallPutFlag, S + 2 * dS, X1, X2, t1, T2, r, b, v) 
             - 3 * ExtendibleWriter(CallPutFlag, S + dS, X1, X2, t1, T2, r, b, v)
             + 3 * ExtendibleWriter(CallPutFlag, S, X1, X2, t1, T2, r, b, v) - ExtendibleWriter(CallPutFlag, S - dS, X1, X2, t1, T2, r, b, v))

    EExtendibleWriter

string OpType = input.string(callString, "Option type", options = [callString, putString], group = "Basic Settings")   
string side = input.string("Long", "Side", options = ["Long", "Short"], group = "Basic Settings")   

float Sm = input.float(100, "Manual Asset Price", group = "Basic Settings")  
float Ssrc = input.source(close, "Source Asset Price", group = "Basic Settings") 
string assetswtich = input.string(manAPrice, "Asset Price Type", options = [srcAPrice, manAPrice], group = "Basic Settings")  

float K1 = input.float(100, "Initial Strike Price", group = "Basic Settings")  
float K2 = input.float(100, "Extended Strike Price", group = "Basic Settings")  

float r = input.float(6., "% Risk-free Rate", group = "Rates Settings") / 100
string rcmp = input.string(Continuous, "% Risk-free Rate Compounding Type", options = [Continuous, Annual, SemiAnnual, Quaterly, Monthly], group = "Rates Settings")

float b = input.float(6., "% Cost of Carry", group = "Rates Settings") / 100
string bcmp = input.string(Continuous, "% Cost of Carry Compounding Type", options = [Continuous, Annual, SemiAnnual, Quaterly, Monthly], group = "Rates Settings")

float v = input.float(20., "% Volatility", group = "Rates Settings") / 100

int histvolper = input.int(22, "Historical Volatility Period", group = "Historical Volatility Settings", tooltip =  "Not used in calculation. This is here for comparison to implied volatility")
string hvoltype = input.string(c2c, "Historical Volatility Type", options = [c2c, gkvol, gkzhvol, rogersatch, ewmavolstr, parkinson], group = "Historical Volatility Settings")

float S = assetswtich == srcAPrice ? Ssrc : Sm

string timein = input.string("Time Now", title = "Time Now Type", options = ["Time Now", "Time Bar", "Trading Day"], group = "Time Intrevals", tooltip = timtoolnow + "; " + timtoolbar + "; " + timetooltrade)
int daysinyear = input.int(252, title = "Days in Year", minval = 1, maxval = 365, group = "Time Intrevals", tooltip = "Typically 252 or 365")
float hoursinday = input.float(24, title = "Hours Per Day", minval = 1, maxval = 24, group = "Time Intrevals", tooltip = "Typically 6.5, 8, or 24")

int startthruMonth = input.int(12, title = "Initial Time Start Month", minval = 1, maxval = 12, group = "Initial Time to Maturity Date/Time")
int startthruDay = input.int(31, title = "Initial Time  Start Day", minval = 1, maxval = 31, group = "Initial Time to Maturity Date/Time")
int startthruYear = input.int(2022, title = "Initial Time  Start Year", minval = 1970, group = "Initial Time to Maturity Date/Time")
int startmins = input.int(0, title = "Initial Time Start Minute", minval = 0, maxval = 60, group = "Initial Time to Maturity Date/Time")
int starthours = input.int(9, title = "Initial Time Start Hour", minval = 0, maxval = 24, group = "Initial Time to Maturity Date/Time")
int startsecs = input.int(0, title = "Initial Time Start Second", minval = 0, maxval = 60, group = "Initial Time to Maturity Date/Time")

int expirythruMonth = input.int(3, title = "Extended Time Month", minval = 1, maxval = 12, group = "Extended Time to Maturity Date/Time")
int expirythruDay = input.int(31, title = "Extended Time Day", minval = 1, maxval = 31, group = "Extended Time to Maturity Date/Time")
int expirythruYear = input.int(2023, title = "Extended Time Year", minval = 1970, group = "Extended Time to Maturity Date/Time")
int expirymins = input.int(0, title = "Extended Time Minute", minval = 0, maxval = 60, group = "Extended Time to Maturity Date/Time")
int expiryhours = input.int(9, title = "Extended Time Hour", minval = 0, maxval = 24, group = "Extended Time to Maturity Date/Time")
int expirysecs = input.int(0, title = "Extended Time Second", minval = 0, maxval = 60, group = "Extended Time to Maturity Date/Time")

// seconds per year given inputs above
int spyr = math.round(daysinyear * hoursinday * 60 * 60)

// precision calculation miliseconds in time intreval from time equals now
float startstart = timein == "Time Now" ? timenow : timein == "Time Bar" ? time : time_tradingday
float startfinish = timestamp(startthruYear, startthruMonth, startthruDay, starthours, startmins, startsecs) 
float starttemp = (startfinish - startstart) 
float T1 = (startfinish - startstart) / spyr / 1000

// precision calculation miliseconds in time intreval from time equals now
float expirystart = timein == "Time Now" ? timenow : timein == "Time Bar" ? time : time_tradingday
float expiryfinish = timestamp(expirythruYear, expirythruMonth, expirythruDay, expiryhours, expirymins, expirysecs) 
float expirytemp = (expiryfinish - expirystart) 
float T2 = (expiryfinish - expirystart) / spyr / 1000

string txtsize = input.string("Auto", title = "Text Size", options = ["Small", "Normal", "Tiny", "Auto", "Large"], group = "UI Options")

string outsize = switch txtsize
    "Small"=> size.small
    "Normal"=> size.normal
    "Tiny"=> size.tiny
    "Auto"=> size.auto
    "Large"=> size.large

float hvolout = switch hvoltype
    parkinson => parkinsonvol(histvolper)
    rogersatch => rogerssatchel(histvolper) 
    c2c => closetoclose(math.log(S / nz(S[1])), histvolper) 
    gkvol => garmanKlass(histvolper) 
    gkzhvol => gkyzvol(histvolper) 
    ewmavolstr => ewmavol(math.log(S / nz(S[1])), histvolper) 

float rcmpval = switch rcmp
    Continuous=> 0
    Annual=> 1
    SemiAnnual=> 2
    Quaterly=> 4
    Monthly=> 12
    => 0

float bcmpval = switch bcmp
    Continuous=> 0
    Annual=> 1
    SemiAnnual=> 2
    Quaterly=> 4
    Monthly=> 12
    => 0

if barstate.islast
    float sideout = side == "Long" ? 1 : -1

    float kouta = convertingToCCRate(r, rcmpval)
    float koutb = convertingToCCRate(b, bcmpval)

    float amaproxprice        = EExtendibleWriter("p", OpType, S, K1, K2, T1, T2, kouta, koutb, v, na)
    float Delta               = EExtendibleWriter("d", OpType, S, K1, K2, T1, T2, kouta, koutb, v, na) * sideout
    float Elasticity          = EExtendibleWriter("e", OpType, S, K1, K2, T1, T2, kouta, koutb, v, na) * sideout
    float Gamma               = EExtendibleWriter("g", OpType, S, K1, K2, T1, T2, kouta, koutb, v, na) * sideout
    float DGammaDvol          = EExtendibleWriter("gv", OpType, S, K1, K2, T1, T2, kouta, koutb, v, na) * sideout
    float GammaP              = EExtendibleWriter("gp", OpType, S, K1, K2, T1, T2, kouta, koutb, v, na) * sideout
    float Vega                = EExtendibleWriter("v", OpType, S, K1, K2, T1, T2, kouta, koutb, v, na) * sideout
    float DvegaDvol           = EExtendibleWriter("dvdv", OpType, S, K1, K2, T1, T2, kouta, koutb, v, na) * sideout
    float VegaP               = EExtendibleWriter("vp", OpType, S, K1, K2, T1, T2, kouta, koutb, v, na) * sideout
    float Theta               = EExtendibleWriter("t", OpType, S, K1, K2, T1, T2, kouta, koutb, v, na) * sideout
    float Rho                 = EExtendibleWriter("r", OpType, S, K1, K2, T1, T2, kouta, koutb, v, na) * sideout
    float RhoFuturesOption    = EExtendibleWriter("fr", OpType, S, K1, K2, T1, T2, kouta, koutb, v, na) * sideout
    float PhiRho2             = EExtendibleWriter("f", OpType, S, K1, K2, T1, T2, kouta, koutb, v, na) * sideout
    float Carry               = EExtendibleWriter("b", OpType, S, K1, K2, T1, T2, kouta, koutb, v, na) * sideout
    float DDeltaDvol          = EExtendibleWriter("dddv", OpType, S, K1, K2, T1, T2, kouta, koutb, v, na) * sideout
    float Speed               = EExtendibleWriter("s", OpType, S, K1, K2, T1, T2, kouta, koutb, v, na) * sideout
 
    var testTable = table.new(position = position.middle_right, columns = 2, rows = 18, bgcolor = color.gray, border_width = 1)

    table.cell(table_id = testTable, column = 0, row = 0,  text = "Writer Extendible Option", bgcolor=color.yellow, text_color = color.black, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 0, row = 1,  text = "Option Type: " + OpType, bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 0, row = 2,  text = "Side: " + side , bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 0, row = 3,  text = "Asset Price: " + str.tostring(S) , bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 0, row = 4,  text = "Asset Price Source: " + assetswtich, bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 0, row = 5,  text = "Iniital Strike Price: " + str.tostring(K1), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 0, row = 6,  text = "Extended Strike Price: " + str.tostring(K2), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 0, row = 7,  text = "% Risk-free Rate: " + str.tostring(r * 100, "##.##") + "%\n" + "Compounding Type: " + rcmp + "\nCC Rate: " + str.tostring(kouta * 100, "##.##") + "%", bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 0, row = 8,  text = "% Cost of Carry: " + str.tostring(b * 100, "##.##") + "%\n" + "Compounding Type: " + bcmp + "\nCC Carry: " + str.tostring(koutb * 100, "##.##") + "%", bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 0, row = 9,  text = "% Volatility (annual): " + str.tostring(v * 100, "##.##") + "%", bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 0, row = 10, text = "Iniital Date/Time to Maturity: " + str.format("{0,date,MMMM dd, yyyy - HH:mm:ss}", startfinish), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 0, row = 11, text = "Extended Date/Time to Maturity: " + str.format("{0,date,MMMM dd, yyyy - HH:mm:ss}", expiryfinish), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    
    table.cell(table_id = testTable, column = 0, row = 12, text = "Calculated Values", bgcolor=color.yellow, text_color = color.black, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 0, row = 13, text = "Hist. Volatility Type: " + hvoltype, bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 0, row = 14, text = "Hist. Daily Volatility: " + str.tostring(hvolout * 100, "##.##") + "%", bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 0, row = 15, text = "Hist. Annualized Volatility: " + str.tostring(hvolout * math.sqrt(daysinyear) * 100, "##.##") + "%", bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)

    table.cell(table_id = testTable, column = 1, row = 0, text = "Option Ouputs", bgcolor=color.yellow, text_color = color.black, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 1, row = 1, text = "Writer Extendible Option Price: " + str.tostring(amaproxprice, format.mintick), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)

    table.cell(table_id = testTable, column = 1, row = 2, text = "Option Sensitivities", bgcolor=color.yellow, text_color = color.black, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 1, row = 3, text = "Delta Δ: " + str.tostring(Delta, "##.#####"), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 1, row = 4, text = "Elasticity Λ: " + str.tostring(Elasticity, "##.########"), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 1, row = 5, text = "Gamma Γ: " + str.tostring(Gamma, "##.########"), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 1, row = 6, text = "DGammaDvol: " + str.tostring(DGammaDvol, "##.########"), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 1, row = 7, text = "GammaP Γ: " + str.tostring(GammaP, "##.########"), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 1, row = 8, text = "Vega: " + str.tostring(Vega, "##.########"), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 1, row = 9, text = "DVegaDvol: " + str.tostring(DvegaDvol, "##.########"), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 1, row = 10, text = "VegaP: " + str.tostring(VegaP, "##.########"), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 1, row = 11, text = "Theta Θ (1 day): " + str.tostring(Theta, "##.########"), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 1, row = 12, text = "Rho ρ: " + str.tostring(Rho, "##.########"), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 1, row = 13, text = "Rho Futures 0ption ρ: " + str.tostring(RhoFuturesOption, "##.########"), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 1, row = 14, text = "Phi/Rho2: " + str.tostring(PhiRho2, "##.########"), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 1, row = 15, text = "Carry: " + str.tostring(Carry, "##.########"), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 1, row = 16, text = "DDeltaDvol: " + str.tostring(DDeltaDvol, "##.########"), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
    table.cell(table_id = testTable, column = 1, row = 17, text = "Speed: " + str.tostring(Speed, "##.########"), bgcolor=darkGreenColor, text_color = color.white, text_size = outsize, text_halign = text.align_left)
 
