Investire in Opzioni

Grazie ragazzi! Cren per me Python va bene. Interessante il tuo suggerimento. Quindi si tratterebbe di fittare una distribuzione parametrica sui dati disponibili, in questo caso una mistura che dovrebbe essere abbastanza flessibile per catturare varie forme.

Posso chiedervi anche come utilizzate queste distribuzioni? L'articolo che ho letto sembra suggerire che prese così servono a poco, certo non per fare predizioni. Fanno vedere come l'hedging impatti sulle code delle implicite, senza poi contare che non sono neppure probabilità reali (anche se da quanto ho capito si potrebbe avere un'idea sulla distribuzione reale sapendo in che modo l'avversione al rischio modifica la simmetria).
 
Grazie ragazzi! Cren per me Python va bene. Interessante il tuo suggerimento. Quindi si tratterebbe di fittare una distribuzione parametrica sui dati disponibili, in questo caso una mistura che dovrebbe essere abbastanza flessibile per catturare varie forme.
Rettifico: non "Python o C++" bensì C++ in Python tramite pybind11 :D

Sorgente in C++ (richiede Armadillo e Boost oltre a pybind11):
Codice:
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <armadillo>
#include <boost/math/distributions/normal.hpp>
#include <assert.h>

namespace py = pybind11;
using boost::math::normal;

const double PI = std::atan(1.0) * 4;

std::map< std::string, std::vector< double >> price_mln_option(
    double r,
    double te,
    double y,
    const std::vector< double >& k,
    double alpha_1,
    double meanlog_1,
    double meanlog_2,
    double sdlog_1,
    double sdlog_2)
{
    double discount_factor = exp(-r * te);
    double alpha_2 = 1 - alpha_1;
    double expected_val_1 = exp(meanlog_1 + .5 * (pow(sdlog_1, 2)));
    double expected_val_2 = exp(meanlog_2 + .5 * (pow(sdlog_2, 2)));
    double s0 = exp((y - r) * te) * (alpha_1 * expected_val_1 + alpha_2 * expected_val_2);
    std::vector< double > c1_vec, c2_vec;
    normal s;
    for (std::vector< double >::const_iterator it = k.begin(); it != k.end(); it++)
    {
        double strike = *it;
        double u1 = (log(strike) - meanlog_1) / sdlog_1;
        double tmp1 = expected_val_1 * (1 - cdf(s, u1 - sdlog_1)) - strike * (1 - cdf(s, u1));
        double c1 = discount_factor * tmp1;
        double u2 = (log(strike) - meanlog_2) / sdlog_2;
        double tmp2 = expected_val_2 * (1 - cdf(s, u2 - sdlog_2)) - strike * (1 - cdf(s, u2));
        double c2 = discount_factor * tmp2;
        c1_vec.push_back(c1);
        c2_vec.push_back(c2);
    }
    arma::vec call_option_price = alpha_1 * arma::vec(c1_vec) + alpha_2 * arma::vec(c2_vec);
    arma::vec put_option_price = call_option_price - s0 * exp(-y * te) + arma::vec(k) * discount_factor;
    std::map< std::string, std::vector< double >> out;
    out["call"] = arma::conv_to< std::vector< double >>::from(arma::max(call_option_price, arma::zeros(call_option_price.size())));
    out["put"] = arma::conv_to< std::vector< double >>::from(arma::max(put_option_price, arma::zeros(put_option_price.size())));
    out["s0"] = arma::conv_to< std::vector< double >>::from(arma::vec(1).fill(s0));
    return out;
}

double mln_objective(
    std::vector< double > theta,
    double r,
    double y,
    double te,
    double s0,
    const std::vector< double >& market_calls,
    const std::vector< double >& call_strikes,
    const std::vector< double >& market_puts,
    const std::vector< double >& put_strikes,
    double call_weights = 1,
    double put_weights = 1,
    double lambda_= 1)
{
    double obj;
    double alpha_1 = theta[0];
    double meanlog_1 = theta[1];
    double meanlog_2 = theta[2];
    double sdlog_1 = theta[3];
    double sdlog_2 = theta[4];
    double discount_factor = exp(-r * te);
    double alpha_2 = 1 - alpha_1;
    double expected_value = alpha_1 * exp(meanlog_1 + .5 * pow(sdlog_1, 2)) + alpha_2 * exp(meanlog_2 + .5 * pow(sdlog_2, 2));
    arma::vec theoretical_calls = arma::vec(price_mln_option(r, te, y, call_strikes, alpha_1, meanlog_1, meanlog_2, sdlog_1, sdlog_2)["call"]);
    arma::vec theoretical_puts = arma::vec(price_mln_option(r, te, y, put_strikes, alpha_1, meanlog_1, meanlog_2, sdlog_1, sdlog_2)["put"]);
    if (alpha_1 < 0 || alpha_2 > 1 || sdlog_1 < 0 || sdlog_2 < 0)
    {
        obj = pow(10, 7);
    }
    else
    {
        obj = arma::sum(call_weights * pow(theoretical_calls - arma::vec(market_calls), 2)) + 
            arma::sum(put_weights * pow(theoretical_puts - arma::vec(market_puts), 2)) +
            lambda_ * pow(s0 - exp(y * te) * expected_value * discount_factor, 2);
    }
    return obj;
}

