Parsing Blocks of Data in REBOL - parsing

I have (games scores) data in this format:
Hotspurs Giants 356 6 275 4 442 3
Fierce Lions Club 371 3 2520 5 0 4
Mountain Tigers 2519 2 291 6 342 1
Shooting Stars Club 2430 5 339 1 2472 2
Gun Tooters 329 4 2512 2 2470 6
Banshee Wolves 301 1 2436 3 412 5
The first two/three words represent the club's names, thereafter follows 6 blocks of data per row which represents the club's round-by-round scores and opponent index (starting from 1). In the data above 3 rounds have been played by each team. Hotspurs Giants (index 1) played Banshee Wolves (6) in the 1st round scoring 356 to Banshee's 301, in round 2 Hotspurs Giants played Shooting Stars Club (4) scoring 275 - 339 and in round 3 played Mountain Tigers (3) scoring 442 to Tiger's 342
My question is how to parse this blocks of data in the most efficient way possible such that each club's data will be in the format below considering that a club's name may comprise of two (2) or more words.
Viz
[Club Round Score Opponent Opponent-Score] for each club

Assuming data is:
data: [
Hotspurs Giants 356 6 275 4 442 3
Fierce Lions Club 371 3 2520 5 0 4
Mountain Tigers 2519 2 291 6 342 1
Shooting Stars Club 2430 5 339 1 2472 2
Gun Tooters 329 4 2512 2 2470 6
Banshee Wolves 301 1 2436 3 412 5
]
I think this solves the problem, please check the result:
clubs: copy []
parse data [
some [
copy club some word!
copy numbers some number!
(append clubs reduce [form club numbers])
|
skip
]
]
new-line/all/skip clubs yes 2
list: copy []
parse clubs [
some [
set club string! into [
copy numbers some number! (
i: 1
foreach [score index] numbers [
append list reduce [
club score
pick clubs index * 2 - 1
pick pick clubs index * 2 i
]
i: i + 2
]
)
]
| skip
]
]
new-line/all/skip list yes 4
Afterwards if you probe clubs you should get:
CLUBS is a block of value: [
"Hotspurs Giants" [356 6 275 4 442 3]
"Fierce Lions Club" [371 3 2520 5 0 4]
"Mountain Tigers" [2519 2 291 6 342 1]
"Shooting Stars Club" [2430 5 339 1 2472 2]
"Gun Tooters" [329 4 2512 2 2470 6]
"Banshee Wolves" [301 1 2436 3 412 5]
]
And if you probe list the output is:
LIST is a block of value: [
"Hotspurs Giants" 356 "Banshee Wolves" 301
"Hotspurs Giants" 275 "Shooting Stars Club" 339
"Hotspurs Giants" 442 "Mountain Tigers" 342
"Fierce Lions Club" 371 "Mountain Tigers" 2519
"Fierce Lions Club" 2520 "Gun Tooters" 2512
"Fierce Lions Club" 0 "Shooting Stars Club" 2472
"Mountain Tigers" 2519 "Fierce Lions Club" 371
"Mountain Tigers" 291 "Banshee Wolves" 2436
"Mountain Tigers" 342 "Hotspurs Giants" 442
"Shooting Stars Club" 2430 "Gun Tooters" 329
"Shooting Stars Club" 339 "Hotspurs Giants" 275
"Shooting Stars Club" 2472 "Fierce Lions Club" 0
"Gun Tooters" 329 "Shooting Stars Club" 2430
"Gun Tooters" 2512 "Fierce Lions Club" 2520
"Gun Tooters" 2470 "Banshee Wolves" 412
"Banshee Wolves" 301 "Hotspurs Giants" 356
"Banshee Wolves" 2436 "Mountain Tigers" 291
"Banshee Wolves" 412 "Gun Tooters" 2470
]

