The following data was imported by left clicking the file on the folder pane to bring up the import window and imported as a cell array. Each column is going to be one of my variables (K = 1st column etc).
StrikePrice UnderlyingPrice mT Rf DividendRate Volatility
47 45 4 0.02 0.5 0.2
50 55 20 0.03 0.1 0.35
And I am using a function first written by Mark Hoyle (2016) that prices American Calls
function LSMAmCallContDiv(S0,K,D,r,sigma,T,NSteps,NSims)
To fill in the first row of my data for this function;
function LSMAmCallContDiv(45, 47, 0.5, 0.02, 0.2, 4, 500, 100)
Is there anyway I can do this function without manually having to change the values for the second row in my cell array? (I'm dealing with a lot of rows in reality). This was something I achieved when pricing puts in RStudio with the following code however I am a complete beginner to MatLab.
jpmitmput30results = apply(jpmitmput30full, 1, function(x) AmerPutLSM(Spot = x['UnderlyingPrice'], sigma = x['Volatility'],
n=500, m=100, Strike = x['StrikePrice'],
r = x['Rf'], dr = x['DividendRate'],
mT = x['mT']))
Given you have a cell array, I presume it looks like this:
data = {47 45 4 0.02 0.5 0.2
50 55 20 0.03 0.1 0.35};
To get one value out, you can index as data{row,column}, for example data{1,3} returns 4.
Now all you need is a loop to repeatedly call your function with the right value in the right order:
for ii=1:size(data,1)
LSMAmCallContDiv(data{ii,2},data{ii,1},data{ii,5},data{ii,4},data{ii,6},data{ii,3},500,100)
end
Since the function has no output arguments, we cannot collect its results in an array. You will have to copy-paste them from the terminal window. If you decide to modify the function to return values, then you can collect them. First modify the first line of the function to read:
function [Price,StdErr] = LSMAmCallContDiv(S0,K,D,r,sigma,T,NSteps,NSims)
and then in your own code:
Price = zeros(size(data,1),1);
StdErr = zeros(size(data,1),1);
for ii=1:size(data,1)
[Price(ii),StdErr(ii)] = LSMAmCallContDiv(data{ii,2},data{ii,1},data{ii,5},data{ii,4},data{ii,6},data{ii,3},500,100)
end
I'm not sure about that function in particular, but most functions can take vectorized input, it's a really useful feature. That is to say, where functions in other languages take single value inputs, matlab thinks of everything as arrays automatically, so you can pass vectors to functions instead, and it calls the function on each row in the input.
For instance,
frame = [47, 45, 4, 0.02, 0.5, 0.2; 50, 55, 20, 0.03, 0.1, 0.35];
out = LSMAmCallContDiv(frame(:,2), frame(:,1), frame(:,5), frame(:,4), frame(:,6), frame(:,3), 500, 100);
should give you a column vector with all the outputs you want. To be clear, the : in (:,2) refers to every row, and the 2 refers to the second column. So, frame(:,2) refers to the entire second column.
Now, this might not be the case for this function, it might not be able to take vectorized input, (I cannot find any documentation on it,) in which case, you might have to take a more programmatical approach.
i = 1;
while i <= height(frame)
out(i) = LSMAmCallContDiv(frame(i,2), frame(i,1), frame(i,5), frame(i,4), frame(i,6), frame(i,3), 500, 100);
i = i+1;
end
This is a more standard approach that one might see in any other language, (albeit less efficient in matlab), but it is certainly a good way to do it.
I'm trying to solve a system of differential equations in python.
I have a system composed by two equations where I have two variables, A and B.
The initial condition are that A0=1e17 and B0=0, they change simultaneously.
I wrote the following code using ODEINT:
import numpy as np
from scipy.integrate import odeint
def dmdt(m,t):
A, B = m
dAdt = A-B
dBdt = (A-B)*A
return [dAdt, dBdt]
# Create time domain
t = np.linspace(0, 100, 1)
# Initial condition
A0=1e17
B0=0
m0=[A0, B0]
solution = odeint(dmdt, m0, t)
Apparently I obtain an output different from the expected one but I don't understand the error.
Can someone help me?
Thanks
From A*A'-B'=0 one concludes
B = 0.5*(A^2 - A0^2)
Inserted into the first equation that gives
A' = A - 0.5*A^2 + 0.5*A0^2
= 0.5*(A0^2+1 - (A-1)^2)
This means that the A dynamic has two fixed points at about A0+1 and -A0+1, is growing inside that interval, the upper fixed point is stable. However, in standard floating point numbers there is no difference between 1e17 and 1e17+1. If you want to see the difference, you have to encode it separately.
Also note that the standard error tolerances atol and rtol in the range somewhere between 1e-6 and 1e-9 are totally incompatible with the scales of the problem as originally stated, also highlighting the need to rescale and shift the problem into a more appreciable range of values.
Setting A = A0+u with |u| in an expected scale of 1..10 then gives
B = 0.5*u*(2*A0+u)
u' = A0+u - 0.5*u*(2*A0+u) = (1-u)*A0 - 0.5*u^2
This now suggests that the time scale be reduced by A0, set t=s/A0. Also, B = A0*v. Insert the direct parametrizations into the original system to get
du/ds = dA/dt / A0 = (A0+u-A0*v)/A0 = 1 + u/A0 - v
dv/ds = dB/dt / A0^2 = (A0+u-A0*v)*(A0+u)/A0^2 = (1+u/A0-v)*(1+u/A0)
u(0)=v(0)=0
Now in floating point and the expected range for u, we get 1+u/A0 == 1, so effectively u'(s)=v'(s)=1-v which gives
u(s)=v(s)=1-exp(-s)`,
A(t) = A0 + 1-exp(-A0*t) + very small corrections
B(t) = A0*(1-exp(-A0*t)) + very small corrections
The system in s,u,v should be well-computable by any solver in the default tolerances.
I'm trying to replicate an excel model in python, and I've used the excel linest formulae to find the y-intercept. Formulae is INDEX(LINEST(known y's, known x's, True),2).
Known y's [Highs]= 79.375, 89.5625, 91.5, 75.125, 72.6875, 70.5, 72.625, 70, 68, 67.1875, 68.625, 65.1875
Known x's = 1, 2, 3,.. 11, 12
The below code is trying to replicate the y-intercept but I'm getting different outputs.
import numpy as np
x = np.array([1,2,3,4,5,6,7,8,9,10,11,12])
drange = 12
A = np.vstack([ np.arange(drange), np.ones(len(x))]).T
df['intercept'] = df['High'].rolling(drange).apply(lambda y: np.linalg.lstsq(A, y, rcond=None)[0][1], raw=False)
In Excel I get 86.82996 for the intercept, in Python I get 84.89503. I'm trying to get the same Excel result in python.
When running my MATLAB script below, I keep getting an error that states:
Error using spa (Line 147)
The value of the window
size must be an integer greater than 2.
Error in "projectName" G = spa(xFunction2, x)
I've tried putting in multiple types of arguments into "spa" (data, windowsize, frequency) but it still yields the same error(s). Help?
n = 1:1024;
%Signal Function
xFunction = sqrt(10)*exp(j*2*pi*0.10*n)+ sqrt(20)*exp(j*2*pi*0.20*n) + sqrt(625);
%Complex Noise Function
zFunction = 0.707*randn(size(n)) + j*0.707*randn(size(n));
%Computing the value of x(n) + sqrt(625)*z
xFunction2 = xFunction + sqrt(625)*zFunction;
G = spa(xFunction2,51);
figure(1);
plot(w, 10*log10(G));
Acording the documentation of spa the first argument is iddata type. In addition, the time serie has to be a column vector.
So, to make it works change G = spa(xFunction2,51); for G = spa(xFunction2(:),51);. To do it the correct way, convert your time serie to iddata:
Ts = 0.1; % what ever is your sampling time.
myiddata = iddata(xFunction2(:),[],Ts);
G = spa(myiddata,51);
In addition, you should use spectrum(G) or bode(G)to plot the result.
Can anybody help me with this assignment please?
I am new to matlab, and passing this year depends on this assignment, i don't have much time to explore matlab and i already wasted alot of time trying to do this assignment in my way.
I have already wrote the equations on the paper, but transfering the equations into matlab codes is really hard for me.
All i have for now is:
syms h
l = (0.75-h.^2)/(3*sqrt((5*h.^2)/4)); %h is h_max
V_default = (h.^2/2)*l;
dv = diff(V_default); %it's max. when the derivative is max.
h1 = solve( dv ==0);
h_max = (h1>0);
l_max = (0.75-h_max.^2)/(3*sqrt((h_max/2).^2+(h_max.^2)));
V_max = ((h_max.^2)./(2.*l_max));
but it keep give me error "Error using ./
Matrix dimensions must agree.
Error in triangle (line 9)
V_max = ((h_max.^2)./(2.*l_max)); "
Not really helping with the assignment here, but with the Matlab syntax. In the following line:
l_max = (0.75-h_max.^2)/(3*sqrt((h_max/2).^2+(h_max.^2)));
you're using / that is a matrix divide. You might want to use ./ which will divide the terms element by element. If I do this
l_max = (0.75-h_max.^2) ./ (3*sqrt((h_max/2).^2+(h_max.^2)));
then your code doesn't return any error. But I have no idea if it's the correct solution of your assignment, I'll leave that to you!
In line 5, the result h1 is a vector of two values but the variable itself remains symbolic, from the Symbolic Math Toolbox. MATLAB treats such variables slightly different. For that reason, the line h_max = (h1>0) doesn't really do what you expect. As I think from this point, you are interested in one value h_max, I would convert h1 to a regular MATLAB variable and change your code to the following:
h1 = double(solve( dv ==0)); % converts symbolic to regular vectors
h_max = h1(h1>0); % filters out all negative and zero values
l_max = (0.75-h_max.^2)/(3*sqrt((h_max/2).^2+(h_max.^2)));
V_max = ((h_max.^2)./(2.*l_max));
EDIT.
If you still have error, it means solve( ...) returns more than 1 positive values. In this case, as suggested, use dotted operations, such as ./ but the results in l_max and V_max will not be a single value but vectors of the same size as h_max. Which means you don't have one max Volume.