/ Take the file index values and convert it so / spindex.date: () / spindex.sp100: () / spindex.sp500: () / Then take the option values and convert them to / option.symb: () / option.delivery: () / option.put_call: () / option.strike: () / option.date: () / option.close: () / option.high: () / option.low: () / option.vol: () / option.openint:() / BASIC ROUTINES lets: ")(ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" nums: "0123456789" round100:{[x] (_ 0.5 + (100*x)) % 100} spit:{[line] (-2) _ ,/ ($line) ,\: (", ")} elimcomma:{[s] i: & ~ s = "," :s[i] } / parses a field based on vertical bars getfields:{[line] i: line = " " j1: &i j2: &~i line @:j2 size: #j1 :(0,(j1 - !size)) _ line } / parses a field based on vertical bars getfieldscomma:{[line] i: line = "," j1: &i j2: &~i line @:j2 size: #j1 :(0,(j1 - !size)) _ line } / get rid of blanks at either end of the string delendblanks:{[string] if[0 = #string; :""] if[string ~ ,"" ; :""] i: & ~ string = " " if[(#string) = (#i); :string] if[0 = (#i); :""] string: (- ((#string) - (1 + *|i))) _ string :(*i) _ string } / find difference between list[0] and list[1] listdiff:{[list] :differ[list[0]; list[1]] } / returns one if x is a subset of y subset:{[x; y] i: y ?/: x : ~ (#y) _in i } / returns one if x is a subset of y subset:{[x;y] (#y) > |/ y ?/: x} differ:{[x;y] x,: () y,: () i: y ?/: x j: & i = #y :?x[j] } / A faster difference, yielding indexes in x that differ from y differindexes:{[x;y] i: y ?/: x j: & i = #y :j } /finds intersection of two lists / fastest of all intersect: {[x;y] x,: () y,: () i: x ?/: y :x[(?i) _dv #x] } /finds intersection of two lists / fastest of all intersect: {[x;y] x,: () y,: () if[(#x) < (#y) i: x ?/: y j: & i < #x :x[?i[j]] ] i: y ?/: x j: & i < #y :y[?i[j]] } /finds intersection of two lists / fastest of all hasintersect: {[x;y] x,: () y,: () i: x ?/: y : (&/i) < #x } / x is a proper subset of y propersubset:{[x;y] x,: () y,: () if[~ (#x) < (#y); :0] / must be smaller :(#x) = (#intersect[x;y]) } / x is a proper subset of y propersubset:{[x;y] x,: () y,: () if[~ (#x) < (#y); :0] / must be smaller :subset[x;y] } /finds indexes in x and y that intersect / If x and y are both sets, then the results will be of the same length / fastest of all intersectindexes: {[x;y] i: x ?/: y / where each y hits j: & i < #x / those ys that hit :(i[j];j) } /finds indexes in x that intersect with y intersectleftindexes: {[x;y] i: x ?/: y / where each y hits j: & i < #x / those ys that hit :i[j] } /finds intersection of two lists / and returns index pairs of matches. Assumes no duplicates / in either list intersectbothindexes: {[x;y] x,: () y,: () i: x ?/: y pairs: (i ,' (!#y)) k: & pairs[;0] < #x :pairs[k] } / finds intersection of two lists that may have duplicates bagintersectbothindexes:{[x;y] alreadyused: out: () i: 0 while[i < #x my: x[i] jj: & y ~\: my jj: differ[jj; alreadyused] if[0 < #jj out,: ,(i;*jj) alreadyused,: *jj ] i+: 1 ] :out } / intersect many lists multiintersect:{[lists] size: #lists if[2 > size; :lists] first: lists[0],() jj: ,/ ?:' first (?/:)/: lists[1+ !(size-1)] / find indexes in first x: @[(1+#first) # 0; jj; + ; 1] x: (-1) _ x / delete missing entry kk: & x = size - 1 :first[kk] } / this is a set intersection so we remove duplicates multiintersect:{[lists] size: #lists if[2 > size; :lists] first: lists[0],() jj: first ?/: (,/ ?:' lists[1+ !(size-1)]) / find indexes in first x: @[(1+#first) # 0; jj; + ; 1] x: (-1) _ x / delete missing entry kk: & x = size - 1 :first[kk] } crossprod:{[listoflists] out: listoflists[0],() i: 1 while[i < #listoflists out: ,/ out ,/:\: (listoflists[i],()) i+: 1 ] :out } avg:{(+/ x) % # x} var:{avg[_sqr x] - _sqr avg[x]} std:{_sqrt var[x]} cov:{avg[x * y] - avg[x] * avg[y]} corr:{ (cov[x;y])%((std[x]) * (std[y]))} / delay based search corrdelay:{[delay;x;y] x: (-delay) _ x y: delay _ y (cov[x;y])%((std[x]) * (std[y]))} / want a line of the form y = bx + a regress:{[x;y] ay: avg y ax: avg x xy_sp: +/(x - ax)*(y - ay) x_ss: +/((x - ax)^2) b: xy_sp % x_ss a: ay - (b*ax) :(b;a) } / END BASICS / DUMP TABLE dumptable / formstring takes a list and makes a string formstring:{[list] list,: () : (-1) _ ,/ ($list) ,\: (" ") } formstringvertbar:{[list] list,: () : (-1) _ ,/ ($list) ,\: ("|") } formstringcomma:{[list] list,: () : (-1) _ ,/ ($list) ,\: (",") } dumptablecsv:{[tablename; table; outfile] out: , formstringcomma[!table] first: *!table numofelements: . ("#"), ($tablename), ("."), ($first) i: 0 while[i < numofelements list: table[;i] x: formstring'list out,: , (-1) _ ,/x ,\: (",") i+: 1 ] outfile 0: out } / Output a table (a variable) to a text file outfile (string) / e.g. output[`guide; guide; "foobar"] dumptable:{[tablename; table; outfile] out: ,("# "), ($tablename), ("|"), formstringvertbar[!table] first: *!table numofelements: . ("#"), ($tablename), ("."), ($first) i: 0 while[i < numofelements list: table[;i] x: formstring'list / out,: , ($x[0]), (": "), (-1) _ ,/(1 _ x) ,\: (" ") out,: , (-1) _ ,/(x) ,\: (",") i+: 1 ] outfile 0: out } dumpmatcsv:{[mat; outfile] if[`disregard _in mat[0] mat: (-1) _' mat ] othernums: 1 _ !#mat[;0] i: 1 while[i < #mat[;0] mat[i]: (` $ $ i),mat[i] i+: 1 ] mat[0]: (`num), mat[0] out: , formstringcomma[mat[0]] / first: *!table numofelements: #mat[;0] i: 1 while[i < numofelements list: mat[i] x: formstring'list out,: , (-1) _ ,/x ,\: (",") i+: 1 ] outfile 0: out } permdetail:{[list] if[1 = #list; :list[0]] out: () i: 0 while[i < #list out,: ,list[i],/: perm[list _di i] i+: 1 ] :out } / get all permutations of a list perm:{[list] x: permdetail[list] :,/x } / APPLICATIONS parseindexval:{[line] x: getfieldscomma[line] :( ( 0 $ x[0]); (0.0 $ x[1]); (0.0 $ x[2])) } delivery: -1 type: `nothing strike: -1 convert:{[string] if[string ~ "Jan"; :"01"] if[string ~ "Feb"; :"02"] if[string ~ "Mar"; :"03"] if[string ~ "Apr"; :"04"] if[string ~ "May"; :"05"] if[string ~ "Jun"; :"06"] if[string ~ "Jul"; :"07"] if[string ~ "Aug"; :"08"] if[string ~ "Sep"; :"09"] if[string ~ "Oct"; :"10"] if[string ~ "Nov"; :"11"] if[string ~ "Dec"; :"12"] !-11 } / find day of month from a field of the form (SPX1017G525-E) / That would give a 17 for the day of the month findday:{[field] :[7 < #field; 0 $ field[6 + !2]; 0]} findday:{[field] if[(weeklyflag = 1) & ((field _sm "*SPXW*") | (field _sm "*GLDW*")); :0 $ field[7 + !2]] if[7 > #field; :0] i: 0 seeingletters: 1 while[seeingletters = 1; if[~ field[i] _in lets seeingletters: 0 ] i+:1 ] x: "" while[field[i] _in nums; x,: field[i] i+: 1 ] y: 0 $ field[(i-2) + !2] d: *1 _draw 1000 :y } / how many days back is currentdate from settlement date finddaysback:{[deliveryyearmonth; deliveryday; currentdate] endday: deliveryday x: $deliveryyearmonth endyear: 0 $ x[!4] endmon: 0 $ x[4+!2] x: $ currentdate beginday: 0 $ 6 _ x beginyear: 0 $ x[!4] beginmon: 0 $ x[4+!2] if[endyear > beginyear; :(endyear-beginyear) * 365] / it's too big if[endmon > (beginmon+1); :(endmon-beginmon) * 30] / it's still too big if[endmon = beginmon; :endday - beginday] daysinprevmonth: daysinmonth[beginyear; beginmon] :(daysinprevmonth + endday) - beginday } / just give back the last lines currentyear:{[year;lines] done: 0 i: 0 while[(i < #lines) & (done = 0) if[((lines[i]) _sm "*@*") if[((lines[i]) _sm ("*"), ($year-3), ("*")) done: 1 ] if[((lines[i]) _sm ("*"), ($year-2), ("*")) done: 1 ] if[((lines[i]) _sm ("*"), ($year-1), ("*")) done: 1 ] if[((lines[i]) _sm ("*"), ($year), ("*")) done: 1 ] if[((lines[i]) _sm ("*"), ($year+1), ("*")) done: 1 ] if[((lines[i]) _sm ("*"), ($year+2), ("*")) done: 1 ] ] i+: 1 ] :(i-1) _ lines } / This is for cboe stuff / xeoflag if an xeo file / fractionshort = 1 means you assume that all openint is owned by someone other / than D. If fractionshort < 1, then you sell that fraction of openint, so / effectively others own 1-(fractionshort). parsesptxt:{[year; xeoflag; fractionshort; myalllines] if[year > 0; alllines: currentyear[year; myalllines] ] if[year = 0; alllines: myalllines ] i: 0 while[i < #alllines myline: alllines[i] done: 0 if[(myline _sm "SPX*") | (myline _sm "OEX*") | (myline _sm "XEO*") | (myline _sm "VIX*") | (myline _sm "VXX*") | (myline _sm "GLD*") done: 1 x: getfieldscomma[alllines[i]] price: 0.0 $ x[1] ] if[(myline _sm "*@*") & (done = 0) done: 1 x: getfields[alllines[i]] date: 0 $ x[2], convert[x[0]], x[1] spindex.date,: date spindex.sp100,: price spindex.sp500,: price ] if[(0 < # myline) & (done = 0) done: 1 / for vxx, we want to avoid VXX1418J38.5-X lines with dashes if[(((myline _sm "*(VXX*" ) & (~ myline _sm "*-?)*")) | (myline _sm "*(S*" )|(myline _sm "*(O*")|(myline _sm "*(X*" )|((myline _sm "*(VIX*")) & ((myline[0]) _in "01")) | ((myline _sm "*(GLD*")) / until 2019 and not weeklies / if[myline _sm "*SPXW*"; !-122] x: getfieldscomma[alllines[i]] option.symb,: `sp500 `sp500 / assuming spx y1: getfields[x[0]] if[(0 < #*y1) & (13 < #x) x1: 0 $ ("20"),y1[0],convert[y1[1]] option.delivery,: x1 x2: findday[y1[3]] option.dayofclose,: x2 if[x2 > 31; !-1222] option.put_call,: `call option.strike,: 0.0 $ y1[2] option.date,: date option.daystosettle,: finddaysback[x1; x2; date] xclose: avg[(0.0 $ x[4]), (0.0 $ x[3])] if[xclose = 0.0; xclose: 0.0 $ x[1]] / official last sale option.close,: xclose option.vol,: 0.0 $ x[5] if[xeoflag = 0 option.openint,: ((fractionshort)) * (0.0 $ x[6]) ] if[xeoflag = 1 xeocallopenint: 0.0 $ x[6] ] option.high,: 0.0 $ x[4] option.low,: 0.0 $ x[3] / if[myline _sm "*SPXW*"; !-123] ] y2: getfields[x[7]] if[(0 < #*y2) & (13 < #x) option.delivery,: 0 $ ("20"),y2[0],convert[y2[1]] option.dayofclose,: findday[y2[3]] option.put_call,: `put option.strike,: 0.0 $ y2[2] option.date,: date option.daystosettle,: finddaysback[x1; x2; date] xclose: avg[(0.0 $ x[11]),(0.0 $ x[10])] if[xclose = 0.0; xclose: 0.0 $ x[8]] / official last sale price option.close,: xclose option.vol,: 0.0 $ x[12] if[xeoflag = 0 option.openint,: ((fractionshort)) * (0.0 $ x[13]) ] if[xeoflag = 1 xeoputopenint: 0.0 $ x[13] xeomin: xeoputopenint & xeocallopenint option.openint,: xeomin option.openint,: -xeomin / long the puts; making the short / position negative / if[(485 = *|option.strike) & (200910 = *|option.delivery) & (20091002 = date); !-11] ] option.high,: 0.0 $ x[11] option.low,: 0.0 $ x[10] / if[myline _sm "*SPXW*"; !-124] ] ] ] i+: 1 ] } / takes leap years into account daysinmonth:{[year; mon] if[mon _in 1 3 5 7 8 10 12; :31] if[mon _in 4 6 9 11; :30] if[(year ! 4) = 0; :29] :28 } / find the price at a certain settlement date (aka / delivery date, maturity date). findprice:{[pair] yearmonth: pair[0] day: pair[1] daystring: :[day < 10; ("0"),($day); $day] mydate: 0 $ ($yearmonth),(daystring) i: spindex.date ? mydate if[i = #spindex.date; :0.0] :spindex.sp500[i] } / find the price at a certain settlement date (aka / delivery date, maturity date). findpricesimple:{[mydate] i: spindex.date ? mydate :spindex.sp500[i] } combinepair:{[pair] yearmonth: pair[0] day: pair[1] daystring: :[day < 10; ("0"),($day); $day] if[day > 31; !-111] mydate: 0 $ ($yearmonth),(daystring) :mydate } / number of days from begin to end diffdays:{[end; begin] x: $ end endday: 0 $ 6 _ x endyear: 0 $ x[!4] endmon: 0 $ x[4+!2] x: $ begin beginday: 0 $ 6 _ x beginyear: 0 $ x[!4] beginmon: 0 $ x[4+!2] if[endmon = beginmon; :endday - beginday] daysinprevmonth: daysinmonth[beginyear; beginmon] :(daysinprevmonth + endday) - beginday } / date comes in as an integer and goes out as one subtractdays:{[current; daystominus] x: $ current day: 0 $ 6 _ x year: 0 $ x[!4] mon: 0 $ x[4+!2] if[(day - daystominus) > 0 daystring: $ day - daystominus if[1 = #daystring; daystring: ("0"),daystring] :0 $ (x[!6]), daystring ] / day - daystominus is 0 or negative so go down one month if[mon = 1; newmon: 12; year-: 1] if[mon > 1; newmon: mon-1] day+: daysinmonth[year; newmon] / add last month's days mon: newmon while[~ (day - daystominus) > 0 if[mon = 1; newmon: 12; year-: 1] if[mon > 1; newmon: mon-1] mon: newmon day+: daysinmonth[year; mon] / add last month's days ] yearstring: $year monstring: :[mon < 10; ("0"),$newmon; $newmon] daystring: $ day - daystominus if[1 = #daystring; daystring: ("0"),daystring] :0 $ yearstring,monstring,daystring } / for 200712 get 200801 / increment month incmonth:{[current] x: $ current year: 0 $ x[!4] mon: 0 $ x[4+!2] if[mon < 12 newmon: mon+1 ] if[mon = 12 newmon: 1 year+: 1 ] monstring: :[newmon < 10; ("0"),$newmon; $newmon] yearstring: $year :0 $ yearstring,monstring } spitcolon:{[trip] ` $ ($trip[0]),(": "),($trip[1]), (" "), ($trip[2])} / for each put and call value, see its value today, yesterday, one week / and two weeks ago openintdirection:{[delivery] ii: & (option.delivery = delivery) putcall: option.put_call[ii] strike: option.strike[ii] date: option.date[ii] openint: option.openint[ii] vol: option.vol[ii] maxdate: |/date todayprice: spindex.sp500[spindex.date ? maxdate] alldates: maxdate alldates,: subtractdays[maxdate; 1] alldates,: subtractdays[maxdate; 3] alldates,: subtractdays[maxdate; 7] alldates,: subtractdays[maxdate; 10] alldates,: subtractdays[maxdate; 14] alldates,: subtractdays[maxdate; 21] alldates,: subtractdays[maxdate; 28] alldates,: subtractdays[maxdate; 35] alldates,: subtractdays[maxdate; 42] alldates,: subtractdays[maxdate; 49] alldates,: subtractdays[maxdate; 56] ii: & (date _lin alldates) & (strike > todayprice - 200) & (strike < todayprice + 200) putcall@: ii strike@: ii date@: ii openint@: ii vol@: ii part: = strike,'putcall,'date uniqs: ? strike,'putcall,'date uopenint: |/'openint[part] / there are some strange terms openint: uopenint uvol: |/'vol[part] vol: uvol strike: uniqs[;0] putcall: uniqs[;1] date: uniqs[;2] part: = strike,'putcall uniqs: ? strike,'putcall dateparts: date[part] openintparts: openint[part] volparts: vol[part] ii: < uniqs uniqs@: ii dateparts@: ii openintparts@: ii volparts@: ii out:, (`"Delivery month is: "),delivery i: 0 while[i < #uniqs dp: dateparts[i] oi: openintparts[i] vi: volparts[i] jj: < dp dp@: jj oi@: jj vi@: jj order: (*|oi); flag: `downoverall] if[(order ~ !#oi) & (1 < #?oi); flag: `upsteady] if[(order ~ |!#oi) & (1 < #?oi); flag: `downsteady] if[1 = #?oi; flag: `unchanged] x: spitcolon' dp,' oi,'vi if[(~ 0.0 _in oi) & (1 < #oi) out,: ,uniqs[i] , flag out,: ,:' x ] i+: 1 ] :out } / This finds the running average of buy and sell prices for each option. / "date, settledate, putoi, putvol, calloi, callvol, sp500price, deltaputoi, deltacalloi, deltasp500price" runningstats:{[tilldate; settledate] / march, june, september, december tripwitch: 0 mon: (-2) _ 4 _ ($settledate) if[mon _in ("03"; "06"; "09"; "12"); tripwitch: 1] delivery: _ settledate % 100 / this is the month of delivery zz: & (option.delivery = delivery) & (option.date < (1 + tilldate)) mydate: &/ option.date i: spindex.date _bin mydate if[spindex.date[i] > mydate; i: i-1] if[i < 0; i: 0] mydate: spindex.date[i] / i might have changed myprice: spindex.sp100[i] putcallall: option.put_call[zz] strikeall: option.strike[zz] openintall: option.openint[zz] volall: option.vol[zz] closeall: option.close[zz] dateall: option.date[zz] ii: < dateall putcallall@: ii strikeall@: ii openintall@: ii volall@: ii closeall@: ii dateall@: ii partall: = dateall uniqsall: ?dateall initialflag: 1 / start at mydate using min of putoi and calloi for each strike out: () / "date, settledate, putoi, calloi, sp500price, deltaputoi, deltacalloi, deltasp500price" i: 0 while[i < #uniqsall / for each date d: uniqsall[i] myprice: spindex.sp100[spindex.date ? d] putcall: putcallall[partall[i]] strike: strikeall[partall[i]] openint: openintall[partall[i]] vol: volall[partall[i]] close: closeall[partall[i]] ii: & putcall = `put totput: +/openint[ii] totputvol: +/vol[ii] ii: & putcall = `call totcall: +/openint[ii] totcallvol: +/vol[ii] out,: ,(d; settledate; totput; totputvol; totcall; totcallvol; myprice) i+: 1 ] extraputs: -': out[;2] extracalls: -': out[;4] extraprices: -': out[;6] :(1 _ out),'extraputs,'extracalls,'extraprices } / This finds the running average of buy and sell prices for each option. runningaverage:{[tilldate; settledate] / march, june, september, december tripwitch: 0 mon: (-2) _ 4 _ ($settledate) if[mon _in ("03"; "06"; "09"; "12"); tripwitch: 1] delivery: _ settledate % 100 / this is the month of delivery zz: & (option.delivery = delivery) & (option.date < (1 + tilldate)) mydate: &/ option.date i: spindex.date _bin mydate if[spindex.date[i] > mydate; i: i-1] if[i < 0; i: 0] mydate: spindex.date[i] / i might have changed myprice: spindex.sp100[i] putcallall: option.put_call[zz] strikeall: option.strike[zz] openintall: option.openint[zz] volall: option.vol[zz] closeall: option.close[zz] dateall: option.date[zz] ii: < dateall putcallall@: ii strikeall@: ii openintall@: ii volall@: ii closeall@: ii dateall@: ii partall: = dateall uniqsall: ?dateall initialflag: 1 / start at mydate using min of putoi and calloi for each strike strikecur: () / list of strikes putoicur: () / put open int for each strike calloicur: () / call open int for each strike stradcur: () / current straddle for each strike callbuyweightedcur: () / close * quantity callbuyquantitycur: () / quantity callsellweightedcur: () / close * quantity callsellquantitycur: () / quantity callvolcur: () callclosecur: () putbuyweightedcur: () / close * quantity putbuyquantitycur: () / quantity putsellweightedcur: () / close * quantity putsellquantitycur: () / quantity putvolcur: () putclosecur: () totstrads: () / total of straddles over the times out: () i: 0 while[i < #uniqsall / for each date d: uniqsall[i] putcall: putcallall[partall[i]] strike: strikeall[partall[i]] openint: openintall[partall[i]] vol: volall[partall[i]] close: closeall[partall[i]] part: = strike uniqs: ? strike / strikes can change; if new ones arise add them in totstrad: 0 j: 0 while[j < #part kk: part[j] s: uniqs[j] mput: & (putcall[kk]) = `put putoi: |/openint[kk[mput]] / change from +/ to |/ putvol: +/vol[kk[mput]] putclose: avg close[kk[mput]] mcall: & (putcall[kk]) = `call calloi: |/openint[kk[mcall]] callvol: +/vol[kk[mcall]] callclose: avg close[kk[mcall]] if[initialflag totstrad+: putoi & calloi strikecur,: s putoicur,: putoi putbuyweightedcur,: putoi * putclose putbuyquantitycur,: putoi / initial buy putsellweightedcur,: 0 putsellquantitycur,: 0 putvolcur,: putvol putclosecur,: putclose calloicur,: calloi callbuyweightedcur,: calloi * callclose callbuyquantitycur,: calloi / initial buy callsellweightedcur,: 0 callsellquantitycur,: 0 callvolcur,: callvol callclosecur,: callclose stradcur,: putoi & calloi / date, strike, settledate, put/call, openint, volume, close, / weighted buy price, quantity buy, weighted sell price, / quantity sell out,: ,(d; s; settledate; `put ; putoi; putvol; putclose; putclose; putoi; 0; 0) out,: ,(d; s; settledate; `call ; calloi; callvol; callclose; callclose; calloi; 0; 0) ] if[~ initialflag p: strikecur ? s if[p < #strikecur oldp: putoicur[p] / the old value of put open int deltap: putoi - oldp / the change in put oi oldclose: putclosecur[p] deltaclose: putclose - oldclose if[deltap > 0 / have bought x: (oldclose + (deltaclose % 2)) * deltap putbuyweightedcur[p]+: x putbuyquantitycur[p]+: deltap ] if[deltap < 0 / have sold x: (oldclose + (deltaclose % 2)) * (- deltap) putsellweightedcur[p]+: x putsellquantitycur[p]+: -deltap ] / date, strike, settledate, put/call, openint, volume, close, / weighted buy price, quantity buy, weighted sell price, / quantity sell out,: ,(d; s; settledate; `put ; putoi; putvol; putclose; round100 (putbuyweightedcur[p]) % putbuyquantitycur[p]; putbuyquantitycur[p]; round100 (putsellweightedcur[p]) % putsellquantitycur[p]; putsellquantitycur[p]) oldc: calloicur[p] deltac: calloi - oldc / change in calloi oldclose: callclosecur[p] deltaclose: callclose - oldclose if[deltac > 0 / have bought x: (oldclose + (deltaclose % 2)) * deltac callbuyweightedcur[p]+: x callbuyquantitycur[p]+: deltac ] if[deltac < 0 / have sold x: (oldclose + (deltaclose % 2)) * (- deltac) callsellweightedcur[p]+: x callsellquantitycur[p]+: -deltac ] putclosecur[p]: putclose callclosecur[p]: callclose ceil: putoi & calloi / can't go above this putoicur[p]: putoi putclosecur[p]: putclose callclosecur[p]: callclose calloicur[p]: calloi if[(deltap < 0) | (deltac < 0) stradcur[p]&: ceil totstrad+: stradcur[p] ] if[~ ((deltap < 0) | (deltac < 0)) / at least 0 stradcur[p]+: deltap & deltac totstrad+: stradcur[p] ] out,: ,(d; s; settledate; `call ; calloi; callvol; callclose; round100 (callbuyweightedcur[p]) % callbuyquantitycur[p]; callbuyquantitycur[p]; round100 (callsellweightedcur[p]) % callsellquantitycur[p]; callsellquantitycur[p]) ] if[p = #strikecur totstrad+: putoi & calloi strikecur,: s putoicur,: putoi putbuyweightedcur,: putoi * putclose putbuyquantitycur,: putoi / initial buy putsellweightedcur,: 0 putsellquantitycur,: 0 putvolcur,: putvol putclosecur,: putclose calloicur,: calloi callbuyweightedcur,: calloi * callclose callbuyquantitycur,: calloi / initial buy callsellweightedcur,: 0 callsellquantitycur,: 0 callvolcur,: callvol callclosecur,: callclose stradcur,: (putoi & calloi) out,: ,(d; s; settledate; `put ; putoi; putvol; putclose; putclose; putoi; 0; 0) out,: ,(d; s; settledate; `call ; calloi; callvol; callclose; callclose; calloi; 0; 0) ] ] j+: 1 ] totstrads,: totstrad initialflag: 0 / no longer at the beginning i+: 1 ] :out } / Look at this particular date / Find straddles and take minimum. / Double contribution of multiples of 25 if flag25 = 1 stradondate:{[mydate; settledate] / march, june, september, december tripwitch: 0 mon: (-2) _ 4 _ ($settledate) if[mon _in ("03"; "06"; "09"; "12"); tripwitch: 1] i: spindex.date _bin mydate if[spindex.date[i] > mydate; i: i-1] if[i < 0; i: 0] mydate: spindex.date[i] / i might have changed myprice: spindex.sp100[i] out: () delivery: _ settledate % 100 / this is the month of delivery zz: & (option.delivery = delivery) & (option.date = mydate) closeprice: option.close[zz] putcall: option.put_call[zz] strike: option.strike[zz] openint: option.openint[zz] part: = strike uniqs: ? strike totstrad: 0 stradlist: () j: 0 while[j < #part kk: part[j] mput: & (putcall[kk]) = `put putoi: +/openint[kk[mput]] mcall: & (putcall[kk]) = `call calloi: +/openint[kk[mcall]] totstrad+: putoi & calloi if[flag25 & (0 = ((s) ! 25)) totstrad+: putoi & calloi ] stradlist,: ,settledate, mydate, (uniqs[j]),(putoi & calloi) j+: 1 ] x:(settledate; tripwitch; mydate; totstrad) :(x; stradlist) } / Look at this number of days out. / Find straddles and take minimum. / Double contribution of multiples of 25. / See max dip, max up, settleprice all related to current price. stradcompute:{[numdays; settledate; settleprice] mydate: subtractdays[settledate;numdays] / march, june, september, december tripwitch: 0 mon: (-2) _ 4 _ ($settledate) if[mon _in ("03"; "06"; "09"; "12"); tripwitch: 1] i: spindex.date _bin mydate if[spindex.date[i] > mydate; i: i-1] if[i < 0; i: 0] mydate: spindex.date[i] / i might have changed myprice: spindex.sp100[i] j: spindex.date _bin settledate pricesinbetween: spindex.sp100[i+1+!(j-(i+1))] / e.g. i = 5, j = 9; this would give 6 + !3 or 6, 7, 8 maxbetween: |/pricesinbetween minbetween: &/pricesinbetween out: () delivery: _ settledate % 100 / this is the month of delivery zz: & (option.delivery = delivery) & (option.date = mydate) closeprice: option.close[zz] putcall: option.put_call[zz] strike: option.strike[zz] openint: option.openint[zz] part: = strike uniqs: ? strike totstrad: 0 stradlist: () j: 0 while[j < #part kk: part[j] mput: & (putcall[kk]) = `put putoi: +/openint[kk[mput]] mcall: & (putcall[kk]) = `call calloi: +/openint[kk[mcall]] totstrad+: putoi & calloi stradlist,: ,(uniqs[j]),(putoi & calloi) j+: 1 ] x:(settledate; tripwitch; numdays; myprice; maxbetween-myprice) x,: minbetween-myprice x,: settleprice-myprice x,: totstrad :x } / find openint of inmoney puts and calls findinmoney:{[mydate; market; runav] ii: & (mydate = runav[;0] ) & (market < runav[;1]) & ((`put) = runav[;3]) openintinmoney: +/runav[ii;4] ii: & (mydate = runav[;0] ) & (market > runav[;1]) & ((`call) = runav[;3]) openintinmoney+: +/runav[ii;4] :openintinmoney } / find total married oi vs. vol findmarriedovervol:{[mydate; runavall] ii: & mydate = runavall[;0] runav: runavall[ii] totvol: +/ runav[;5] part: = runav[;1] totmarried: 0 i: 0 while[i < #part myrun: runav[part[i]] myputoi: +/myrun[(& `put = myrun[;3]);4] mycalloi: +/myrun[(& `call = myrun[;3]);4] totmarried+: myputoi & mycalloi i+: 1 ] :(totmarried; totvol) } / runav is the result of the running average / x-axisdel is the number of the increase in OI of the in-the-money side, / y-axisdel is the %Increase in OI/Volume of marrieds. / z-axisdel is the delta of the index marriedanal:{[runavall; settledate] ii: & runavall[;2] = settledate runav: runavall[ii] mindate: &/runav[;0] prices: spindex.sp500[& spindex.date > (mindate - 1)] dates: spindex.date[& spindex.date > (mindate - 1)] part: = runav[;0] uniqdates: ?runav[;0] jj: < uniqdates part@: jj uniqdates@: jj xaxis: () yaxis: () zaxis: () i: 0 while[i < #uniqdates market: spindex.sp500[spindex.date ? uniqdates[i]] pair: findmarriedovervol[uniqdates[i]; runav] if[0 < pair[1] yaxis,: pair[0] % pair[1] xaxis,: findinmoney[uniqdates[i]; market; runav] zaxis,: market ] if[0 & 0 = pair[1] ` 0: ,("date is: "), $uniqdates[i] ] i+: 1 ] xaxisdel: -': xaxis yaxisdel: -': yaxis zaxisdel: -': zaxis :(xaxisdel,' yaxisdel,' zaxisdel) } / check that a strategy of selling call at 14 day out price / and buying at market 7 days out / when price has gone up by numpoints / works well. / premiumprofit -- of selling expensive call / and netprofits -- net profit given settle date price updownstratcall:{[settledate;originalback; newback; numpoints; buyoptionflag] mindelivery: settledate / get all recent days based on originalback mydate: subtractdays[mindelivery; originalback] ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.put_call = `call) numback: originalback while[(0 = #ii) & (numback < 2 * originalback) mydate: subtractdays[mydate; 1] ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.put_call = `call) numback+: 1 ] if[(0 = #ii); !-113] k: (spindex.date _bin mydate) originalindexprice: spindex.sp500[k] / price when we start / now for later date mydatenew: subtractdays[mindelivery; newback] iinew: & (option.date = mydatenew) & (option.delivery = _ mindelivery % 100) & (option.put_call = `call) numback: newback while[(0 = #iinew) & (numback < 2 * newback) mydatenew: subtractdays[mydate; 1] iinew: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.put_call = `call) numback+: 1 ] if[(0 = #iinew); !-114] k: (spindex.date _bin mydatenew) newindexprice: spindex.sp500[k] / price when we start if[newindexprice < (originalindexprice + numpoints);:()] / no bet / now we have a straddlebet if[(_ mindelivery % 100) > 200911 ii: & (option.date = mydatenew) & (option.delivery = _ mindelivery % 100) & (option.dayofclose = mindelivery ! 100) & (option.put_call = `call) ] closeprice: option.close[ii] strike: option.strike[ii] / now buy the call options at newindexprice and sell / the options at originalindexprice / sort the options by strike jj: < strike strike@: jj closeprice@: jj k1: strike _bin newindexprice k2: strike _bin originalindexprice if[1 = buyoptionflag mypremiumprofit: closeprice[k2] - closeprice[k1] / sell at original and buy at new ] if[0 = buyoptionflag mypremiumprofit: closeprice[k2] / sell at original price and buy nothing ] k: (spindex.date _bin mindelivery) - 1 settleprice: spindex.sp500[k] ` 0: ,("Settledate: "), ($ mindelivery) ` 0: ,("At settlement price is $"), ($ settleprice) myprofit: mypremiumprofit if[(1 = buyoptionflag) & (settleprice > strike[k1]) myprofit+: settleprice - strike[k1] / we bought these calls ] if[settleprice > strike[k2] myprofit-: settleprice - strike[k2] / we sold these ] settledates,: mindelivery settleprices,: settleprice highstrikes,: strike[k1] lowstrikes,: strike[k2] premiumprofit,: mypremiumprofit netprofits,: myprofit } / check that a strategy of buying put at market and then selling / it at price when originalback is a good idea / side effect to: / premiumprofit -- cost of buying expensive put and selling cheap one / and netprofits -- net profit given settle date updownstratput:{[settledate;originalback; newback; numpoints; buyoptionflag] mindelivery: settledate / get all recent days based on originalback mydate: subtractdays[mindelivery; originalback] ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.put_call = `put) numback: originalback while[(0 = #ii) & (numback < 2 * originalback) mydate: subtractdays[mydate; 1] ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.put_call = `put) numback+: 1 ] if[(0 = #ii); !-113] k: (spindex.date _bin mydate) originalindexprice: spindex.sp500[k] / price when we start / now for later date mydatenew: subtractdays[mindelivery; newback] iinew: & (option.date = mydatenew) & (option.delivery = _ mindelivery % 100) & (option.put_call = `put) numback: newback while[(0 = #iinew) & (numback < 2 * newback) mydatenew: subtractdays[mydate; 1] iinew: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.put_call = `put) numback+: 1 ] if[(0 = #iinew); !-114] k: (spindex.date _bin mydatenew) newindexprice: spindex.sp500[k] / price when we start if[newindexprice < (originalindexprice + numpoints);:()] / no bet / now we have a straddlebet if[(_ mindelivery % 100) > 200911 ii: & (option.date = mydatenew) & (option.delivery = _ mindelivery % 100) & (option.dayofclose = mindelivery ! 100) & (option.put_call = `put) ] closeprice: option.close[ii] strike: option.strike[ii] / now buy the options at newindexprice and sell / the options at originalindexprice jj: < strike strike@: jj closeprice@: jj k1: strike _bin newindexprice k2: strike _bin originalindexprice if[1 = buyoptionflag mypremiumprofit: closeprice[k2] - closeprice[k1] / sell at original and buy at new ] if[0 = buyoptionflag mypremiumprofit: closeprice[k2] / sell at original and buy nothing ] / sort the options by strike k: (spindex.date _bin mindelivery) - 1 settleprice: spindex.sp500[k] ` 0: ,("Settledate: "), ($ mindelivery) ` 0: ,("At settlement price is $"), ($ settleprice) myprofit: mypremiumprofit if[(1 = buyoptionflag) & (settleprice < strike[k1]) myprofit+: strike[k1] - settleprice / we bought these ] if[settleprice < strike[k2] myprofit-: strike[k2] - settleprice / we sold these ] settledates,: mindelivery settleprices,: settleprice highstrikes,: strike[k1] lowstrikes,: strike[k2] premiumprofit,: mypremiumprofit netprofits,: myprofit } / check that a put two weeks out is still good to sell / and that if the optimal says price should be substantially higher / than it is, then it will be backtest:{[settledate; daysback] mindelivery: settledate / get all recent days mydate: subtractdays[mindelivery; daysback] ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.put_call = `put) if[0 = #ii mydate: subtractdays[mydate; 1] ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.put_call = `put) ] if[0 = #ii mydate: subtractdays[mydate; 1] ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.put_call = `put) ] if[0 = #ii mydate: subtractdays[mydate; 1] ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.put_call = `put) ] if[0 = #ii mydate: subtractdays[mydate; 1] ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.put_call = `put) ] if[0 = #ii mydate: subtractdays[mydate; 1] ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.put_call = `put) ] if[(_ mindelivery % 100) > 200911 ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.dayofclose = mindelivery ! 100) & (option.put_call = `put) ] closeprice: option.close[ii] strike: option.strike[ii] / sort the options by strike x: _abs[closeprice - 7] mindiff: &/x k: (spindex.date _bin mindelivery) - 1 j: * & x = mindiff ` 0: ,("Settledate: "), ($ mindelivery) ` 0: ,("Sell puts at: "), ($ strike[j]), (" for $"), ($closeprice[j]) ` 0: ,("At settlement price is $"), ($ spindex.sp500[k]) profit: closeprice[j] if[spindex.sp500[k] < strike[j] profit-: strike[j] - spindex.sp500[k] ] ` 0: ,("Profit is $"), ($ profit) allprofits,: profit totalprofit+: profit } / check that a put two weeks out is still good to sell / and that if the optimal says price should be substantially higher / than it is, then it will be backtestweek:{[settledate; daysback] mindelivery: settledate / get all recent days mydate: subtractdays[mindelivery; daysback] ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.put_call = `put) if[0 = #ii mydate: subtractdays[mydate; 1] ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.put_call = `put) ] if[0 = #ii mydate: subtractdays[mydate; 1] ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.put_call = `put) ] if[0 = #ii mydate: subtractdays[mydate; 1] ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.put_call = `put) ] if[0 = #ii mydate: subtractdays[mydate; 1] ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.put_call = `put) ] if[0 = #ii mydate: subtractdays[mydate; 1] ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.put_call = `put) ] if[(_ mindelivery % 100) > 200911 ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.dayofclose = mindelivery ! 100) & (option.put_call = `put) ] closeprice: option.close[ii] strike: option.strike[ii] myprice: spindex.sp500[spindex.date ? mydate] pair: giveresults[mydate; _ mindelivery % 100; mindelivery ! 100; myprice] out: pair[0] jjj: () if[0 < # pair[1]; allout: *:'pair[1] / strike and openint diff jjj: & allout[;1] > 8000 m: 0 if[0 < #jjj; m: |/ allout[jjj;0] j: allout[jjj;0] ? m if[(myprice - m) < 100; ` 0: ,("Highest strike that has 8,000 difference is: "), ($m), (" relative to price: "), ($myprice) ] if[(myprice - m) > 100; ` 0: ,("Highest strike that has 8,000 difference IS TOO LOW: "), ($m), (" relative to price: "), ($myprice) ] ] ] if[ (0 = #pair[1]) | (0 = #jjj) / This is based on the price of the option x: _abs[closeprice - 7] mindiff: &/x j: * & x = mindiff ` 0: ,("$7 dollar option") ] k: (spindex.date _bin mindelivery) ` 0: ,("Settledate: "), ($ mindelivery) ` 0: ,("Date of transaction: "), ($ mydate) ` 0: ,("Sell puts at: "), ($ strike[j]), (" for $"), ($closeprice[j]) ` 0: ,("At settlement price is $"), ($ spindex.sp500[k]) profit: closeprice[j] if[spindex.sp500[k] < strike[j] profit-: strike[j] - spindex.sp500[k] ] ` 0: ,("Profit is $"), ($ profit) ` 0: ,("Current price is $"), ($ myprice) allprofits,: profit totalprofit+: profit } / check that buying a deep out of the money put may be a good idea blackswan:{[settledate] out: ," " mindelivery: settledate k: spindex.date ? mindelivery while[k = #spindex.date mindelivery: subtractdays[mindelivery;1] k: spindex.date ? mindelivery ] out,: ,("Settledate: "), ($ mindelivery) mydate: subtractdays[mindelivery; 28] / one month out / now compute optimal price ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) while[0 = #ii mydate: subtractdays[mydate;1] ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) ] if[(_ mindelivery % 100) > 200911 ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.dayofclose = mindelivery ! 100) ] closeprice: option.close[ii] putcall: option.put_call[ii] strike: option.strike[ii] openint: option.openint[ii] pair: findoptimal[putcall; strike; openint] x: pair[0] / end of computing optimal price / get all recent days ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.put_call = `put) while[0 = #ii mydate: subtractdays[mydate; 1] ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.put_call = `put) ] if[(_ mindelivery % 100) > 200911 ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.dayofclose = mindelivery ! 100) & (option.put_call = `put) ] closeprice: option.close[ii] strike: option.strike[ii] spprice: spindex.sp500[spindex.date ? mydate] mystrike: spprice - 100 mystrike: x mystrike: 5 * (_ mystrike % 5) if[mystrike > spprice; out,: ,"Optimal D price is too high"; :out] kk: & strike = mystrike while[0 = #kk mystrike-: 5 kk: & strike = mystrike ] myprice: |/ closeprice[kk] k: spindex.date ? mindelivery while[k = #spindex.date mindelivery: subtractdays[mindelivery;1] k: spindex.date ? mindelivery ] out,: ,("sp500 price at buydate is: $"), $spprice out,: ,("Optimal price for D is: $"), $x out,: ,("Buy puts at: $"), ($ mystrike), (" for $"), ($myprice) out,: ,("At settlement price is $"), ($ spindex.sp500[k]) profit: - myprice if[spindex.sp500[k] < mystrike profit+: mystrike - spindex.sp500[k] ] out,: ,("Profit is $"), ($ profit) totalprofit+: profit :out } / Look at trend of optimals for a given settledate findoptimal_global:{[settledate] k: spindex.date ? settledate ` 0: ,("Settle date: "), ($settledate) , (" Settleprice: "), ($ spindex.sp500[k]) ` 0: ,("Previous date, Closing price, Predicted optimal") backnum: 21 mydate: subtractdays[settledate; backnum] while[backnum > 0 x: findoptimal_multi[mydate; settledate] backnum: backnum-1 mydate: subtractdays[settledate;backnum] ] ` 0: ," " } / Find optimal for a given date for a given settledate findoptimal_multi:{[mydate; settledate] mindelivery: settledate / get all recent days ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) if[0 = #ii :() ] if[(_ mindelivery % 100) > 200911 ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.dayofclose = mindelivery ! 100) ] if[0 = #ii; :()] closeprice: option.close[ii] strike: option.strike[ii] putcall: option.put_call[ii] openint: option.openint[ii] curprice: spindex.sp500[spindex.date ? mydate] pair: findoptimal[putcall; strike; openint] bestpredictedsettle: pair[0] ` 0: ,($mydate), (","), ($curprice), (","), ($bestpredictedsettle) } / see whether morris's insider trading indicator suggests market / will go up or down backtesttargetval:{[settledate] mindelivery: settledate ` 0: ,("Settledate: "), ($ mindelivery) / get all recent days mydate: subtractdays[mindelivery; 14] ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) if[0 = #ii mydate: subtractdays[mydate; 1] ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) ] if[(_ mindelivery % 100) > 200911 ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.dayofclose = mindelivery ! 100) ] if[0 = #ii; :()] closeprice: option.close[ii] strike: option.strike[ii] putcall: option.put_call[ii] openint: option.openint[ii] curprice: spindex.sp500[spindex.date ? mydate] pair: findoptimal[putcall; strike; openint] bestpredictedsettle: pair[0] ` 0: ,("Predicted settle price: "), $bestpredictedsettle worthinvesting: bestpredictedsettle > curprice / sort the options by strike x: _abs[closeprice - 7] mindiff: &/x k: spindex.date ? mindelivery ` 0: ,("At settlement price is $"), ($ spindex.sp500[k]) if[~worthinvesting; ` 0: ,"No investment done"; :()] j: * & x = mindiff ` 0: ,("Sell puts at: "), ($ strike[j]), (" for $"), ($closeprice[j]) ` 0: ,("Difference between spindex and strike price is: "), ($ curprice-strike[j]) profit: closeprice[j] if[spindex.sp500[k] < strike[j] profit-: strike[j] - spindex.sp500[k] ] ` 0: ,("Profit is $"), ($ profit) totalprofit+: profit } / naive sell twoweeks out without regard for oi, but buy hedging puts way / out of the money backtestinsurance:{[settledate] mindelivery: settledate / get all recent days mydate: subtractdays[mindelivery; 14] ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.put_call = `put) if[0 = #ii mydate: subtractdays[mydate; 1] ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) ] if[(_ mindelivery % 100) > 200911 ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.dayofclose = mindelivery ! 100) ] closeprice: option.close[ii] strike: option.strike[ii] / sort the options by strike x: _abs[closeprice - 7] mindiff: &/x j: * & x = mindiff ` 0: ,("Settledate: "), ($ mindelivery) ` 0: ,("Sell puts at: "), ($ strike[j]), (" for $"), ($closeprice[j]) mybuystrike: strike[j] - 39 jbuy: *| & strike < mybuystrike / last one that is lower k: spindex.date ? mindelivery ` 0: ,("Buy a put at: "), ($ strike[jbuy]), (" for $"), ($closeprice[jbuy]) ` 0: ,("At settlement price is $"), ($ spindex.sp500[k]) profit: closeprice[j] - closeprice[jbuy] if[spindex.sp500[k] < strike[j] profit-: (strike[j] - spindex.sp500[k]) & 40 / can't lose more than 40 ] ` 0: ,("Profit is $"), ($ profit) totalprofit+: profit } / associate with each settle data a breakout up ($20 greater than predicted) / a , breakout down ($20 less than predicted) / or a nobreakout (within $20 either way). That is the target variable. / Other variables are current price vs. predicted price / (uppredicted when target is $10 greater than current; / -1 when target $10 less; 0 otherwise) / if flag7 is 1 then lowwall is the highest strike where the closeprice > $7 / if flag7 is 0, then lowwall is the highest strike where wall > 20000 / And then show the walls up to settle price and beyond. findwallpatterns:{[flag7; settledate] / Like backtesttargetval from here mindelivery: settledate myoutresults: settledate ` 0: ,("Settledate: "), ($ mindelivery) / get all recent days mydate: subtractdays[mindelivery; 14] ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) if[0 = #ii mydate: subtractdays[mydate; 1] ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) ] if[((_ mindelivery % 100) > 200911) & (oexflag | spxflag) ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.dayofclose = mindelivery ! 100) ] if[0 = #ii; :()] closeprice: option.close[ii] strike: option.strike[ii] putcall: option.put_call[ii] openint: option.openint[ii] curprice: spindex.sp500[spindex.date ? mydate] if[0 = #putcall; :()] pair: findoptimal[putcall; strike; openint] bestpredictedsettle: pair[0] ` 0: ,("Predicted settle price: "), $bestpredictedsettle / Like backtesttargetval up to here ` 0: ,("Current price: "), $curprice k: spindex.date ? mindelivery mysettleprice: spindex.sp500[k] ` 0: ,("Settlement price is $"), ($ mysettleprice) if[ bestpredictedsettle > (curprice + 10) ` 0: ,"Up predicted" myoutresults,: `"Up predicted" ] if[ bestpredictedsettle < (curprice - 10) ` 0: ,"Down predicted" myoutresults,: `"Down predicted" ] if[ (~ bestpredictedsettle > (curprice + 10)) & (~ bestpredictedsettle < (curprice - 10)) ` 0: ,"Neutral prediction" myoutresults,: `"Neutral predicted" ] if[(mysettleprice) > (bestpredictedsettle + 20) ` 0: ,"Breakout up" ] if[(mysettleprice) < (bestpredictedsettle - 20) ` 0: ,"Breakout down" ] if[(~ (mysettleprice ) < (bestpredictedsettle - 20)) & (~(mysettleprice) > (bestpredictedsettle + 20)) ` 0: ,"No breakout" ] x: findwalls[putcall; strike; openint; closeprice] if[flag7 = 1 / lowwall is highest strike with $7 strike ii: & putcall = `put zz: _abs[(closeprice[ii]) - 7] mindiff: &/zz j: * & zz = mindiff ` 0: ,("Sell puts at: "), ($ strike[ii[j]]), (" for $"),($closeprice[ii[j]]) lowwall: strike[ii[j]] mywinlose: :[mysettleprice > lowwall ,("Win") ,("Lose")] ` 0: mywinlose myoutresults,: ` $ *mywinlose ] if[flag7 = 0 / lowwall is 20,000 high ii: & (20000 > x[;1]) y: x _di ii lowwall: |/y[;0] / lowest strike that has oi wall > 20,000 ` 0: ,("Lowest strike that has oi wall greater than 20,000: "), $lowwall ] ii: & (-20000 < x[;1]) y: x _di ii highwall: &/y[;0] ` 0: ,("Highest strike that has oi wall less than -20,000: "), $highwall ` 0: :[(lowwall < (spindex.sp500[k])) & (highwall > (spindex.sp500[k])) ,"Within walls" ,"Outside walls"] outhigh: () outhighvalues:() outlow: () outlowvalues:() k: 14 while[k < 18 mydate: subtractdays[mindelivery; k] ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) if[0 = #ii mydate: subtractdays[mydate; 1] ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.put_call = `put) ] if[(_ mindelivery % 100) > 200911 ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.dayofclose = mindelivery ! 100) & (option.put_call = `put) ] if[0 < #ii closeprice: option.close[ii] strike: option.strike[ii] putcall: option.put_call[ii] openint: option.openint[ii] z: findwalls[putcall; strike; openint; closeprice] ii: & (z[;0] = lowwall) outlow,: ,($k), (" days earlier than today, wall at "),($lowwall), (" is "), $z[*ii;1] outlowvalues,: z[*ii;1] ii: & (z[;0] = highwall) outhigh,: ,($k), (" days earlier than today, wall at "),($highwall), (" is "), $z[*ii;1] outhighvalues,: z[*ii;1] ] k+: 1 ] diff: (*outhighvalues) - (*|outhighvalues) myoutresults,: :[diff > 0 ` $ "highwall open interest has increased" ` $ "highwall open interest has decreased"] ` 0: :[diff > 0 ,($highwall),(" open interest has increased by "),$diff ,($highwall),(" open interest has decreased by "),$-diff] diff: (*outlowvalues) - (*|outlowvalues) ` 0: :[diff > 0 ,($lowwall),(" open interest has increased by "),$diff ,($lowwall),(" open interest has decreased by "),$-diff] ` 0: outhigh ` 0: outlow outresults,: ,myoutresults / ` 0: spit'x } / See whether there are any changes in direction of the wall open interest / associate with each settle data a breakout up ($20 greater than predicted) / a , breakout down ($20 less than predicted) / or a nobreakout (within $20 either way). That is the target variable. / Other variables are current price vs. predicted price / (uppredicted when target is $10 greater than current; / -1 when target $10 less; 0 otherwise) / if flag7 is 1 then lowwall is the highest strike where the closeprice > $7 / if flag7 is 0, then lowwall is the highest strike where wall > 20000 / And then show the walls up to settle price and beyond. findbreakpoints:{[flag7; settledate] mydayofclose: settledate ! 100 mindelivery: settledate myoutresults: settledate ` 0: ,("Settledate: "), ($ mindelivery) / get all recent days mydate: subtractdays[mindelivery; 14] ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.dayofclose = mydayofclose) if[0 = #ii mydate: subtractdays[mydate; 1] ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.dayofclose = mydayofclose) ] if[0 = #ii; :()] closeprice: option.close[ii] strike: option.strike[ii] putcall: option.put_call[ii] openint: option.openint[ii] curprice: spindex.sp500[spindex.date ? mydate] if[0 = #putcall; :()] pair: findoptimal[putcall; strike; openint] bestpredictedsettle: pair[0] ` 0: ,("Predicted settle price: "), $bestpredictedsettle / Like backtesttargetval up to here ` 0: ,("Current price: "), $curprice k: spindex.date ? mindelivery if[k = #spindex.date; k: spindex.date ? subtractdays[mindelivery; 1]] mysettleprice: spindex.sp500[k] ` 0: ,("Settlement price is $"), ($ mysettleprice) if[ bestpredictedsettle > (curprice + 10) ` 0: ,"Up predicted" myoutresults,: `"Up predicted" ] if[ bestpredictedsettle < (curprice - 10) ` 0: ,"Down predicted" myoutresults,: `"Down predicted" ] if[ (~ bestpredictedsettle > (curprice + 10)) & (~ bestpredictedsettle < (curprice - 10)) ` 0: ,"Neutral prediction" myoutresults,: `"Neutral predicted" ] if[(mysettleprice) > (bestpredictedsettle + 20) ` 0: ,"Breakout up" ] if[(mysettleprice) < (bestpredictedsettle - 20) ` 0: ,"Breakout down" ] if[(~ (mysettleprice ) < (bestpredictedsettle - 20)) & (~(mysettleprice) > (bestpredictedsettle + 20)) ` 0: ,"No breakout" ] x: findwalls[putcall; strike; openint; closeprice] if[flag7 = 1 / lowwall is highest strike with $7 strike ii: & putcall = `put zz: _abs[(closeprice[ii]) - 7] mindiff: &/zz j: * & zz = mindiff ` 0: ,("Sell puts at: "), ($ strike[ii[j]]), (" for $"),($closeprice[ii[j]]) lowwall: strike[ii[j]] mywinlose: :[mysettleprice > lowwall ,("Win") ,("Lose")] ` 0: mywinlose myoutresults,: ` $ *mywinlose ] if[flag7 = 0 / lowwall is 20,000 high ii: & (20000 > x[;1]) y: x _di ii lowwall: |/y[;0] / lowest strike that has oi wall > 20,000 ` 0: ,("Lowest strike that has oi wall greater than 20,000: "), $lowwall ] ii: & (-20000 < x[;1]) y: x _di ii highwall: &/y[;0] ` 0: ,("Highest strike that has oi wall less than -20,000: "), $highwall ` 0: :[(lowwall < (spindex.sp500[k])) & (highwall > (spindex.sp500[k])) ,"Within walls" ,"Outside walls"] outhigh: () outhighvalues:() outlow: () outlowvalues:() k: 3 putlowopenints: () calllowopenints: () puthighopenints: () callhighopenints: () while[k < 18 mydate: subtractdays[mindelivery; k] ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.dayofclose = mydayofclose) if[0 = #ii mydate: subtractdays[mydate; 1] ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.dayofclose = mydayofclose) ] if[0 < #ii closeprice: option.close[ii] strike: option.strike[ii] putcall: option.put_call[ii] openint: option.openint[ii] jj: & (strike = lowwall) & (putcall = `put) putlowopenints,: * openint[jj] jj: & (strike = lowwall) & (putcall = `call) calllowopenints,: * openint[jj] jj: & (strike = highwall) & (putcall = `put) puthighopenints,: * openint[jj] jj: & (strike = highwall) & (putcall = `call) callhighopenints,: * openint[jj] ] k+: 1 ] flag: ~ ((!#calllowopenints) ~ (calllowopenints)) if[flag myoutresults,:,(`"break in low call openint") ] flag: ~ ((!#putlowopenints) ~ (putlowopenints)) if[flag myoutresults,:,(`"break in low put openint") ] flag: ~ ((!#callhighopenints) ~ (callhighopenints)) if[flag myoutresults,:,(`"break in high call openint") ] flag: ~ ((!#puthighopenints) ~ (puthighopenints)) if[flag myoutresults,:,(`"break in high put openint") ] outresults,: ,myoutresults / ` 0: spit'x } / this routine looks at the optimal settle date, the rising / or lowering of the walls, and whether oi is going up as 0.4 of / the volume based on today's price / This should be run on oex. (we don't trade oex, but this / is where Morris feels there is a signal). / flag is 1 means we know the settle price (i.e. we are backtesting) / putcallind is either ` in which we take both puts and calls or is / putonly or callonly backtestoptwalloivsvol:{[flag; maxdate; settledate; daysback; putcallind] mindelivery: settledate mydayofclose: mindelivery ! 100 myoutresults: settledate out: ,("For vol/oi level based prediction, Settledate: "), ($ mindelivery) if[flag = 1 k: spindex.date ? mindelivery while[k = #spindex.date mindelivery: subtractdays[mindelivery;1] k: spindex.date ? mindelivery ] mysettleprice: spindex.sp500[k] ] / get all recent days mydate: subtractdays[mindelivery; daysback] if[vixflag; mydate: subtractdays[mindelivery; daysback-1]] if[flag = 0; mydate: maxdate] / actual date / collect data for finding the optimal ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) if[(_ mindelivery % 100) > 200911 ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.dayofclose = mydayofclose) ] numtries: 0 while[(0 = #ii ) & (numtries < 10) mydate: subtractdays[mydate;1] ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) if[(_ mindelivery % 100) > 200911 ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.dayofclose = mydayofclose) ] if[(0 = #ii) & (vixflag=1) mindelivery: subtractdays[mindelivery;-7] / sometimes vix is off by a week ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.dayofclose = mindelivery ! 100) ] numtries+: 1 ] if[numtries = 10; :,(" NO RESULTS FOR "),$settledate] dates: option.date[ii] vols: option.vol[ii] closeprice: option.close[ii] strike: option.strike[ii] putcall: option.put_call[ii] openint: option.openint[ii] currprice: spindex.sp500[ spindex.date ? mydate] out,: ,("Current price: "), ($ currprice) out,: ,("Current date: "), ($ mydate) pair: findoptimal[putcall; strike; openint] doptimal: pair[0] out,: ,("Optimal price for D: "), ($ doptimal) bestbalance: findbestbalancepoint[pair[1]] out,: ,("Price at which profit of in-the-money calls = profit for in-the-money puts: "), ($ bestbalance) if[flag out,: ,("Settle price : "), ($ mysettleprice) ] collectall: (mysettleprice; currprice; bestbalance; doptimal) predictdir::[doptimal > currprice; `predictup; `predictdown] / now look at historical data / ii: & (option.date < mydate) & (option.date > subtractdays[mydate; daysback-1]) & (option.delivery = _ mindelivery % 100) ii: & (option.date < (mydate+1)) & (option.date > subtractdays[mydate; 14 | (daysback-1)]) & (option.delivery = _ mindelivery % 100) if[(_ mindelivery % 100) > 200911 ii: & (option.date < (mydate+1)) & (option.date > subtractdays[mydate; 14 | (daysback-1)]) & (option.delivery = _ mindelivery % 100) & (option.dayofclose = mydayofclose) ] if[0 = #ii; : ,(" NO TWO WEEK HISTORY FOR "),$settledate] / relevant dates is ii dates: option.date[ii] vols: option.vol[ii] closeprice: option.close[ii] strike: option.strike[ii] putcall: option.put_call[ii] openint: option.openint[ii] ii: & (strike > (currprice - 150)) & (strike < (currprice + 150)) if[putcallind = `putonly ii: & (strike > (currprice - 100)) & (strike < (currprice + 100)) & (putcall = `put) ] if[putcallind = `callonly ii: & (strike > (currprice - 100)) & (strike < (currprice + 100)) & (putcall = `call) ] / relevant range of prices is ii dates@: ii vols@: ii closeprice@: ii strike@: ii putcall@: ii openint@: ii a: avg[vols] / jj: & vols > a / dates@: jj / vols@: jj / closeprice@: jj / strike@: jj / putcall@: jj / openint@: jj jj: < putcall,'strike,'dates / sort by dates within each option type and strike is jj dates@: jj vols@: jj closeprice@: jj strike@: jj putcall@: jj openint@: jj / group together option type and strike, in case we have more than one. part: = putcall,'strike uniqs: ? putcall,'strike / ?? Changed in September of 2016 / allvols: +/' vols[part] / a: avg[allvols] / jj: & allvols > a allois: +/'openint[part] jj: & allois > 5000 / otherwise uninteresting part@: jj uniqs@: jj myout: () totnumhiopenint: () totnumupopenint: () i: 0 while[i < #uniqs / for each put or call and strike combination myprice: (uniqs[i])[1] settledir: `settleunknown if[flag settledir: `settledown if[mysettleprice > myprice; settledir: `settleup] ] mydates: dates[part[i]] myvols: vols[part[i]] myopenint: openint[part[i]] mycloseprice: closeprice[part[i]] mypart: = mydates myuniqs: ? mydates totvols: +/' myvols[mypart] totopenint: +/' myopenint[mypart] totcloseprice: avg' mycloseprice[mypart] jj: < myuniqs myuniqs@: jj totvols@: jj totopenint@: jj totcloseprice@: jj numhiopenint: 0 k: 1 while[k < #myuniqs if[totopenint[k] > (totopenint[k-1] + (0.4* totvols[k])) numhiopenint+: 1 ] k+: 1 ] numupopenint: 0 xx: () k: 1 while[k < #myuniqs if[totopenint[k] > (totopenint[k-1]) numupopenint+: 1 ] xx,: totopenint[k] k+: 1 ] lastindex: (#myuniqs)-1 openintratio: totopenint[lastindex] % totopenint[lastindex-1] volratio: totvols[lastindex] % totvols[lastindex-1] myout,: ,spit (uniqs[i]),(#myuniqs),`"numhiopenint: ", (numhiopenint),`"numopenintincreases: ", (numupopenint),`"oi ratio last day: ", (round100 openintratio), `"vol ratio: ", (round100 volratio) myout,: ,spit (`"open ints over last several days:"), xx / csvout: ,`currentprice `settledate `currentdate `optiontype `strike `numdays `numhiopenint csvout,: ,(currprice, settledate, mydate, uniqs[i], (#myuniqs), numhiopenint, mysettleprice) totnumupopenint,: numupopenint totnumhiopenint,: numhiopenint i+: 1 ] out,: ,("Avg Open int increases this number: "), $avg[totnumupopenint] out,: ,("Avg Open int above 0.4 of vol: "), $avg[totnumhiopenint] if[flag & 0 isup: :[0 < mysettleprice - currprice; `isup; `isdown] predup: :[0 < doptimal - currprice; `predup; `preddown] out,: ,($isup),(" "), ($predup), (" price change: "), ($mysettleprice - currprice) if[predup = `preddown; downprofit+: currprice - mysettleprice; alldownprofits,: currprice - mysettleprice] / if[predup = `predup; upprofit+: mysettleprice - currprice ; allupprofits,: mysettleprice - currprice] if[4 < avg[totnumupopenint]; upprofit+: mysettleprice - currprice ; allupprofits,: mysettleprice - currprice] alwaysupprofit+: mysettleprice - currprice allalwaysupprofit,: mysettleprice - currprice allalwaysupavgupopenint,: avg[totnumupopenint] ] out,: myout :(out; collectall) } / compute the total value for each option as of mydate for mindelivery morriscalc:{[mydate; enddate] out:() mydayofclose: enddate ! 100 ii: & (option.date = mydate) & (option.delivery = _ enddate % 100) & (option.dayofclose = enddate ! 100) closeprice: option.close[ii] strike: option.strike[ii] putcall: option.put_call[ii] openint: option.openint[ii] currprice: spindex.sp500[ spindex.date ? mydate] jj: & putcall = `put kk: & strike[jj] > currprice intrinsicval: 0.0 intrinsicval+: 100.0 * +/ (openint[jj[kk]]) * (strike[jj[kk]] - currprice) out,: ,(`"current date: "), mydate, (`"for delivery: "), enddate out,: ,(`"current price: "), currprice out,: `put ,/: (strike[jj[kk]]),'(100.0 * (openint[jj[kk]]) * (strike[jj[kk]] - currprice)) jj: & putcall = `call kk: & strike[jj] < currprice intrinsicval+: 100.0 * +/ (openint[jj[kk]]) * (currprice - strike[jj[kk]]) out,: `call ,/: (strike[jj[kk]]),'(100.0 * (openint[jj[kk]]) * (currprice - strike[jj[kk]])) totprice: 100.0 * +/openint * closeprice out,: `avgofbidasked ,/: putcall,'strike,'100.0*openint * closeprice x: netprem[out] morrisout,: out,x :(mydate; enddate; +/x[;3]) } / find the net premium for each option-strike netprem:{[out] myout: () bits: `avgofbidasked = out[;0] pos: out[& bits = 1] / closing price negs: out[& bits = 0] / intrinsic worth i: 0 while[i < #pos trip: 1 _ pos[i] jj: & (trip[0] = negs[;0]) & (trip[1] = negs[;1]) if[0 = #jj; myout,: ,`netpremium , trip] if[1 = #jj trip[2]-: negs[*jj;2] myout,: ,`netpremium , trip ] / if[1 < #jj ; !-4] /error, I don't think this is an error i+: 1 ] :myout } / this routine looks at the optimal settle price compared to current, the rising / or lowering of the walls. / This should be run on oex. (we don't trade oex, but this / is where Morris feels there is a signal). / flag is 1 means we know the settle price (i.e. we are backtesting) / We also test whether the price of the option we intend to sell (always / a put option) ever goes higher than "pricemultiple" the price we sell it at. / pricemultiple is set in this function. backtestopenintincrease:{[flag; maxdate; settledate] pricemultiple: 2 / if option goes higher than twice what we sold it at / then we lose money mindelivery: settledate mydayofclose: mindelivery ! 100 myoutresults: settledate out: ,(" ") out,: ,(" For vol/oi level based prediction, Settledate: "), ($ mindelivery) if[flag k: spindex.date ? mindelivery while[k = #spindex.date mindelivery: subtractdays[mindelivery;1] k: spindex.date ? mindelivery ] mysettleprice: spindex.sp500[k] ] / get all recent days or go back to maxdate mydate: maxdate & subtractdays[mindelivery; 15] if[vixflag; mydate: maxdate & subtractdays[mindelivery; 13]] / collect data for finding the optimal ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) if[(_ mindelivery % 100) > 200911 ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.dayofclose = mydayofclose) ] numtries: 0 while[(0 = #ii ) & (numtries < 10) mydate: subtractdays[mydate;1] ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) if[((_ mindelivery % 100) > 200911) & (oexflag | spxflag) ii: & (option.date = mydate) & (option.delivery = _ mindelivery % 100) & (option.dayofclose = mydayofclose) ] numtries+: 1 ] if[numtries = 10; !-4; :,(" NO RESULTS FOR "),$settledate] dates: option.date[ii] vols: option.vol[ii] closeprice: option.close[ii] strike: option.strike[ii] putcall: option.put_call[ii] openint: option.openint[ii] currprice: spindex.sp500[ spindex.date ? mydate] out,: ,("Current price: "), ($ currprice) out,: ,("Current date: "), ($ mydate) pair: findoptimal[putcall; strike; openint] doptimal: pair[0] out,: ,("Optimal price for D: "), ($ doptimal) if[flag out,: ,("Settle price : "), ($ mysettleprice) ] predictdir::[doptimal > currprice; `predictup; `predictdown] / if[predictdir = `predictdown; :out] / not interested / now look at historical data ii: & (option.date < mydate) & (option.date > subtractdays[mydate; 14]) & (option.delivery = _ mindelivery % 100) if[(_ mindelivery % 100) > 200911 ii: & (option.date < mydate) & (option.date > subtractdays[mydate; 14]) & (option.delivery = _ mindelivery % 100) & (option.dayofclose = mydayofclose) ] if[0 = #ii; : ,(" NO TWO WEEK HISTORY FOR "),$settledate] dates: option.date[ii] vols: option.vol[ii] closeprice: option.close[ii] strike: option.strike[ii] putcall: option.put_call[ii] openint: option.openint[ii] ii: & (strike > (currprice - 60)) & (strike < (currprice )) & (putcall = `put) / looking for out of the money puts but not too far dates@: ii vols@: ii closeprice@: ii strike@: ii putcall@: ii openint@: ii a: avg[vols] / jj: & vols > a / dates@: jj / vols@: jj / closeprice@: jj / strike@: jj / putcall@: jj / openint@: jj jj: < putcall,'strike,'dates dates@: jj vols@: jj closeprice@: jj strike@: jj putcall@: jj openint@: jj part: = putcall,'strike uniqs: ? putcall,'strike allvols: +/' vols[part] a: avg[allvols] / jj: & allvols > a / part@: jj / uniqs@: jj myout: () totnumhiopenint: () totnumupopenint: () i: 0 while[i < #uniqs / for each put and strike combination mystrike: (uniqs[i])[1] settledir: `settleunknown if[flag settledir: `settledown if[mysettleprice > mystrike; settledir: `settleup] ] mydates: dates[part[i]] myvols: vols[part[i]] myopenint: openint[part[i]] mycloseprice: closeprice[part[i]] mypart: = mydates myuniqs: ? mydates totvols: +/' myvols[mypart] totopenint: +/' myopenint[mypart] totcloseprice: avg' mycloseprice[mypart] jj: < myuniqs myuniqs@: jj totvols@: jj totopenint@: jj totcloseprice@: jj myoptionsaleprice: *|totcloseprice if[(myoptionsaleprice < 15) & (myoptionsaleprice > 2) numhiopenint: 0 k: 1 while[k < #myuniqs if[totopenint[k] > (totopenint[k-1] + (0.4* totvols[k])) numhiopenint+: 1 ] k+: 1 ] numupopenint: 0 k: 1 while[k < #myuniqs if[totopenint[k] > (totopenint[k-1]) numupopenint+: 1 ] k+: 1 ] if[1 | (~ (numupopenint > 5) & (numhiopenint > 3) ) myout,: ,("Strike is : "), $mystrike myout,: ,("Sale price: "), $myoptionsaleprice myout,: ,("Type of option: "), $uniqs[i;0] myout,: ,("Number of high open interest is (want > 3): "), $numhiopenint myout,: ,("Number of increasing open interest is (want > 5) : "), $numupopenint if[flag myout,: ,("Settle price is: "), $mysettleprice ] ] if[flag & (numupopenint > 5) & (numhiopenint > 3) / will sell; must check that we / don't see the price rise to more than / pricemultiple * price we sold at jj2: & (option.date < settledate) & (option.date > mydate) & (option.delivery = _ mindelivery % 100) & (option.put_call = `put) & (option.strike = mystrike) if[(_ mindelivery % 100) > 200911 jj2: & (option.date < settledate) & (option.date > mydate) & (option.delivery = _ mindelivery % 100) & (option.dayofclose = mydayofclose) & (option.put_call = `put) & (option.strike = mystrike) ] maxotheroptionprice: |/option.close[jj2] if[maxotheroptionprice > (myoptionsaleprice * pricemultiple) mygainloss: myoptionsaleprice - (myoptionsaleprice * pricemultiple) ] if[~ maxotheroptionprice > (myoptionsaleprice * pricemultiple) mygainloss: myoptionsaleprice if[mysettleprice < mystrike mygainloss-: mystrike-mysettleprice ] ] kk2: & (spindex.date < mindelivery) & (~ spindex.date < mydate) minspxprice: &/ spindex.sp500[kk2] x2: spit (mindelivery), (`" strike: "),(uniqs[i;1]),(`" previous days: "),(#myuniqs),`" numhiopenint: ", (numhiopenint),`" numopenintincreases: ", (numupopenint), (`" spx price when put sold: "), currprice, (`" min spx price after sale: "), minspxprice, (`" settle spx price: "), mysettleprice, (`" max option price after sale: "), maxotheroptionprice, (`" mygainloss: "), (mygainloss) myout,: ,x2 totgainloss,: mygainloss totnumupopenint,: numupopenint totnumhiopenint,: numhiopenint ] ] / if price within range i+: 1 ] / out,: ,("Avg Open int increases this number: "), $avg[totnumupopenint] / out,: ,("Avg Open int above 0.4 of vol: "), $avg[totnumhiopenint] if[flag isup: :[0 < mysettleprice - currprice; `isup; `isdown] predup: :[0 < doptimal - currprice; `predup; `preddown] out,: ,($isup),(" "), ($predup), (" "), ($avg[totnumupopenint]),(" "), $avg[totnumhiopenint] ] out,: myout :out } / See where oi levels have gone up with volume, suggesting that D has / sold there. Determine whether price ever goes below that level if put / or above that level if call. / If flag is 1 then we know settle price findDmoves:{[flag; settledate] mydayofclose: settledate ! 100 mindelivery: settledate myoutresults: settledate out: ,("For vol/oi level based prediction, Settledate: "), ($ mindelivery) if[flag k: spindex.date ? mindelivery while[k = #spindex.date mindelivery: subtractdays[mindelivery;1] k: spindex.date ? mindelivery ] mysettleprice: spindex.sp500[k] ] / get all recent days mydate: subtractdays[mindelivery; 14] ii: & (option.date < mydate) & (option.date > subtractdays[mydate; 14]) & (option.delivery = _ mindelivery % 100) if[(_ mindelivery % 100) > 200911 ii: & (option.date < mydate) & (option.date > subtractdays[mydate; 14]) & (option.delivery = _ mindelivery % 100) & (option.dayofclose = mydayofclose) ] if[0 = #ii; :()] dates: option.date[ii] vols: option.vol[ii] closeprice: option.close[ii] strike: option.strike[ii] putcall: option.put_call[ii] openint: option.openint[ii] a: avg[vols] / jj: & vols > a / dates@: jj / vols@: jj / closeprice@: jj / strike@: jj / putcall@: jj / openint@: jj jj: < putcall,'strike,'dates dates@: jj vols@: jj closeprice@: jj strike@: jj putcall@: jj openint@: jj part: = putcall,'strike uniqs: ? putcall,'strike allvols: +/' vols[part] a: avg[allvols] jj: & allvols > a part@: jj uniqs@: jj i: 0 while[i < #uniqs myprice: (uniqs[i])[1] settledir: `settleunknown if[flag settledir: `settledown if[mysettleprice > myprice; settledir: `settleup] ] mydates: dates[part[i]] myvols: vols[part[i]] myopenint: openint[part[i]] mycloseprice: closeprice[part[i]] mypart: = mydates myuniqs: ? mydates totvols: +/' myvols[mypart] totopenint: +/' myopenint[mypart] totcloseprice: avg' mycloseprice[mypart] jj: < myuniqs myuniqs@: jj totvols@: jj totopenint@: jj totcloseprice@: jj numgood: 0 k: 1 while[k < #myuniqs if[totopenint[k] > (totopenint[k-1] + (totvols[k] % 3)) numgood+: 1 ] k+: 1 ] if[(numgood > 0.5 * #myuniqs) if[(uniqs[i][0] = `put); predictdir: `settleup] if[(uniqs[i][0] = `call); predictdir: `settledown] out,: ,spit (uniqs[i]),numgood,(#myuniqs),predictdir,settledir,totcloseprice[k-1] ] i+: 1 ] :out } / find the total oi at this origdate relative to this closing date (mindelivery) findtotaloi:{[origdate; mindelivery] ii: & (option.date = origdate) & (option.delivery = _ mindelivery % 100) if[(_ mindelivery % 100) > 200911 ii: & (option.date = origdate) & (option.delivery = _ mindelivery % 100) & (option.dayofclose = mindelivery ! 100) if[0 = #ii origdate: subtractdays[origdate;1] ii: & (option.date = origdate) & (option.delivery = _ mindelivery % 100) & (option.dayofclose = mindelivery ! 100) ] if[(0 = #ii) & (vixflag=1) mindelivery: subtractdays[mindelivery;-7] / sometimes vix is off by a week ii: & (option.date = origdate) & (option.delivery = _ mindelivery % 100) & (option.dayofclose = mindelivery ! 100) ] ] openint: option.openint[ii] :+/openint } giveresults:{[maxdate; mindelivery; dayclose; myprice] out: () ` 0: ,("Current date is "),($maxdate) stringdayclose: :[10 < dayclose; $dayclose; ("0"),$dayclose] ` 0: ,("Settledate is "),($mindelivery),(stringdayclose) / 8 days before dayclose is the earlier week; / 7 days before that is the first friday unless the first falls on a Saturday / dayclose +6 is next friday ` 0: ,"Don't care so much if optimal price is above current. " ` 0: ,"Hi open interest increases exceeds 4 then we are in good shape for prices to rise" ii: & (option.date = maxdate) & (option.delivery = mindelivery) & (option.dayofclose = dayclose) if[0 = #ii; :("Nothing from this day and for this delivery";())] closeprice: option.close[ii] putcall: option.put_call[ii] strike: option.strike[ii] openint: option.openint[ii] / get rid of strange options part: = strike,'putcall uniqs: ? strike,'putcall uopenint: |/'openint[part] / there are some strange terms uopenint: +/'openint[part] / there are some strange terms openint: uopenint strike: uniqs[;0] putcall: uniqs[;1] / sort the options by strike jj: < strike,'putcall closeprice@: jj putcall@: jj strike@: jj openint@: jj / x: strike,'putcall,'openint / spit'x / x: findoptimal[putcall; strike; openint] / ` 0: ,("For month: "), ($mindelivery) / ` 0: ,("at date: "), ($maxdate) / ` 0: ,("Optimal settle price (assuming D is short on oex and matched on xeo): "), ($x) / ` 0: ,("Current price: "), ($myprice) out,: findwalls[putcall; strike; openint; closeprice] ii: & (closeprice > 6) & (closeprice < 8) out,: closeprice[ii],'putcall[ii],'strike[ii] x: putcall,'strike,'openint,'closeprice x@: 0.498 d: diffdays[my[0;1]; my[0;2]] movement: _abs[my[0;0] - my[0;7]] if[1 < #kk status: :[my[kk[1];4] > my[kk[1];7]; `bad; `good] out,:,(uniqs[i;1]; uniqs[i;0]; d; my[kk[1];4]; status; movement; my[0;0]; my[0;7]) / my[kk[1]] is the second wall element ] if[~ 1 < #kk out,:,(uniqs[i;1]; uniqs[i;0]; d; 0; `nowall; movement; my[0;0]; my[0;7]) ] ] if[uniqs[i][1] = `call my@: & my[;4] > my[;0] / out of the money my@: < my[;4] / sorted kk: & (my[;6]%my[;5]) > 0.498 d: diffdays[my[0;1]; my[0;2]] movement: _abs[my[0;0] - my[0;7]] if[1 < #kk status: :[my[kk[1];4] < my[kk[1];7]; `bad; `good] out,:,(uniqs[i;1]; uniqs[i;0]; d; my[kk[1];4]; status; movement; my[0;0]; my[0;7]) / my[kk[1]] is the second wall element ] if[~ 1 < #kk out,:,(uniqs[i;1]; uniqs[i;0]; d; 0; `nowall; movement; my[0;0]; my[0;7]) ] ] if[1 < #kk ` 0: ,"iteration: ", ($i), (" settledate: "), ($uniqs[i;0]), " option: ", ($uniqs[i;1]), (" strike: "), ($my[kk[1];4]), (" days before expiration: "), ($d) ] if[timeunitflag = `weekly "tmpwallstatsweekly" 0: spit' out ] if[timeunitflag = `monthly "tmpwallstatsmonthly" 0: spit' out ] i+: 1 ] } / DATA / DATA spindex.date: () spindex.sp100: () spindex.sp500: () / Then take the option values and convert them to option.symb: () option.delivery: () option.dayofclose: () option.put_call: () option.strike: () option.date: () option.daystosettle: () option.close: () option.high: () option.low: () option.vol: () option.openint: () option.settleprice: () / EXECUTION csvout: ,`currentprice `settledate `currentdate `optiontype `strike `numdays `numhiopenint `settleprice if[1 > #_i ` 0: ,"Format: k cboeparse filename (e.g. k cboeparse spx.dat) " ` 0: ,"You can also ask for a second filename having the same format " ` 0: ,"Format: k cboeparse oex.dat xeo.dat " . "\\\\" ] args: _i file: _i[0] instring: _i[0] a: 0: file xeoflag: (_i[0]) ~ "xeo.dat" spxflag1: (_i[0]) ~ "spx.dat" spxflag2: (_i[0]) ~ "spxtmp.dat" spxflag3: (_i[0]) ~ "tmpspx.dat" spxflag: spxflag1 | spxflag2 | spxflag3 oexflag: (_i[0]) ~ "oex.dat" vixflag: (_i[0]) ~ "vix.dat" vxxflag: (_i[0]) ~ "vxx.dat" weeklyflag: 1 | vxxflag / ??? 1 if we want weeklies / ?? Add in approved end of month / x: parsesptxt[2013; xeoflag; 1 ;a] / ??? make sure that year is actual year x: parsesptxt[0; xeoflag; 1 ;a] / ??? make sure that year is actual year / if 0.75, then 75% sold to others; if D purely short then 1. / if year is 0 then take all the data part: = spindex.date counts: #:'part uniqs: ?spindex.date if[1 < |/counts; ii: & 1 < counts; uniqs[ii]; !-13] / k csiparse SP.TXT SP500 / k csiparse SPX.CSV SP500 / "spindexbac" 1: spindex / "cboespindex" 1: spindex ii: & (option.openint > 5000) & (option.daystosettle < 20) & (option.daystosettle > 1) option.symb@: ii option.delivery@: ii option.dayofclose@: ii option.put_call@: ii option.strike@: ii option.date@: ii option.daystosettle@: ii option.close@: ii option.high@: ii option.low@: ii option.vol@: ii option.openint@: ii option.settleprice: findprice'[option.delivery,' option.dayofclose] ii: & (option.openint > 0.0) & (option.settleprice > 0.0) option.symb@: ii option.delivery@: ii option.dayofclose@: ii option.put_call@: ii option.strike@: ii option.date@: ii option.daystosettle@: ii option.close@: ii option.high@: ii option.low@: ii option.vol@: ii option.openint@: ii option.settleprice@: ii newoption.todaydate: option.date newoption.settledate: combinepair'[option.delivery,'option.dayofclose] newoption.daystosettle: option.daystosettle newoption.today_sp_price: findpricesimple'option.date newoption.settle_sp_price: option.settleprice newoption.optiontype: option.put_call newoption.optionstrike: option.strike newoption.optionclosingprice: option.close newoption.optionhighprice: option.high newoption.optionlowprice: option.low newoption.optionvol: option.vol newoption.optionopenint: option.openint ii: & (newoption.optionstrike > (newoption.today_sp_price - 120)) & (newoption.optionstrike < (newoption.today_sp_price + 120)) newoption.todaydate@:ii newoption.settledate@:ii newoption.daystosettle@:ii newoption.today_sp_price@:ii newoption.settle_sp_price@:ii newoption.optiontype@:ii newoption.optionstrike@:ii newoption.optionclosingprice@:ii newoption.optionhighprice@:ii newoption.optionlowprice@:ii newoption.optionvol@:ii newoption.optionopenint@:ii ii: < newoption.settledate newoption.todaydate@:ii newoption.settledate@:ii newoption.daystosettle@:ii newoption.today_sp_price@:ii newoption.settle_sp_price@:ii newoption.optiontype@:ii newoption.optionstrike@:ii newoption.optionclosingprice@:ii newoption.optionhighprice@:ii newoption.optionlowprice@:ii newoption.optionvol@:ii newoption.optionopenint@:ii / "cboeoption" 1: option / option values dumptable[`newoption; newoption; "relevantoptions"] \\