Here is one example (using Rebol 3) showing how this could be done:
club-data: map [] ; store data in hash map is one option
foreach line read/lines %games-scores.txt [
fields: split line space
; lets take last 6 cols of data
scores: reverse collect [loop 6 [keep to-integer take/last fields]]
; and whats left is the club name
club-name: form fields
; build club data
club-data/(club-name): scores
]
Above assumes data is in file games-scores.txt and returns you a MAP! (hash map) called club-data where your club data would look like this:
make map! [
"Hotspurs Giants" [356 6 275 4 442 3]
"Fierce Lions Club" [371 3 2520 5 0 4]
"Mountain Tigers" [2519 2 291 6 342 1]
"Shooting Stars Club" [2430 5 339 1 2472 2]
"Gun Tooters" [329 4 2512 2 2470 6]
"Banshee Wolves" [301 1 2436 3 412 5]
]
One caveat... READ/LINES will load whole file into memory. So if games-scores.txt is big you should look at using OPEN instead and read in one line at a time.
Update - re: your comment here is same example in Rebol 2 [tested in REBOL/Core 2.7.8.2.5 (2-Jan-2011)]:
club-data: make hash! [] ; of course doesn't have to be hash!
foreach line read/lines %games-scores.txt [
fields: parse line none
scores: reverse collect [loop 6 [keep to-integer take/last fields]]
club-name: form fields
append club-data reduce [club-name scores]
]

Related

IBrokers R API and same day intraday prices

I think this is be an IB API more than the IBrokers R package.
I am using reqHistoricalData to get 30 minutes intraday historical data. The market is open and I am not getting the same day's data. I only get yesterday's data.
Is it possible to get the same day intraday bar data?
here is the code I am using, it only gives data for the previous day, not same day.
library(tidyverse)
library(IBrokers)
tws = twsConnect()
contract <- twsEquity('VOD','SMART')
VOD_intraday = IBrokers::reqHistoricalData(tws, Contract = contract, endDateTime = "20210408 13:24:28", barSize = "1 min", duration = "1 D")
VOD_intraday %>% as.data.frame() %>% rownames_to_column(var = "time") %>% arrange(desc(time)) %>% head()
It's 13:27 GMT on 2021-04-08 and London is open. And here is the response - it only gives data from 2020-04-07:
> contract <- twsEquity('VOD','SMART')
> VOD_intraday = IBrokers::reqHistoricalData(tws, Contract = contract, endDateTime = "20210408 13:24:28", barSize = "1 min", duration = "1 D")
waiting for TWS reply on VOD .... done.
> VOD_intraday %>% as.data.frame() %>% rownames_to_column(var = "time") %>% arrange(desc(time)) %>% head()
time VOD.Open VOD.High VOD.Low VOD.Close VOD.Volume VOD.WAP VOD.hasGaps VOD.Count
1 2021-04-07 20:59:00 18.96 18.98 18.95 18.98 1131 18.958 0 265
2 2021-04-07 20:58:00 18.96 18.96 18.95 18.96 90 18.957 0 42
3 2021-04-07 20:57:00 18.96 18.97 18.95 18.95 258 18.960 0 72
4 2021-04-07 20:56:00 18.96 18.96 18.95 18.95 124 18.959 0 58
5 2021-04-07 20:55:00 18.96 18.96 18.95 18.96 56 18.958 0 34
6 2021-04-07 20:54:00 18.95 18.96 18.95 18.95 26 18.951 0 12
Instead of VOD, you can use SPY, MSFT or any US security while the US market is open.
Edit: It turns out you need realtime subscription to get same day data. The answer below works.
One has to specify the ending time, or leave it blank to get the most recent data available.
Try this:
VOD_intraday = IBrokers::reqHistoricalData(tws, Contract = contract, endTime = "", barSize = "1 min", duration = "1 D")
Here's the execution when I run it:
> library(tidyverse)
> library(IBrokers)
IBrokers version 0.9-10. Implementing API Version 9.64
IBrokers comes with NO WARRANTY. Not intended for production use!
See ?IBrokers for details.
> tws = twsConnect()
> contract <- twsEquity('SPY','SMART')
> VOD_intraday = IBrokers::reqHistoricalData(tws, Contract = contract, endDateTime = "", barSize = "1 min", duration = "1 D")
waiting for TWS reply on SPY ........... done.
> head(VOD_intraday)
SPY.Open SPY.High SPY.Low SPY.Close SPY.Volume SPY.WAP SPY.hasGaps SPY.Count
2021-04-08 07:30:00 407.93 407.98 407.68 407.80 5042 407.846 0 1709
2021-04-08 07:31:00 407.81 408.00 407.74 407.98 1615 407.844 0 1065
2021-04-08 07:32:00 407.99 408.05 407.81 407.90 2451 407.932 0 1560
2021-04-08 07:33:00 407.89 407.98 407.88 407.95 2353 407.932 0 1300
2021-04-08 07:34:00 407.95 407.97 407.81 407.81 1708 407.907 0 1012
2021-04-08 07:35:00 407.82 407.86 407.61 407.67 2729 407.726 0 1458
And for symbol VOD:
> contract <- twsEquity('VOD','SMART')
> VOD_intraday = IBrokers::reqHistoricalData(tws, Contract = contract, endDateTime = "", barSize = "1 min", duration = "1 D")
waiting for TWS reply on VOD .... done.
> head(VOD_intraday)
VOD.Open VOD.High VOD.Low VOD.Close VOD.Volume VOD.WAP VOD.hasGaps VOD.Count
2021-04-08 07:30:00 18.95 18.95 18.91 18.92 246 18.921 0 49
2021-04-08 07:31:00 18.91 18.91 18.90 18.90 69 18.905 0 31
2021-04-08 07:32:00 18.90 18.90 18.87 18.87 237 18.881 0 44
2021-04-08 07:33:00 18.87 18.87 18.86 18.87 45 18.870 0 20
2021-04-08 07:34:00 18.87 18.87 18.85 18.86 173 18.860 0 57
2021-04-08 07:35:00 18.86 18.87 18.85 18.86 39 18.859 0 19

