Альтернативным решением является использование пакета tidyquant
, который позволяет использовать функциональные возможности финансовых пакетов, включая функциональные возможности временных рядов, с кадрами данных. Следующие примеры показывают, как вы можете получить отношение Calmar для нескольких активов. tidyquant vignettes более подробно расскажут о том, как использовать пакет.
library(tidyquant)
# Get prices
price_tbl <- c("FB", "AMZN", "NFLX", "GOOG") %>%
tq_get(get = "stock.prices",
from = "2010-01-01",
to = "2016-12-31")
price_tbl
#> # A tibble: 6,449 × 8
#> symbol date open high low close volume adjusted
#>
#> 1 FB 2012-05-18 42.05 45.00 38.00 38.23 573576400 38.23
#> 2 FB 2012-05-21 36.53 36.66 33.00 34.03 168192700 34.03
#> 3 FB 2012-05-22 32.61 33.59 30.94 31.00 101786600 31.00
#> 4 FB 2012-05-23 31.37 32.50 31.36 32.00 73600000 32.00
#> 5 FB 2012-05-24 32.95 33.21 31.77 33.03 50237200 33.03
#> 6 FB 2012-05-25 32.90 32.95 31.11 31.91 37149800 31.91
#> 7 FB 2012-05-29 31.48 31.69 28.65 28.84 78063400 28.84
#> 8 FB 2012-05-30 28.70 29.55 27.86 28.19 57267900 28.19
#> 9 FB 2012-05-31 28.55 29.67 26.83 29.60 111639200 29.60
#> 10 FB 2012-06-01 28.89 29.15 27.39 27.72 41855500 27.72
#> # ... with 6,439 more rows
# Convert to period returns
return_tbl <- price_tbl %>%
group_by(symbol) %>%
tq_transmute(ohlc_fun = Ad,
mutate_fun = periodReturn,
period = "daily")
return_tbl
#> Source: local data frame [6,449 x 3]
#> Groups: symbol [4]
#>
#> symbol date daily.returns
#>
#> 1 FB 2012-05-18 0.00000000
#> 2 FB 2012-05-21 -0.10986139
#> 3 FB 2012-05-22 -0.08903906
#> 4 FB 2012-05-23 0.03225806
#> 5 FB 2012-05-24 0.03218747
#> 6 FB 2012-05-25 -0.03390854
#> 7 FB 2012-05-29 -0.09620809
#> 8 FB 2012-05-30 -0.02253811
#> 9 FB 2012-05-31 0.05001770
#> 10 FB 2012-06-01 -0.06351355
#> # ... with 6,439 more rows
# Calculate performance
return_tbl %>%
tq_performance(Ra = daily.returns,
performance_fun = CalmarRatio)
#> Source: local data frame [4 x 2]
#> Groups: symbol [4]
#>
#> symbol CalmarRatio
#>
#> 1 FB 0.50283172
#> 2 AMZN 0.91504597
#> 3 NFLX 0.14444744
#> 4 GOOG 0.05068483
Не используйте группы:
import re
s = "Za @Foo_Bar: @BAR_foo @FooBAR @BArfoo"
g = re.findall(r'(?:Za\s)@\w+|(?<=@)\w+', s)
print(g)
Вывод:
['Za @Foo_Bar', 'BAR_foo', 'FooBAR', 'BArfoo']
Объяснение:
(?:Za\s) # non capture group
@ # @
\w+ # 1 or more word character
| #
(?<=@) # lookbehind, make sure we have @ before
\w+ # 1 or more word character
В качестве альтернативы вы можете использовать (?<!\AZa):? @
и разделить на необязательный двоеточие, за которым следует пробел и @
, за исключением первого в строке:
import re
s = "Za @Foo_Bar: @BAR_foo @FooBAR @BArfoo"
print(re.split('(?<!\AZa):? @', s))
Результат
[ 111] regex.fullmatch()
- неправильный метод для использования здесь, я не думаю, что вы поняли, для чего он полезен.
Из документации модуля regex
:
blockquote>
fullmatch
ведет себя подобноmatch
, за исключением того, что оно должно соответствовать всей строке.Ваш шаблон не соответствует всем входной строке. Только если шаблон охватывает все, что , от первого символа до последнего,
fullmatch()
вернет совпадение.Где
re.match()
соответствует только в начале строки, как если бы вы добавили\A
в начало вашего паттерна,regex.fullmatch()
соответствует, как если бы вы добавили\A
в начало, а\Z
до конца вашего шаблона.Обратите внимание, что вам не нужна опция
|(@[A-Za-z0-9_]*)
; этот паттерн полностью покрыт частью(Za\s)?@[A-Za-z0-9_]*
, когда(Za\s)?
не совпадает.Чтобы получить чистый список, используйте
re.findall()
, но используйте группу(?:...)
без захвата , чтобы покрыть необязательную часть, поэтому вы не получите отдельных строк в результатеre.findall()
:>>> import re >>> a = "Za @Foo_Bar: @BAR_foo @FooBAR @BArfoo" >>> re.findall(r'(?:Za\s)?@[A-Za-z0-9_]*', a) ['Za @Foo_Bar', '@BAR_foo', '@FooBAR', '@BArfoo']
Без групп захвата возвращается все совпадение.