diff --git a/integration_tests/__init__.py b/integration_tests/__init__.py index 9c8997b..02df6ff 100644 --- a/integration_tests/__init__.py +++ b/integration_tests/__init__.py @@ -5,6 +5,7 @@ from .bithumb_data_provider_ITG_test import BithumbDataProviderIntegrationTests from .binance_data_provider_ITG_test import BinanceDataProviderIntegrationTests from .upbit_data_provider_ITG_test import UpbitDataProviderIntegrationTests +from .upbit_binance_data_provider_ITG_test import UpbitBinanceDataProviderIntegrationTests from .data_repository_ITG_test import ( DataRepositoryUpbitIntegrationTests, DataRepositoryBinanceIntegrationTests, diff --git a/integration_tests/upbit_binance_data_provider_ITG_test.py b/integration_tests/upbit_binance_data_provider_ITG_test.py new file mode 100644 index 0000000..00dd83a --- /dev/null +++ b/integration_tests/upbit_binance_data_provider_ITG_test.py @@ -0,0 +1,140 @@ +import time +import unittest +from smtm import UpbitBinanceDataProvider +from unittest.mock import * + + +class UpbitBinanceDataProviderIntegrationTests(unittest.TestCase): + def test_ITG_get_info_return_correct_data(self): + dp = UpbitBinanceDataProvider() + upbit_info = dp.get_info()[0] + self.assertEqual(upbit_info["type"], "primary_candle") + self.assertEqual("market" in upbit_info, True) + self.assertEqual("date_time" in upbit_info, True) + self.assertEqual("opening_price" in upbit_info, True) + self.assertEqual("high_price" in upbit_info, True) + self.assertEqual("low_price" in upbit_info, True) + self.assertEqual("closing_price" in upbit_info, True) + self.assertEqual("acc_price" in upbit_info, True) + self.assertEqual("acc_volume" in upbit_info, True) + + binance_info = dp.get_info()[1] + self.assertEqual(binance_info["type"], "binance") + self.assertEqual("market" in binance_info, True) + self.assertEqual("date_time" in binance_info, True) + self.assertEqual("opening_price" in binance_info, True) + self.assertEqual("high_price" in binance_info, True) + self.assertEqual("low_price" in binance_info, True) + self.assertEqual("closing_price" in binance_info, True) + self.assertEqual("acc_price" in binance_info, True) + self.assertEqual("acc_volume" in binance_info, True) + # avoid throttling + time.sleep(0.5) + + def test_ITG_get_info_return_correct_data_when_currency_is_BTC(self): + dp = UpbitBinanceDataProvider("BTC") + info = dp.get_info()[0] + self.assertEqual(info["type"], "primary_candle") + self.assertEqual(info["market"], "BTC") + self.assertEqual("date_time" in info, True) + self.assertEqual("opening_price" in info, True) + self.assertEqual("high_price" in info, True) + self.assertEqual("low_price" in info, True) + self.assertEqual("closing_price" in info, True) + self.assertEqual("acc_price" in info, True) + self.assertEqual("acc_volume" in info, True) + + binance_info = dp.get_info()[1] + self.assertEqual(binance_info["type"], "binance") + self.assertEqual(binance_info["market"], "BTC") + self.assertEqual("date_time" in binance_info, True) + self.assertEqual("opening_price" in binance_info, True) + self.assertEqual("high_price" in binance_info, True) + self.assertEqual("low_price" in binance_info, True) + self.assertEqual("closing_price" in binance_info, True) + self.assertEqual("acc_price" in binance_info, True) + self.assertEqual("acc_volume" in binance_info, True) + + # avoid throttling + time.sleep(0.5) + + def test_ITG_get_info_return_correct_data_when_currency_is_ETH(self): + dp = UpbitBinanceDataProvider("ETH") + info = dp.get_info()[0] + self.assertEqual(info["type"], "primary_candle") + self.assertEqual(info["market"], "ETH") + self.assertEqual("date_time" in info, True) + self.assertEqual("opening_price" in info, True) + self.assertEqual("high_price" in info, True) + self.assertEqual("low_price" in info, True) + self.assertEqual("closing_price" in info, True) + self.assertEqual("acc_price" in info, True) + self.assertEqual("acc_volume" in info, True) + + binance_info = dp.get_info()[1] + self.assertEqual(binance_info["type"], "binance") + self.assertEqual(binance_info["market"], "ETH") + self.assertEqual("date_time" in binance_info, True) + self.assertEqual("opening_price" in binance_info, True) + self.assertEqual("high_price" in binance_info, True) + self.assertEqual("low_price" in binance_info, True) + self.assertEqual("closing_price" in binance_info, True) + self.assertEqual("acc_price" in binance_info, True) + self.assertEqual("acc_volume" in binance_info, True) + + # avoid throttling + time.sleep(0.5) + + def test_ITG_get_info_return_correct_data_when_currency_is_DOGE(self): + dp = UpbitBinanceDataProvider("DOGE") + info = dp.get_info()[0] + self.assertEqual(info["type"], "primary_candle") + self.assertEqual(info["market"], "DOGE") + self.assertEqual("date_time" in info, True) + self.assertEqual("opening_price" in info, True) + self.assertEqual("high_price" in info, True) + self.assertEqual("low_price" in info, True) + self.assertEqual("closing_price" in info, True) + self.assertEqual("acc_price" in info, True) + self.assertEqual("acc_volume" in info, True) + + binance_info = dp.get_info()[1] + self.assertEqual(binance_info["type"], "binance") + self.assertEqual(binance_info["market"], "DOGE") + self.assertEqual("date_time" in binance_info, True) + self.assertEqual("opening_price" in binance_info, True) + self.assertEqual("high_price" in binance_info, True) + self.assertEqual("low_price" in binance_info, True) + self.assertEqual("closing_price" in binance_info, True) + self.assertEqual("acc_price" in binance_info, True) + self.assertEqual("acc_volume" in binance_info, True) + + # avoid throttling + time.sleep(0.5) + + def test_ITG_get_info_return_correct_data_when_currency_is_XRP(self): + dp = UpbitBinanceDataProvider("XRP") + info = dp.get_info()[0] + self.assertEqual(info["type"], "primary_candle") + self.assertEqual(info["market"], "XRP") + self.assertEqual("date_time" in info, True) + self.assertEqual("opening_price" in info, True) + self.assertEqual("high_price" in info, True) + self.assertEqual("low_price" in info, True) + self.assertEqual("closing_price" in info, True) + self.assertEqual("acc_price" in info, True) + self.assertEqual("acc_volume" in info, True) + + binance_info = dp.get_info()[1] + self.assertEqual(binance_info["type"], "binance") + self.assertEqual(binance_info["market"], "XRP") + self.assertEqual("date_time" in binance_info, True) + self.assertEqual("opening_price" in binance_info, True) + self.assertEqual("high_price" in binance_info, True) + self.assertEqual("low_price" in binance_info, True) + self.assertEqual("closing_price" in binance_info, True) + self.assertEqual("acc_price" in binance_info, True) + self.assertEqual("acc_volume" in binance_info, True) + + # avoid throttling + time.sleep(0.5) diff --git a/smtm/__init__.py b/smtm/__init__.py index 848abd2..e9fd002 100644 --- a/smtm/__init__.py +++ b/smtm/__init__.py @@ -9,6 +9,7 @@ from .data.simulation_data_provider import SimulationDataProvider from .data.simulation_dual_data_provider import SimulationDualDataProvider from .data.upbit_data_provider import UpbitDataProvider +from .data.upbit_binance_data_provider import UpbitBinanceDataProvider from .data.bithumb_data_provider import BithumbDataProvider from .data.binance_data_provider import BinanceDataProvider from .data.data_repository import DataRepository diff --git a/smtm/data/simulation_dual_data_provider.py b/smtm/data/simulation_dual_data_provider.py index 25aca0a..59c1900 100644 --- a/smtm/data/simulation_dual_data_provider.py +++ b/smtm/data/simulation_dual_data_provider.py @@ -2,7 +2,6 @@ import copy from datetime import datetime, timedelta -from ..config import Config from .data_provider import DataProvider from .database import Database from ..log_manager import LogManager diff --git a/smtm/data/upbit_binance_data_provider.py b/smtm/data/upbit_binance_data_provider.py new file mode 100644 index 0000000..37eb635 --- /dev/null +++ b/smtm/data/upbit_binance_data_provider.py @@ -0,0 +1,41 @@ +"""DataProvider 구현체이며 Upbit, Binance 2개의 거래소 실시간 데이터를 전달하는 클래스""" + +import copy +from datetime import datetime, timedelta +from .data_provider import DataProvider +from ..log_manager import LogManager +from .upbit_data_provider import UpbitDataProvider +from .binance_data_provider import BinanceDataProvider + +class UpbitBinanceDataProvider(DataProvider): + """Upbit, Binance 2개의 거래소로부터 과거 데이터를 수집해서 순차적으로 제공하는 클래스 + Upbit 데이터의 타입을 primary_candle로 설정, Binance 데이터를 binance로 설정 + 어느 거래소의 데이터를 기준으로 거래할지는 DataProvider는 관여하지 않음 + """ + + def __init__(self, currency="BTC", interval=60): + self.upbit_dp = UpbitDataProvider(currency, interval) + self.binance_dp = BinanceDataProvider(currency, interval) + + def get_info(self): + """순차적으로 거래 정보 전달한다 + + Returns: 거래 정보 딕셔너리 + { + "market": 거래 시장 종류 BTC + "date_time": 정보의 기준 시간 + "opening_price": 시작 거래 가격 + "high_price": 최고 거래 가격 + "low_price": 최저 거래 가격 + "closing_price": 마지막 거래 가격 + "acc_price": 단위 시간내 누적 거래 금액 + "acc_volume": 단위 시간내 누적 거래 양 + } + """ + upbit_info = self.upbit_dp.get_info() + upbit_info[0]["type"] = "primary_candle" + + binance_info = self.binance_dp.get_info() + binance_info[0]["type"] = "binance" + return [upbit_info[0], binance_info[0]] + diff --git a/tests/upbit_binance_data_provider_test.py b/tests/upbit_binance_data_provider_test.py new file mode 100644 index 0000000..6338c1c --- /dev/null +++ b/tests/upbit_binance_data_provider_test.py @@ -0,0 +1,57 @@ +import unittest +from smtm import UpbitBinanceDataProvider +from unittest.mock import * +import requests + + +class UpbitBinanceDataProviderTests(unittest.TestCase): + def test_get_info_return_result_from_upbit_binance_data_provider(self): + dp = UpbitBinanceDataProvider("BTC") + dp.upbit_dp = MagicMock() + dp.upbit_dp.get_info.return_value = [ + { + "market": "BTC-KRW", + "date_time": "2020-03-10T22:52:00", + "opening_price": 9777000, + "high_price": 9778000, + "low_price": 9763000, + "closing_price": 9778000, + "acc_price": 11277224.71063000, + "acc_volume": 1.15377852, + } + ] + dp.binance_dp = MagicMock() + dp.binance_dp.get_info.return_value = [ + { + "market": "BTC-USDT", + "date_time": "2020-03-10T22:52:00", + "opening_price": 0.0163479, + "high_price": 0.8, + "low_price": 0.015758, + "closing_price": 0.015771, + "acc_price": 2434.19055334, + "acc_volume": 148976.11427815, + } + ] + + info = dp.get_info() + + self.assertEqual(info[0]["type"], "primary_candle") + self.assertEqual(info[0]["market"], "BTC-KRW") + self.assertEqual(info[0]["date_time"], "2020-03-10T22:52:00") + self.assertEqual(info[0]["opening_price"], 9777000) + self.assertEqual(info[0]["high_price"], 9778000) + self.assertEqual(info[0]["low_price"], 9763000) + self.assertEqual(info[0]["closing_price"], 9778000) + self.assertEqual(info[0]["acc_price"], 11277224.71063000) + self.assertEqual(info[0]["acc_volume"], 1.15377852) + + self.assertEqual(info[1]["type"], "binance") + self.assertEqual(info[1]["market"], "BTC-USDT") + self.assertEqual(info[1]["date_time"], "2020-03-10T22:52:00") + self.assertEqual(info[1]["opening_price"], 0.0163479) + self.assertEqual(info[1]["high_price"], 0.8) + self.assertEqual(info[1]["low_price"], 0.015758) + self.assertEqual(info[1]["closing_price"], 0.015771) + self.assertEqual(info[1]["acc_price"], 2434.19055334) + self.assertEqual(info[1]["acc_volume"], 148976.11427815)