Fixing joining two datasets with same variables

I want to join two datasets.
Datasets had same columns/ variables.
Dataset 1 (n11)
caseid v000 v005 age v021 v022 v023 v024 resi region v102 education pregnant v445 v501 v717 wealth stra occupation
1 101 15 2 NP6 342191 5 101 10 1 1 2 1 2 1 0 2190 1 4 4 NPIR61FL$ssubreg=1, NPIR61FL$v025=2 2
2 101 19 2 NP6 342191 7 101 10 1 1 2 1 2 0 0 2300 1 4 3 NPIR61FL$ssubreg=1, NPIR61FL$v025=2 2
3 101 19 4 NP6 342191 2 101 10 1 1 2 1 2 1 0 2139 1 4 3 NPIR61FL$ssubreg=1, NPIR61FL$v025=2 2
4 101 21 4 NP6 342191 5 101 10 1 1 2 1 2 0 0 1855 1 4 2 NPIR61FL$ssubreg=1, NPIR61FL$v025=2 2
5 101 45 3 NP6 342191 5 101 10 1 1 2 1 2 0 0 2133 3 4 3 NPIR61FL$ssubreg=1, NPIR61FL$v025=2 2
6 101 47 2 NP6 342191 1 101 10 1 1 2 1 2 2 0 2022 1 4 4 NPIR61FL$ssubreg=1, NPIR61FL$v025=2 2
Dataset 2 (n16)
caseid v000 v005 age v021 v022 v023 v024 resi region v102 education pregnant v445 v501 v717 wealth stra occupation
1 101 2 2 NP5 295061 6 101 1 1 1 2 1 2 0 0 2534 1 4 2 NPIR51FL$v024=1, NPIR51FL$v025=2 2
2 101 2 3 NP5 295061 1 101 1 1 1 2 1 2 2 0 2061 0 4 2 NPIR51FL$v024=1, NPIR51FL$v025=2 2
3 101 3 3 NP5 295061 1 101 1 1 1 2 1 2 2 0 2157 1 4 1 NPIR51FL$v024=1, NPIR51FL$v025=2 2
4 101 4 1 NP5 295061 4 101 1 1 1 2 1 2 0 0 2370 1 4 1 NPIR51FL$v024=1, NPIR51FL$v025=2 2
5 101 6 6 NP5 295061 2 101 1 1 1 2 1 2 3 0 2254 0 4 2 NPIR51FL$v024=1, NPIR51FL$v025=2 2
6 101 7 2 NP5 295061 2 101 1 1 1 2 1 2 2 0 2364 0 4 1 NPIR51FL$v024=1, NPIR51FL$v025=2 2
I used rbind function.
code was d2 <-rbind(n11, n16)
I found the following error. How can I fix this?
Error: Can't convert from <labelled<double>> to <labelled<double>> due to loss of precision.
* Locations: 5723, 5724, 5725, 5726, 5727, 5728, 5729, 5730, 5731, 5732, 5733, 5734, 5735, 5736, 5...
Values are labelled in `` but not in ``.
Run `rlang::last_error()` to see where the error occurred.
I have found the solution now.
We can use full_join function of dplyr package to solve this.
d2<- full_join(n11, n16)

