This is an example of using the QuantLib Monte Carlo framework.
#include <ql/qldefines.hpp>
#ifdef BOOST_MSVC
#  include <ql/auto_link.hpp>
#endif
#include <ql/methods/montecarlo/montecarlomodel.hpp>
#include <ql/processes/blackscholesprocess.hpp>
#include <ql/termstructures/yield/flatforward.hpp>
#include <ql/termstructures/volatility/equityfx/blackconstantvol.hpp>
#include <ql/pricingengines/blackcalculator.hpp>
#include <ql/quotes/simplequote.hpp>
#include <ql/time/calendars/target.hpp>
#include <ql/time/daycounters/actual365fixed.hpp>
#include <boost/timer.hpp>
#include <iostream>
#include <iomanip>
#if defined(QL_ENABLE_SESSIONS)
}
#endif
class ReplicationError
{
public:
    ReplicationError(Option::Type type,
    : maturity_(maturity), payoff_(type, strike), s0_(s0),
      sigma_(sigma), r_(r) {
        
        Real forward = s0_*qDiscount/rDiscount;
         Real stdDev = std::sqrt(sigma_*sigma_*maturity_);
         boost::shared_ptr<StrikedTypePayoff> payoff(
        std::cout << "Option value: " << black.value() << std::endl;
        
        vega_ = black.vega(maturity_);
        std::cout << std::endl;
        std::cout << std::setw(8) << " " << " | "
                  << std::setw(8) << " " << " | "
                  << std::setw(8) << "P&L" << " | "
                  << std::setw(8) << "P&L" << " | "
                  << std::setw(12) << "Derman&Kamal" << " | "
                  << std::setw(8) << "P&L" << " | "
                  << std::setw(8) << "P&L" << std::endl;
        std::cout << std::setw(8) << "samples" << " | "
                  << std::setw(8) << "trades" << " | "
                  << std::setw(8) << "mean" << " | "
                  << std::setw(8) << "std.dev." << " | "
                  << std::setw(12) << "formula" << " | "
                  << std::setw(8) << "skewness" << " | "
                  << std::setw(8) << "kurtosis" << std::endl;
        std::cout << std::string(78, '-') << std::endl;
    }
    
    void compute(
Size nTimeSteps, 
Size nSamples);
 private:
};
class ReplicationPathPricer : 
public PathPricer<Path> {
   public:
    
    ReplicationPathPricer(Option::Type type,
    : type_(type), strike_(strike),
      r_(r), maturity_(maturity), sigma_(sigma) {
        QL_REQUIRE(strike_ > 0.0, "strike must be positive");
        QL_REQUIRE(r_ >= 0.0,
                   "risk free rate (r) must be positive or zero");
        QL_REQUIRE(maturity_ > 0.0, "maturity must be positive");
        QL_REQUIRE(sigma_ >= 0.0,
                   "volatility (sigma) must be positive or zero");
    }
    
    Real operator()(
const Path& path) 
const;
   private:
    Option::Type type_;
};
int main(int, char* []) {
    try {
        boost::timer timer;
        std::cout << std::endl;
        Time maturity = 1.0/12.0;   
         Rate riskFreeRate = 0.05; 
         ReplicationError rp(Option::Call, maturity, strike, underlying,
        hedgesNum = 21;
        rp.compute(hedgesNum, scenarios);
        hedgesNum = 84;
        rp.compute(hedgesNum, scenarios);
        double seconds = timer.elapsed();
        seconds -= hours * 3600;
        seconds -= minutes * 60;
        std::cout << " \nRun completed in ";
        if (hours > 0)
            std::cout << hours << " h ";
        if (hours > 0 || minutes > 0)
            std::cout << minutes << " m ";
        std::cout << std::fixed << std::setprecision(0)
                  << seconds << " s\n" << std::endl;
        return 0;
    } catch (std::exception& e) {
        std::cerr << e.what() << std::endl;
        return 1;
    } catch (...) {
        std::cerr << "unknown error" << std::endl;
        return 1;
    }
}
Real ReplicationPathPricer::operator()(
const Path& path)
 const {
     Size n = path.
length()-1;
     QL_REQUIRE(n>0, "the path cannot be empty");
    
    
    Rate stockDividendYield = 0.0;
     
    
    
    Real money_account = 0.0;
     
    
    
    
    Real forward = stock*qDiscount/rDiscount;
     Real stdDev = std::sqrt(sigma_*sigma_*maturity_);
     boost::shared_ptr<StrikedTypePayoff> payoff(
    
    money_account += black.value();
    
    Real delta = black.delta(stock);
     
    Real stockAmount = delta;
     money_account -= stockAmount*stock;
    
    
    
    for (
Size step = 0; step < n-1; step++){
         
        t += dt;
        
        money_account *= std::exp( r_*dt );
        
        stock = path[step+1];
        
        
        rDiscount = std::exp(-r_*(maturity_-t));
        qDiscount = std::exp(-stockDividendYield*(maturity_-t));
        forward = stock*qDiscount/rDiscount;
        stdDev = std::sqrt(sigma_*sigma_*(maturity_-t));
        
        delta = black.delta(stock);
        
        money_account -= (delta - stockAmount)*stock;
        stockAmount = delta;
    }
    
    
    
    
    money_account *= std::exp( r_*dt );
    
    stock = path[n];
    
    money_account -= optionPayoff;
    
    money_account += stockAmount*stock;
    
    return money_account;
}
void ReplicationError::compute(
Size nTimeSteps, 
Size nSamples)
 {
    QL_REQUIRE(nTimeSteps>0, "the number of steps must be > 0");
    
    
    
                          boost::shared_ptr<YieldTermStructure>(
                          boost::shared_ptr<YieldTermStructure>(
                          boost::shared_ptr<BlackVolTermStructure>(
    boost::shared_ptr<StochasticProcess1D> diffusion(
    
    
    
        PseudoRandom::make_sequence_generator(nTimeSteps, 0);
    bool brownianBridge = false;
    boost::shared_ptr<generator_type> myPathGenerator(new
        generator_type(diffusion, maturity_, nTimeSteps,
                       rsg, brownianBridge));
    
    
    
    boost::shared_ptr<PathPricer<Path> > myPathPricer(new
        ReplicationPathPricer(payoff_.optionType(), payoff_.strike(),
                              r_, maturity_, sigma_));
    
    
    
    
        MCSimulation(myPathGenerator,
                     myPathPricer,
                     statisticsAccumulator,
                     false);
    
    MCSimulation.addSamples(nSamples);
    
    
    Real PLMean  = MCSimulation.sampleAccumulator().mean();
     Real PLStDev = MCSimulation.sampleAccumulator().standardDeviation();
     Real PLSkew  = MCSimulation.sampleAccumulator().skewness();
     Real PLKurt  = MCSimulation.sampleAccumulator().kurtosis();
     
    Real theorStD = std::sqrt(M_PI/4/nTimeSteps)*vega_*sigma_;
     std::cout << std::fixed
              << std::setw(8) << nSamples << " | "
              << std::setw(8) << nTimeSteps << " | "
              << std::setw(8) << std::setprecision(3) << PLMean << " | "
              << std::setw(8) << std::setprecision(2) << PLStDev << " | "
              << std::setw(12) << std::setprecision(2) << theorStD << " | "
              << std::setw(8) << std::setprecision(2) << PLSkew << " | "
              << std::setw(8) << std::setprecision(2) << PLKurt << std::endl;
}