This series looks at building a near full-scale application in q and, in the process, tries to answer questions on the amount of code a q application requires, and how that code can be organised so that it is both comprehensible and straightforward to change. The target application is a participation strategy and some of its associated testing framework.
Looking ahead, here is the same test as in the previous installment, but with both "far" and "near" execution tactics. To get to this stage required eight orders from the user session.
Note how the average prices,
avgprx, are now closer to VWAP. A view,
benchmarks has been added to the strategy to give a clearer view of how the orders perform against the target participation rate and various prices. Since all the user session orders hit the ask side of the book, performance is skewed for buys and sells: the slippage from VWAP ranges from 1 - 7bps for buys to 32bps for sells.
Testing multiple execution tactics and multiple orders requires more power tools. The
user.q script is now extended to load another script,
player.q which can enter a table of orders. Inside a user session, a table can be loaded and each row played every 50 milliseconds with the following statement:
play [`:/kdb/qx/player.csv; 50]
player.q uses the built-in q timer function
.z.ts and the timer command
system "t" (more often typed as
\t on the command line). The
play function can accept either a file name (a symbol) or a table: the table is held in the
.player context while it is being played.
This script helped discover an overlooked defect with id's in matching within
qx.q, fixed in this installment.
The implementation of the "near" tactic closely follows the pattern of
far.q, although the rules are slightly simpler. Recall that "near" pegs a single downstream for each upstream order allocation in the control table,
controlnear. There are a couple of differences from the specification.
leavesless the quantity already on the book, which can be computed from the downstream orders. Otherwise the tactic will overcommit.
The amount of decision making now inside the strategy means more instrumentation is needed.
near.q uses an "alarm" concept built into
participation.q to record significant events in a table, via an
upd function of course.
All allocations are made through the
upd pattern, passing a list of id's that need to be allocated. Allocations are made in multiples of
minqty, as specified. The size of the multiple is currently fixed, likewise the threshold at which further allocations are made. These will be examined in the market trials. One aspect not yet implemented is the transfer of quantity from "near" to "far".
As mentioned above,
user.q now loads the player script and
qx.q has a defect fixed. The other changes are:
global.qto provide a function that gives a performance measure relative to direction: numbers within or improving on the benchmark are always negative.
tactic.qhas an extra required column for the
far.qhave the additions for alarms, benchmarks and, for the strategy only, deciding allocations for new orders and when fills are received.
All other code can be downloaded through the links in the section below.
This installment has added 30% more lines of code:
|Lines of code|
The ratio of application code to testing code is now 60:40.
|2.||Further updates, and more q code, can be found at code.kx.com. This is a secure site: for browsing the user name is anonymous with password anonymous.|