Laura
Forum Replies Created
-
See article on the accumulator iteration operators:
-
-
Laura
AdministratorMay 5, 2022 at 12:00 am in reply to: Capstone Project Issue | 3. Data Analytics and ReportingThe structure does seem ok at a glance.
One thing it might be is this 3.1 test does have a dependency on the trade table remaining unchanged :
q)meta trade c | t f a ---------| ----- date | d option_id| s p trade_id | C time | t price | f qty | j side | s edge | f exch_id | j broker_id| j
If that also looks correct on your side can you please share your definition of tradeContext so I can further assist?
Thanks
-
Laura
AdministratorMay 5, 2022 at 12:00 am in reply to: Capstone Project Issue | 3. Data Analytics and ReportingHi Venu,
The error is on the date column – check does it exist in your tradeContext table and is called date?
>> exercise3.1 Fail “abort” “abort in before block due to error “date“”
Thanks,
Michaela
-
Laura
AdministratorMay 5, 2022 at 12:00 am in reply to: Title: Capstone Project Issue | 3. Data Analytics and Reporting | No such file or directoryHi Venu,
The issue here is likely to do with the filepath. When i try to resolve what you have above first without using save you can see what the filepath is.
q)`:ORIG_HOME/badTrades.csv
`:ORIG_HOME/badTrades.csv // ORIG_HOME is a variable so needs to be joined accordingly q)hsym `$ORIG_HOME”/badTrades.csv”
`:d n // this is closer! just missing the join operator between the first and second part..
You can check out the Working with Files module to learn more about creating filepaths and using hsym.
I will add a hint below if you are still stuck – hope this helps.
save `$ORIG_HOME,”/badTrades.csv”
Thanks,
Michaela
-
Laura
AdministratorMay 5, 2022 at 12:00 am in reply to: Capstone Project Issue | 3. Data Analytics and ReportingThe database at /dbs is a date partitioned one meaning the partition domain (date in this case) is a virtual column and only visible when the database it loaded into memory. The method you have used is loading each partition separately.
To load/map the entire database in correctly you can use l , for more resources for beginners to kdb+ databases and quick tips on working with them check out Q4Mortals
l /dbs/
-
Join Over
,/
is of courseraze
, soraze t`sym
would do nicely.Watch Out:
scan
is a q keyword and you cant assign it a value. -
q)show val:.01 .0125 .01234568 .9999 .008 0.01 0.0125 0.01234568 0.9999 0.008 q).001*floor .5+1000*val 0.01 0.013 0.012 1 0.008
More generally, as a function which takes number of decimal places as its left argument:
q){%[;s]floor .5+y*s:10 xexp x}[3]val 0.01 0.013 0.012 1 0.008
Slightly less obviously you can elide
floor .5+
with a faster Cast:q){%[;s]"i"$y*s:10 xexp x}[3]val 0.01 0.013 0.012 1 0.008
-
Laura
AdministratorApril 29, 2022 at 12:00 am in reply to: Question about query that stuck the KDB processLooks like you have already spotted part of the problem. The
/
does not denote Divide%
but the iteration operator Over. Depending on the values in thesize
column, you might have inadvertently specified a Converge iteration, and one that might not actually converge. Iterations defined this way run very tight and can be difficult to interrupt.The result column you want is perhaps
sums[size]%sum[size]
, or, avoiding computing bothsum
andsums
,
.[%]1 lastsums size
.q)show size:5?10 6 6 1 8 5 q)sums[size]%sum[size] 0.2307692 0.4615385 0.5 0.8076923 1 q).[%]1 lastsums size 0.2307692 0.4615385 0.5 0.8076923 1
The use above of
1 last
is an example of the Zen monks idiom. -
Laura
AdministratorApril 25, 2022 at 12:00 am in reply to: Insert a not matching dictionary to a tableq)x upsert td2 cols x a b c ------- 1 I 10 2 J 20 3 K 30 99 a
-
The dictionary
Id!PrevID
is a unary. Applying the Converge iterator to a unaryf
derives a functionf/
(f
Over). When you evaluatef/[x]
, the unaryf
gets applied successively until either (a) the result stops changing (convergence) or (b) the result matchesx
i.e. comes full circle.The white paper on iteration has some examples of iterating lists and dictionaries as finite-state machines.
All this assumes your ID => previous ID paths actually terminate! (You can use the Converge iterator to start an open loop!)
-
If Im following you, your two lists
L1
andL2
are the same length. You want a listA
of the same length in which itemA[i]
is the greater ofL1[i]
andL2[i]
.The Greater operator
|
is atomic, so iterates implicitly.q)show L1:10?10. 3.927524 5.170911 5.159796 4.066642 1.780839 3.017723 7.85033 5.347096 7.111716 4.11597 q)show L2:10?10. 4.931835 5.785203 0.8388858 1.959907 3.75638 6.137452 5.294808 6.916099 2.296615 6.919531 q)show A:L1|L2 / Greater 4.931835 5.785203 5.159796 4.066642 3.75638 6.137452 7.85033 6.916099 7.111716 6.919531
A good deal of vector programming is just letting go of loops and tests. (Just takes practice.)
-
Because underscores can be part of names, separate a name from the Drop operator with spaces.
q)n:3 q)n_ til 5 'n_ [0] n_ til 5 ^ q)n _ til 5 3 4 q)-2_ 3_ til 10 3 4 5 6 7
The
null
keyword will find nulls. You can usewhere not null
to remove all nulls. Or, to remove leading and trailing nulls, you can count and Drop the nulls from each end. Note below the use of the Zen monks idiom to return both the boolean and its reverse. And commuting (switching the arguments of) Drop in order to use Over to apply it to a list of left arguments.q)q:0N 0N 3 4 0N 6 7 0N 8 0N q)q where not null q / lose all nulls 3 4 6 7 8 q)1 reversenot null q / Zen monks 0011011010b 0101101100b q)?'[;1b]1 reversenot null q 2 1 q)q {y _ x}/1 -1*?'[;1b]1 reversenot null q / commuted Drop 3 4 0N 6 7 0N 8
All neat tricks. But if you simply want to drop leading and trailing nulls, just
trim
them.q)trim q 3 4 0N 6 7 0N 8
-
Couple of syntax errors above, but lets break down what we can. The trailing backtick was probably you trying to use Markdown for the expression; we can ignore that.
The query defines a new column
OriginalId
by applying a lambda to each ID. The lambda is projected on (curried to) its second argument. That is, within the lambday
refers toId!PrevId
, which is a dictionary mapping IDs to previous IDs. The lambda has two expressions. The first expression appliesy
(the dictionary) tox
(the ID) to get the previous ID,x1
. The second expression is a ternary conditional, Cond. This testsx1
and here is your second syntax error: the comparison term is missing. I strongly suspect it should bex
. That is, ifx=x1
, if the previous ID is the same as this ID, then return it as the result. Otherwise apply.z.s
tox1
andy
. Now.z.s
is a reference to the current function, so this is a recursion; it ends when the previous ID is just the ID.There is a simpler way to get there. We can use the Converge iterator to keep applying the
Id!PrevId
dictionary to the IDs until the results stop changing:update OriginalId:(Id!PrevId)/[Id] from table
This exploits implicit iteration. On each application of the dictionary all the IDs get mapped to their previous ones. So there is no need to iterate through each ID and then recurse to find its original.
-
count each field2
implies each item offield2
is a list its length to be counted- Similarly, the lambda
{x 1 0}
specifies the second and first items of a list, implyingfield1
is also nested
q)show t:([]field1:(2+5?3)?:`$string[til 10],'"m";field2:(1+5?5)?:5?`3) field1 field2 ------------------------------ `9m`1m `dmp`gce`gdp `4m`3m`9m `gce`dmp`dmp`nmo`gdp `8m`9m ,`icg `9m`5m`4m `icg`gce`nmo`nmo`gce `0m`4m`3m `dmp`icg`icg`gce q)select {x 1 0}each field1, #[;1b] each count each field2 from t field1 field2 ------------- 1m 9m 111b 3m 4m 11111b 9m 8m ,1b 5m 9m 11111b 4m 0m 1111b
Above:
- the second and first items from each list in
field1
- a boolean true for each symbol in the
field2
lists
Alternative expression:
q)select reverse each 2#'field1, not null field2 from t field1 field2 ------------- 1m 9m 111b 3m 4m 11111b 9m 8m ,1b 5m 9m 11111b 4m 0m 1111b