std::vector< double > extract_mln_density_grid(
    double r,
    double y,
    double te,
    double s0,
    const std::vector< double >& market_calls,
    const std::vector< double >& call_strikes,
    const std::vector< double >& market_puts,
    const std::vector< double >& put_strikes,
    double call_weights = 1,
    double put_weights = 1,
    double lambda_ = 1)
{
    double band = (r - y - .5 * pow(.3, 2)) * te;
    arma::vec alpha_1 = arma::regspace(.1, .05, .95);
    arma::vec meanlog_1 = arma::linspace(log(s0) - band, log(s0) + band, 4);
    arma::vec meanlog_2 = arma::linspace(log(s0) - band, log(s0) + band, 4);
    arma::vec sdlog_1 = sqrt(te) * arma::linspace(.05, .9, 7);
    arma::vec sdlog_2 = sqrt(te) * arma::linspace(.05, .9, 7);
    size_t nrows = alpha_1.size() + meanlog_1.size() + meanlog_2.size() + sdlog_1.size() + sdlog_2.size();
    arma::mat mln_grid(1, 5, arma::fill::zeros);
    std::vector< double > mln_vals;
    mln_vals.push_back(pow(10, 7));
    for (arma::vec::iterator i = alpha_1.begin(); i != alpha_1.end(); i++)
    {
        for (arma::vec::iterator j = meanlog_1.begin(); j != meanlog_1.end(); j++)
        {
            for (arma::vec::iterator k = meanlog_2.begin(); k != meanlog_2.end(); k++)
            {
                for (arma::vec::iterator l = sdlog_1.begin(); l != sdlog_1.end(); l++)
                {
                    for (arma::vec::iterator m = sdlog_2.begin(); m != sdlog_2.end(); m++)
                    {
                        double alpha_1 = *i;
                        double meanlog_1 = *j;
                        double meanlog_2 = *k;
                        double sdlog_1 = *l;
                        double sdlog_2 = *m;
                        double obj = mln_objective(std::vector< double >({ alpha_1, meanlog_1, meanlog_2, sdlog_1, sdlog_2 }),
                            r,
                            y,
                            te,
                            s0,
                            market_calls,
                            call_strikes,
                            market_puts,
                            put_strikes);
                        mln_grid = arma::join_vert(mln_grid, arma::rowvec({ alpha_1, meanlog_1, meanlog_2, sdlog_1, sdlog_2 }));
                        mln_vals.push_back(obj);
                    }
                }
            }
        }
    }
    arma::rowvec initial_values = mln_grid.row(arma::vec(mln_vals).index_min());
    return arma::conv_to< std::vector< double >>::from(initial_values);
}

arma::vec dlnorm(
    arma::vec x,
    double meanlog = 0,
    double sdlog = 0
)
{
    sdlog += 1e-08;
    arma::vec num = exp(-pow(log(x) - meanlog, 2) / (2 * pow(sdlog, 2)));
    arma::vec den = sdlog * x * sqrt(2 * PI);
    return num / den;
}

std::vector< double > dmln(
    std::vector< double > x,
    double alpha_1,
    double meanlog_1,
    double meanlog_2,
    double sdlog_1,
    double sdlog_2
)
{
    double alpha_2 = 1 - alpha_1;
    arma::vec x_ = arma::vec(x);
    arma::vec out = alpha_1 * dlnorm(x_, meanlog_1, sdlog_1) + alpha_2 * dlnorm(x_, meanlog_2, sdlog_2);
    return arma::conv_to< std::vector< double >>::from(out);
}

PYBIND11_MODULE(rnd_cpp, m) {
    m.doc() = "price_mln_option example plugin"; // optional module docstring
    m.def("price_mln_option", &price_mln_option, "Gives the price of a call and a put option at a set strike when the risk neutral density is a mixture of two lognormals.",
        py::arg("r"),
        py::arg("te"),
        py::arg("y"),
        py::arg("k"),
        py::arg("alpha_1"),
        py::arg("meanlog_1"),
        py::arg("meanlog_2"),
        py::arg("sdlog_1"),
        py::arg("sdlog_2"));
    m.def("mln_objective", &mln_objective, "The objective function to be minimized.",
        py::arg("theta"),
        py::arg("r"),
        py::arg("y"),
        py::arg("te"),
        py::arg("s0"),
        py::arg("market_calls"),
        py::arg("call_strikes"),
        py::arg("market_puts"),
        py::arg("put_strikes"),
        py::arg("call_weights") = 1,
        py::arg("put_weights") = 1,
        py::arg("lambda_") = 1);
    m.def("extract_mln_density_grid", &extract_mln_density_grid, "Extracts the parameters of the mixture of two lognormals densities.",
        py::arg("r"),
        py::arg("y"),
        py::arg("te"),
        py::arg("s0"),
        py::arg("market_calls"),
        py::arg("call_strikes"),
        py::arg("market_puts"),
        py::arg("put_strikes"),
        py::arg("call_weights") = 1,
        py::arg("put_weights") = 1,
        py::arg("lambda_") = 1);
    m.def("dmln", &dmln, "The probability density function of a mixture of two lognormal densities.",
        py::arg("x"),
        py::arg("alpha_1"),
        py::arg("meanlog_1"),
        py::arg("meanlog_2"),
        py::arg("sdlog_1"),
        py::arg("sdlog_2"));
}
Dopo aver compilato per il sistema operativo preferito e aver rinominato il modulo ad es. "rnd_cpp", interfaccia in Python con esempio funzionante:
Codice:
from rnd_cpp import *
from scipy.optimize import minimize
import numpy as np
import time
import warnings

warnings.simplefilter("ignore")

def ExtractMlnDensity(r, 
                      y, 
                      te, 
                      s0,  
                      market_calls, 
                      call_strikes, 
                      market_puts, 
                      put_strikes, 
                      call_weights = 1,
                      put_weights = 1, 
                      lambda_ = 1, 
                      hessian_flag = False,
                      initial_values = np.repeat(np.NaN, 5),
                      cl = {'maxit': 10000}):
                          if np.sum(np.isnan(initial_values)) >= 1:
                              initial_values = extract_mln_density_grid(r,
                                                                        y, 
                                                                        te,
                                                                        s0, 
                                                                        market_calls, 
                                                                        call_strikes, 
                                                                        market_puts, 
                                                                        put_strikes)
                              optim_obj = minimize(fun = MlnObjective,
                                                   x0 = initial_values,
                                                   method = 'Nelder-Mead',
                                                   bounds = [(0, 1), (0, 1e10), (0, 1e10), (0, 1e10), (0, 1e10)],
                                                   args = (r, y, te, s0, market_calls, call_strikes, market_puts, put_strikes),
                                                   options={'ftol': 1e-04, 'maxiter': 10000, 'disp': False})
                              alpha_1 = optim_obj.x[0]
                              meanlog_1 = optim_obj.x[1]
                              meanlog_2 = optim_obj.x[2]
                              sdlog_1 = optim_obj.x[3]
                              sdlog_2 = optim_obj.x[4]
                              converge_result = optim_obj.status
                              out = {'alpha_1': alpha_1, 'meanlog_1': meanlog_1, 'meanlog_2': meanlog_2, 'sdlog_1': sdlog_1, 'sdlog_2': sdlog_2}
                              return out

def MlnObjective(theta,
                 r,
                 y,
                 te,
                 s0,
                 market_calls,
                 call_strikes,
                 market_puts,
                 put_strikes,
                 call_weights = 1,                 
                 put_weights = 1,
                 lambda_ = 1):                     
    return mln_objective(theta,
                         r,
                         y,
                         te,
                         s0,
                         market_calls,
                         call_strikes,
                         market_puts,
                         put_strikes,
                         call_weights,                 
                         put_weights,
                         lambda_)
    
