Skip to content

Commit 80c606a

Browse files
committed
br-libs dir
1 parent 7158e1c commit 80c606a

File tree

13 files changed

+5443
-0
lines changed

13 files changed

+5443
-0
lines changed

src/br-libs/bloomr-bbg.R

Lines changed: 372 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,372 @@
1+
## ----store, opts.label='purlme'----------------------------------------------------------------------------------------------------
2+
## Purl this first
3+
## Store br.* objects in dedicated namespace
4+
bloomr.bbg <- new.env(parent=asNamespace("stats"))
5+
6+
## func: store(func); var: store("var")
7+
store=function(sym){
8+
if(is.function(sym)){
9+
name=deparse(substitute(sym))
10+
val=sym
11+
} else {
12+
name=sym
13+
val=get(sym)
14+
}
15+
16+
assign(name, val, envir=bloomr.bbg)
17+
rm(list=name, envir=parent.frame())
18+
}
19+
20+
21+
## ----br.bdh, opts.label='purlme'---------------------------------------------------------------------------------------------------
22+
br.bdh=function(
23+
con, securities, fields="PX_LAST", start.date, end.date = NULL,
24+
option.names = NULL, option.values = NULL,
25+
always.display.tickers = FALSE, dates.as.row.names = (length(securities) == 1),
26+
include.non.trading.days = NULL
27+
) {
28+
if(is.null(con)) stop("'con' is NULL, but br.bdh() does not support simulated mode.")
29+
bdh(con, securities, fields, start.date, end.date, override_fields = NULL, override_values = NULL,
30+
option.names, option.values, always.display.tickers, dates.as.row.names,
31+
include.non.trading.days)
32+
}
33+
store(br.bdh)
34+
35+
## ----br.bulk.csv, opts.label='purlme'----------------------------------------------------------------------------------------------
36+
br.bulk.csv=function(con, file, start=Sys.Date()-5, field="PX_LAST", cols=NULL,
37+
addtype=FALSE, showtype=FALSE, use.xts=TRUE, comma=TRUE,
38+
price=TRUE, nrow=5, same.dates=FALSE, no.na=FALSE, empty.sec=0
39+
)
40+
{
41+
42+
## Check csv file
43+
if(!file.exists(file)) stop(paste('Unable to find the csv file', file))
44+
if(comma) csv=read.csv(file=file, as.is=TRUE) else{
45+
csv=read.csv2(file=file, as.is=TRUE)}
46+
47+
## Check cols arg
48+
if(!is.null(cols)){
49+
if(is.logical(cols) && !length(cols)==ncol(csv))
50+
stop(paste('Length of logical vector', paste(cols, collapse=' '),
51+
'not equal to number of groups in', file))
52+
53+
if(is.integer(cols) && max(cols)>ncol(csv))
54+
stop(paste('Unable to subset groups in', file, 'with columns', paste(cols, collapse=' ')))
55+
56+
if(!is.logical(cols) && !all(cols%%1==0)) stop(paste(
57+
"'Col argument should be an integer or a logical vector of the same length of the groups in", file))
58+
csv=csv[cols]
59+
}
60+
61+
## Get group names and count
62+
gnams=names(csv)
63+
gcnt=ncol(csv)
64+
65+
## Loop groups in csv
66+
grps=list()
67+
for(g in 1:gcnt){
68+
message('Processing ', gnams[g], ' ...')
69+
x=list(br.bulk.tiks(con, csv[[g]],
70+
start, field, addtype, showtype, use.xts,
71+
price=price, nrow=nrow, same.dates=FALSE, no.na=FALSE, empty.sec=empty.sec))
72+
names(x)=gnams[g]
73+
grps=c(grps, x)
74+
}
75+
if(length(grps)==1) grps=grps[[1]]
76+
grps
77+
}
78+
store(br.bulk.csv)
79+
80+
## ----br.bulk.desc, opts.label='purlme'---------------------------------------------------------------------------------------------
81+
br.bulk.desc=function(con, tiks) {
82+
83+
LL = lapply(tiks, function(tik){
84+
message('Reading ', tik)
85+
br.desc(con, tik)
86+
})
87+
names(LL)=tiks
88+
LL
89+
}
90+
store(br.bulk.desc)
91+
92+
## ----br.bulk.idx, opts.label='purlme'----------------------------------------------------------------------------------------------
93+
br.bulk.idx=function(con, index, start=Sys.Date()-5, field="PX_LAST", showtype=FALSE,
94+
include.idx=TRUE, use.xts=TRUE,
95+
nsec=10, price=TRUE, nrow=5,
96+
same.dates=FALSE, no.na=FALSE, empty.sec=0, sec.names = NULL
97+
)
98+
{
99+
100+
## Check connection
101+
if(!is.null(con) && !.br.is.con(con)) stop('Invalid connection parameter')
102+
103+
## Check index format. Add 'INDEX' if missing
104+
if(!is.character(index)) stop('Index should be a string')
105+
if(length(index)>1) stop('Only one index')
106+
if(!grepl("INDEX$", toupper(index))) index=paste(index, 'INDEX')
107+
108+
## Get index members
109+
if(is.null(con)) tiks=paste0('memb', 1:nsec) else{
110+
tiks=bds(con, index, 'INDX_MEMBERS')
111+
tiks=paste(tiks[[1]], 'Equity')
112+
}
113+
114+
## Check sec.names
115+
if(is.null(con) && !is.null(sec.names)) {
116+
if(!is.character(sec.names)) stop("'sec.names' should be a character vector")
117+
if(length(sec.names)!=nsec) stop("'sec.names' length should be equal to the number of index constituents")
118+
tiks=sec.names
119+
}
120+
121+
## Include index?
122+
if(include.idx) tiks=c(tiks, index)
123+
124+
## Get data
125+
br.bulk.tiks(
126+
con=con,
127+
tiks=tiks,
128+
start=start,
129+
field=field,
130+
addtype=FALSE,
131+
showtype=showtype,
132+
use.xts=use.xts,
133+
price=price,
134+
nrow=nrow,
135+
same.dates=same.dates,
136+
no.na=no.na,
137+
empty.sec=empty.sec
138+
)
139+
}
140+
store(br.bulk.idx)
141+
142+
## ----br.bulk.tiks, opts.label='purlme'---------------------------------------------------------------------------------------------
143+
br.bulk.tiks=function(
144+
con,
145+
tiks,
146+
start=Sys.Date()-5, field="PX_LAST",
147+
addtype=FALSE, showtype=FALSE, use.xts=TRUE,
148+
price=TRUE, nrow=5, same.dates=FALSE, no.na=FALSE, empty.sec=0
149+
)
150+
{
151+
152+
## Check connection
153+
if(!is.null(con) && !.br.is.con(con)) stop('Invalid connection parameter')
154+
155+
## Check tickers (skip possible empty CSV cells)
156+
if(!is.character(tiks)) stop('Tickers should be in the form of a character vector')
157+
tiks=tiks[!is.na(tiks)]
158+
tiks=tiks[tiks!='']
159+
160+
## Check start date
161+
if(is.na(as.Date(start, format='%Y%m%d'))) stop(paste('Invalida date', start))
162+
163+
## Check security type to add/show
164+
.br.check.type(addtype)
165+
.br.check.type(showtype)
166+
if(addtype==TRUE) addtype="Equity"
167+
if(addtype!=FALSE) tiks=paste(tiks, addtype)
168+
if(!showtype) tiks.show=.br.cuttype(tiks) else tiks.show=tiks
169+
170+
## Check xts library availability
171+
if(use.xts && !require("xts", quietly=TRUE, character.only=TRUE)) stop("Can't find library xts")
172+
173+
## Get data as an xts class
174+
if(use.xts){
175+
LL = lapply(tiks, function(tik){
176+
message('Loading ', tik)
177+
if(!is.null(con)) x=br.bdh(con, tik, field, start) else {
178+
x=br.sample(nrow, 1, price=price, start=start,
179+
df=TRUE, same.dates=same.dates, no.na=no.na,
180+
sec.names=c('date', field))
181+
}
182+
x=xts(x[-1], as.Date (x[[1]]))
183+
if(nrow(x)==0) x=NA else x
184+
})
185+
186+
## Randomly identify empty.sec
187+
if(is.null(con)){
188+
x=round(length(tiks.show) * empty.sec)
189+
empty=sample(length(tiks.show), x)
190+
LL[empty] = NA
191+
}
192+
193+
##print(LL ) ###################
194+
## If there are only NAs, output an empty xts else merge ts and in simul. mode use no.na val
195+
if(all(is.na(LL))) LL=na.omit(xts(t(unlist(LL)), Sys.Date())) else {
196+
# if(!is.null(con)) no.na=FALSE # in merge c(LL, all=!no.na)
197+
if(length(LL)>1) LL=do.call("merge.xts", LL) else LL=LL[[1]]
198+
}
199+
200+
## Set labels
201+
if(nrow(LL)>0) names(LL) = tiks.show else dimnames(LL)= list(NULL,tiks.show)
202+
LL
203+
204+
} else {
205+
## Get data in list format
206+
LL=lapply(tiks, function(tik){
207+
message('Loading ', tik)
208+
if(!is.null(con)) br.bdh(con, tik, field, start) else {
209+
br.sample(nrow, 1, price=price, empty.sec=empty.sec, start=start,
210+
df=TRUE, sec.names=c('date', field))
211+
}
212+
})
213+
214+
## Randomly identify empty.sec
215+
if(is.null(con)){
216+
x=round(length(tiks.show) * empty.sec)
217+
empty=sample(length(tiks.show), x)
218+
LL[empty] = NA
219+
}
220+
221+
setNames(LL, tiks.show)
222+
}
223+
}
224+
store(br.bulk.tiks)
225+
226+
## ----br.desc, opts.label='purlme'--------------------------------------------------------------------------------------------------
227+
br.desc=function(con, tik)
228+
{
229+
230+
## Check connection
231+
if(!.br.is.con(con)) stop('Invalid connection parameter')
232+
233+
## Check ticker format
234+
if(!is.character(tik)) stop('The ticker should be a string')
235+
if(length(tik)>1) stop('Only one ticker')
236+
237+
## Short description fields as data frame
238+
des=paste0('ds00', 1:9)
239+
des=des[-7] # not usually working
240+
x=bdp(con, tik, des)
241+
x=data.frame(t(x), stringsAsFactors=FALSE)
242+
243+
## Long description field
244+
xx=bds(con, tik, 'CIE_DES_BULK')
245+
246+
## Merge fields add long desc to DF
247+
if(!is.null(xx)) colnames(xx) = colnames(x)
248+
rnams=c(rownames(x), rownames(xx))
249+
x=rbind(x,xx)
250+
rownames(x)=rnams
251+
x
252+
}
253+
store(br.desc)
254+
255+
## ----br.sample, opts.label='purlme'------------------------------------------------------------------------------------------------
256+
br.sample=function(nrow, nsec=1, price=TRUE, start=Sys.Date(), mean=ifelse(price, 10, 0.1), sd=1,
257+
jitter=0, same.dates=FALSE, no.na=FALSE, df=FALSE, empty.sec=0, sec.names=NULL)
258+
{
259+
260+
if(!require("xts", quietly=TRUE, character.only=TRUE)) stop("Can't find library xts")
261+
262+
## Start can be Date class or ISO string without sep
263+
if(is.na(as.Date(start, format='%Y%m%d'))) stop(paste('Invalida date', start)) else
264+
start=as.Date(start, '%Y%m%d')
265+
266+
## Check sec.names
267+
if(!is.null(sec.names)) {
268+
if(!is.character(sec.names)) stop("'sec.names' should be a character vector")
269+
if(!df && length(sec.names)!=nsec) stop("'sec.names' length should be equal to 'nsec'")
270+
if(df && length(sec.names)!=nsec+1) stop("'sec.names' length should be equal to 'nsec'+1")
271+
}
272+
273+
## Check empty.sec is a ratio
274+
if(empty.sec<0 || empty.sec>1) stop("'empty.sec' must be between 0 and 1")
275+
276+
## Randomly identify empty.sec
277+
x=round(nsec * empty.sec)
278+
empty=sample(nsec, x)
279+
280+
## Make xts matrix
281+
tss=lapply(1:nsec, function(col){
282+
283+
## Jitter
284+
mean.jit= mean + runif(1, -jitter, jitter)
285+
286+
## Generate TS with fixed or random dates
287+
if(same.dates) r=nrow else r=sample(1:nrow,1)
288+
289+
## Generate column if not among the empty ones
290+
if(col %in% empty){
291+
x=NA
292+
} else {
293+
x=xts(round(rnorm(r,mean.jit, sd),3), sort(sample(start+1:nrow-1,r)))
294+
if(price) coredata(x)=abs(coredata(x)) # Price always non-negative
295+
}
296+
297+
x
298+
})
299+
300+
## If there are only NAs cells output an empty date/val xts else merge and fill empty cells with NAs
301+
if(all(is.na(tss))) tss=na.omit(xts(t(unlist(tss)), Sys.Date())) else {
302+
if(length(tss)>1) tss=do.call("merge.xts", tss) else
303+
tss=tss[[1]]
304+
}
305+
306+
## Remove NAs
307+
if(no.na) tss=na.omit(tss)
308+
309+
## Set labels
310+
x=paste0('sample', 1:ncol(tss))
311+
if(nrow(tss)>0) names(tss) = x else dimnames(tss)= list(NULL,x)
312+
313+
## Convert to data frame
314+
if(df) tss=data.frame(date=time(tss), tss)
315+
316+
if(is.null(sec.names)) tss else
317+
setNames(tss, sec.names)
318+
319+
}
320+
store(br.sample)
321+
322+
## ----bbg-internal, opts.label='purlme'---------------------------------------------------------------------------------------------
323+
324+
## Check connection token
325+
.br.is.con=function(con) identical(attr(con, 'jclass'), "org/findata/blpwrapper/Connection")
326+
327+
## Legal security types
328+
.br.types=c('Govt', 'Corp', 'Mtge', 'M-Mkt', 'Muni', 'Pfd', 'Equity', 'Comdty', 'Index', 'Curncy')
329+
330+
## Check security type
331+
.br.check.type=function(type) {
332+
if(is.character(type)){
333+
x=toupper(type)
334+
xx=toupper(.br.types)
335+
if(!any(xx %in% x)) stop(paste(x, 'not in', paste(xx, collapse=' ')))
336+
}
337+
}
338+
339+
## Cut trailing security type from character vector
340+
.br.cuttype=function(type){
341+
p=paste0(' +', .br.types, '$|', collapse='')
342+
p=sub('\\|$', '', p)
343+
sub(p, '', type, ignore.case=TRUE)
344+
}
345+
346+
347+
.br.jar=function(){
348+
jarpath=.br.home("/blpapi/bin")
349+
Sys.glob(file.path(jarpath, "blpapi-[0-9]*.jar"))
350+
}
351+
352+
353+
store(.br.is.con)
354+
store(".br.types")
355+
store(.br.check.type)
356+
store(.br.cuttype)
357+
store(.br.jar)
358+
359+
## ----connections, opts.label='purlme'----------------------------------------------------------------------------------------------
360+
br.open=function() blpConnect(blpapi.jar.file=.br.jar())
361+
br.close=function(conn) if(!is.null(conn)) blpDisconnect(conn)
362+
363+
store(br.open)
364+
store(br.close)
365+
366+
## ----attach, opts.label='purlme'---------------------------------------------------------------------------------------------------
367+
### Make visible br.* in bloomr env and base ns
368+
attach(bloomr.bbg)
369+
rm(store)
370+
rm(bloomr.bbg)
371+
372+

0 commit comments

Comments
 (0)