MrMarc

3158 Reputation

18 Badges

16 years, 267 days

MaplePrimes Activity


These are answers submitted by MrMarc

I thought this sorting code was going to be easy but that was not the case.
I tried to put the below code in the outerproc after Ans but that just destroyed the performance/speed
hummm....

for ap to 10 do
for i to nstock do
for j to nstock do

if Ans[i, j] = max(Ans) then cc[ap] := [i, -j, Ans[i, j]]:   Ans[i, j] := 0: end if :

end do :
end do :
end do;

data1 := [seq(cc[ap], ap = 1 .. 10)]:

Matrix(sort(data1, proc (a, b) options operator, arrow; b[3] < a[3] end proc));
 

Nice indeed . Thank you. You definitely saved Maple from being dumped. I did some serious research
on Matlab last night which might have been in vain. I ran you code and it did 850 stocks in 4.025 seconds. nice :-)
I am just amassed that you can get such a performance difference by doing things slighty different ...hummm

I assume that in your matrix approach you go short in the stock corresponding to the column index and go long in the stock corresponding to the row index. I also noticed that the Result matrix seems to be more or less symmetrical in absolute
value terms which is very interesting. The question i ask myself now is which is the best way to sort the matrix or how to
identify the 20 pairs with highest Sharpe ratio and sort them and extract the information so it has the matrix form

[ stock [ i ], -1*stock [ j ], SH [ i, j ]  ]
[ stock [ i ], -1*stock [ j ], SH [ i, j ]  ]
[ stock [ i ], -1*stock [ j ], SH [ i, j ]  ]


Another thing why do you write the code with tabs in it ? Is it personal preferences or will it make it faster ?
Also I do not understand the Results matrix completely. In the outputproc as seen below

outerproc:=proc(SR::Matrix(datatype=float[8]))
local Ans, n, nstock;
n,nstock := op(1,SR);
Ans := Matrix(nstock,nstock,storage=rectangular,datatype=float[8]);
Sharpe(Ans,nstock,n,SR); 
Ans;
end proc:

 
I assume that Ans is the "outputmatrix" where the Sharpe procedure puts all the outputs
but why is not the Result matrix full by default ?. It is only the lower part that contain data the upper part only contains
0's hummm. Why does Maple hide haft the Matrix ? The matrix is not completely symmetrical ie the absolute value it
might be symmetrical but in simple value terms it is not there are -1 and +1 differences...humm 
Does there exist any other way to force Maple to display the entite Matrix ?

I must say that I am a bit disappointed with the "increase" in speed
I ran the old algorithm ( located in the beginning of this post. I did a slight correction the add section 
should be divided by n to get the expected value) for 150 simulated stocks and it took 66 seconds.
I now ran the compiled version ( see below) and it took 63 seconds, ha ha. An improvement of 3 seconds :-(
The compiled version does not even sort the result which by it self probably takes 3 seconds.
So I have some follow up questions: 1) Can I increase the speed further. 2) How can I incorporate
a sorting function in the compiled version ( sorting column 3 in decending order) 3) Is it possible
to define an Array initially (in compiled version) without specifying dimensions. Now I have got many
rows that have 0 because the loop exist ( to save time. No need to save insignificant values) before
values are assign or can I remove these lines with zeros to save resources ?


restart:
with(Statistics):
with(LinearAlgebra):
with(combinat):

nstock := 150:
n := 100:

StockReturn := Transpose(Matrix(`<,>`(seq(Sample(RandomVariable(Normal(0, 1)), n), i = 1 .. nstock)))):

per := permute(nstock, 2):
nper := numbperm(nstock, 2):

A := Array(1 .. nper, 1 .. 3, datatype = float[8]):

Sharpe := proc (A) local i, ap1, r, Xmean, ap2, Xstdev, SH; option autocompile;

for i to nper do

ap1 := 0.; for r to n do ap1 := ap1+StockReturn[r, per[i][1]]-StockReturn[r, per[i][2]] end do:
Xmean := ap1/n;

if Xmean < 0 then next end if :

ap2 := 0.; for r to n do ap2 := ap2+(StockReturn[r, per[i][1]]-StockReturn[r, per[i][2]]-Xmean)^2 end do:
Xstdev := sqrt(ap2/(n-1)):

SH := Xmean/Xstdev:

if SH < 0 then next end if :

A[i, 1] := per[i][1] :
A[i, 2] := -per[i][2] :
A[i, 3] := SH :

end do:

return A ;

end proc:



Sharpe(A);

 

I am already struggeling here. I am trying to make a procedure based upon your code
for expected value but I dont know how to get nops(X) which I cant use because it
can not be compiled humm....

restart:
with(Statistics):

X := Sample(RandomVariable(Normal(0, 1)), 30):

XMean := proc (X::Vector) local ap, i;

ap := 0.; for i in X do ap := ap+i end do;

ap /  ????????????????????????

end proc:

XMean(X);
Mean(X);
 

all right thank acer. I will try to follow your instructions.
I could probably solve expected return but StandardDeviations was one of
those things I was expecting to have a problem with in the compiled procedure.
If you have any time or if you come up with any working version feel free to post it
because it most likely is going to take a while for me :-)

humm ok thanx but the problem is that I first have to call FileTools[ModificationTime] and see
if the file was updated and if it was updated then I have to call readdata to get the updated data .
I could write a procedure that does this for me but the problem with that is that it will keep
the comand prompt bussy. I just hate that you can not seem to do many things simultaneously
in Maple. You could have different thread but they cannot communicate back there finds
to the GUI user until the thread has ended ...hummm. This dynamically updated Matrix form
a txt file would be very nice if I could have access to the command prompt while it is doing that.