def PriceMlnOption(r, 
                   te, 
                   y, 
                   k, 
                   alpha_1,
                   meanlog_1,
                   meanlog_2, 
                   sdlog_1, 
                   sdlog_2):                       
    return price_mln_option(r,
                            te, 
                            y, 
                            k, 
                            alpha_1,
                            meanlog_1,
                            meanlog_2, 
                            sdlog_1, 
                            sdlog_2)

# def dmln(x, alpha_1, meanlog_1, meanlog_2, sdlog_1, sdlog_2):    
#     return dmln(x, 
#                 alpha_1, 
#                 meanlog_1, 
#                 meanlog_2, 
#                 sdlog_1, 
#                 sdlog_2)

if __name__ == '__main__':
    
    import matplotlib.pyplot as plt
    
    #
    # Create some calls and puts based on mln and 
    # see if we can extract the correct values.
    #
    
    r         = 0.05
    y         = 0.02
    te        = 60/365
    meanlog_1 = 6.8
    meanlog_2 = 6.95
    sdlog_1   = 0.065
    sdlog_2   = 0.055
    alpha_1   = 0.4
    
    call_strikes = np.arange(800, 1210, 10)
    market_calls = PriceMlnOption(r = r, y = y, te = te, k = call_strikes, alpha_1 = alpha_1, meanlog_1 = meanlog_1, meanlog_2 = meanlog_2, sdlog_1 = sdlog_1, sdlog_2 = sdlog_2)['call']
    s0 = PriceMlnOption(r = r, y = y, te = te, k = call_strikes, alpha_1 = alpha_1, meanlog_1 = meanlog_1, meanlog_2 = meanlog_2, sdlog_1 = sdlog_1, sdlog_2 = sdlog_2)['s0']
    put_strikes  = np.arange(800, 1210, 10)
    market_puts  = PriceMlnOption(r = r, y = y, te = te, k = call_strikes, alpha_1 = alpha_1, meanlog_1 = meanlog_1, meanlog_2 = meanlog_2, sdlog_1 = sdlog_1, sdlog_2 = sdlog_2)['put']
    
    t1 = time.time()
    print(ExtractMlnDensity(r, 
                            y, 
                            te, 
                            s0[0], 
                            market_calls, 
                            call_strikes.astype(float).tolist(), 
                            market_puts, 
                            put_strikes.astype(float).tolist()))
    print(time.time() - t1)
    
    #
    # The mln objective function should be close to zero.
    # The weights are automatically set to 1.
    #
    
    r  = 0.05
    te = 60/365
    y  = 0.02
    
    meanlog_1 = 6.8
    meanlog_2 = 6.95
    sdlog_1   = 0.065
    sdlog_2   = 0.055
    alpha_1   = 0.4
    
    # This is the current price implied by parameter values:
    s0 = 981.8815
    
    call_strikes = np.arange(800, 1210, 10)
    market_calls = PriceMlnOption(r=r, y = y, te = te, k = call_strikes,
                    alpha_1 = alpha_1, meanlog_1 = meanlog_1, meanlog_2 = meanlog_2,
                    sdlog_1 = sdlog_1, sdlog_2 = sdlog_2)['call']
    
    put_strikes  = np.arange(800, 1210, 10)
    market_puts  = PriceMlnOption(r=r, y = y, te = te, k = call_strikes,
                    alpha_1 = alpha_1, meanlog_1 = meanlog_1, meanlog_2 = meanlog_2,
                    sdlog_1 = sdlog_1, sdlog_2 = sdlog_2)['put']
    
    MlnObjective(theta=[alpha_1,meanlog_1, meanlog_2 , sdlog_1, sdlog_2],
                    r = r, y = y, te = te, s0 = s0,
                    market_calls = market_calls, call_strikes = call_strikes,
                    market_puts = market_puts, put_strikes = put_strikes, lambda_ = 1)
    
    #
    # Try out a range of options
    #
    
    r  = 0.05
    te = 60/365
    k  = np.arange(700, 1301, 1)
    y  = 0.02
    meanlog_1 = 6.80
    meanlog_2 = 6.95
    sdlog_1   = 0.065
    sdlog_2   = 0.055
    alpha_1   = 0.4
    
    mln_prices = PriceMlnOption(r = r, y = y, te = te, k = k, alpha_1 = alpha_1,
      meanlog_1 = meanlog_1, meanlog_2 = meanlog_2, sdlog_1 = sdlog_1, sdlog_2 = sdlog_2)
    
    plt.scatter(x = k, y = mln_prices['call'], c = 'black')
    plt.scatter(x = k, y = mln_prices['put'], c = 'red')
    plt.grid()
    plt.show()
    
    #
    # A bimodal risk neutral density!
    #
    
    mln_alpha_1   = 0.4
    mln_meanlog_1 = 6.3
    mln_meanlog_2 = 6.5
    mln_sdlog_1   = 0.08
    mln_sdlog_2   = 0.06
    
    k  = np.arange(300, 900)
    dx = dmln(x = k, alpha_1 = mln_alpha_1, meanlog_1 = mln_meanlog_1, 
              meanlog_2 = mln_meanlog_2, 
              sdlog_1 = mln_sdlog_1, sdlog_2 = mln_sdlog_2)
    plt.plot(k, dx)
    plt.grid()
Posso chiedervi anche come utilizzate queste distribuzioni? L'articolo che ho letto sembra suggerire che prese così servono a poco, certo non per fare predizioni. Fanno vedere come l'hedging impatti sulle code delle implicite, senza poi contare che non sono neppure probabilità reali (anche se da quanto ho capito si potrebbe avere un'idea sulla distribuzione reale sapendo in che modo l'avversione al rischio modifica la simmetria).
Vedi allegato .pdf (Trading on Deviations of Implied and Historical Densities): se la usi così ancora non ce la fai a non perdere soldi, però è un punto di partenza per capire in che direzione andare.

Poi puoi divertirti con il secondo allegato .zip che invece è un lavoro fatto dal sottoscritto per l'Università della Svizzera Italiana e che va un pelo oltre: dentro ci trovi sia la parte teorica che ti interessa per la mistura di distribuzioni lognormali sia come usarla per quantificare e modellare la memoria del mercato in termini di selettività degli eventi critici, come sarebbe piaciuto a Taleb quando scriveva «[...] traders have GARCH in their heads» o qualcosa di simile.
 

Allegati

  • TalkOJBpdf1.pdf
    325,9 KB · Visite: 76
  • QuantileDiscount.zip
    456,1 KB · Visite: 29
Ultima modifica:
2812000-investire-opzioni-pdf.jpg

