msaltnet / smtm

It's a game to get money
https://smtm.msalt.net
MIT License
91 stars 96 forks source link

simulator - trader #21

Closed msaltnet closed 3 years ago

msaltnet commented 3 years ago

공통

SimulatorDataProvider

StrategyBuyAndHold VirtualMarket

class SimulatorDataProvider(DataProvider): ''' 거래소로부터 과거 데이터를 수집해서 순차적으로 제공하는 클래스 '''

url = "https://api.upbit.com/v1/candles/minutes/1"
querystring = {"market":"KRW-BTC"}

def __init__(self):
    self.logger = LogManager.get_logger(__name__)
    self.is_initialized = False
    self.end = None #"2020-01-19 20:34:42"
    self.http = None
    self.data = []
    self.count = 0
    self.index = 0

def get_info(self):
    '''순차적으로 거래 정보 전달'''

    now = self.index
    self.index = now + 1
    if now >= len(self.data):
        return None
    return self.__create_candle_info(self.data[now])

def __initialize(self, end=None, count=100):
    self.index = 0
    self.is_initialized = True
    self.end = end
    self.count = count

def initialize(self, http):
    self.initialize_from_server(http)

def initialize_with_file(self, filepath, end=None, count=100):
    if self.is_initialized:
        return

    self.__initialize(end, count)
    self.__get_data_from_file(filepath)

def initialize_from_server(self, http, end=None, count=100):
    if self.is_initialized:
        return

    self.__initialize(end, count)
    self.http = http
    self.__get_data_from_server()

def __get_data_from_file(self, filepath):
    try :
        with open(filepath, 'r') as data_file:
            self.data = json.loads(data_file.read())
            self.is_initialized = True
    except FileNotFoundError as msg:
        self.logger.warning(msg)

def __create_candle_info(self, data):
    candle = CandleInfo()
    try:
        candle.market = data["market"]
        candle.date_time = data["candle_date_time_utc"]
        candle.opening_price = data["opening_price"]
        candle.high_price = data["high_price"]
        candle.low_price = data["low_price"]
        candle.closing_price = data["trade_price"]
        candle.acc_price = data["candle_acc_trade_price"]
        candle.acc_volume = data["candle_acc_trade_volume"]
    except KeyError:
        self.logger.warning("invalid data for candle info")
        return None

    return candle

def __get_data_from_server(self):
    if self.http is None or self.is_initialized != True:
        return False

    if self.end is not None :
        self.querystring["to"] = self.end
    else :
        self.querystring["to"] = "2020-11-11 00:00:00"

    if self.count is not None :
        self.querystring["count"] = self.count
    else :
        self.querystring["count"] = 100

    response = self.http.request("GET", self.url, params=self.querystring)
    self.data = json.loads(response.text)
msaltnet commented 3 years ago

test

import unittest
from smtm import SimulatorTrader
from unittest.mock import *
import requests

class SimulatorTraderTests(unittest.TestCase):
    def setUp(self):
        pass

    def tearDown(self):
        pass

    def test_handle_request_call_callback_with_result_of_market_handle_quest(self):
        trader = SimulatorTrader()
        class DummyRequest():
            pass
        dummy_request = DummyRequest()
        dummy_request.id = "mango"
        dummy_request.type = "orange"
        callback = MagicMock()
        trader.market.handle_request = MagicMock(return_value="banana")
        trader.handle_request(dummy_request, callback)
        trader.market.handle_request.assert_called_once_with(dummy_request)
        callback.assert_called_once_with("banana")
    def test_initialize_initialize_virtual_market(self):
        trader = SimulatorTrader()
        class DummyHttp():
            pass
        http = DummyHttp()
        trader.market.initialize = MagicMock()
        trader.market.deposit = MagicMock()
        trader.initialize(http, "mango", 500, 5000)
        trader.market.initialize.assert_called_once_with(http, "mango", 500)
        trader.market.deposit.assert_called_once_with(5000)