Hi, TTR/xts/quantmod maintainer here. On Sun, Jan 5, 2025 at 10:58?AM Sparks, John <jspark4 at uic.edu> wrote:> > Hi, > > In looking at the documentation for the TTR library and particularly the > example for calculating the ATR (average true range). The example shows > how to calculate ATR for a file of a single stock. > > If I have multiple stocks in one file, isn't there a way to get the ATR > for each of them? Or does one have to break out each stock and calculate > the ATR separately using some sort of loop. >Yes, the TTR functions only work on a single stock at a time.> In terms of a reproducible example, the file below contains open, high, > low, close, etc. for AAPL and then MSFT. >Thanks for the reproducible data!> If the ATR calculation were fully working, then there would be blanks for > records 41 through 54 and then the ATR calculation would start up again. > > Guidance would be very much appreciated. > > --John Sparks > > > Hist<- > structure(list(symbol = c("AAPL", "AAPL", "AAPL", "AAPL", "AAPL", > "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", > "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", > "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", > "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", > "AAPL", "AAPL", "AAPL", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", > "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", > "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", > "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", > "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", > "MSFT", "MSFT", "MSFT"), date = structure(c(20033, 20034, 20035, > 20038, 20039, 20040, 20041, 20042, 20045, 20046, 20047, 20048, > 20049, 20052, 20053, 20054, 20056, 20059, 20060, 20061, 20062, > 20063, 20066, 20067, 20068, 20069, 20070, 20073, 20074, 20075, > 20076, 20077, 20080, 20081, 20083, 20084, 20087, 20088, 20090, > 20091, 20033, 20034, 20035, 20038, 20039, 20040, 20041, 20042, > 20045, 20046, 20047, 20048, 20049, 20052, 20053, 20054, 20056, > 20059, 20060, 20061, 20062, 20063, 20066, 20067, 20068, 20069, > 20070, 20073, 20074, 20075, 20076, 20077, 20080, 20081, 20083, > 20084, 20087, 20088, 20090, 20091), class = "Date"), open = c(222.61, > 224.63, 227.17, 225, 224.55, 224.01, 225.02, 226.4, 225.25, 226.98, > 228.06, 228.88, 228.06, 231.46, 233.33, 234.47, 234.81, 237.27, > 239.81, 242.87, 243.99, 242.91, 241.83, 246.89, 247.96, 246.89, > 247.82, 247.99, 250.08, 252.16, 247.5, 248.04, 254.77, 255.49, > 258.19, 257.83, 252.23, 252.44, 248.93, 243.36, 412.42, 421.28, > 425.32, 422.52, 418.25, 421.64, 425, 419.82, 414.87, 413.11, > 416.87, 419.5, 411.37, 418.38, 419.59, 425.11, 420.09, 421.57, > 429.84, 433.03, 437.92, 442.3, 442.6, 444.39, 444.05, 449.11, > 448.44, 447.27, 451.01, 451.32, 441.62, 433.11, 436.74, 434.65, > 439.08, 434.6, 426.06, 426.1, 425.53, 421.08), high = c(226.07, > 227.88, 228.66, 225.7, 225.59, 226.65, 228.87, 226.92, 229.74, > 230.16, 229.93, 230.16, 230.72, 233.25, 235.57, 235.69, 237.81, > 240.79, 242.76, 244.11, 244.54, 244.63, 247.24, 248.21, 250.8, > 248.74, 249.29, 251.38, 253.83, 254.28, 252, 255, 255.65, 258.21, > 260.1, 258.7, 253.5, 253.28, 249.1, 244.18, 420.45, 426.85, 426.5, > 424.81, 424.44, 429.33, 428.17, 422.8, 418.4, 417.94, 417.29, > 419.78, 417.4, 421.08, 429.04, 427.23, 424.88, 433, 432.47, 439.67, > 444.66, 446.1, 448.33, 449.62, 450.35, 456.16, 451.43, 452.18, > 455.29, 452.65, 443.18, 443.74, 437.65, 439.6, 440.94, 435.22, > 427.55, 426.73, 426.07, 424.03), low = c(221.19, 224.57, 226.41, > 221.5, 223.36, 222.76, 225, 224.27, 225.17, 226.66, 225.89, 225.71, > 228.06, 229.74, 233.33, 233.81, 233.97, 237.16, 238.9, 241.25, > 242.13, 242.08, 241.75, 245.34, 246.26, 245.68, 246.24, 247.65, > 249.78, 247.74, 247.09, 245.69, 253.45, 255.29, 257.63, 253.06, > 250.75, 249.43, 241.82, 241.89, 410.52, 419.88, 421.78, 416, > 417.2, 418.21, 420, 413.64, 412.1, 411.55, 410.58, 410.29, 411.06, > 414.85, 418.85, 422.02, 417.8, 421.31, 427.74, 432.63, 436.17, > 441.77, 440.5, 441.6, 444.05, 449.11, 445.58, 445.28, 449.57, > 437.02, 436.32, 428.63, 432.83, 434.19, 436.63, 426.35, 421.9, > 420.66, 414.85, 419.54), close = c(222.72, 227.48, 226.96, 224.23, > 224.23, 225.12, 228.22, 225, 228.02, 228.28, 229, 228.52, 229.87, > 232.87, 235.06, 234.93, 237.33, 239.59, 242.65, 243.01, 243.04, > 242.84, 246.75, 247.77, 246.49, 247.96, 248.13, 251.04, 253.48, > 248.05, 249.79, 254.49, 255.27, 258.2, 259.02, 255.59, 252.2, > 250.42, 243.85, 243.36, 420.18, 425.43, 422.54, 418.01, 423.03, > 425.2, 426.89, 415, 415.76, 417.79, 415.49, 412.87, 417, 418.79, > 427.99, 422.99, 423.46, 430.98, 431.2, 437.42, 442.62, 443.57, > 446.02, 443.33, 448.99, 449.56, 447.27, 451.59, 454.46, 437.39, > 437.03, 436.6, 435.25, 439.33, 438.11, 430.53, 424.83, 421.5, > 418.58, 423.35), adjClose = c(222.48, 227.23, 226.96, 224.23, > 224.23, 225.12, 228.22, 225, 228.02, 228.28, 229, 228.52, 229.87, > 232.87, 235.06, 234.93, 237.33, 239.59, 242.65, 243.01, 243.04, > 242.84, 246.75, 247.77, 246.49, 247.96, 248.13, 251.04, 253.48, > 248.05, 249.79, 254.49, 255.27, 258.2, 259.02, 255.59, 252.2, > 250.42, 243.85, 243.36, 419.34, 424.58, 421.7, 417.17, 422.18, > 424.35, 426.04, 414.17, 414.93, 416.96, 414.66, 412.87, 417, > 418.79, 427.99, 422.99, 423.46, 430.98, 431.2, 437.42, 442.62, > 443.57, 446.02, 443.33, 448.99, 449.56, 447.27, 451.59, 454.46, > 437.39, 437.03, 436.6, 435.25, 439.33, 438.11, 430.53, 424.83, > 421.5, 418.58, 423.35)), class = "data.frame", row.names = c(NA, > -80L)) > > library(TTR) > atr <- ATR(Hist[,c("high","low","close")], n=14) > atr > >Here's a function that splits your data into a list by symbol, then does the TTR calculation for each symbol and re-combines the result into an object with the same structure as the input. library(quantmod) my_atr <- function(ohlc, n = 14, ...) { cn <- names(ohlc) # get all the necessary columns atr_cols <- c(which(grepl("date", cn, ignore.case = TRUE)), has.HLC(ohlc, which = TRUE)) # find the symbol column sym_col <- which(grepl("symbol", cn, ignore.case = TRUE)) # convert the input data.frame into a list of xts objects # this ensures the data are correctly ordered by date xts_list <- lapply(split(ohlc[, atr_cols], ohlc[, sym_col]), as.xts) # calculate ATR for each symbol atr_list <- lapply(xts_list, ATR, n = n, ...) # convert the list results into data.frames to_df <- function(nm) { i <- atr_list[[nm]]; data.frame(symbol = nm, date = index(i), coredata(i)) } atr_df <- lapply(names(atr_list), to_df) # rbind all the list elements into a single data frame do.call(rbind, atr_df) } Hope that helps. -- Joshua Ulrich | about.me/joshuaulrich FOSS Trading | www.fosstrading.com
Thanks! Appears helpful and the quick turnaround is very much appreciated. I'll do some testing now. --JJS ________________________________ From: Joshua Ulrich <josh.m.ulrich at gmail.com> Sent: Sunday, January 5, 2025 11:31 AM To: Sparks, John <jspark4 at uic.edu> Cc: R-help at r-project.org <R-help at r-project.org> Subject: Re: Using library(TTR) Calculate ATR by Symbol CAUTION: External Sender Hi, TTR/xts/quantmod maintainer here. On Sun, Jan 5, 2025 at 10:58?AM Sparks, John <jspark4 at uic.edu> wrote:> > Hi, > > In looking at the documentation for the TTR library and particularly the > example for calculating the ATR (average true range). The example shows > how to calculate ATR for a file of a single stock. > > If I have multiple stocks in one file, isn't there a way to get the ATR > for each of them? Or does one have to break out each stock and calculate > the ATR separately using some sort of loop. >Yes, the TTR functions only work on a single stock at a time.> In terms of a reproducible example, the file below contains open, high, > low, close, etc. for AAPL and then MSFT. >Thanks for the reproducible data!> If the ATR calculation were fully working, then there would be blanks for > records 41 through 54 and then the ATR calculation would start up again. > > Guidance would be very much appreciated. > > --John Sparks > > > Hist<- > structure(list(symbol = c("AAPL", "AAPL", "AAPL", "AAPL", "AAPL", > "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", > "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", > "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", > "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", > "AAPL", "AAPL", "AAPL", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", > "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", > "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", > "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", > "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", > "MSFT", "MSFT", "MSFT"), date = structure(c(20033, 20034, 20035, > 20038, 20039, 20040, 20041, 20042, 20045, 20046, 20047, 20048, > 20049, 20052, 20053, 20054, 20056, 20059, 20060, 20061, 20062, > 20063, 20066, 20067, 20068, 20069, 20070, 20073, 20074, 20075, > 20076, 20077, 20080, 20081, 20083, 20084, 20087, 20088, 20090, > 20091, 20033, 20034, 20035, 20038, 20039, 20040, 20041, 20042, > 20045, 20046, 20047, 20048, 20049, 20052, 20053, 20054, 20056, > 20059, 20060, 20061, 20062, 20063, 20066, 20067, 20068, 20069, > 20070, 20073, 20074, 20075, 20076, 20077, 20080, 20081, 20083, > 20084, 20087, 20088, 20090, 20091), class = "Date"), open = c(222.61, > 224.63, 227.17, 225, 224.55, 224.01, 225.02, 226.4, 225.25, 226.98, > 228.06, 228.88, 228.06, 231.46, 233.33, 234.47, 234.81, 237.27, > 239.81, 242.87, 243.99, 242.91, 241.83, 246.89, 247.96, 246.89, > 247.82, 247.99, 250.08, 252.16, 247.5, 248.04, 254.77, 255.49, > 258.19, 257.83, 252.23, 252.44, 248.93, 243.36, 412.42, 421.28, > 425.32, 422.52, 418.25, 421.64, 425, 419.82, 414.87, 413.11, > 416.87, 419.5, 411.37, 418.38, 419.59, 425.11, 420.09, 421.57, > 429.84, 433.03, 437.92, 442.3, 442.6, 444.39, 444.05, 449.11, > 448.44, 447.27, 451.01, 451.32, 441.62, 433.11, 436.74, 434.65, > 439.08, 434.6, 426.06, 426.1, 425.53, 421.08), high = c(226.07, > 227.88, 228.66, 225.7, 225.59, 226.65, 228.87, 226.92, 229.74, > 230.16, 229.93, 230.16, 230.72, 233.25, 235.57, 235.69, 237.81, > 240.79, 242.76, 244.11, 244.54, 244.63, 247.24, 248.21, 250.8, > 248.74, 249.29, 251.38, 253.83, 254.28, 252, 255, 255.65, 258.21, > 260.1, 258.7, 253.5, 253.28, 249.1, 244.18, 420.45, 426.85, 426.5, > 424.81, 424.44, 429.33, 428.17, 422.8, 418.4, 417.94, 417.29, > 419.78, 417.4, 421.08, 429.04, 427.23, 424.88, 433, 432.47, 439.67, > 444.66, 446.1, 448.33, 449.62, 450.35, 456.16, 451.43, 452.18, > 455.29, 452.65, 443.18, 443.74, 437.65, 439.6, 440.94, 435.22, > 427.55, 426.73, 426.07, 424.03), low = c(221.19, 224.57, 226.41, > 221.5, 223.36, 222.76, 225, 224.27, 225.17, 226.66, 225.89, 225.71, > 228.06, 229.74, 233.33, 233.81, 233.97, 237.16, 238.9, 241.25, > 242.13, 242.08, 241.75, 245.34, 246.26, 245.68, 246.24, 247.65, > 249.78, 247.74, 247.09, 245.69, 253.45, 255.29, 257.63, 253.06, > 250.75, 249.43, 241.82, 241.89, 410.52, 419.88, 421.78, 416, > 417.2, 418.21, 420, 413.64, 412.1, 411.55, 410.58, 410.29, 411.06, > 414.85, 418.85, 422.02, 417.8, 421.31, 427.74, 432.63, 436.17, > 441.77, 440.5, 441.6, 444.05, 449.11, 445.58, 445.28, 449.57, > 437.02, 436.32, 428.63, 432.83, 434.19, 436.63, 426.35, 421.9, > 420.66, 414.85, 419.54), close = c(222.72, 227.48, 226.96, 224.23, > 224.23, 225.12, 228.22, 225, 228.02, 228.28, 229, 228.52, 229.87, > 232.87, 235.06, 234.93, 237.33, 239.59, 242.65, 243.01, 243.04, > 242.84, 246.75, 247.77, 246.49, 247.96, 248.13, 251.04, 253.48, > 248.05, 249.79, 254.49, 255.27, 258.2, 259.02, 255.59, 252.2, > 250.42, 243.85, 243.36, 420.18, 425.43, 422.54, 418.01, 423.03, > 425.2, 426.89, 415, 415.76, 417.79, 415.49, 412.87, 417, 418.79, > 427.99, 422.99, 423.46, 430.98, 431.2, 437.42, 442.62, 443.57, > 446.02, 443.33, 448.99, 449.56, 447.27, 451.59, 454.46, 437.39, > 437.03, 436.6, 435.25, 439.33, 438.11, 430.53, 424.83, 421.5, > 418.58, 423.35), adjClose = c(222.48, 227.23, 226.96, 224.23, > 224.23, 225.12, 228.22, 225, 228.02, 228.28, 229, 228.52, 229.87, > 232.87, 235.06, 234.93, 237.33, 239.59, 242.65, 243.01, 243.04, > 242.84, 246.75, 247.77, 246.49, 247.96, 248.13, 251.04, 253.48, > 248.05, 249.79, 254.49, 255.27, 258.2, 259.02, 255.59, 252.2, > 250.42, 243.85, 243.36, 419.34, 424.58, 421.7, 417.17, 422.18, > 424.35, 426.04, 414.17, 414.93, 416.96, 414.66, 412.87, 417, > 418.79, 427.99, 422.99, 423.46, 430.98, 431.2, 437.42, 442.62, > 443.57, 446.02, 443.33, 448.99, 449.56, 447.27, 451.59, 454.46, > 437.39, 437.03, 436.6, 435.25, 439.33, 438.11, 430.53, 424.83, > 421.5, 418.58, 423.35)), class = "data.frame", row.names = c(NA, > -80L)) > > library(TTR) > atr <- ATR(Hist[,c("high","low","close")], n=14) > atr > >Here's a function that splits your data into a list by symbol, then does the TTR calculation for each symbol and re-combines the result into an object with the same structure as the input. library(quantmod) my_atr <- function(ohlc, n = 14, ...) { cn <- names(ohlc) # get all the necessary columns atr_cols <- c(which(grepl("date", cn, ignore.case = TRUE)), has.HLC(ohlc, which = TRUE)) # find the symbol column sym_col <- which(grepl("symbol", cn, ignore.case = TRUE)) # convert the input data.frame into a list of xts objects # this ensures the data are correctly ordered by date xts_list <- lapply(split(ohlc[, atr_cols], ohlc[, sym_col]), as.xts) # calculate ATR for each symbol atr_list <- lapply(xts_list, ATR, n = n, ...) # convert the list results into data.frames to_df <- function(nm) { i <- atr_list[[nm]]; data.frame(symbol = nm, date = index(i), coredata(i)) } atr_df <- lapply(names(atr_list), to_df) # rbind all the list elements into a single data frame do.call(rbind, atr_df) } Hope that helps. -- Joshua Ulrich | about.me/joshuaulrich FOSS Trading | https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.fosstrading.com%2F&data=05%7C02%7Cjspark4%40uic.edu%7C2aac1a65ee7c4120930d08dd2daecd07%7Ce202cd477a564baa99e3e3b71a7c77dd%7C0%7C0%7C638716950981045350%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=zXHcmYaGJN7iyOUvxLhRWr8E%2BjrDyG5ze3LB0uf4n%2BI%3D&reserved=0<http://www.fosstrading.com/> This email originated from outside the University of Illinois System. Use caution when replying, clicking links, or opening attachments. DO NOT reply to any requests asking you to reply from a personal account or SMS. [[alternative HTML version deleted]]
I don't see atr_df appearing in my current directory. Also, I assume that the input data frame is named ohlc? Or am I missing something. Thanks, --JJS ________________________________ From: Joshua Ulrich <josh.m.ulrich at gmail.com> Sent: Sunday, January 5, 2025 11:31 AM To: Sparks, John <jspark4 at uic.edu> Cc: R-help at r-project.org <R-help at r-project.org> Subject: Re: Using library(TTR) Calculate ATR by Symbol CAUTION: External Sender Hi, TTR/xts/quantmod maintainer here. On Sun, Jan 5, 2025 at 10:58?AM Sparks, John <jspark4 at uic.edu> wrote:> > Hi, > > In looking at the documentation for the TTR library and particularly the > example for calculating the ATR (average true range). The example shows > how to calculate ATR for a file of a single stock. > > If I have multiple stocks in one file, isn't there a way to get the ATR > for each of them? Or does one have to break out each stock and calculate > the ATR separately using some sort of loop. >Yes, the TTR functions only work on a single stock at a time.> In terms of a reproducible example, the file below contains open, high, > low, close, etc. for AAPL and then MSFT. >Thanks for the reproducible data!> If the ATR calculation were fully working, then there would be blanks for > records 41 through 54 and then the ATR calculation would start up again. > > Guidance would be very much appreciated. > > --John Sparks > > > Hist<- > structure(list(symbol = c("AAPL", "AAPL", "AAPL", "AAPL", "AAPL", > "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", > "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", > "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", > "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", "AAPL", > "AAPL", "AAPL", "AAPL", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", > "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", > "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", > "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", > "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", "MSFT", > "MSFT", "MSFT", "MSFT"), date = structure(c(20033, 20034, 20035, > 20038, 20039, 20040, 20041, 20042, 20045, 20046, 20047, 20048, > 20049, 20052, 20053, 20054, 20056, 20059, 20060, 20061, 20062, > 20063, 20066, 20067, 20068, 20069, 20070, 20073, 20074, 20075, > 20076, 20077, 20080, 20081, 20083, 20084, 20087, 20088, 20090, > 20091, 20033, 20034, 20035, 20038, 20039, 20040, 20041, 20042, > 20045, 20046, 20047, 20048, 20049, 20052, 20053, 20054, 20056, > 20059, 20060, 20061, 20062, 20063, 20066, 20067, 20068, 20069, > 20070, 20073, 20074, 20075, 20076, 20077, 20080, 20081, 20083, > 20084, 20087, 20088, 20090, 20091), class = "Date"), open = c(222.61, > 224.63, 227.17, 225, 224.55, 224.01, 225.02, 226.4, 225.25, 226.98, > 228.06, 228.88, 228.06, 231.46, 233.33, 234.47, 234.81, 237.27, > 239.81, 242.87, 243.99, 242.91, 241.83, 246.89, 247.96, 246.89, > 247.82, 247.99, 250.08, 252.16, 247.5, 248.04, 254.77, 255.49, > 258.19, 257.83, 252.23, 252.44, 248.93, 243.36, 412.42, 421.28, > 425.32, 422.52, 418.25, 421.64, 425, 419.82, 414.87, 413.11, > 416.87, 419.5, 411.37, 418.38, 419.59, 425.11, 420.09, 421.57, > 429.84, 433.03, 437.92, 442.3, 442.6, 444.39, 444.05, 449.11, > 448.44, 447.27, 451.01, 451.32, 441.62, 433.11, 436.74, 434.65, > 439.08, 434.6, 426.06, 426.1, 425.53, 421.08), high = c(226.07, > 227.88, 228.66, 225.7, 225.59, 226.65, 228.87, 226.92, 229.74, > 230.16, 229.93, 230.16, 230.72, 233.25, 235.57, 235.69, 237.81, > 240.79, 242.76, 244.11, 244.54, 244.63, 247.24, 248.21, 250.8, > 248.74, 249.29, 251.38, 253.83, 254.28, 252, 255, 255.65, 258.21, > 260.1, 258.7, 253.5, 253.28, 249.1, 244.18, 420.45, 426.85, 426.5, > 424.81, 424.44, 429.33, 428.17, 422.8, 418.4, 417.94, 417.29, > 419.78, 417.4, 421.08, 429.04, 427.23, 424.88, 433, 432.47, 439.67, > 444.66, 446.1, 448.33, 449.62, 450.35, 456.16, 451.43, 452.18, > 455.29, 452.65, 443.18, 443.74, 437.65, 439.6, 440.94, 435.22, > 427.55, 426.73, 426.07, 424.03), low = c(221.19, 224.57, 226.41, > 221.5, 223.36, 222.76, 225, 224.27, 225.17, 226.66, 225.89, 225.71, > 228.06, 229.74, 233.33, 233.81, 233.97, 237.16, 238.9, 241.25, > 242.13, 242.08, 241.75, 245.34, 246.26, 245.68, 246.24, 247.65, > 249.78, 247.74, 247.09, 245.69, 253.45, 255.29, 257.63, 253.06, > 250.75, 249.43, 241.82, 241.89, 410.52, 419.88, 421.78, 416, > 417.2, 418.21, 420, 413.64, 412.1, 411.55, 410.58, 410.29, 411.06, > 414.85, 418.85, 422.02, 417.8, 421.31, 427.74, 432.63, 436.17, > 441.77, 440.5, 441.6, 444.05, 449.11, 445.58, 445.28, 449.57, > 437.02, 436.32, 428.63, 432.83, 434.19, 436.63, 426.35, 421.9, > 420.66, 414.85, 419.54), close = c(222.72, 227.48, 226.96, 224.23, > 224.23, 225.12, 228.22, 225, 228.02, 228.28, 229, 228.52, 229.87, > 232.87, 235.06, 234.93, 237.33, 239.59, 242.65, 243.01, 243.04, > 242.84, 246.75, 247.77, 246.49, 247.96, 248.13, 251.04, 253.48, > 248.05, 249.79, 254.49, 255.27, 258.2, 259.02, 255.59, 252.2, > 250.42, 243.85, 243.36, 420.18, 425.43, 422.54, 418.01, 423.03, > 425.2, 426.89, 415, 415.76, 417.79, 415.49, 412.87, 417, 418.79, > 427.99, 422.99, 423.46, 430.98, 431.2, 437.42, 442.62, 443.57, > 446.02, 443.33, 448.99, 449.56, 447.27, 451.59, 454.46, 437.39, > 437.03, 436.6, 435.25, 439.33, 438.11, 430.53, 424.83, 421.5, > 418.58, 423.35), adjClose = c(222.48, 227.23, 226.96, 224.23, > 224.23, 225.12, 228.22, 225, 228.02, 228.28, 229, 228.52, 229.87, > 232.87, 235.06, 234.93, 237.33, 239.59, 242.65, 243.01, 243.04, > 242.84, 246.75, 247.77, 246.49, 247.96, 248.13, 251.04, 253.48, > 248.05, 249.79, 254.49, 255.27, 258.2, 259.02, 255.59, 252.2, > 250.42, 243.85, 243.36, 419.34, 424.58, 421.7, 417.17, 422.18, > 424.35, 426.04, 414.17, 414.93, 416.96, 414.66, 412.87, 417, > 418.79, 427.99, 422.99, 423.46, 430.98, 431.2, 437.42, 442.62, > 443.57, 446.02, 443.33, 448.99, 449.56, 447.27, 451.59, 454.46, > 437.39, 437.03, 436.6, 435.25, 439.33, 438.11, 430.53, 424.83, > 421.5, 418.58, 423.35)), class = "data.frame", row.names = c(NA, > -80L)) > > library(TTR) > atr <- ATR(Hist[,c("high","low","close")], n=14) > atr > >Here's a function that splits your data into a list by symbol, then does the TTR calculation for each symbol and re-combines the result into an object with the same structure as the input. library(quantmod) my_atr <- function(ohlc, n = 14, ...) { cn <- names(ohlc) # get all the necessary columns atr_cols <- c(which(grepl("date", cn, ignore.case = TRUE)), has.HLC(ohlc, which = TRUE)) # find the symbol column sym_col <- which(grepl("symbol", cn, ignore.case = TRUE)) # convert the input data.frame into a list of xts objects # this ensures the data are correctly ordered by date xts_list <- lapply(split(ohlc[, atr_cols], ohlc[, sym_col]), as.xts) # calculate ATR for each symbol atr_list <- lapply(xts_list, ATR, n = n, ...) # convert the list results into data.frames to_df <- function(nm) { i <- atr_list[[nm]]; data.frame(symbol = nm, date = index(i), coredata(i)) } atr_df <- lapply(names(atr_list), to_df) # rbind all the list elements into a single data frame do.call(rbind, atr_df) } Hope that helps. -- Joshua Ulrich | about.me/joshuaulrich FOSS Trading | https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.fosstrading.com%2F&data=05%7C02%7Cjspark4%40uic.edu%7C2aac1a65ee7c4120930d08dd2daecd07%7Ce202cd477a564baa99e3e3b71a7c77dd%7C0%7C0%7C638716950981045350%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=zXHcmYaGJN7iyOUvxLhRWr8E%2BjrDyG5ze3LB0uf4n%2BI%3D&reserved=0<http://www.fosstrading.com/> This email originated from outside the University of Illinois System. Use caution when replying, clicking links, or opening attachments. DO NOT reply to any requests asking you to reply from a personal account or SMS. [[alternative HTML version deleted]]