// Copyright (C) 2018 EDF
// All Rights Reserved
#ifndef _GLOBALL2HEDGEMINIMIZE_H_
#define _GLOBALL2HEDGEMINIMIZE_H_
#include <map>
#include <memory>
#include <Eigen/Dense>
#include "StOpt/regression/BaseRegression.h"
#include "StOpt/core/grids/SpaceGrid.h"

/// \brief  Permits to optimize a position in delta at the  next date
///         given a a current position in delta.
///         Global L2 minimization
///         See "Variance optimal hedging with application to Electricity markets"
///         The delta at next date is given back
///         This delta is constant per mesh
///         The cost in shifting a position from \f$p\f$ is given by \f$ (p_spread1 + p_spread2 asset) p f$
///
/// \param p_difS                difference in asset value (nb asset, nb sim)  (asset at next time minus asset value)
/// \param p_asset               asset value (nb asset, nb sim)
/// \param p_delta               current delta position (number of assets)
/// \param p_spread1             constant part of semi spread bid ask per asset
/// \param p_spread2             linear part of semi spread bid ask (proportional cost)
/// \param p_commandGrid         the grid of all the commands
/// \param p_regressor           regressor for current date
/// \param p_gridNext            grid at the next time step
/// \param p_hMinusGainNext      store  payoff minus the gain function on each trajectory
/// \return the value per simulation for the current delta position and the delta position (nbSimul per nb hedge)
std::pair<Eigen::ArrayXd, Eigen::ArrayXXd>  globalL2HedgeMinimize(const Eigen::ArrayXXd &p_difS,
        const Eigen::ArrayXXd &p_asset,
        const Eigen::ArrayXd &p_delta,
        const Eigen::ArrayXd &p_spread1,
        const Eigen::ArrayXd &p_spread2,
        const StOpt::SpaceGrid &p_commandGrid,
        const std::shared_ptr< StOpt::BaseRegression > &p_regressor,
        const StOpt::SpaceGrid &p_gridNext,
        const Eigen::ArrayXXd &p_hMinusGainNext);

#endif