Ho capito che devo calcolare i prezzi B&S ai vari strike con distanza delta K molto piccola. Su QQQ ha senso una distanza di 1 centesimo o è ancora troppo larga? In generale come faccio a capire quanto vicino devo scegliere gli strike?
Inoltre, credo che il tipo di interpolazione non faccia molta differenza, corretto?

Il procedimento descrive semplicemente il calcolo per punti della curvatura che ha l'andamento del prezzo delle opzioni, che agli estremi è zero perché la curva è piatta.

put_call_parity_test.png


Nella parte centrale la curvatura osservata dell'andamento dei prezzi differisce da quella normale.

Example-of-a-Pdf-with-Negative-Skewness-and-Large-Kurtosis.png
 
Rettifico: non "Python o C++" bensì C++ in Python tramite pybind11 :D

Sorgente in C++ (richiede Armadillo e Boost oltre a pybind11):
Codice:
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <armadillo>
#include <boost/math/distributions/normal.hpp>
#include <assert.h>

namespace py = pybind11;
using boost::math::normal;

const double PI = std::atan(1.0) * 4;

std::map< std::string, std::vector< double >> price_mln_option(
    double r,
    double te,
    double y,
    const std::vector< double >& k,
    double alpha_1,
    double meanlog_1,
    double meanlog_2,
    double sdlog_1,
    double sdlog_2)
{
    double discount_factor = exp(-r * te);
    double alpha_2 = 1 - alpha_1;
    double expected_val_1 = exp(meanlog_1 + .5 * (pow(sdlog_1, 2)));
    double expected_val_2 = exp(meanlog_2 + .5 * (pow(sdlog_2, 2)));
    double s0 = exp((y - r) * te) * (alpha_1 * expected_val_1 + alpha_2 * expected_val_2);
    std::vector< double > c1_vec, c2_vec;
    normal s;
    for (std::vector< double >::const_iterator it = k.begin(); it != k.end(); it++)
    {
        double strike = *it;
        double u1 = (log(strike) - meanlog_1) / sdlog_1;
        double tmp1 = expected_val_1 * (1 - cdf(s, u1 - sdlog_1)) - strike * (1 - cdf(s, u1));
        double c1 = discount_factor * tmp1;
        double u2 = (log(strike) - meanlog_2) / sdlog_2;
        double tmp2 = expected_val_2 * (1 - cdf(s, u2 - sdlog_2)) - strike * (1 - cdf(s, u2));
        double c2 = discount_factor * tmp2;
        c1_vec.push_back(c1);
        c2_vec.push_back(c2);
    }
    arma::vec call_option_price = alpha_1 * arma::vec(c1_vec) + alpha_2 * arma::vec(c2_vec);
    arma::vec put_option_price = call_option_price - s0 * exp(-y * te) + arma::vec(k) * discount_factor;
    std::map< std::string, std::vector< double >> out;
    out["call"] = arma::conv_to< std::vector< double >>::from(arma::max(call_option_price, arma::zeros(call_option_price.size())));
    out["put"] = arma::conv_to< std::vector< double >>::from(arma::max(put_option_price, arma::zeros(put_option_price.size())));
    out["s0"] = arma::conv_to< std::vector< double >>::from(arma::vec(1).fill(s0));
    return out;
}

double mln_objective(
    std::vector< double > theta,
    double r,
    double y,
    double te,
    double s0,
    const std::vector< double >& market_calls,
    const std::vector< double >& call_strikes,
    const std::vector< double >& market_puts,
    const std::vector< double >& put_strikes,
    double call_weights = 1,
    double put_weights = 1,
    double lambda_= 1)
{
    double obj;
    double alpha_1 = theta[0];
    double meanlog_1 = theta[1];
    double meanlog_2 = theta[2];
    double sdlog_1 = theta[3];
    double sdlog_2 = theta[4];
    double discount_factor = exp(-r * te);
    double alpha_2 = 1 - alpha_1;
    double expected_value = alpha_1 * exp(meanlog_1 + .5 * pow(sdlog_1, 2)) + alpha_2 * exp(meanlog_2 + .5 * pow(sdlog_2, 2));
    arma::vec theoretical_calls = arma::vec(price_mln_option(r, te, y, call_strikes, alpha_1, meanlog_1, meanlog_2, sdlog_1, sdlog_2)["call"]);
    arma::vec theoretical_puts = arma::vec(price_mln_option(r, te, y, put_strikes, alpha_1, meanlog_1, meanlog_2, sdlog_1, sdlog_2)["put"]);
    if (alpha_1 < 0 || alpha_2 > 1 || sdlog_1 < 0 || sdlog_2 < 0)
    {
        obj = pow(10, 7);
    }
    else
    {
        obj = arma::sum(call_weights * pow(theoretical_calls - arma::vec(market_calls), 2)) + 
            arma::sum(put_weights * pow(theoretical_puts - arma::vec(market_puts), 2)) +
            lambda_ * pow(s0 - exp(y * te) * expected_value * discount_factor, 2);
    }
    return obj;
}

std::vector< double > extract_mln_density_grid(
    double r,
    double y,
    double te,
    double s0,
    const std::vector< double >& market_calls,
    const std::vector< double >& call_strikes,
    const std::vector< double >& market_puts,
    const std::vector< double >& put_strikes,
    double call_weights = 1,
    double put_weights = 1,
    double lambda_ = 1)
{
    double band = (r - y - .5 * pow(.3, 2)) * te;
    arma::vec alpha_1 = arma::regspace(.1, .05, .95);
    arma::vec meanlog_1 = arma::linspace(log(s0) - band, log(s0) + band, 4);
    arma::vec meanlog_2 = arma::linspace(log(s0) - band, log(s0) + band, 4);
    arma::vec sdlog_1 = sqrt(te) * arma::linspace(.05, .9, 7);
    arma::vec sdlog_2 = sqrt(te) * arma::linspace(.05, .9, 7);
    size_t nrows = alpha_1.size() + meanlog_1.size() + meanlog_2.size() + sdlog_1.size() + sdlog_2.size();
    arma::mat mln_grid(1, 5, arma::fill::zeros);
    std::vector< double > mln_vals;
    mln_vals.push_back(pow(10, 7));
    for (arma::vec::iterator i = alpha_1.begin(); i != alpha_1.end(); i++)
    {
        for (arma::vec::iterator j = meanlog_1.begin(); j != meanlog_1.end(); j++)
        {
            for (arma::vec::iterator k = meanlog_2.begin(); k != meanlog_2.end(); k++)
            {
                for (arma::vec::iterator l = sdlog_1.begin(); l != sdlog_1.end(); l++)
                {
                    for (arma::vec::iterator m = sdlog_2.begin(); m != sdlog_2.end(); m++)
                    {
                        double alpha_1 = *i;
                        double meanlog_1 = *j;
                        double meanlog_2 = *k;
                        double sdlog_1 = *l;
                        double sdlog_2 = *m;
                        double obj = mln_objective(std::vector< double >({ alpha_1, meanlog_1, meanlog_2, sdlog_1, sdlog_2 }),
                            r,
                            y,
                            te,
                            s0,
                            market_calls,
                            call_strikes,
                            market_puts,
                            put_strikes);
                        mln_grid = arma::join_vert(mln_grid, arma::rowvec({ alpha_1, meanlog_1, meanlog_2, sdlog_1, sdlog_2 }));
                        mln_vals.push_back(obj);
                    }
                }
            }
        }
    }
    arma::rowvec initial_values = mln_grid.row(arma::vec(mln_vals).index_min());
    return arma::conv_to< std::vector< double >>::from(initial_values);
}

