n = 500 pmin = -1 # minimum log price pmax = 1 # maximum log price Value = BasisSpline(n, pmin, pmax, labels=['logprice'], l=['value']) print(Value) # In the last expression, by passing the option `l` with a one-element list we are telling the ```BasisSpline``` class that we a single function named "value". On creation, the function will be set by default to $V(p)=0$ for all values of $p$, which conveniently corresponds to the terminal condition of this problem. # ## Finding the critical exercise prices # # We are going to find the prices recursively, starting form a option in the expiration date. Notice that the solution to this problem is trivial: since next-period value is zero, the exercise price is $K$. Either way, we can find it numerically by calling the ```zero``` method on the `f` object. # In[7]: pcrit[0] = f.zero(0.0) # Next, for each possible price shock, we compute next period log-price by adding the shock to current log-prices (the nodes of the Value object). Then, we use each next-period price to compute the expected value of an option with one-period to maturity (save the values in ```v```). We update the value function to reflect the new time-to-maturity and use ```broyden``` to solve for the critical value. We repeat this procedure until we reach the $T=300$ horizon. # In[8]: for t in range(T): v = np.zeros((1, n)) for k in range(m): pnext = Value.nodes + e[k] v += w[k] * np.maximum(K - np.exp(pnext), delta * Value(pnext)) Value[:] = v pcrit[t + 1] = f.broyden(pcrit[t]) # ### Print Critical Exercise Price 300 Periods to Expiration
pmax = 1 # maximum log price Value = BasisSpline(n, pmin, pmax, labels=['logprice'], l=['value']) print(Value) # In the last expression, by passing the option `l` with a one-element list we are telling the ```BasisSpline``` class that we a single function named "value". On creation, the function will be set by default to $V(p)=0$ for all values of $p$, which conveniently corresponds to the terminal condition of this problem. # ## Finding the critical exercise prices # # We are going to find the prices recursively, starting form a option in the expiration date. Notice that the solution to this problem is trivial: since next-period value is zero, the exercise price is $K$. Either way, we can find it numerically by calling the ```zero``` method on the `f` object. # In[7]: pcrit[0] = f.zero(0.0) # Next, for each possible price shock, we compute next period log-price by adding the shock to current log-prices (the nodes of the Value object). Then, we use each next-period price to compute the expected value of an option with one-period to maturity (save the values in ```v```). We update the value function to reflect the new time-to-maturity and use ```broyden``` to solve for the critical value. We repeat this procedure until we reach the $T=300$ horizon. # In[8]: for t in range(T): v = np.zeros((1, n)) for k in range(m): pnext = Value.nodes + e[k] v += w[k] * np.maximum(K - np.exp(pnext), delta * Value(pnext)) Value[:] = v pcrit[t + 1] = f.broyden(pcrit[t])
print('q1 = ', x[0], '\nq2 = ', x[1]) ''' Example page 43 ''' # numbers don't match those of Table 3.1, but CompEcon2014' broyden gives same answer as this code example(43) opts = {'maxit': 30, 'all_x': True, 'print': True} g = NLP(lambda x: sqrt(x), 0.5) f = NLP(lambda x: (x - sqrt(x), 1 - 0.5 / sqrt(x)), 0.5) x_fp = g.fixpoint(**opts) x_br = f.broyden(**opts) x_nw = f.newton(**opts) ''' Example page 51 ''' example(51) f = MCP(lambda x: (1.01 - (1 - x)**2, 2 * (1 - x)), 0, np.inf) x = f.zero(0.0) # ssmooth transform by default print('Using', f.opts.transform, 'transformation, x = ', x) x = f.zero(0.0, transform='minmax') print('Using', f.opts.transform, 'transformation, x = ', x, 'FAILED TO CONVERGE') # ============================================================== ''' Exercise 3.1 ''' exercise('3.1') def newtroot(c): x = c / 2 for it in range(150): fx = x**2 - c if abs(fx) < 1.e-9:
'linewidth': 1.0, 'markersize': 6, 'markerfacecolor': 'red', 'markeredgecolor': 'red' } contour_options = {'levels': [0.0], 'colors': '0.25', 'linewidths': 0.5} Q1, Q2 = np.meshgrid(q1, q2) Z0 = np.reshape(z[0], (n, n), order='F') Z1 = np.reshape(z[1], (n, n), order='F') methods = ['newton', 'broyden'] cournot_problem.opts['maxit', 'maxsteps', 'all_x'] = 10, 0, True qmin, qmax = 0.1, 1.3 fig = plt.figure() for it in range(2): x = cournot_problem.zero(method=methods[it]) demo.subplot(1, 2, it + 1, methods[it].capitalize() + "'s method", '$q_1$', '$q_2$', [qmin, qmax], [qmin, qmax]) plt.contour(Q1, Q2, Z0, **contour_options) plt.contour(Q1, Q2, Z1, **contour_options) plt.plot(*cournot_problem.x_sequence, **steps_options) demo.text(0.85, qmax, '$\pi_1 = 0$', 'left', 'top') demo.text(qmax, 0.55, '$\pi_2 = 0$', 'right', 'center') plt.show() demo.savefig([fig])
contour_options = {'levels': [0.0], 'colors': '0.25', 'linewidths': 0.5} Q1, Q2 = np.meshgrid(q1, q2) Z0 = np.reshape(z[0], (n,n), order='F') Z1 = np.reshape(z[1], (n,n), order='F') methods = ['newton', 'broyden'] cournot_problem.opts['all_x'] = True fig = plt.figure() for it in range(2): cournot_problem.zero(x0=q, method=methods[it]) demo.subplot(1, 2, it + 1, methods[it].capitalize() + "'s method", '$x$', '$y$', [min(q1), max(q1)], [min(q2), max(q2)]) plt.contour(Q1, Q2, Z0, **contour_options) plt.contour(Q1, Q2, Z1, **contour_options) plt.plot(*cournot_problem.x_sequence, **steps_options) ax = plt.gca() ax.set_xticks([0.3, 0.7, 1.1]) ax.set_yticks([0.4, 0.8, 1.2]) demo.text(0.7, 0.45, '$f_1(x,y) = 0$', 'left', 'top',fs=12) demo.text(0.3, 0.55, '$f_2(x,y) = 0$', 'left', 'center',fs=12) plt.show() demo.savefig([fig])
'markersize': 6, 'markerfacecolor': 'red', 'markeredgecolor': 'red' } contour_options = {'levels': [0.0], 'colors': '0.25', 'linewidths': 0.5} Q1, Q2 = np.meshgrid(q1, q2) Z0 = np.reshape(z[0], (n, n), order='F') Z1 = np.reshape(z[1], (n, n), order='F') methods = ['newton', 'broyden'] cournot_problem.opts['all_x'] = True fig = plt.figure() for it in range(2): cournot_problem.zero(x0=q, method=methods[it]) demo.subplot(1, 2, it + 1, methods[it].capitalize() + "'s method", '$x$', '$y$', [min(q1), max(q1)], [min(q2), max(q2)]) plt.contour(Q1, Q2, Z0, **contour_options) plt.contour(Q1, Q2, Z1, **contour_options) plt.plot(*cournot_problem.x_sequence, **steps_options) ax = plt.gca() ax.set_xticks([0.3, 0.7, 1.1]) ax.set_yticks([0.4, 0.8, 1.2]) demo.text(0.7, 0.45, '$f_1(x,y) = 0$', 'left', 'top', fs=12) demo.text(0.3, 0.55, '$f_2(x,y) = 0$', 'left', 'center', fs=12) plt.show() demo.savefig([fig])
'markerfacecolor': 'red', 'markeredgecolor': 'red'} contour_options = {'levels': [0.0], 'colors': '0.25', 'linewidths': 0.5} Q1, Q2 = np.meshgrid(q1, q2) Z0 = np.reshape(z[0], (n,n), order='F') Z1 = np.reshape(z[1], (n,n), order='F') methods = ['newton', 'broyden'] cournot_problem.opts['maxit', 'maxsteps', 'all_x'] = 10, 0, True qmin, qmax = 0.1, 1.3 fig = plt.figure() for it in range(2): x = cournot_problem.zero(method=methods[it]) demo.subplot(1, 2, it + 1, methods[it].capitalize() + "'s method", '$q_1$', '$q_2$', [qmin, qmax], [qmin, qmax]) plt.contour(Q1, Q2, Z0, **contour_options) plt.contour(Q1, Q2, Z1, **contour_options) plt.plot(*cournot_problem.x_sequence, **steps_options) demo.text(0.85, qmax, '$\pi_1 = 0$', 'left', 'top') demo.text(qmax, 0.55, '$\pi_2 = 0$', 'right', 'center') plt.show() demo.savefig([fig])