コード例 #1
0
        private int sendpacker(OptionFunction function, CT2Packer packer, bool IsAsync = true)
        {
            try
            {
                CT2BizMessage BizMessage = new CT2BizMessage();     //构造消息
                BizMessage.SetFunction((int)function);              //设置功能号
                BizMessage.SetPacketType(0);                        //设置消息类型为请求

                unsafe
                {
                    BizMessage.SetContent(packer.GetPackBuf(), packer.GetPackLen());
                }

                /************************************************************************/

                /* 此处使用异步发送 同步发送可以参考下面注释代码
                 * connection.SendBizMsg(BizMessage, 0);
                 * 1=异步,0=同步
                 * /************************************************************************/
                int iRet = this.connMain.SendBizMsg(BizMessage, (IsAsync) ? 1 : 0);
                if (iRet < 0)
                {
                    MessageManager.GetInstance().Add(MessageType.Error, string.Format("发送错误:{0}", connMain.GetErrorMsg(iRet)));
                }
                packer.Dispose();
                BizMessage.Dispose();

                return(iRet);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
コード例 #2
0
        public virtual void test_trinomialTree_down()
        {
            int nSteps = 133;
            LatticeSpecification lattice = new CoxRossRubinsteinLatticeSpecification();
            DoubleArray          rebate  = DoubleArray.of(nSteps + 1, i => REBATE_AMOUNT);
            double barrierLevel          = 76d;
            double tol = 1.0e-2;

            foreach (bool isCall in new bool[] { true, false })
            {
                foreach (double strike in STRIKES)
                {
                    foreach (double interest in INTERESTS)
                    {
                        foreach (double vol in VOLS)
                        {
                            foreach (double dividend in DIVIDENDS)
                            {
                                OptionFunction function = ConstantContinuousSingleBarrierKnockoutFunction.of(strike, TIME, PutCall.ofPut(!isCall), nSteps, BarrierType.DOWN, barrierLevel, rebate);
                                SimpleConstantContinuousBarrier barrier = SimpleConstantContinuousBarrier.of(BarrierType.DOWN, KnockType.KNOCK_OUT, barrierLevel);
                                double exact    = REBATE_AMOUNT * REBATE_PRICER.price(SPOT, TIME, interest - dividend, interest, vol, barrier.inverseKnockType()) + BARRIER_PRICER.price(SPOT, strike, TIME, interest - dividend, interest, vol, isCall, barrier);
                                double computed = TRINOMIAL_TREE.optionPrice(function, lattice, SPOT, vol, interest, dividend);
                                assertEquals(computed, exact, Math.Max(exact, 1d) * tol);
                            }
                        }
                    }
                }
            }
        }
        public virtual void test_trinomialTree()
        {
            int nSteps = 135;

            LatticeSpecification[] lattices = new LatticeSpecification[]
            {
                new CoxRossRubinsteinLatticeSpecification(),
                new TrigeorgisLatticeSpecification()
            };
            double tol = 5.0e-3;

            foreach (bool isCall in new bool[] { true, false })
            {
                foreach (double strike in STRIKES)
                {
                    foreach (double interest in INTERESTS)
                    {
                        foreach (double vol in VOLS)
                        {
                            foreach (double dividend in DIVIDENDS)
                            {
                                OptionFunction function = EuropeanVanillaOptionFunction.of(strike, TIME, PutCall.ofPut(!isCall), nSteps);
                                double         exact    = BlackScholesFormulaRepository.price(SPOT, strike, TIME, vol, interest, interest - dividend, isCall);
                                foreach (LatticeSpecification lattice in lattices)
                                {
                                    double computed = TRINOMIAL_TREE.optionPrice(function, lattice, SPOT, vol, interest, dividend);
                                    assertEquals(computed, exact, Math.Max(exact, 1d) * tol);
                                }
                            }
                        }
                    }
                }
            }
        }
コード例 #4
0
        /// <summary>
        /// Price an option under the specified trinomial lattice.
        /// <para>
        /// It is assumed that the volatility, interest rate and continuous dividend rate are constant
        /// over the lifetime of the option.
        ///
        /// </para>
        /// </summary>
        /// <param name="function">  the option </param>
        /// <param name="lattice">  the lattice specification </param>
        /// <param name="spot">  the spot </param>
        /// <param name="volatility">  the volatility </param>
        /// <param name="interestRate">  the interest rate </param>
        /// <param name="dividendRate">  the dividend rate </param>
        /// <returns> the option price </returns>
        public virtual double optionPrice(OptionFunction function, LatticeSpecification lattice, double spot, double volatility, double interestRate, double dividendRate)
        {
            int         nSteps          = function.NumberOfSteps;
            double      timeToExpiry    = function.TimeToExpiry;
            double      dt              = timeToExpiry / (double)nSteps;
            double      discount        = Math.Exp(-interestRate * dt);
            DoubleArray @params         = lattice.getParametersTrinomial(volatility, interestRate - dividendRate, dt);
            double      middleFactor    = @params.get(1);
            double      downFactor      = @params.get(2);
            double      upProbability   = @params.get(3);
            double      midProbability  = @params.get(4);
            double      downProbability = @params.get(5);

            ArgChecker.isTrue(upProbability > 0d, "upProbability should be greater than 0");
            ArgChecker.isTrue(upProbability < 1d, "upProbability should be smaller than 1");
            ArgChecker.isTrue(midProbability > 0d, "midProbability should be greater than 0");
            ArgChecker.isTrue(midProbability < 1d, "midProbability should be smaller than 1");
            ArgChecker.isTrue(downProbability > 0d, "downProbability should be greater than 0");
            DoubleArray values = function.getPayoffAtExpiryTrinomial(spot, downFactor, middleFactor);

            for (int i = nSteps - 1; i > -1; --i)
            {
                values = function.getNextOptionValues(discount, upProbability, midProbability, downProbability, values, spot, downFactor, middleFactor, i);
            }
            return(values.get(0));
        }
コード例 #5
0
        /// <summary>
        /// Price an option under the specified trinomial tree gird.
        /// </summary>
        /// <param name="function">  the option </param>
        /// <param name="data">  the trinomial tree data </param>
        /// <returns> the option price </returns>
        public virtual double optionPrice(OptionFunction function, RecombiningTrinomialTreeData data)
        {
            int nSteps = data.NumberOfSteps;

            ArgChecker.isTrue(nSteps == function.NumberOfSteps, "mismatch in number of steps");
            DoubleArray values = function.getPayoffAtExpiryTrinomial(data.getStateValueAtLayer(nSteps));

            for (int i = nSteps - 1; i > -1; --i)
            {
                values = function.getNextOptionValues(data.getDiscountFactorAtLayer(i), data.getProbabilityAtLayer(i), data.getStateValueAtLayer(i), values, i);
            }
            return(values.get(0));
        }
コード例 #6
0
        /// <summary>
        /// Test consistency between price methods, and Greek via finite difference.
        /// </summary>
        public virtual void test_trinomialTree()
        {
            int    nSteps = 135;
            double dt     = TIME / nSteps;
            LatticeSpecification lattice = new CoxRossRubinsteinLatticeSpecification();
            double fdEps = 1.0e-4;

            foreach (bool isCall in new bool[] { true, false })
            {
                foreach (double strike in STRIKES)
                {
                    foreach (double interest in INTERESTS)
                    {
                        foreach (double vol in VOLS)
                        {
                            foreach (double dividend in DIVIDENDS)
                            {
                                OptionFunction function   = EuropeanVanillaOptionFunction.of(strike, TIME, PutCall.ofPut(!isCall), nSteps);
                                double[]       @params    = lattice.getParametersTrinomial(vol, interest - dividend, dt).toArray();
                                DoubleArray    time       = DoubleArray.of(nSteps + 1, i => dt * i);
                                DoubleArray    df         = DoubleArray.of(nSteps, i => Math.Exp(-interest * dt));
                                double[][]     stateValue = new double[nSteps + 1][];
                                stateValue[0] = new double[] { SPOT };
                                IList <DoubleMatrix> prob  = new List <DoubleMatrix>();
                                double[]             probs = new double[] { @params[5], @params[4], @params[3] };
                                for (int i = 0; i < nSteps; ++i)
                                {
                                    int index = i;
                                    stateValue[i + 1] = DoubleArray.of(2 * i + 3, j => SPOT * Math.Pow(@params[2], index + 1 - j) * Math.Pow(@params[1], j)).toArray();
                                    double[][] probMatrix = new double[2 * i + 1][];
                                    Arrays.fill(probMatrix, probs);
                                    prob.Add(DoubleMatrix.ofUnsafe(probMatrix));
                                }
                                RecombiningTrinomialTreeData treeData = RecombiningTrinomialTreeData.of(DoubleMatrix.ofUnsafe(stateValue), prob, df, time);
                                double priceData   = TRINOMIAL_TREE.optionPrice(function, treeData);
                                double priceParams = TRINOMIAL_TREE.optionPrice(function, lattice, SPOT, vol, interest, dividend);
                                assertEquals(priceData, priceParams);
                                ValueDerivatives priceDeriv = TRINOMIAL_TREE.optionPriceAdjoint(function, treeData);
                                assertEquals(priceDeriv.Value, priceData);
                                double priceUp = TRINOMIAL_TREE.optionPrice(function, lattice, SPOT + fdEps, vol, interest, dividend);
                                double priceDw = TRINOMIAL_TREE.optionPrice(function, lattice, SPOT - fdEps, vol, interest, dividend);
                                double fdDelta = 0.5 * (priceUp - priceDw) / fdEps;
                                assertEquals(priceDeriv.getDerivative(0), fdDelta, 3.0e-2);
                            }
                        }
                    }
                }
            }
        }
コード例 #7
0
        /// <summary>
        /// Compute option price and delta under the specified trinomial tree gird.
        /// <para>
        /// The delta is the first derivative of the price with respect to spot, and approximated by the data embedded in
        /// the trinomial tree.
        ///
        /// </para>
        /// </summary>
        /// <param name="function">  the option </param>
        /// <param name="data">  the trinomial tree data </param>
        /// <returns> the option price and spot delta </returns>
        public virtual ValueDerivatives optionPriceAdjoint(OptionFunction function, RecombiningTrinomialTreeData data)
        {
            int nSteps = data.NumberOfSteps;

            ArgChecker.isTrue(nSteps == function.NumberOfSteps, "mismatch in number of steps");
            DoubleArray values = function.getPayoffAtExpiryTrinomial(data.getStateValueAtLayer(nSteps));
            double      delta  = 0d;

            for (int i = nSteps - 1; i > -1; --i)
            {
                values = function.getNextOptionValues(data.getDiscountFactorAtLayer(i), data.getProbabilityAtLayer(i), data.getStateValueAtLayer(i), values, i);
                if (i == 1)
                {
                    DoubleArray stateValue = data.getStateValueAtLayer(1);
                    double      d1         = (values.get(2) - values.get(1)) / (stateValue.get(2) - stateValue.get(1));
                    double      d2         = (values.get(1) - values.get(0)) / (stateValue.get(1) - stateValue.get(0));
                    delta = 0.5 * (d1 + d2);
                }
            }
            return(ValueDerivatives.of(values.get(0), DoubleArray.of(delta)));
        }