Skip to content

Commit 60fa7eb

Browse files
committed
Implements faster format_POSIXct(), thanks @gaborcsardi
1 parent 8820c27 commit 60fa7eb

File tree

9 files changed

+81
-34
lines changed

9 files changed

+81
-34
lines changed

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export(autostrat)
2020
export(coredata)
2121
export(df_append)
2222
export(df_merge)
23+
export(format_POSIXct)
2324
export(grid_dup)
2425
export(hasStrat)
2526
export(ichimoku)

NEWS.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# ichimoku 1.5.5.9000 (development)
22

3+
#### New features:
4+
5+
* `format_POSIXct()` is a much faster equivalent of the base R `format.POSIXct()`, used internally and exported as a utility.
6+
37
# ichimoku 1.5.5
48

59
#### New features:

R/iplot.R

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (C) 2021-2023 Hibiki AI Limited <info@hibiki-ai.com>
1+
# Copyright (C) 2021-2025 Hibiki AI Limited <info@hibiki-ai.com>
22
#
33
# This file is part of ichimoku.
44
#
@@ -78,7 +78,7 @@ iplot <- function(x,
7878
tformat <- if (attr(x, "periodicity") > 80000) "%F" else "%F %T"
7979
start <- index.ichimoku(x, 1L)
8080
end <- index.ichimoku(x, dims[1L])
81-
xadj <- if (nchar(format.POSIXct(start)) > 10) -17 else 5
81+
xadj <- if (nchar(format_POSIXct(start)) > 10) -17 else 5
8282

8383
ui <- fluidPage(
8484
tags$head(tags$style("
@@ -210,7 +210,7 @@ drawInfotip <- function(sidx, sdata, left, top, type, custom = NULL) {
210210
<div style='text-align: center; margin: 0; padding: 0'>L: %.5g</div>
211211
<div style='margin: 2px 0 0 0; padding: 0'>Tenkan: %.5g<br />Kijun: %.5g<br />Senkou A: %.5g<br />Senkou B: %.5g<br />Chikou: %.5g%s</div>",
212212
if (is.na(cd) || cd == 0) "&#8212;" else if (cd == 1) "&#9651;" else if (cd == -1) "&#9660;",
213-
format.POSIXct(sidx), sdata[["high"]], sdata[["open"]], sdata[["close"]], sdata[["low"]],
213+
format_POSIXct(sidx), sdata[["high"]], sdata[["open"]], sdata[["close"]], sdata[["low"]],
214214
sdata[["tenkan"]], sdata[["kijun"]], sdata[["senkouA"]], sdata[["senkouB"]], sdata[["chikou"]],
215215
switch(
216216
type,

R/methods.R

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (C) 2021-2023 Hibiki AI Limited <info@hibiki-ai.com>
1+
# Copyright (C) 2021-2025 Hibiki AI Limited <info@hibiki-ai.com>
22
#
33
# This file is part of ichimoku.
44
#
@@ -85,10 +85,10 @@ str.ichimoku <- function(object, ...) {
8585
dims <- attr(object, "dim")
8686
if (is.null(dims)) {
8787
xlen <- length(object)
88-
dates <- format.POSIXct(index.ichimoku(object, c(1L, xlen)))
88+
dates <- format_POSIXct(index.ichimoku(object, c(1L, xlen)))
8989
cat("ichimoku object with no dimensions\nVector <numeric> w/ length:", xlen, file = stdout())
9090
} else {
91-
dates <- format.POSIXct(index.ichimoku(object, c(1L, dims[1L])))
91+
dates <- format_POSIXct(index.ichimoku(object, c(1L, dims[1L])))
9292
cat("ichimoku object [", dates[1L], " / ", dates[2L], "] (",
9393
dims[1L], ", ", dims[2L], ")", if (hasStrat(object)) " w/ strat",
9494
"\n <double> $", file = stdout(), sep = "")
@@ -171,7 +171,7 @@ summary.ichimoku <- function(object, strat = TRUE, ...) {
171171
end <- sum(!is.na(core[, "close"]))
172172
high <- which.max(core[1:end, "high"])
173173
low <- which.min(core[1:end, "low"])
174-
dates <- format.POSIXct(index.ichimoku(object, c(1L, high, low, end)))
174+
dates <- format_POSIXct(index.ichimoku(object, c(1L, high, low, end)))
175175
cat("\n Max: ", dates[2L], " [", core[high, "high"],
176176
"]\nStart: ", dates[1L], " [", core[1L, "open"],
177177
"] End: ", dates[4L], " [", core[end, "close"],
@@ -262,20 +262,23 @@ NULL
262262
#' @method coredata ichimoku
263263
#' @export
264264
#'
265-
coredata.ichimoku <- function(x, fmt, ...)
266-
if (missing(fmt))
267-
.Call(ichimoku_coredata, x) else if (is.null(attr(x, "dim")))
268-
`attributes<-`(
269-
x,
270-
list(names = if (is.character(fmt)) format.POSIXct(index.ichimoku(x), format = fmt) else
271-
format.POSIXct(index.ichimoku(x)))
272-
) else
273-
`attributes<-`(
274-
x,
275-
list(dim = attr(x, "dim"),
276-
dimnames = list(if (is.character(fmt)) format.POSIXct(index.ichimoku(x), format = fmt) else
277-
format.POSIXct(index.ichimoku(x)), attr(x, "dimnames")[[2L]]))
278-
)
265+
coredata.ichimoku <- function(x, fmt, ...) {
266+
missing(fmt) && return(.Call(ichimoku_coredata, x))
267+
if (is.null(attr(x, "dim"))) {
268+
`attributes<-`(
269+
x,
270+
list(names = if (is.character(fmt)) format.POSIXct(index.ichimoku(x), format = fmt) else
271+
format_POSIXct(index.ichimoku(x)))
272+
)
273+
} else {
274+
`attributes<-`(
275+
x,
276+
list(dim = attr(x, "dim"),
277+
dimnames = list(if (is.character(fmt)) format.POSIXct(index.ichimoku(x), format = fmt) else
278+
format_POSIXct(index.ichimoku(x)), attr(x, "dimnames")[[2L]]))
279+
)
280+
}
281+
}
279282

280283
#' @name index
281284
#' @rdname index.ichimoku
@@ -311,7 +314,7 @@ NULL
311314
#' @method index ichimoku
312315
#' @export
313316
#'
314-
index.ichimoku <- function(x, subset, ...)
315-
if (missing(subset))
316-
.Call(ichimoku_index, x) else
317-
.Call(ichimoku_psxct, .subset(attr(x, "index"), subset))
317+
index.ichimoku <- function(x, subset, ...) {
318+
missing(subset) && return(.Call(ichimoku_index, x))
319+
.Call(ichimoku_psxct, .subset(attr(x, "index"), subset))
320+
}

R/mltools.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (C) 2021-2023 Hibiki AI Limited <info@hibiki-ai.com>
1+
# Copyright (C) 2021-2025 Hibiki AI Limited <info@hibiki-ai.com>
22
#
33
# This file is part of ichimoku.
44
#
@@ -284,7 +284,7 @@ mlgrid <- function(x,
284284

285285
veclist <- switch(y, none = veclist, c(list(y = target), veclist))
286286
grid <- do.call(cbind, veclist)
287-
dimnames(grid)[[1L]] <- format.POSIXct(index.ichimoku(x))
287+
dimnames(grid)[[1L]] <- format_POSIXct(index.ichimoku(x))
288288
grid <- .Call(ichimoku_naomit, grid)
289289

290290
if (type == "z-score") {

R/oanda.R

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (C) 2021-2024 Hibiki AI Limited <info@hibiki-ai.com>
1+
# Copyright (C) 2021-2025 Hibiki AI Limited <info@hibiki-ai.com>
22
#
33
# This file is part of ichimoku.
44
#
@@ -941,7 +941,7 @@ oanda_view <- function(market = c("allfx", "bonds", "commodities", "fx", "metals
941941
timestamp = time)
942942
)
943943

944-
cat("\n", format.POSIXct(time), " / ", price, "\n", file = stdout(), sep = "")
944+
cat("\n", format_POSIXct(time), " / ", price, "\n", file = stdout(), sep = "")
945945
print(df)
946946

947947
}
@@ -980,7 +980,7 @@ oanda_quote <- function(instrument, price = c("M", "B", "A"), server, apikey) {
980980
server = server, apikey = apikey, .validate = FALSE)
981981
pctchg <- 100 * (data[["c"]] / data[["o"]] - 1)
982982
cat(sprintf("%s %s open: %.6g high: %.6g low: %.6g last:\u001b[7m %.6g \u001b[27m %%chg: %.4f %s\n",
983-
instrument, format.POSIXct(.Call(ichimoku_psxct, data[["t"]])),
983+
instrument, format_POSIXct(.Call(ichimoku_psxct, data[["t"]])),
984984
data[["o"]], data[["h"]], data[["l"]], data[["c"]], pctchg, price), file = stdout())
985985

986986
}
@@ -1063,7 +1063,7 @@ oanda_positions <- function(instrument, time, server, apikey) {
10631063
scale_y_continuous(),
10641064
labs(x = "Price", y = "% short / % long",
10651065
title = paste0("OANDA Position Book: ", instrument, " at ",
1066-
format.POSIXct(timestamp), " / Current Price: ", currentprice)),
1066+
format_POSIXct(timestamp), " / Current Price: ", currentprice)),
10671067
coord_flip(),
10681068
theme_ichimoku_light()
10691069
)
@@ -1158,7 +1158,7 @@ oanda_orders <- function(instrument, time, server, apikey) {
11581158
scale_y_continuous(),
11591159
labs(x = "Price", y = "% short / % long",
11601160
title = paste0("OANDA Order Book: ", instrument, " at ",
1161-
format.POSIXct(timestamp), " / Current Price: ", currentprice)),
1161+
format_POSIXct(timestamp), " / Current Price: ", currentprice)),
11621162
coord_flip(),
11631163
theme_ichimoku_light()
11641164
)

R/utils.R

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (C) 2021-2023 Hibiki AI Limited <info@hibiki-ai.com>
1+
# Copyright (C) 2021-2025 Hibiki AI Limited <info@hibiki-ai.com>
22
#
33
# This file is part of ichimoku.
44
#
@@ -364,6 +364,23 @@ more <- function(rows)
364364
#'
365365
is.ichimoku <- function(x) .Call(ichimoku_isichimoku, x)
366366

367+
#' Format POSIXct
368+
#'
369+
#' Converts a POSIXct double timestamp into a character string much faster
370+
#' than \code{\link{format.POSIXct}}.
371+
#'
372+
#' @param x an object of class \sQuote{POSIXct}.
373+
#'
374+
#' @return A character string
375+
#'
376+
#' @examples
377+
#' format_POSIXct(Sys.time())
378+
#'
379+
#' @export
380+
#'
381+
format_POSIXct <- function(x)
382+
format.POSIXlt(as.POSIXlt.POSIXct(x, tz = "UTC"), "%Y-%m-%d %H:%M:%S")
383+
367384
#' match.arg Replacement
368385
#'
369386
#' Internal version of match.arg used to return an integer value for integer

man/format_POSIXct.Rd

Lines changed: 22 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vignettes/xoanda.Rmd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,7 @@ layers <- list(
538538
ggplot2::scale_y_continuous(),
539539
ggplot2::labs(x = "Price", y = "% short / % long",
540540
title = paste0("OANDA Position Book: ", instrument, " at ",
541-
format.POSIXct(timestamp), " / Current Price: ", currentprice)),
541+
format_POSIXct(timestamp), " / Current Price: ", currentprice)),
542542
ggplot2::coord_flip(),
543543
ichimoku:::theme_ichimoku_light()
544544
)

0 commit comments

Comments
 (0)