ok thanx . I did it this way instead it seems to work :-)

files := FileTools:-ListDirectory("C:\\MetaStock\\FX", 'returnonly' = "*.TXT");
seq(Matrix(readdata(cat("C:\\MetaStock\\FX\\", files[i]), [string, string, float])), i = 1 .. 3);
 

The problem I am having now is that you code correctly list the name of the TXT files in the folder but it wont read them

restart:
with(FileTools):
files := ListDirectory("C:\\MetaStock\\FX", 'returnonly' = "*.TXT");
for file in files do readdata file end do;

files:=["AUDCAD.TXT", "AUDCHF.TXT" .........]

Error, invalid terms in product

 

However, when I use the below code then I can read one file and the data is correctly displayed

readdata("C:\\MetaStock\\FX\\AUDCAD.TXT", [string, string, float]);
 

[["21/07/06", "AUDCAD", 0.86], ["24/07/06", "AUDCAD", 0.86].........]  

why do I get :

Error, ReadDirectory is not a command in the FileTools package
Error, unable to read `files`
 

Yes, this Wget thing seams interesting. I wonder if you can call Wget from inside Maple.
For example have a matrix with ticker symbols in Maple and then tell Wget to download
historical close for these securities, name the different files with corresponding ticker symbol,
and save the txt file in some folder on the hardrive and then if you want to plot any of these securities
Maple can simply load the txt file....hummm

Thank you Doug :-)   Your input is worth a million $$ and I get it for free under 30 min.
It makes me very happy :-) I like the TextArea example. That did exactly what I wanted.
The MathContainer was ok but it is still in a Matrix but it does not matter because the
TextArea did the trick. Again thanx for your input.

@ Axel Vogt to my understanding is very skilled when it comes to writting DLL's (which I still dont know really what it is) .
Maybe a dll file would be appropriate here. Is it possible to create a super efficient function in c that extract
and stores these closing prices for 1000 + stocks in a file on the harddrive which can be read by Maple ?!


I have designed a cute little thing in Maple where you first click on the button to download all the stock names

( takes 5-8 second).  Then you can select in the listbox the index name which will give you all the corresponding

stock in the ComboBox which is very fast since all downloads are done in the button.

 

View 8342_AAmmAA.mw on MapleNet or Download 8342_AAmmAA.mw
View file details

Now everything would be perfect if I could access the data as quickly as well which unfortunately is not the case.

I wrote this StockImport procedure

 


StockImport := proc (ticker, Start, End, Step) local Data, toMatrix; 

Data := proc () local startYear, startMonth, startDay, endYear, 
endMonth, endDay, timeStep, sid, str, b, Ap; 

startYear := parse(Start[1 .. 4]); startMonth := parse(Start[5 .. 6]); 
startDay := parse(Start[7 .. 8]); endYear := parse(End[1 .. 4]); 
endMonth := parse(End[5 .. 6]); endDay := parse(End[7 .. 8]); 

timeStep := Step; sid := Sockets:-Open("ichart.yahoo.com", 80); 

Sockets:-Write(sid, cat("GET /table.csv?s=", ticker, "&a=", startMonth-1, "&b=", 
startDay, "&c=", startYear, "&d=", endMonth-1, "&e=", endDay, "&f=", 
endYear, "&g=", timeStep, "&ignore=.csv HTTP/1.0 \n\n")); 

str := ""; b := Sockets:-Read(sid); while b <> false do str := cat(str, b); 
b := Sockets:-Read(sid) end do; 

Sockets:-Close(sid); return str end proc; 

toMatrix := proc (S::string) local s, m, hdr, id, body; 

s := StringTools:-SubString(S, StringTools:-SearchAll("Date", S)[2] .. -2); 
s := StringTools:-Split(s, "\n\f"); 
s := map(StringTools:-Split, s, ","); 

m := Matrix(s); hdr := map(convert, m[1, () .. ()], name); 
id := map(convert, m[2 .. (), 1], name); 

body := map(parse, m[2 .. (), 2 .. ()]); 

return `<,>`(hdr, `<|>`(id, body)) end proc; 

toMatrix(Data(ticker, Start, End, Step)) 

end proc;

StockImport("AA", "20050101", "20090825", "m");




Which works very well when we have a small number of stocks.

Now the thing is that some of these indexes have over 1000 stock in them. So I would like to find

a very efficient and fast way that I can download closing prices in one call for 1000 + stocks and

store such a data in Maple / MySQL database / or maybe in text file on the hard drive for quick access.


Then when you click on a button the data is updated only with the newest observations etc.


I could simply load the data in Maple as a csv file but it is boring. It would be much cooler if I could download and

access the data directly in Maple because it would open up many nice applications.
I have tried creating many

separate threads as seen below but it is still extremly slow. Any suggestions ?

 



with(Threads):

Create(StockImport("AA", "20050101", "20090825", "m"));

Create(StockImport("AAPL", "20050101", "20090825", "m"));

Does there exist a better way to do this ?  Maximum likelihood ?

The mean for an AR(1) is given by:    mu = c/(1-phi);

and the variance is given by :    var = sigma^2/(1-phi^2);

We could simply substitute in that in the pdf for the normal distribution and then derive the conditional distribution

and then apply MLH in some way...?

finmath.uchicago.edu/new/msfm/current/Time%20Series%202.pdf


thank you acer !

Matrix(5, 5, (i,j)->`if`(i=j,1,9));

did the trick :-)

4 5 6 7 8 9 10 Last Page 6 of 24