arma::vec dlnorm(
    arma::vec x,
    double meanlog = 0,
    double sdlog = 0
)
{
    sdlog += 1e-08;
    arma::vec num = exp(-pow(log(x) - meanlog, 2) / (2 * pow(sdlog, 2)));
    arma::vec den = sdlog * x * sqrt(2 * PI);
    return num / den;
}

std::vector< double > dmln(
    std::vector< double > x,
    double alpha_1,
    double meanlog_1,
    double meanlog_2,
    double sdlog_1,
    double sdlog_2
)
{
    double alpha_2 = 1 - alpha_1;
    arma::vec x_ = arma::vec(x);
    arma::vec out = alpha_1 * dlnorm(x_, meanlog_1, sdlog_1) + alpha_2 * dlnorm(x_, meanlog_2, sdlog_2);
    return arma::conv_to< std::vector< double >>::from(out);
}

PYBIND11_MODULE(rnd_cpp, m) {
    m.doc() = "price_mln_option example plugin"; // optional module docstring
    m.def("price_mln_option", &price_mln_option, "Gives the price of a call and a put option at a set strike when the risk neutral density is a mixture of two lognormals.",
        py::arg("r"),
        py::arg("te"),
        py::arg("y"),
        py::arg("k"),
        py::arg("alpha_1"),
        py::arg("meanlog_1"),
        py::arg("meanlog_2"),
        py::arg("sdlog_1"),
        py::arg("sdlog_2"));
    m.def("mln_objective", &mln_objective, "The objective function to be minimized.",
        py::arg("theta"),
        py::arg("r"),
        py::arg("y"),
        py::arg("te"),
        py::arg("s0"),
        py::arg("market_calls"),
        py::arg("call_strikes"),
        py::arg("market_puts"),
        py::arg("put_strikes"),
        py::arg("call_weights") = 1,
        py::arg("put_weights") = 1,
        py::arg("lambda_") = 1);
    m.def("extract_mln_density_grid", &extract_mln_density_grid, "Extracts the parameters of the mixture of two lognormals densities.",
        py::arg("r"),
        py::arg("y"),
        py::arg("te"),
        py::arg("s0"),
        py::arg("market_calls"),
        py::arg("call_strikes"),
        py::arg("market_puts"),
        py::arg("put_strikes"),
        py::arg("call_weights") = 1,
        py::arg("put_weights") = 1,
        py::arg("lambda_") = 1);
    m.def("dmln", &dmln, "The probability density function of a mixture of two lognormal densities.",
        py::arg("x"),
        py::arg("alpha_1"),
        py::arg("meanlog_1"),
        py::arg("meanlog_2"),
        py::arg("sdlog_1"),
        py::arg("sdlog_2"));
}
Dopo aver compilato per il sistema operativo preferito e aver rinominato il modulo ad es. "rnd_cpp", interfaccia in Python con esempio funzionante:
Codice:
from rnd_cpp import *
from scipy.optimize import minimize
import numpy as np
import time
import warnings

warnings.simplefilter("ignore")

def ExtractMlnDensity(r, 
                      y, 
                      te, 
                      s0,  
                      market_calls, 
                      call_strikes, 
                      market_puts, 
                      put_strikes, 
                      call_weights = 1,
                      put_weights = 1, 
                      lambda_ = 1, 
                      hessian_flag = False,
                      initial_values = np.repeat(np.NaN, 5),
                      cl = {'maxit': 10000}):
                          if np.sum(np.isnan(initial_values)) >= 1:
                              initial_values = extract_mln_density_grid(r,
                                                                        y, 
                                                                        te,
                                                                        s0, 
                                                                        market_calls, 
                                                                        call_strikes, 
                                                                        market_puts, 
                                                                        put_strikes)
                              optim_obj = minimize(fun = MlnObjective,
                                                   x0 = initial_values,
                                                   method = 'Nelder-Mead',
                                                   bounds = [(0, 1), (0, 1e10), (0, 1e10), (0, 1e10), (0, 1e10)],
                                                   args = (r, y, te, s0, market_calls, call_strikes, market_puts, put_strikes),
                                                   options={'ftol': 1e-04, 'maxiter': 10000, 'disp': False})
                              alpha_1 = optim_obj.x[0]
                              meanlog_1 = optim_obj.x[1]
                              meanlog_2 = optim_obj.x[2]
                              sdlog_1 = optim_obj.x[3]
                              sdlog_2 = optim_obj.x[4]
                              converge_result = optim_obj.status
                              out = {'alpha_1': alpha_1, 'meanlog_1': meanlog_1, 'meanlog_2': meanlog_2, 'sdlog_1': sdlog_1, 'sdlog_2': sdlog_2}
                              return out

def MlnObjective(theta,
                 r,
                 y,
                 te,
                 s0,
                 market_calls,
                 call_strikes,
                 market_puts,
                 put_strikes,
                 call_weights = 1,                 
                 put_weights = 1,
                 lambda_ = 1):                     
    return mln_objective(theta,
                         r,
                         y,
                         te,
                         s0,
                         market_calls,
                         call_strikes,
                         market_puts,
                         put_strikes,
                         call_weights,                 
                         put_weights,
                         lambda_)
    
def PriceMlnOption(r, 
                   te, 
                   y, 
                   k, 
                   alpha_1,
                   meanlog_1,
                   meanlog_2, 
                   sdlog_1, 
                   sdlog_2):                       
    return price_mln_option(r,
                            te, 
                            y, 
                            k, 
                            alpha_1,
                            meanlog_1,
                            meanlog_2, 
                            sdlog_1, 
                            sdlog_2)

