Reputation: 101
I'm trying to build a stock index and I'm using Q for the purpose. As you can probably tell, I'm very new at this. Whereas I've built it in SQL, it takes way too long to process, hence my resorting to Q.
The setup so far is the following:
The table; add data to the table, sort it:
tickers:`ibm`bac`dis`gs`ibm`gs`dis`bac
pxs:100 50 30 250 110 240 45 48
dates:2013.05.01 2013.01.05 2013.02.03 2013.02.11 2013.06.17 2013.06.21 2013.04.24 2013.01.06
sectors:`auto`money`funny`money`auto`money`funny`money
trades:([sectors;tickers;dates];pxs)
`sectors`dates`tickers xasc `trades
The processing so far (thanks to other friendly SO users):
I've calculated by how much has each stock price changes from the previous time the price was recorded
trades: update delta:{0,1_deltas x}pxs by tickers from trades
I've calculated the total market value of the components of the sectorial index
trades: update idxmv:sums[?[delta<>0;delta;pxs]] by sectors from trades
How it looks:
sectors tickers dates | pxs delta idxmv
--------------------------| ---------------
auto ibm 2013.05.01| 100 0 100
auto ibm 2013.06.17| 110 10 110
funny dis 2013.02.03| 30 0 30
funny dis 2013.04.24| 45 15 45
money bac 2013.01.05| 50 0 50
money bac 2013.01.06| 48 -2 48
money gs 2013.02.11| 250 0 298
money gs 2013.06.21| 240 -10 288
What I want to do:
I want compute a sector index, that changes when its components change; in order to do this I need to compute a divisor column and the actual index column. The logic I'm trying to implement is as follows:
delta != 0
, then divisor = the last value of the divisor, in the same sector
delta != 0
, then index = idxmv % the value of the divisor computed above
delta = 0
, then index = the last value of the index, in the same sector
delta = 0
, then divisor = idxmv % the value of the index computed above
, where the initial value of the index is 100; all the sector have a starting value of the index of 100So essentially, what I want to end up with, is something similar to the below:
sectors tickers dates | pxs delta idxmv divisor index
--------------------------| ------------------------------
auto ibm 2013.05.01| 100 0 100 1 100
auto ibm 2013.06.17| 110 10 110 1 110
funny dis 2013.02.03| 30 0 30 0.30 100
funny dis 2013.04.24| 45 15 45 0.30 150
money bac 2013.01.05| 50 0 50 0.50 100
money bac 2013.01.06| 48 -2 48 0.50 96
money gs 2013.02.11| 250 0 298 3.10 96
money gs 2013.06.21| 240 -10 288 3.10 92.78
Thanks for your help,
Dan
Upvotes: 1
Views: 652
Reputation: 131
trades1:update index:{100f,1_count[x]#0n}[delta] by sectors from trades; / starting value of index as 100
trades1:update divisor:?[delta=0;idxmv%index;0n] by sectors from trades1; / divisor=y%z when delta=0
trades1:update divisor:?[delta<>0;fills divisor;divisor] by sectors from trades1; / divisor=last divisor when delta <> 0
trades1:update index:?[delta<>0;idxmv%divisor;index] by sectors from trades1; / index=i%d when delta <>0
trades1:update index:?[delta=0;fills index;index] by sectors from trades1 / index=last index when delta=0
trades1:update divisor:?[delta=0;idxmv%index;divisor] by sectors from trades1; /divisor=y%z when delta=0
This should solve your problem.
The last row doesn't seem to be matching.I have taken sectors as a primary key.You should be able to match the last row by changing the primary key to sectors/tickers.
Upvotes: 2