-
Notifications
You must be signed in to change notification settings - Fork 10
Tutorial
In this tutorial, we will cover how to test a piece of code used for calculating volume curves with qspec and using qspec to help ensure the validity of the code as we change and refactor it to suit the changing capabilities that the code needs to support.
To start with, let’s take a look at the code currently being used for calculating the volume curves.
curve-v1.q
curve:{[syms;start;end];
v:select avgBucket:avg volume, total: sum volume by sym, time.minute from trade where date within `date$(start;end), sym in syms, time within `time$(start;end);
tv: exec sum total by sym from v;
`sym`minute xasc select avgBucket, pctDaily:total%tv[first sym] by sym,minute from v
}
curve:{[syms;start;end];
v:select avgBucket:avg volume, total: sum volume by sym, time.minute from trade where date within `date$(start;end), sym in syms, time within `time$(start;end);
tv: exec sum total by sym from v;
`sym`minute xasc select avgBucket, pctDaily:total%tv[first sym] by sym,minute from v
}
This is pretty simple and might represent what we would have after a very preliminary pass to get something up and working. The results it produces look like this:
q)curve[`IBM`MSFT;2009.11.01T09:30;2009.11.30T16:00]
sym minute| avgBucket pctDaily
----------| ----------------------
IBM 09:30 | 792 0.00466508
IBM 09:31 | 965.2778 0.005458301
IBM 09:32 | 980.4878 0.006314351
IBM 09:33 | 874.3902 0.005631082
IBM 09:34 | 360.9195 0.002466053
IBM 09:35 | 135.6164 0.0007775134
IBM 09:36 | 970.4225 0.005411179
IBM 09:37 | 394.7368 0.002356101
IBM 09:38 | 134.4444 0.0009502941
IBM 09:39 | 271.25 0.001704246
IBM 09:40 | 271.6418 0.001429368
IBM 09:41 | 140.9091 0.0007303913
IBM 09:42 | 656.8966 0.002992248
IBM 09:43 | 1018.182 0.005277667
IBM 09:44 | 274.6479 0.001531466
IBM 09:45 | 387.5 0.002434638
IBM 09:46 | 163.2911 0.001013123
IBM 09:47 | 800 0.005654643
Now, ideally, you would actually be using somewhat real data to test against. Since I don’t have a contract with Reuters to republish marketdata or any generously donated sample data sets, I’ll make due with some random data that I cooked up.
If you would like to follow along exactly, here is the code I’m using to make the random data and the commands used to generate it:
gen.q
gen:{[syms;prices;nums;start;days];
raze (enlist each flip `sym`date!flip syms cross start + til days) cross' {[num;price]
invAbs:{(count[x]?1 -1)*x};
n:`int$num + first invAbs 1?(1?1f)*num; / Adjust num to generate within 0-100% of base num up or down
freqs:0f, sums .8 .1 .05 .01 .01 .01 .016 .001 .001 .001;
sizes:100 200 300 400 500 1000 10000 20000 30000 40000 50000;
([]time:asc 09:30t + n?16t - 09:30t;price:price + invAbs n?first 1?.1;size:sizes freqs bin n?1f)
} .' raze days#'enlist each nums,'prices
}
gen:{[syms;prices;nums;start;days];
raze (enlist each flip `sym`date!flip syms cross start + til days) cross' {[num;price]
invAbs:{(count[x]?1 -1)*x};
n:`int$num + first invAbs 1?(1?1f)*num; / Adjust num to generate within 0-100% of base num up or down
freqs:0f, sums .8 .1 .05 .01 .01 .01 .016 .001 .001 .001;
sizes:100 200 300 400 500 1000 10000 20000 30000 40000 50000;
([]time:asc 09:30t + n?16t - 09:30t;price:price + invAbs n?first 1?.1;size:sizes freqs bin n?1f)
} .' raze days#'enlist each nums,'prices
}
q gen.q -S 200
KDB+ 2.6 2009.12.04 Copyright (C) 1993-2009 Kx Systems
q)`:trade set gen[`IBM`MSFT`AAPL;100 30 200f;1000 2000 10000;2009.11.01;30]
`:trade