Define a function : Fibonacci Sequence

Define a function to implement Fibonacci Sequence: 1, 1, 2, 3, 5, 8, 13, 21, 34. Please use the function output first 20 figures of Fibonacci Sequence.
Here is a python implementation
def fib(n):
a, b = 0, 1
while a < n:
print(a, end=' ')
a, b = b, a+b
print()
fib(5000)
Output
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181
A recursive implementation
memo = [-1] * 21
memo[0] = 0
memo[1] = 1
print(memo[0], end=' ')
print(memo[1], end=' ')
def fibrec(n):
if(memo[n] == -1):
memo[n] = fibrec(n-2) + fibrec(n-1)
print(memo[n], end=' ')
return memo[n]
fibrec(20)
Output
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765

LSTM predicting time series yields odd results

I'm trying to predict time series data for the next few days looking at past few days, using Keras. My label data is target values for multiple future days, regression model has multiple output neurons (the "direct approach" for time series).
Here is test data with predictions for 10 days, using 60 days history.
10 days prediction for test data
As you can see, future values for all days are about the same. I've spent quite some time on it, and must admit that I'm probably missing something with respect to LSTM...
Here is training data with prediction:
10 days prediction for training data
In order to confirm that I'm preparing data properly, I've created a "tracking data set" which I used to visualize data transformations. Here it is...
Data set:
Open,High,Low,Close,Volume,OpenInt
111,112,113,114,115,0
121,122,123,124,125,0
131,132,133,134,135,0
141,142,143,144,145,0
151,152,153,154,155,0
161,162,163,164,165,0
171,172,173,174,175,0
181,182,183,184,185,0
191,192,193,194,195,0
201,202,203,204,205,0
211,212,213,214,215,0
221,222,223,224,225,0
231,232,233,234,235,0
241,242,243,244,245,0
251,252,253,254,255,0
261,262,263,264,265,0
271,272,273,274,275,0
281,282,283,284,285,0
291,292,293,294,295,0
Training set using 2 days history, predicting 3 days future values (I used different values of history days and future days, and it all makes sense to me), without feature scaling in order to visualize data transformations:
X train (6, 2, 5)
[[[111 112 113 114 115]
[121 122 123 124 125]]
[[121 122 123 124 125]
[131 132 133 134 135]]
[[131 132 133 134 135]
[141 142 143 144 145]]
[[141 142 143 144 145]
[151 152 153 154 155]]
[[151 152 153 154 155]
[161 162 163 164 165]]
[[161 162 163 164 165]
[171 172 173 174 175]]]
Y train (6, 3)
[[131 141 151]
[141 151 161]
[151 161 171]
[161 171 181]
[171 181 191]
[181 191 201]]
Test set
X test (6, 2, 5)
[[[201 202 203 204 205]
[211 212 213 214 215]]
[[211 212 213 214 215]
[221 222 223 224 225]]
[[221 222 223 224 225]
[231 232 233 234 235]]
[[231 232 233 234 235]
[241 242 243 244 245]]
[[241 242 243 244 245]
[251 252 253 254 255]]
[[251 252 253 254 255]
[261 262 263 264 265]]]
Y test (6, 3)
[[221 231 241]
[231 241 251]
[241 251 261]
[251 261 271]
[261 271 281]
[271 281 291]]
Model:
def CreateRegressor(self,
optimizer='adam',
activation='tanh', # RNN activation
init_mode='glorot_uniform',
hidden_neurons=50,
dropout_rate=0.0,
weight_constraint=0,
stateful=False,
# SGD parameters
learn_rate=0.01,
momentum=0):
kernel_constraint = maxnorm(weight_constraint) if weight_constraint > 0 else None
model = Sequential()
model.add(LSTM(units=hidden_neurons, activation=activation, kernel_initializer=init_mode, kernel_constraint=kernel_constraint,
return_sequences=True, input_shape=(self.X_train.shape[1], self.X_train.shape[2]), stateful=stateful))
model.add(Dropout(dropout_rate))
model.add(LSTM(units=hidden_neurons, activation=activation, kernel_initializer=init_mode, kernel_constraint=kernel_constraint,
return_sequences=True, stateful=stateful))
model.add(Dropout(dropout_rate))
model.add(LSTM(units=hidden_neurons, activation=activation, kernel_initializer=init_mode, kernel_constraint=kernel_constraint,
return_sequences=True, stateful=stateful))
model.add(Dropout(dropout_rate))
model.add(LSTM(units=hidden_neurons, activation=activation, kernel_initializer=init_mode, kernel_constraint=kernel_constraint,
return_sequences=False, stateful=stateful))
model.add(Dropout(dropout_rate))
model.add(Dense(units=self.y_train.shape[1]))
if (optimizer == 'SGD'):
optimizer = SGD(lr=learn_rate, momentum=momentum)
model.compile(optimizer=optimizer, loss='mean_squared_error')
return model
...which I create with these params:
self.CreateRegressor(optimizer = 'adam', hidden_neurons = 100)
... and then fit like this:
self.regressor.fit(self.X_train, self.y_train, epochs=100, batch_size=32)
... and predict:
y_pred = self.regressor.predict(X_test)
... or
y_pred_train = self.regressor.predict(X_train)
What am I missing?

