{"id":32203137,"url":"https://github.com/serkor1/cryptoquotes","last_synced_at":"2026-02-21T18:04:23.434Z","repository":{"id":197397133,"uuid":"695205675","full_name":"serkor1/cryptoQuotes","owner":"serkor1","description":"cryptoQuotes is an R package for retrieving historical and real-time cryptocurrency market data from multiple exchanges. It offers an easy-to-use interface for accessing price quotes, trading volumes, and market data, making it valuable for analysts, developers, and crypto enthusiasts.","archived":false,"fork":false,"pushed_at":"2026-02-15T11:23:43.000Z","size":34599,"stargazers_count":45,"open_issues_count":0,"forks_count":24,"subscribers_count":4,"default_branch":"main","last_synced_at":"2026-02-15T16:28:58.845Z","etag":null,"topics":["binance","binance-api","bitmart","bybit","bybit-api","cryptocurrencies","cryptocurrency","cryptocurrency-exchanges","huobi","huobi-api","kraken-api","kraken-exchange-api","kucoin","kucoin-api","r","rstats","rstats-package"],"latest_commit_sha":null,"homepage":"https://serkor1.github.io/cryptoQuotes/","language":"R","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/serkor1.png","metadata":{"files":{"readme":"README.Rmd","changelog":"NEWS.Rmd","contributing":".github/CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":"codemeta.json","zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["serkor1"]}},"created_at":"2023-09-22T15:29:36.000Z","updated_at":"2026-02-15T11:17:02.000Z","dependencies_parsed_at":null,"dependency_job_id":"2ddd2eda-013a-4add-b8c2-d5dcdd3bd18f","html_url":"https://github.com/serkor1/cryptoQuotes","commit_stats":null,"previous_names":["serkor1/cryptoquotes"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/serkor1/cryptoQuotes","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/serkor1%2FcryptoQuotes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/serkor1%2FcryptoQuotes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/serkor1%2FcryptoQuotes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/serkor1%2FcryptoQuotes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/serkor1","download_url":"https://codeload.github.com/serkor1/cryptoQuotes/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/serkor1%2FcryptoQuotes/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29689644,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-21T15:51:39.154Z","status":"ssl_error","status_checked_at":"2026-02-21T15:49:03.425Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["binance","binance-api","bitmart","bybit","bybit-api","cryptocurrencies","cryptocurrency","cryptocurrency-exchanges","huobi","huobi-api","kraken-api","kraken-exchange-api","kucoin","kucoin-api","r","rstats","rstats-package"],"created_at":"2025-10-22T04:32:17.224Z","updated_at":"2026-02-21T18:04:23.429Z","avatar_url":"https://github.com/serkor1.png","language":"R","funding_links":["https://github.com/sponsors/serkor1"],"categories":[],"sub_categories":[],"readme":"---\noutput: github_document\nalways_allow_html: true\n---\n\u003c!-- README.md is generated from README.Rmd. Please edit that file --\u003e\n\n```{r setup, include = FALSE}\n# set options\nSys.setenv(OPENSSL_CONF=\"/dev/null\")\n\nknitr::opts_chunk$set(\n  collapse = FALSE,\n  comment  = \"#\u003e\",\n  fig.path = \"man/figures/README-\",\n  message  = FALSE,\n  warning  = FALSE,\n  echo     = FALSE \n)\n```\n\n# {cryptoQuotes}: Open access to cryptocurrency market data \u003ca href=\"https://serkor1.github.io/cryptoQuotes/\"\u003e\u003cimg src=\"man/figures/logo.png\" align=\"right\" height=\"154\" alt=\"cryptocurrency in R\"/\u003e\u003c/a\u003e\n\n\u003c!-- badges: start --\u003e\n[![CRAN status](https://www.r-pkg.org/badges/version/cryptoQuotes)](https://CRAN.R-project.org/package=cryptoQuotes)\n[![CRAN RStudio mirror downloads](https://cranlogs.r-pkg.org/badges/last-month/cryptoQuotes?color=blue)](https://r-pkg.org/pkg/cryptoQuotes)\n[![R-CMD-check](https://github.com/serkor1/cryptoQuotes/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/serkor1/cryptoQuotes/actions/workflows/R-CMD-check.yaml)\n[![codecov](https://codecov.io/gh/serkor1/cryptoQuotes/graph/badge.svg?token=D7NF1BPVL5)](https://app.codecov.io/gh/serkor1/cryptoQuotes)\n[![Lifecycle: stable](https://img.shields.io/badge/lifecycle-stable-brightgreen.svg)](https://lifecycle.r-lib.org/articles/stages.html#stable)\n![GitHub last commit (branch)](https://img.shields.io/github/last-commit/serkor1/cryptoQuotes/development)\n\u003c!-- badges: end --\u003e\n\n## :information_source: About\n\n[{cryptoQuotes}](https://serkor1.github.io/cryptoQuotes/) is a high-level API client for accessing public market data endpoints on major cryptocurrency exchanges. It supports open, high, low, close and volume (OHLC-V) data and a variety of sentiment indicators; the market data is high quality and can be retrieved in intervals ranging from *seconds* to *months*. All the market data is accessed and processed without relying on crawlers, or API keys, ensuring an open, and reliable, access for researchers, traders and students alike. There are currently `r length(invisible(cryptoQuotes::available_exchanges(type = \"ohlc\")))` supported cryptocurrency exchanges,\n\n```{r Exchanges (Raw),include=FALSE, echo=FALSE}\n# 1) create a data.table of available\n# exchanges and store as dat.table\nDT \u003c- data.table::data.table(\n  value = suppressMessages(\n    cryptoQuotes::available_exchanges()\n  )\n)\n\n# 2) add labels\n# to the data data\nDT[\n  ,\n  label := data.table::fcase(\n    value == \"binance\", \"Binance\",\n    value == \"kraken\", \"Kraken\",\n    value == \"crypto.com\", \"Crypto.com\",\n    value == \"kucoin\", \"KuCoin\",\n    value == \"bitmart\", \"BitMart\",\n    value == \"huobi\", \"Huobi (HTX)\",\n    value == \"mexc\", \"MEXC\",\n    value == \"bybit\", \"Bybit\",\n    value == \"cmc\", \"CoinMarketCap\"\n  )\n  ,\n]\n```\n\n\n\u003cdiv align=\"center\"\u003e\n```{r Exchanges (Table), echo=FALSE}\n# 1) define all available\n# exchanges\nall_exchanges \u003c- DT$label\n\nif (length(DT$label) %% 2 != 0) {\n  # If odd, append an empty string to make it even\n  all_exchanges \u003c- c(DT$label, \"\")\n}\n\n# Convert the character vector to a single-row data frame\nall_exchanges \u003c- data.table::data.table(\n  matrix(\n    data = all_exchanges, \n    ncol = 4,\n    byrow = TRUE)\n)\n\n# Create a horizontal table\nkableExtra::kable_styling(\n  knitr::kable(\n    x = all_exchanges, \n    digits = 2,\n    col.names = NULL,\n    caption = 'All supported exchanges.',\n    align = 'c',\n    table.attr = \"style='width:100%;'\",\n    format = 'html'\n  ),\n  full_width = TRUE,\n  position = 'center'\n)\n```\n\u003c/div\u003e\n\nAll data is returned as [{xts}](https://github.com/joshuaulrich/xts)-objects which enables seamless interaction with with [{quantmod}](https://github.com/joshuaulrich/quantmod) and [{TTR}](https://github.com/joshuaulrich/TTR), for developing and evaluating trading strategies or general purpose cryptocurrency market analysis with a historical or temporal perspective. \n\n## :information_source: Overview\n\n[{cryptoQuotes}](https://serkor1.github.io/cryptoQuotes/) has *two* main features; retrieving cryptocurrency market data, and charting. The market data consists of *OHLC-V* data and sentiment indicators; including, but not limited to, cryptocurrency *fear and greed index*, *long-short ratio* and *open interest*. All market data is retrieved using the family of `get_*`-functions. To get a full overview of the package and functionality please see the documentation via [{pkgdown}](https://serkor1.github.io/cryptoQuotes/).\n\n\u003e [!WARNING]\n\u003e\n\u003e Given the nature of crypotcurrency data and general legislative restrictions, some `exchanges` may not work in your geolocation.\n\nBelow is a quick overview of the package and basic usage examples on retrieving and charting Bitcoin (BTC) *OHLC-V* and *long-short ratio* in 30 minute intervals.\n\n### :information_source: Cryptocurrency market data\n\n#### OHLC-V\n\nAll supported exchanges and markets are listed in the table below, alongside the available range of intervals available from the respective exchanges,\n\n\u003cdiv align=\"center\"\u003e\n```{r supported calls, echo=FALSE,fig.alt=\"Cryptocurrency market data in R\"}\n# function to make \n# first letter uppercase without\n# declaring dependency on stringr\n# Thank you Stackoverflow\n# https://stackoverflow.com/a/18509816\nfirstup \u003c- function(x) {\n  substr(x, 1, 1) \u003c- toupper(substr(x, 1, 1))\n  x\n}\n\nsort_granularities \u003c- function(granularity_vector) {\n  # Define a custom ordering based on granularity\n  custom_order \u003c- c(\"s\",\"m\", \"h\", \"d\", \"w\", \"M\")\n  \n  # Extract numeric and non-numeric parts\n  numeric_part \u003c- as.numeric(gsub(\"[^0-9]\", \"\", granularity_vector))\n  non_numeric_part \u003c- gsub(\"[0-9]\", \"\", granularity_vector)\n  \n  # Map non-numeric part to custom order\n  non_numeric_part_order \u003c- match(non_numeric_part, custom_order)\n  \n  # Create a sorting index\n  sorting_index \u003c- order(non_numeric_part_order, numeric_part)\n  \n  # Sort the vector\n  sorted_granularity_vector \u003c- granularity_vector[sorting_index]\n  \n  return(sorted_granularity_vector)\n}\n\n# 1) Supported Exchanges\n# sorted alphabetically\nexchange \u003c- firstup(\n  sort(\n    suppressMessages(\n      cryptoQuotes::available_exchanges()\n    )\n  )\n)\n\n\n# 2) calculate available\n# intervals\nintervals \u003c- sapply(\n  DT$value,\n  function(x){\n    suppressMessages(\n      {\n        futures = cryptoQuotes::available_intervals(\n          type   = 'ohlc',\n          source = tolower(x),\n          futures = TRUE\n        )\n        \n        spot = cryptoQuotes::available_intervals(\n          type   = 'ohlc',\n          source = tolower(x),\n          futures = FALSE\n        )\n        \n      }\n    )\n    \n    length(union(futures, spot))\n    \n  }\n)\n\n\n# 2) calculate available\n# intervals\ngranularity \u003c- function(\n    lowest = TRUE\n)\n{\n  sapply(\n    DT$value,\n    function(x){\n      suppressMessages(\n        {\n          futures = cryptoQuotes::available_intervals(\n            source = tolower(x),\n            futures = TRUE\n          )\n          \n          spot = cryptoQuotes::available_intervals(\n            source = tolower(x),\n            futures = FALSE\n          )\n          \n        }\n      )\n      \n      available_granularity \u003c- sort_granularities(union(\n        futures,\n        spot\n      ))\n      \n      \n      if (lowest) {\n        \n        output \u003c- available_granularity[1]\n        \n        \n        \n      } else {\n        \n        output \u003c- available_granularity[length(available_granularity)]\n        \n      }\n      \n      \n      output \u003c- gsub(\"(.)(.)\", \"\\\\1 \\\\2\", output)\n      \n      output \u003c- strsplit(\n        output,\n        split = \" \"\n      )[[1]]\n      \n      \n      number \u003c- output[1]\n      \n      granularity \u003c- switch(\n        EXPR = output[2],\n        s = \"second(s)\",\n        m = \"minute(s)\",\n        h = \"hour(s)\",\n        w = \"week(s)\",\n        d = \"day(s)\",\n        M = \"month(s)\"\n      )\n      \n      paste(number, granularity)\n      \n    }\n  )\n}\n\n# 2) create\n# table\ngt::as_raw_html(\n  gt::fmt_markdown(\n    gt::cols_label(\n     gt::cols_align(\n      data = gt::gt(\n        data.frame(\n          row.names = NULL,\n          Exchange  = DT$label,\n          Spot = rep(x = \":white_check_mark:\",length(exchange)),\n          Futures = rep(x = \":white_check_mark:\",length(exchange)),\n          `Available Intervals` = c(intervals),\n          `Smallest Interval` = c(granularity(TRUE)),\n          `Biggest Interval` = c(granularity(FALSE))\n        ),\n        auto_align = FALSE,\n        caption = 'Supported exchanges by spot and futures markets with available intervals.'),\n      align = \"left\",\n      columns = \"Exchange\"\n      \n    ),\n    Available.Intervals = \"Available Intervals\",\n    Smallest.Interval   = \"Smallest Interval\",\n    Biggest.Interval    = \"Biggest Interval\"\n    )\n    \n    \n  )\n)\n```\n\u003c/div\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eExample: Bitcoin OHLC-V\u003c/summary\u003e\n\nGet USDT denominated Bitcoin (BTC) on the spot market from Binance in `30m`-intervals using the `get_quote()`-function,\n\n```{r cryptocurrency market data in R, eval=TRUE, echo=TRUE}\n## BTC OHLC prices\n## from Binance spot market\n## in 30 minute intervals\nBTC \u003c- cryptoQuotes::get_quote(\n  ticker   = 'BTCUSDT',\n  source   = 'binance',\n  futures  = FALSE,\n  interval = '30m',\n  from     = Sys.Date() - 2\n)\n```\n\n\u003cdiv align=\"center\"\u003e\n```{r print table, echo=FALSE, fig.alt=\"cryptocurrency prices in R\"}\nkableExtra::kable_styling(\n  knitr::kable(\n    caption = 'Bitcoin (BTC) OHLC-V data',\n    align = 'lcccc',\n    table.attr = \"style='width:100%;'\",\n    x = data.frame(\n      cbind(\n        index = paste(tail(zoo::index(BTC))),\n        tail(zoo::coredata(BTC))\n      ),row.names = NULL\n    ),\n    format = 'html'\n  ),\n  full_width = TRUE,\n  position = 'center'\n)\n```\n\u003c/div\u003e\n__________\n\u003c/details\u003e\n\n#### Sentiment indicators\n\nThe sentiment indicators available in [{cryptoQuotes}](https://serkor1.github.io/cryptoQuotes/) can be divided in two; *derived indicators* and *market indicators*. The former is calculated based on, for example, the price actions such as the *Moving Average Convergence Divergence* (MACD) indicator. The latter are public indicators such as the *long-short ratio* or *fear and greed index*; these are retrieved using the family of `get_*`-functions, while the derived indicators can be created using, for example, [{TTR}](https://github.com/joshuaulrich/TTR).\n\nIn this overview we are focusing on *market indicators* made public by the cryptocurrency exchanges. For a full overview of sentiment indicators please refer to the documentation via [{pkgdown}](https://serkor1.github.io/cryptoQuotes/). All supported *market indicators* by exchange are listed in the table below,\n\n\u003cdiv align=\"center\"\u003e\n```{r Available Endpoints by Exchange, echo = FALSE}\n## 0) Get all available\n## endpoints\nendpoint_label \u003c- c(\"Long-Short Ratio\", \"Open Interest\", \"Fundingrate\")\nendpoint_value \u003c- c(         \"lsratio\",      \"interest\", \"fundingrate\")\nall_exchanges  \u003c- DT$value\n\nDT_ \u003c- data.table::rbindlist(\n  lapply(\n    seq_along(all_exchanges),\n    FUN = function(i) {\n      \n      # 0) extract exchange\n      exchange \u003c- all_exchanges[i]\n      \n      data.table::rbindlist(\n        lapply(\n          seq_along(endpoint_value),\n          FUN = function(j) {\n            \n            \n            # 0) generate table\n            DT \u003c- data.table::data.table(\n              order    = j,\n              Exchange = DT$label[i],\n              Endpoint = endpoint_label[j]\n            )\n            \n            DT[\n              ,\n              available := data.table::fifelse(\n                test = exchange %in% suppressMessages(cryptoQuotes::available_exchanges(endpoint_value[j])),\n                yes  = \":white_check_mark:\",\n                no   =  \":x:\"\n              )\n              ,\n            ]\n            \n            DT\n            \n            \n          }\n        )\n      )\n      \n      \n      \n      \n    }\n  )\n)\n\nDT_ \u003c- data.table::dcast(\n  data = DT_,\n  formula = order +  Endpoint ~ Exchange,\n  value.var = \"available\"\n)\nDT_$order \u003c- NULL\n\n## 4) present table\n## for as is\ngt::as_raw_html(\n  gt::fmt_markdown(\n    gt::cols_align(\n      data = gt::gt(\n        DT_,\n        auto_align = FALSE,\n        caption = 'Available sentiment indicators by exchange'),\n      align = \"left\",\n      columns = \"Endpoint\"\n      \n    )\n    \n  )\n)\n```\n\u003c/div\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eExample: Bitcoin Long-Short Ratio\u003c/summary\u003e\n\nGet the *long-short ratio* on Bitcoin (BTC) using the `get_lsratio()`-function,\n\n```{r cryptocurrency sentiment indicators in R, eval=TRUE, echo=TRUE}\n## BTC OHLC prices\n## from Binance spot market\n## in 30 minute intervals\nBTC_LS \u003c- cryptoQuotes::get_lsratio(\n  ticker   = 'BTCUSDT',\n  source   = 'binance',\n  interval = '30m',\n  from     = Sys.Date() - 2\n)\n```\n\n\u003cdiv align=\"center\"\u003e\n```{r print LS table, echo=FALSE, fig.alt=\"cryptocurrency prices in R\"}\nkableExtra::kable_styling(\n  knitr::kable(\n    caption = 'Long-Short Ratio on Bitcoin (BTC)',\n    align = 'lccc',\n    table.attr = \"style='width:100%;'\",\n    x = data.frame(\n      cbind(\n        index = paste(tail(zoo::index(BTC_LS))),\n        tail(zoo::coredata(round(BTC_LS,3)))\n      ),row.names = NULL\n    ),\n    format = 'html'\n  ),\n  full_width = TRUE,\n  position = 'center'\n)\n```\n\u003c/div\u003e\n__________\n\u003c/details\u003e\n\n### :information_source: Charting\n\n```{r, echo=FALSE, include=FALSE}\n## Chart BTC\n## using klines, SMA, \n## MACD and Bollinger Bands\ncryptoQuotes::chart(\n  ticker = BTC,\n  main   = cryptoQuotes::kline(),\n  sub    = list(\n    cryptoQuotes::lsr(ratio = BTC_LS),\n    cryptoQuotes::volume()\n  ),\n  indicator = list(\n    cryptoQuotes::sma(n = 7),\n    cryptoQuotes::sma(n = 14),\n    cryptoQuotes::sma(n = 21),\n    cryptoQuotes::bollinger_bands()\n  )\n)\n```\n\nCharting in [{cryptoQuotes}](https://serkor1.github.io/cryptoQuotes/) is built on [{plotly}](https://github.com/plotly/plotly.R) for interactivity. It supports *light* and *dark* themes, and accounts for *color-deficiency* via the `options`-argument in the `chart()`-function.\n\n#### Charting with indicators\n\nThe OHLC-V data and the sentiment indicator can be charted using the `chart()`-function,\n\n```{r chartquote, fig.align='center',fig.dpi=180, fig.alt=\"cryptocurrency charts in R\"}\n## Chart BTC\n## using klines, SMA\n## Bollinger Bands and\n## long-short ratio\ncryptoQuotes::chart(\n  ticker = BTC,\n  main   = cryptoQuotes::kline(),\n  sub    = list(\n    cryptoQuotes::lsr(ratio = BTC_LS),\n    cryptoQuotes::volume()\n  ),\n  indicator = list(\n    cryptoQuotes::sma(n = 7),\n    cryptoQuotes::sma(n = 14),\n    cryptoQuotes::sma(n = 21),\n    cryptoQuotes::bollinger_bands()\n  ),\n  options = list(\n    static     = TRUE\n  )\n)\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eSource\u003c/summary\u003e\n\n```{r chartquote (Source),echo=TRUE, fig.align='center',fig.dpi=180, fig.alt=\"cryptocurrency charts in R\", eval=FALSE}\n## Chart BTC\n## using klines, SMA\n## Bollinger Bands and\n## long-short ratio\ncryptoQuotes::chart(\n  ticker = BTC,\n  main   = cryptoQuotes::kline(),\n  sub    = list(\n    cryptoQuotes::lsr(ratio = BTC_LS),\n    cryptoQuotes::volume()\n  ),\n  indicator = list(\n    cryptoQuotes::sma(n = 7),\n    cryptoQuotes::sma(n = 14),\n    cryptoQuotes::sma(n = 21),\n    cryptoQuotes::bollinger_bands()\n  ),\n  options = list(\n    static     = TRUE\n  )\n)\n```\n\n\u003c/details\u003e\n\n## :information_source: Installation\n\n### :shield: Stable version\n```{r stable version guide, eval = FALSE, echo=TRUE}\n## install from CRAN\ninstall.packages(\n  pkgs = 'cryptoQuotes',\n  dependencies = TRUE\n)\n```\n\n### :hammer_and_wrench: Development version\n```{r development version guide, eval = FALSE,echo=TRUE}\n## install from github\ndevtools::install_github(\n  repo = 'https://github.com/serkor1/cryptoQuotes/',\n  ref  = 'development'\n)\n```\n\n## :information_source: Code of Conduct\n\nPlease note that the [{cryptoQuotes}](https://serkor1.github.io/cryptoQuotes/) project is released with a [Contributor Code of Conduct](https://serkor1.github.io/cryptoQuotes/CODE_OF_CONDUCT.html). By contributing to this project, you agree to abide by its terms.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fserkor1%2Fcryptoquotes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fserkor1%2Fcryptoquotes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fserkor1%2Fcryptoquotes/lists"}