# def dmln(x, alpha_1, meanlog_1, meanlog_2, sdlog_1, sdlog_2):    
#     return dmln(x, 
#                 alpha_1, 
#                 meanlog_1, 
#                 meanlog_2, 
#                 sdlog_1, 
#                 sdlog_2)

if __name__ == '__main__':
    
    import matplotlib.pyplot as plt
    
    #
    # Create some calls and puts based on mln and 
    # see if we can extract the correct values.
    #
    
    r         = 0.05
    y         = 0.02
    te        = 60/365
    meanlog_1 = 6.8
    meanlog_2 = 6.95
    sdlog_1   = 0.065
    sdlog_2   = 0.055
    alpha_1   = 0.4
    
    call_strikes = np.arange(800, 1210, 10)
    market_calls = PriceMlnOption(r = r, y = y, te = te, k = call_strikes, alpha_1 = alpha_1, meanlog_1 = meanlog_1, meanlog_2 = meanlog_2, sdlog_1 = sdlog_1, sdlog_2 = sdlog_2)['call']
    s0 = PriceMlnOption(r = r, y = y, te = te, k = call_strikes, alpha_1 = alpha_1, meanlog_1 = meanlog_1, meanlog_2 = meanlog_2, sdlog_1 = sdlog_1, sdlog_2 = sdlog_2)['s0']
    put_strikes  = np.arange(800, 1210, 10)
    market_puts  = PriceMlnOption(r = r, y = y, te = te, k = call_strikes, alpha_1 = alpha_1, meanlog_1 = meanlog_1, meanlog_2 = meanlog_2, sdlog_1 = sdlog_1, sdlog_2 = sdlog_2)['put']
    
    t1 = time.time()
    print(ExtractMlnDensity(r, 
                            y, 
                            te, 
                            s0[0], 
                            market_calls, 
                            call_strikes.astype(float).tolist(), 
                            market_puts, 
                            put_strikes.astype(float).tolist()))
    print(time.time() - t1)
    
    #
    # The mln objective function should be close to zero.
    # The weights are automatically set to 1.
    #
    
    r  = 0.05
    te = 60/365
    y  = 0.02
    
    meanlog_1 = 6.8
    meanlog_2 = 6.95
    sdlog_1   = 0.065
    sdlog_2   = 0.055
    alpha_1   = 0.4
    
    # This is the current price implied by parameter values:
    s0 = 981.8815
    
    call_strikes = np.arange(800, 1210, 10)
    market_calls = PriceMlnOption(r=r, y = y, te = te, k = call_strikes,
                    alpha_1 = alpha_1, meanlog_1 = meanlog_1, meanlog_2 = meanlog_2,
                    sdlog_1 = sdlog_1, sdlog_2 = sdlog_2)['call']
    
    put_strikes  = np.arange(800, 1210, 10)
    market_puts  = PriceMlnOption(r=r, y = y, te = te, k = call_strikes,
                    alpha_1 = alpha_1, meanlog_1 = meanlog_1, meanlog_2 = meanlog_2,
                    sdlog_1 = sdlog_1, sdlog_2 = sdlog_2)['put']
    
    MlnObjective(theta=[alpha_1,meanlog_1, meanlog_2 , sdlog_1, sdlog_2],
                    r = r, y = y, te = te, s0 = s0,
                    market_calls = market_calls, call_strikes = call_strikes,
                    market_puts = market_puts, put_strikes = put_strikes, lambda_ = 1)
    
    #
    # Try out a range of options
    #
    
    r  = 0.05
    te = 60/365
    k  = np.arange(700, 1301, 1)
    y  = 0.02
    meanlog_1 = 6.80
    meanlog_2 = 6.95
    sdlog_1   = 0.065
    sdlog_2   = 0.055
    alpha_1   = 0.4
    
    mln_prices = PriceMlnOption(r = r, y = y, te = te, k = k, alpha_1 = alpha_1,
      meanlog_1 = meanlog_1, meanlog_2 = meanlog_2, sdlog_1 = sdlog_1, sdlog_2 = sdlog_2)
    
    plt.scatter(x = k, y = mln_prices['call'], c = 'black')
    plt.scatter(x = k, y = mln_prices['put'], c = 'red')
    plt.grid()
    plt.show()
    
    #
    # A bimodal risk neutral density!
    #
    
    mln_alpha_1   = 0.4
    mln_meanlog_1 = 6.3
    mln_meanlog_2 = 6.5
    mln_sdlog_1   = 0.08
    mln_sdlog_2   = 0.06
    
    k  = np.arange(300, 900)
    dx = dmln(x = k, alpha_1 = mln_alpha_1, meanlog_1 = mln_meanlog_1, 
              meanlog_2 = mln_meanlog_2, 
              sdlog_1 = mln_sdlog_1, sdlog_2 = mln_sdlog_2)
    plt.plot(k, dx)
    plt.grid()

Vedi allegato .pdf (Trading on Deviations of Implied and Historical Densities): se la usi così ancora non ce la fai a non perdere soldi, però è un punto di partenza per capire in che direzione andare.

Poi puoi divertirti con il secondo allegato .zip che invece è un lavoro fatto dal sottoscritto per l'Università della Svizzera Italiana e che va un pelo oltre: dentro ci trovi sia la parte teorica che ti interessa per la mistura di distribuzioni lognormali sia come usarla per quantificare e modellare la memoria del mercato in termini di selettività degli eventi critici, come sarebbe piaciuto a Taleb quando scriveva «[...] traders have GARCH in their heads» o qualcosa di simile.

:bow::bow::bow:
 
Su Elite Trader hanno risposto suggerendo anche un R package chiamato RND.
Implied distributions | Elite Trader
Confermo, il codice che ti ho allegato è la traduzione in C++ e Python del sorgente in R di Kam Hamidieh.

Più nello specifico, entrambi i codici costruiscono una griglia di parametri verosimili prima di ottimizzare i parametri per ricostruire la catena di opzioni.

Sorprendentemente, però, l'applicazione della funzione di loss ad ogni nodo della griglia è più veloce con R che con NumPy (accetto critiche di non essere abbastanza bravo con NumPy, perché no?), da cui il passaggio a C++ che è sicuramente più veloce di tutti e taglia la testa al toro.

Se hai dimestichezza con R, suggerisco di giocare un po' con RND per vedere se fa al caso tuo.

Io ci avevo fatto trading un po' con l'EuroSTOXX 50 qualche anno fa proprio seguendo il paper che ti ho allegato.
 