Try to simulate a neural network in MATLAB by myself

I tried to create a neural network to estimate y = x ^ 2. So I created a fitting neural network and gave it some samples for input and output. I tried to build this network in C++. But the result is different than I expected.
With the following inputs:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 -1
-2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71
and the following outputs:
0 1 4 9 16 25 36 49 64 81 100 121 144 169 196 225 256 289 324 361 400
441 484 529 576 625 676 729 784 841 900 961 1024 1089 1156 1225 1296
1369 1444 1521 1600 1681 1764 1849 1936 2025 2116 2209 2304 2401 2500
2601 2704 2809 2916 3025 3136 3249 3364 3481 3600 3721 3844 3969 4096
4225 4356 4489 4624 4761 4900 5041 1 4 9 16 25 36 49 64 81 100 121 144
169 196 225 256 289 324 361 400 441 484 529 576 625 676 729 784 841
900 961 1024 1089 1156 1225 1296 1369 1444 1521 1600 1681 1764 1849
1936 2025 2116 2209 2304 2401 2500 2601 2704 2809 2916 3025 3136 3249
3364 3481 3600 3721 3844 3969 4096 4225 4356 4489 4624 4761 4900 5041
I used fitting tool network. with matrix rows. Training is 70%, validation is 15% and testing is 15% as well. The number of hidden neurons is two. Then in command lines I wrote this:
purelin(net.LW{2}*tansig(net.IW{1}*inputTest+net.b{1})+net.b{2})
Other information :
My net.b[1] is: -1.16610230053776 1.16667147712026
My net.b[2] is: 51.3266249426358
And net.IW(1) is: 0.344272596370387 0.344111217766824
net.LW(2) is: 31.7635369693519 -31.8082184881063
When my inputTest is 3, the result of this command is 16, while it should be about 9. Have I made an error somewhere?
I found the Stack Overflow post Neural network in MATLAB that contains a problem like my problem, but there is a little difference, and the differences is in that problem the ranges of input and output are same, but in my problem is no. That solution says I need to scale out the results, but how can I scale out my result?
You are right about scaling. As was mentioned in the linked answer, the neural network by default scales the input and output to the range [-1,1]. This can be seen in the network processing functions configuration:
>> net = fitnet(2);
>> net.inputs{1}.processFcns
ans =
'removeconstantrows' 'mapminmax'
>> net.outputs{2}.processFcns
ans =
'removeconstantrows' 'mapminmax'
The second preprocessing function applied to both input/output is mapminmax with the following parameters:
>> net.inputs{1}.processParams{2}
ans =
ymin: -1
ymax: 1
>> net.outputs{2}.processParams{2}
ans =
ymin: -1
ymax: 1
to map both into the range [-1,1] (prior to training).
This means that the trained network expects input values in this range, and outputs values also in the same range. If you want to manually feed input to the network, and compute the output yourself, you have to scale the data at input, and reverse the mapping at the output.
One last thing to remember is that each time you train the ANN, you will get different weights. If you want reproducible results, you need to fix the state of the random number generator (initialize it with the same seed each time). Read the documentation on functions like rng and RandStream.
You also have to pay attention that if you are dividing the data into training/testing/validation sets, you must use the same split each time (probably also affected by the randomness aspect I mentioned).
Here is an example to illustrate the idea (adapted from another post of mine):
%%# data
x = linspace(-71,71,200); %# 1D input
y_model = x.^2; %# model
y = y_model + 10*randn(size(x)).*x; %# add some noise
%%# create ANN, train, simulate
net = fitnet(2); %# one hidden layer with 2 nodes
net.divideFcn = 'dividerand';
net.trainParam.epochs = 50;
net = train(net,x,y);
y_hat = net(x);
%%# plot
plot(x, y, 'b.'), hold on
plot(x, x.^2, 'Color','g', 'LineWidth',2)
plot(x, y_hat, 'Color','r', 'LineWidth',2)
legend({'data (noisy)','model (x^2)','fitted'})
hold off, grid on
%%# manually simulate network
%# map input to [-1,1] range
[~,inMap] = mapminmax(x, -1, 1);
in = mapminmax('apply', x, inMap);
%# propagate values to get output (scaled to [-1,1])
hid = tansig( bsxfun(#plus, net.IW{1}*in, net.b{1}) ); %# hidden layer
outLayerOut = purelin( net.LW{2}*hid + net.b{2} ); %# output layer
%# reverse mapping from [-1,1] to original data scale
[~,outMap] = mapminmax(y, -1, 1);
out = mapminmax('reverse', outLayerOut, outMap);
%# compare against MATLAB output
max( abs(out - y_hat) ) %# this should be zero (or in the order of `eps`)
I opted to use the mapminmax function, but you could have done that manually as well. The formula is a pretty simply linear mapping:
y = (ymax-ymin)*(x-xmin)/(xmax-xmin) + ymin;

Resources