diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8833a26..99b9161 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,20 @@
All notable changes to this project will be documented in this file.
+## [2.0.0] - 2026-02-19
+
+### Added
+- OHLC endpoint (`currency.ohlc()`) for Open, High, Low, Close price data (Tier 3+)
+ - Parameters: `currency` (required), `date` (required), `base` (optional), `interval` (optional)
+ - Supported intervals: `5m`, `15m`, `30m`, `1h`, `4h`, `12h`, `1d`
+
+### Changed
+- **Breaking:** Updated to API v2 (`https://currencyapi.net/api/v2/`)
+- Updated README with OHLC endpoint documentation and usage examples
+
+### Removed
+- **Breaking:** API v1 support dropped; all requests now use v2
+
## [1.1.0] - 2026-02-13
### Added
diff --git a/README.md b/README.md
index 3473a39..a24cdf2 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,10 @@
-# CurrencyApi Python wrapper
+# CurrencyApi Python wrapper
-[](https://pypi.org/project/currencyapinet/) [](https://coveralls.io/github/houseofapis/currencyapi-python?branch=main)
+[](https://pypi.org/project/currencyapinet/) [](https://coveralls.io/github/houseofapis/currencyapi-python?branch=main)
-CurrencyApi.net provides live currency rates via a REST API. A live currency feed for over 152 currencies, including physical (USD, GBP, EUR + more) and cryptos (Bitcoin, Litecoin, Ethereum + more). A JSON and XML currency api updated every 60 seconds.
+CurrencyApi.net provides live currency rates via a REST API. A live currency feed for over 152 currencies, including physical (USD, GBP, EUR + more) and cryptos (Bitcoin, Litecoin, Ethereum + more). A JSON and XML currency api updated every 60 seconds.
Features:
@@ -13,13 +13,14 @@ Features:
- Popular cryptocurrencies included; Bitcoin, Litecoin etc.
- Convert currencies on the fly with the convert endpoint.
- Historical currency rates back to year 2000.
+- OHLC (Open, High, Low, Close) data for technical analysis (Tier 3+).
- Easy to follow documentation
Signup for a free or paid account here.
## This package is a:
-Python wrapper for CurrencyApi.net endpoints.
+Python wrapper for CurrencyApi.net endpoints (API v2).
## Developer Guide
@@ -39,4 +40,128 @@ Alternatively keep reading below.
## Installation
-View our Python SDK guide
\ No newline at end of file
+View our Python SDK guide
+
+```
+pip install currencyapinet
+```
+
+## Usage
+
+```python
+from currencyapinet import Currency
+
+currency = Currency('YOUR_API_KEY')
+```
+
+---
+
+### Rates
+
+Returns live currency rates for all supported currencies. Base currency defaults to USD.
+
+```python
+result = currency.rates().get()
+
+# With optional base currency
+result = currency.rates().base('EUR').get()
+
+# XML output
+result = currency.rates().output('XML').get()
+```
+
+---
+
+### Convert
+
+Converts an amount from one currency to another.
+
+```python
+result = currency.convert().from_currency('USD').to_currency('EUR').amount(100).get()
+```
+
+---
+
+### History
+
+Returns historical currency rates for a specific date.
+
+```python
+result = currency.history().date('2023-12-25').get()
+
+# With optional base currency
+result = currency.history().base('GBP').date('2023-12-25').get()
+```
+
+---
+
+### Timeframe
+
+Returns historical currency rates for a date range (max 365 days).
+
+```python
+result = currency.timeframe().start_date('2023-12-01').end_date('2023-12-31').get()
+
+# With optional base currency
+result = currency.timeframe().base('GBP').start_date('2023-12-01').end_date('2023-12-31').get()
+```
+
+---
+
+### Currencies
+
+Returns a list of all supported currencies.
+
+```python
+result = currency.currencies().get()
+```
+
+---
+
+### OHLC
+
+Returns OHLC (Open, High, Low, Close) data for a currency pair on a specific date. Requires a Tier 3 subscription.
+
+**Parameters:**
+
+| Parameter | Required | Description |
+|------------|----------|-------------|
+| `currency` | Yes | Target currency code (e.g. `EUR`, `GBP`, `BTC`) |
+| `date` | Yes | Date in `YYYY-MM-DD` format (must be in the past) |
+| `base` | No | Base currency code (defaults to `USD`) |
+| `interval` | No | Time interval: `5m`, `15m`, `30m`, `1h`, `4h`, `12h`, `1d` (defaults to `1d`) |
+
+```python
+# Basic request (1-day interval)
+result = currency.ohlc().currency('EUR').date('2023-12-25').get()
+
+# With custom interval
+result = currency.ohlc().currency('GBP').date('2023-12-25').interval('1h').get()
+
+# With custom base currency and interval
+result = currency.ohlc().currency('JPY').date('2023-12-25').base('EUR').interval('4h').get()
+
+# XML output
+result = currency.ohlc().currency('EUR').date('2023-12-25').output('XML').get()
+```
+
+**Example response:**
+
+```json
+{
+ "valid": true,
+ "base": "USD",
+ "quote": "EUR",
+ "date": "2023-12-25",
+ "interval": "1d",
+ "ohlc": [
+ {
+ "start": "2023-12-25T00:00:00Z",
+ "open": 0.92000000000000,
+ "high": 0.92500000000000,
+ "low": 0.91800000000000,
+ "close": 0.92200000000000
+ }
+ ]
+}
+```
diff --git a/currencyapinet/currency.py b/currencyapinet/currency.py
index 9595d7f..5293c2f 100644
--- a/currencyapinet/currency.py
+++ b/currencyapinet/currency.py
@@ -3,6 +3,7 @@
from currencyapinet.endpoints.history import History
from currencyapinet.endpoints.timeframe import Timeframe
from currencyapinet.endpoints.currencies import Currencies
+from currencyapinet.endpoints.ohlc import Ohlc
class Currency:
def __init__(self, api_key: str):
@@ -10,15 +11,18 @@ def __init__(self, api_key: str):
def rates(self) -> Rates:
return Rates(self._api_key)
-
+
def convert(self) -> Convert:
return Convert(self._api_key)
-
+
def history(self) -> History:
return History(self._api_key)
-
+
def timeframe(self) -> Timeframe:
return Timeframe(self._api_key)
-
+
def currencies(self) -> Currencies:
return Currencies(self._api_key)
+
+ def ohlc(self) -> Ohlc:
+ return Ohlc(self._api_key)
diff --git a/currencyapinet/endpoints/__init__.py b/currencyapinet/endpoints/__init__.py
index 1bddcf1..66478f2 100644
--- a/currencyapinet/endpoints/__init__.py
+++ b/currencyapinet/endpoints/__init__.py
@@ -2,4 +2,5 @@
from currencyapinet.endpoints.convert import Convert
from currencyapinet.endpoints.history import History
from currencyapinet.endpoints.timeframe import Timeframe
-from currencyapinet.endpoints.currencies import Currencies
\ No newline at end of file
+from currencyapinet.endpoints.currencies import Currencies
+from currencyapinet.endpoints.ohlc import Ohlc
\ No newline at end of file
diff --git a/currencyapinet/endpoints/endpoint.py b/currencyapinet/endpoints/endpoint.py
index 884a7ab..a0188c8 100644
--- a/currencyapinet/endpoints/endpoint.py
+++ b/currencyapinet/endpoints/endpoint.py
@@ -1,6 +1,6 @@
import requests
-API_VERSION = 'v1'
+API_VERSION = 'v2'
BASE_URL = 'https://currencyapi.net/api/' + API_VERSION + '/'
DEFAULT_BASE = 'USD'
DEFAULT_OUTPUT = 'JSON'
diff --git a/currencyapinet/endpoints/ohlc.py b/currencyapinet/endpoints/ohlc.py
new file mode 100644
index 0000000..18c8184
--- /dev/null
+++ b/currencyapinet/endpoints/ohlc.py
@@ -0,0 +1,23 @@
+from currencyapinet.endpoints.endpoint import Endpoint
+
+OHLC_ENDPOINT = 'ohlc'
+
+class Ohlc(Endpoint):
+ def __init__(self, api_key: str):
+ super().__init__(api_key, OHLC_ENDPOINT)
+
+ def currency(self, currency: str):
+ self.add_param('currency', currency.upper())
+ return self
+
+ def date(self, date: str):
+ self.add_param('date', date)
+ return self
+
+ def base(self, currency: str):
+ self._base(currency)
+ return self
+
+ def interval(self, interval: str):
+ self.add_param('interval', interval)
+ return self
diff --git a/setup.py b/setup.py
index 7a8f355..9ad3a4f 100644
--- a/setup.py
+++ b/setup.py
@@ -6,7 +6,7 @@
setup(
name="currencyapinet",
- version="1.1.0",
+ version="2.0.0",
packages=find_packages(exclude="tests"),
description="Python wrapper for CurrencyApi.net",
long_description=README_MD,
diff --git a/tests/endpoints/test_ohlc.py b/tests/endpoints/test_ohlc.py
new file mode 100644
index 0000000..2b77ba7
--- /dev/null
+++ b/tests/endpoints/test_ohlc.py
@@ -0,0 +1,70 @@
+from unittest import TestCase
+from unittest.mock import Mock, patch
+from currencyapinet.endpoints.ohlc import Ohlc
+import requests
+
+class Test(TestCase):
+
+ def setUp(self):
+ self.class_under_test = Ohlc('fakekey')
+
+ def test_ohlc_currency(self):
+ self.class_under_test.currency('eUr')
+ self.assertEqual('EUR', self.class_under_test.param.get('currency'))
+ self.assertIsInstance(self.class_under_test.currency('EUR'), Ohlc)
+
+ def test_ohlc_date(self):
+ self.class_under_test.date('2023-12-25')
+ self.assertEqual('2023-12-25', self.class_under_test.param.get('date'))
+ self.assertIsInstance(self.class_under_test.date('2023-12-25'), Ohlc)
+
+ def test_ohlc_base(self):
+ self.class_under_test.base('gBp')
+ self.assertEqual('GBP', self.class_under_test.param.get('base'))
+ self.assertIsInstance(self.class_under_test.base('USD'), Ohlc)
+
+ def test_ohlc_interval(self):
+ self.class_under_test.interval('1h')
+ self.assertEqual('1h', self.class_under_test.param.get('interval'))
+ self.assertIsInstance(self.class_under_test.interval('1d'), Ohlc)
+
+ def test_ohlc_endpoint_set(self):
+ self.assertEqual('ohlc', self.class_under_test.endpoint)
+
+ def test_ohlc__build_url_params(self):
+ self.assertDictEqual(
+ {'key': 'fakekey', 'output': 'JSON'},
+ self.class_under_test._build_url_params()
+ )
+ self.class_under_test.currency('EUR')
+ self.class_under_test.date('2023-12-25')
+ self.assertDictEqual(
+ {'key': 'fakekey', 'output': 'JSON', 'currency': 'EUR', 'date': '2023-12-25'},
+ self.class_under_test._build_url_params()
+ )
+ self.class_under_test.base('gbP')
+ self.class_under_test.interval('1h')
+ self.assertDictEqual(
+ {'key': 'fakekey', 'output': 'JSON', 'currency': 'EUR', 'date': '2023-12-25', 'base': 'GBP', 'interval': '1h'},
+ self.class_under_test._build_url_params()
+ )
+
+ @patch.object(requests, 'get')
+ def test_ohlc_get(self, mock_requests_get):
+ mock_data = [{"id": 1}, {"id": 2}]
+ response_mock = Mock(return_value=mock_data)
+ mock_requests_get.return_value.json = response_mock
+ self.assertEqual(
+ mock_data,
+ self.class_under_test.get()
+ )
+
+ @patch.object(requests, 'get')
+ def test_ohlc_get_xml(self, mock_requests_get):
+ self.class_under_test.output('xMl')
+ mock_data = [{"id": 1}, {"id": 2}]
+ mock_requests_get.return_value.text = mock_data
+ self.assertEqual(
+ mock_data,
+ self.class_under_test.get()
+ )
diff --git a/tests/test_currency.py b/tests/test_currency.py
index 8edb9d6..e45d76b 100644
--- a/tests/test_currency.py
+++ b/tests/test_currency.py
@@ -4,6 +4,7 @@
from currencyapinet.endpoints.timeframe import Timeframe
from currencyapinet.endpoints.convert import Convert
from currencyapinet.endpoints.currencies import Currencies
+from currencyapinet.endpoints.ohlc import Ohlc
from unittest import TestCase
class Test(TestCase):
@@ -25,4 +26,8 @@ def test_convert_method(self):
def test_currencies_method(self):
class_under_test = Currency('fakeKey')
- self.assertIsInstance(class_under_test.currencies(), Currencies)
\ No newline at end of file
+ self.assertIsInstance(class_under_test.currencies(), Currencies)
+
+ def test_ohlc_method(self):
+ class_under_test = Currency('fakeKey')
+ self.assertIsInstance(class_under_test.ohlc(), Ohlc)
\ No newline at end of file