Mi sto approcciando a questo mondo per cercare di crearmi una rendita mensile (l'obiettivo annuo sarebbe un rendimento del 20%-30%) attraverso il selling di naked put

Ma quando si vendono le opzioni come viene calcolato il rendimento?

Forse rispetto al margine massimo richiesto nel corso dell'operazione?

E se si vendono ad es. 10 opzioni i margini richiesti vengono moltiplicati per 10 ?
 
Ma quando si vendono le opzioni come viene calcolato il rendimento?

Forse rispetto al margine massimo richiesto nel corso dell'operazione?

E se si vendono ad es. 10 opzioni i margini richiesti vengono moltiplicati per 10 ?

Il rendimento di una posizione in opzioni, long o short che sia, io lo calcolo solo sul totale del mio portafoglio e non dal margine richiesto (per la short position) e nè dal premio pagato (per la long position).
Quindi, se io lavoro con un portafoglio di 100k destinato all'operatività in derivati, e vendo una put su un qualsiasi sottostante ricevendo un premio di 1500 euro e, non volendo portare la posizione a scadenza, mi accontento di chiuderla quando il guadagno è di 1000 euro, bene, quei 1000 euro sono il risultato operativo reale e rappresentano, al lordo dei costi commissionali e delle tasse, l'1% del rendimento reale del mio portafoglio da 100k.
Se vendi una opzione e il tuo broker ti chiede un margine di 1000 euro, va da sè che se ne vendi 10 te ne chiede dieci volte tante, ovvero 10.000.
 
Io ci avevo fatto trading un po' con l'EuroSTOXX 50 qualche anno fa proprio seguendo il paper che ti ho allegato.

Quindi il tuo lavoro per l'università svizzera è una evoluzione di quanto sopra? (premetto che devo vedere ancora se riesco a capirlo seriamente).

P.s. a che facoltà era indirizzato?
 
Quindi il tuo lavoro per l'università svizzera è una evoluzione di quanto sopra? (premetto che devo vedere ancora se riesco a capirlo seriamente).
Il principio del primo paper è quello di confrontare ciò che prezza il mercato con ciò che potrebbe accadere in futuro assumendo un comportamento in linea con quello storico, quindi il solito anello debole del modellare i mercati.

Il principio del progetto che ho messo nel secondo allegato è quello di usare la densità implicita per capire di quali eventi estremi passati il mercato si sta completamente dimenticando, quindi quanto è "ciecamente ottimista" nel trascurare l'eventualità di altri cigni neri: per farlo non si modella il passato nel solito modo tramite finestre fisse etc. ma si vanno a scremare in modo selettivo gli eventi estremi; la calibrazione avviene facendo combaciare il più possibile la densità implicita con quella "scremata".
P.s. a che facoltà era indirizzato?
Un corso incentrato su tecniche di ML applicate ai mercati finanziari.
 
Grazie ancora Cren per aver condiviso quel materiale. Anche io devo ancora studiarmelo bene e poi passare alla parte di codice. C'è tanto da vedere.
Pero ho una domanda sulla parte RND vs aspettative di mercato. In questo articolo che ho citato si dice che l'attività di hedging sia una delle ragioni principali per cui non bisogna dare troppa importanza alle aspettative che leggiamo nelle RND. Come hai tenuto conto di questo nelle tue analisi?

Trading Mate
 

Allegati

  • aspettative e hedging.PNG
    aspettative e hedging.PNG
    69,5 KB · Visite: 17
Il rendimento di una posizione in opzioni, long o short che sia, io lo calcolo solo sul totale del mio portafoglio e non dal margine richiesto (per la short position) e nè dal premio pagato (per la long position).

Il portafoglio personale può essere comunque parametrato al valore del sottostante.

Nell'approssimazione che le opzioni mensili ATM valgano una percentuale del sottostante pari a 0.4×σ√t= IV/8.66 e che le opzioni OTM di σ√t valgano 1/7 di quelle ATM, si ha che per IV=30 una put OTM di σ√t=8.5% vale circa lo 0.5% del sottostante. Per IV=60 una put OTM di σ√t=17% vale circa l' 1% del sottostante.

Cioè vendendo mensilmente put OTM di σ√t per IV=30 si può pensare di ricavare lo 0.5% del sottostante al mese e il 6% all'anno. Se la IV arriva a 60 si può pensare di ricavare il 12% all'anno.

Per arrivare a ricavare il 20% o 30% all'anno tenendo le opzioni fino a scadenza come nell'ipotesi, bisognerebbe avere un portafoglio equivalente a circa il 30% del sottostante; che mi sembra simile al margine massimo che può essere richiesto.

Sempre nell'ipotesi che esistano sottostanti che difficilmente abbiano cali superiori a σ√t (almeno quando la IV supera un valore minimo). Ma esistono?

Se ci si spostasse OTM di 2σ√t i ricavi sarebbero di molto inferiori. Quindi la risposta è che non è possibile ottenere quei rendimenti vendendo meccanicamente opzioni mensili?
 
Ultima modifica:
Pero ho una domanda sulla parte RND vs aspettative di mercato. In questo articolo che ho citato si dice che l'attività di hedging sia una delle ragioni principali per cui non bisogna dare troppa importanza alle aspettative che leggiamo nelle RND. Come hai tenuto conto di questo nelle tue analisi?
La densità implicita, come suggerisce l'acronimo, è neutrale al rischio, quindi ovviamente è sbagliato guardarla e ritenere che si tratti delle reali aspettative degli operatori su dove andrà il mercato.

Tuttavia questo non significa che non sia confrontabile grazie a qualche "aggiustamento" con le proprie stime sulla densità "reale" del sottostante; per semplicità assumiamo di basarci su stime storiche e di simulare dove sarà il sottostante tra T giorni mediante block bootstrap:

  1. il drift storico del sottostante può essere sostituito da un drift neutrale al rischio semplicemente posto pari alla differenza tra tasso privo di rischio e dividend yield del sottostante;
  2. grazie al teorema di Girsanov, il passaggio al punto precedente consente di lasciare invariata la volatilità;
  3. se la figura in opzioni costruita in corrispondenza del disallineamento - assumendo di aver azzeccato la "vera" distribuzione del sottostante - è Delta-neutrale ed è tenuta tale per la vita del trade, non è necessario nemmeno porsi il problema di tornare alla misura di probabilità precedente.
La vera domanda è se questo approccio possa evidenziare delle situazioni che non siano già in parte segnalate da una forte differenza tra volatilità storica (comunque la si misuri) e volatilità implicita, visto che alla fine della fiera la densità implicità non è altro se non un modo diverso di osservare lo smile/skew del sottostante.
 
Ma questo aggiustamento per passare da densità implicita a reale è quello che viene menzionato nel secondo punto, giusto?
Se ho capito bene, questo è solo funzione del premio per il rischio. Ma attività come l'hedging, nel primo punto, dovrebbero essere scollegate a quest'ultimo per cui non ho capito se l'aggiustamento di cui parli possa tenere conto anche di questi meccanismi di mercato. :confused:
 
Il portafoglio personale può essere comunque parametrato al valore del sottostante.

Nell'approssimazione che le opzioni mensili ATM valgano una percentuale del sottostante pari a 0.4×σ√t= IV/8.66 e che le opzioni OTM di σ√t valgano 1/7 di quelle ATM, si ha che per IV=30 una put OTM di σ√t=8.5% vale circa lo 0.5% del sottostante. Per IV=60 una put OTM di σ√t=17% vale circa l' 1% del sottostante.

Cioè vendendo mensilmente put OTM di σ√t per IV=30 si può pensare di ricavare lo 0.5% del sottostante al mese e il 6% all'anno. Se la IV arriva a 60 si può pensare di ricavare il 12% all'anno.

Per arrivare a ricavare il 20% o 30% all'anno tenendo le opzioni fino a scadenza come nell'ipotesi, bisognerebbe avere un portafoglio equivalente a circa il 30% del sottostante; che mi sembra simile al margine massimo che può essere richiesto.

Sempre nell'ipotesi che esistano sottostanti che difficilmente abbiano cali superiori a σ√t (almeno quando la IV supera un valore minimo). Ma esistono?

Se ci si spostasse OTM di 2σ√t i ricavi sarebbero di molto inferiori. Quindi la risposta è che non è possibile ottenere quei rendimenti vendendo meccanicamente opzioni mensili?

Secondo me troppe formule e parametri rendono esageratamente complicato un discorso che è invece molto più terra terra visto che si parla di soldi, ovvero della "estrema bassezza".
Innanzitutto credere che vendendo opzioni in modo meccanico si possano avere quei risultati positivi è assolutamente fuori dalla realtà. Il mercato non è fatto di statistiche, il mercato è fatto da denaro e da interesse contrapposti di svariate operatori e illudersi di poter automatizzare il tutto come se fosse una sorta di bancomat di solo prelievo, facendo credere che la volatilità implicita sovraprezza sempre la reale volatilità storica, porta a cocenti delusioni ed a perdite più o meno importanti.
Per come lavoro io so che ci saranno dei momenti dove è preferibile essere venditori, altri dove è preferibile essere compratori, altri dove è meglio forzare sul delta, altri ancora dove forzare sul vega, posso anche difendermi appiattendo il gamma o aggredire rendendolo più ripido. Devo poi, in base a dove si trova il mercato e a quali reazioni mi aspetto, decidere cosa comprare o vendere, perchè con le opzioni si possono contrattare svariate cose, in primis il vega, poi il delta e per ultimo il theta. Insomma, le sfaccettature operative sono talmente ampie che è di fatto impossibile automatizzare e protocollare una operatività in opzioni, ci si possono intavolare tante belle chiacchierate, ma all'atto pratico rimangono pur sempre chiacchierate.
In tutti i casi, nella mia gestione di portafoglio, non vorrei mai avere un margine pari al 30%, se non in rarissimi casi, altrimenti cerco sempre di mantenerlo tra il 10 e il 20 per cento del massimale operativo. E le performance di portafoglio non le calcolo sul margine utilizzato ma solo ed esclusivamente sul massimale operativo.
 
Secondo me troppe formule e parametri rendono esageratamente complicato un discorso che è invece molto più terra terra visto che si parla di soldi, ovvero della "estrema bassezza".

Innanzitutto credere che vendendo opzioni in modo meccanico si possano avere quei risultati positivi è assolutamente fuori dalla realtà. Il mercato non è fatto di statistiche, il mercato è fatto da denaro e da interessi contrapposti di svariati operatori e illudersi di poter automatizzare il tutto come se fosse una sorta di bancomat di solo prelievo, facendo credere che la volatilità implicita sovrapprezzi sempre la reale volatilità storica, porta a cocenti delusioni ed a perdite più o meno importanti.

Per come lavoro io so che ci saranno dei momenti dove è preferibile essere venditori, altri dove è preferibile essere compratori, altri dove è meglio forzare sul delta, altri ancora dove forzare sul vega, posso anche difendermi appiattendo il gamma o aggredire rendendolo più ripido. Devo poi, in base a dove si trova il mercato e a quali reazioni mi aspetto, decidere cosa comprare o vendere, perchè con le opzioni si possono contrattare svariate cose, in primis il vega, poi il delta e per ultimo il theta.

Insomma, le sfaccettature operative sono talmente ampie che è di fatto impossibile automatizzare e protocollare una operatività in opzioni, ci si possono intavolare tante belle chiacchierate, ma all'atto pratico rimangono pur sempre chiacchierate.

In tutti i casi, nella mia gestione di portafoglio, non vorrei mai avere un margine pari al 30%, se non in rarissimi casi, altrimenti cerco sempre di mantenerlo tra il 10 e il 20 per cento del massimale operativo. E le performance di portafoglio non le calcolo sul margine utilizzato ma solo ed esclusivamente sul massimale operativo.

intervento da incorniciare OK!
 
Secondo me troppe formule e parametri rendono esageratamente complicato un discorso che è invece molto più terra terra visto che si parla di soldi, ovvero della "estrema bassezza".

E' quello che penso anch'io quando vedo profluvi di greche.

Secondo me avere una formuletta di riferimento per poter fare a mente due conti su quanti sono i soldi che girano aiuta ad evitare di impelagarsi in vicoli ciechi.

Innanzitutto credere che vendendo opzioni in modo meccanico si possano avere quei risultati positivi è assolutamente fuori dalla realtà.

Quando "altorendimento" ha fatto la domanda non ha avuto una risposta così chiara.

Io ho provato a quantificarlo matematicamente, per rendermene conto a priori.

I rendimenti richiesti da "altorendimento" si potrebbero ottenere solo con massimali operativi poco verosimili.

In tutti i casi, nella mia gestione di portafoglio, non vorrei mai avere un margine pari al 30%, se non in rarissimi casi, altrimenti cerco sempre di mantenerlo tra il 10 e il 20 per cento del massimale operativo.

Cioè nel caso in questione per ogni opzione venduta verrebbe mantenuto un massimale operativo equivalente al valore del sottostante.
 
Ultima modifica:
Indietro