Esempio n. 1
0
	def computeCryptoFiatRate(self,
							  crypto,
							  fiat,
							  dateStr=None):
		'''

		:raise UnsupportedCryptoFiatPairError in case the crypto fiat exchange
		 	   CSV file does not have the necessary information to compute the
		 	   crypto/fiat pair rate.
		:raise AfterNowPriceRequestDateError in case the passed dateStr is after
			   now.

		@param crypto:
		@param fiat:
		@param dateStr: if not None, means that an historical rate must be
						obtained. Otherwise, a current rate is returned.

		:return crypto/fiat pair current rate
		'''
		if dateStr is not None:
			nowDateArrow = DateTimeUtil.localNow(LOCAL_TIME_ZONE)
			requestDateArrow = DateTimeUtil.dateTimeStringToArrowLocalDate(dateStr, LOCAL_TIME_ZONE, DATE_FORMAT)
			if DateTimeUtil.isAfter(requestDateArrow, nowDateArrow):
				raise AfterNowPriceRequestDateError(dateStr)

		intermediateExchangeRateRequestLst = self._getIntermediateExchangeRateRequests(crypto, fiat)

		rateRequestNumber = len(intermediateExchangeRateRequestLst)

		if rateRequestNumber == 1:
			exchange = intermediateExchangeRateRequestLst[0][2]
			if exchange == '1':
				# the case if the crypto/fiat pair is a stablecoin/ coin fiat pair,
				# like USDC/USD !
				return 1
			else:
				resultData = self._getCurrentOrHistoRate(crypto, dateStr, exchange, fiat)

				if not self._checkIfProblem(resultData):
					return resultData.getValue(resultData.RESULT_KEY_PRICE)
		elif rateRequestNumber == 2:
				crypto = intermediateExchangeRateRequestLst[0][0]
				unit = intermediateExchangeRateRequestLst[0][1]
				exchange = intermediateExchangeRateRequestLst[0][2]
				if exchange == '1':
					resultData = ResultData()
					resultData.setValue(resultData.RESULT_KEY_PRICE, 1)
				else:
					resultData = self._getCurrentOrHistoRate(crypto, dateStr, exchange, unit)
				if not self._checkIfProblem(resultData):
					firstRate = resultData.getValue(resultData.RESULT_KEY_PRICE)
					crypto = intermediateExchangeRateRequestLst[1][0]
					fiat = intermediateExchangeRateRequestLst[1][1]
					exchange = intermediateExchangeRateRequestLst[1][2]
					resultData = self._getCurrentOrHistoRate(crypto, dateStr, exchange, fiat)
					if not self._checkIfProblem(resultData):
						secondRate = resultData.getValue(resultData.RESULT_KEY_PRICE)
						return firstRate * secondRate

		raise UnsupportedCryptoFiatPairError(crypto, fiat, self.cryptoFiatCsvFilePathName)
Esempio n. 2
0
 def test_getHistoDayPriceAtUTCTimeStampMidOfDay(self):
     crypto = 'BTC'
     fiat = 'USD'
     exchange = 'CCCAGG'
     utcArrowDateTimeObj_midOfDay = DateTimeUtil.dateTimeStringToArrowLocalDate("2017/09/30 12:59:59", 'UTC',
                                                                                "YYYY/MM/DD HH:mm:ss")
     resultData = ResultData()
     resultData = self.priceRequester._getHistoDayPriceAtUTCTimeStamp(crypto,
                                                                       fiat,
                                                                       utcArrowDateTimeObj_midOfDay.timestamp,
                                                                       exchange,
                                                                       resultData)
     self.assertEqual(1506729600, resultData.getValue(resultData.RESULT_KEY_PRICE_TIME_STAMP))
     priceArrowUTCDateTime = DateTimeUtil.timeStampToArrowLocalDate(resultData.getValue(resultData.RESULT_KEY_PRICE_TIME_STAMP),
                                                                    'UTC')
     self.assertEqual(resultData.getValue(resultData.RESULT_KEY_PRICE_TYPE), resultData.PRICE_TYPE_HISTO_DAY)
     self.assertEqual('30/09/17', priceArrowUTCDateTime.format(self.configMgr.dateOnlyFormat))
     self.assertEqual(4360.62, resultData.getValue(resultData.RESULT_KEY_PRICE))
Esempio n. 3
0
class TestResultData(unittest.TestCase):
    def setUp(self):
        self.resultData = ResultData()


    def testInit(self):
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_CRYPTO), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_UNIT), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_EXCHANGE), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_PRICE_TIME_STAMP), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_PRICE_DATE_TIME_STRING), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_PRICE), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_PRICE_TYPE), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_ERROR_MSG), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_WARNINGS_DIC), {})
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_INITIAL_COMMAND_PARMS), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_OPTION_VALUE_CRYPTO), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_OPTION_VALUE_UNIT), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_OPTION_VALUE_FIAT), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_OPTION_VALUE_SAVE), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_OPTION_FIAT_RATE), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_OPTION_FIAT_COMPUTED_AMOUNT), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_OPTION_FIAT_SYMBOL), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_OPTION_FIAT_EXCHANGE), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_OPTION_FIAT_SAVE), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_OPTION_PRICE_AMOUNT), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_OPTION_PRICE_SAVE), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_OPTION_RESULT_COMPUTED_AMOUNT_UNIT), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_OPTION_RESULT_COMPUTED_PERCENT_UNIT), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_OPTION_RESULT_COMPUTED_AMOUNT_FIAT), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_OPTION_RESULT_COMPUTED_PERCENT_FIAT), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_OPTION_RESULT_SAVE), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_OPTION_LIMIT_AMOUNT), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_OPTION_LIMIT_COMPUTED_UNIT_AMOUNT), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_OPTION_LIMIT_SYMBOL), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_OPTION_LIMIT_EXCHANGE), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_OPTION_LIMIT_SAVE), None)
        

    def testNoError(self):
        self.assertTrue(self.resultData.noError())
        
        errorMsg = "ERROR - test error"
        
        self.resultData.setError(errorMsg)
        self.assertFalse(self.resultData.noError())


    def testSetValue(self):
        self.resultData.setValue(self.resultData.RESULT_KEY_CRYPTO, 'USD')
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_CRYPTO), 'USD')


    def testSetGetWarning(self):
        commValWarningMsg = "test warning command value"
        futureDateWarningMsg = "test warning future date"

        self.resultData.setWarning(ResultData.WARNING_TYPE_OPTION_VALUE, commValWarningMsg)
        self.resultData.setWarning(ResultData.WARNING_TYPE_FUTURE_DATE, futureDateWarningMsg)

        self.assertEqual(commValWarningMsg, self.resultData.getWarningMessage(ResultData.WARNING_TYPE_OPTION_VALUE))
        self.assertEqual(futureDateWarningMsg, self.resultData.getWarningMessage(ResultData.WARNING_TYPE_FUTURE_DATE))


    def testGetAllWarningMessages(self):
        commValWarningMsg = "test warning command value"
        futureDateWarningMsg = "test warning future date"

        self.resultData.setWarning(ResultData.WARNING_TYPE_OPTION_VALUE, commValWarningMsg)
        self.resultData.setWarning(ResultData.WARNING_TYPE_FUTURE_DATE, futureDateWarningMsg)

        self.assertEqual([commValWarningMsg, futureDateWarningMsg], self.resultData.getAllWarningMessages())


    def testContainsWarning(self):
        commValWarningMsg = "test warning command value"
        futureDateWarningMsg = "test warning future date"

        self.assertFalse(self.resultData.containsWarnings())

        self.resultData.setWarning(ResultData.WARNING_TYPE_OPTION_VALUE, commValWarningMsg)
        self.assertTrue(self.resultData.containsWarning(ResultData.WARNING_TYPE_OPTION_VALUE))
        self.assertFalse(self.resultData.containsWarning(ResultData.WARNING_TYPE_FUTURE_DATE))

        self.resultData.setWarning(ResultData.WARNING_TYPE_FUTURE_DATE, futureDateWarningMsg)
        self.assertTrue(self.resultData.containsWarning(ResultData.WARNING_TYPE_FUTURE_DATE))


    def testOverwriteWarning(self):
        commValWarningMsgOne = "test warning command value one"
        futureDateWarningMsgOne = "test warning future date one"

        self.resultData.setWarning(ResultData.WARNING_TYPE_OPTION_VALUE, commValWarningMsgOne)
        self.resultData.setWarning(ResultData.WARNING_TYPE_FUTURE_DATE, futureDateWarningMsgOne)

        commValWarningMsgTwo = "test warning command value two"
        futureDateWarningMsgTwo = "test warning future date two"

        self.resultData.setWarning(ResultData.WARNING_TYPE_OPTION_VALUE, commValWarningMsgTwo)
        self.resultData.setWarning(ResultData.WARNING_TYPE_FUTURE_DATE, futureDateWarningMsgTwo)

        self.assertEqual(commValWarningMsgTwo, self.resultData.getWarningMessage(ResultData.WARNING_TYPE_OPTION_VALUE))
        self.assertEqual(futureDateWarningMsgTwo, self.resultData.getWarningMessage(ResultData.WARNING_TYPE_FUTURE_DATE))
Esempio n. 4
0
class TestResultData(unittest.TestCase):
    def setUp(self):
        self.resultData = ResultData()


    def testInit(self):
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_CRYPTO), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_FIAT), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_EXCHANGE), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_PRICE_TIME_STAMP), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_PRICE_DATE_TIME_STRING), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_PRICE), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_PRICE_TYPE), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_ERROR_MSG), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_PRICE_VALUE_FIAT), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_PRICE_VALUE_CRYPTO), None)
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_PRICE_VALUE_SAVE), None)


    def testIsEmpty(self):
        self.assertTrue(self.resultData.isEmpty(self.resultData.RESULT_KEY_CRYPTO))


    def testSetValue(self):
        self.resultData.setValue(self.resultData.RESULT_KEY_CRYPTO, 'USD')
        self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_CRYPTO), 'USD')


    def testSetGetWarning(self):
        commValWarningMsg = "test warning command value"
        futureDateWarningMsg = "test warning future date"

        self.resultData.setWarning(ResultData.WARNING_TYPE_COMMAND_VALUE, commValWarningMsg)
        self.resultData.setWarning(ResultData.WARNING_TYPE_FUTURE_DATE, futureDateWarningMsg)

        self.assertEqual(commValWarningMsg, self.resultData.getWarningMessage(ResultData.WARNING_TYPE_COMMAND_VALUE))
        self.assertEqual(futureDateWarningMsg, self.resultData.getWarningMessage(ResultData.WARNING_TYPE_FUTURE_DATE))


    def testGetAllWarningMessages(self):
        commValWarningMsg = "test warning command value"
        futureDateWarningMsg = "test warning future date"

        self.resultData.setWarning(ResultData.WARNING_TYPE_COMMAND_VALUE, commValWarningMsg)
        self.resultData.setWarning(ResultData.WARNING_TYPE_FUTURE_DATE, futureDateWarningMsg)

        self.assertEqual([commValWarningMsg, futureDateWarningMsg], self.resultData.getAllWarningMessages())


    def testContainsWarning(self):
        commValWarningMsg = "test warning command value"
        futureDateWarningMsg = "test warning future date"

        self.assertFalse(self.resultData.containsWarnings())

        self.resultData.setWarning(ResultData.WARNING_TYPE_COMMAND_VALUE, commValWarningMsg)
        self.assertTrue(self.resultData.containsWarning(ResultData.WARNING_TYPE_COMMAND_VALUE))
        self.assertFalse(self.resultData.containsWarning(ResultData.WARNING_TYPE_FUTURE_DATE))

        self.resultData.setWarning(ResultData.WARNING_TYPE_FUTURE_DATE, futureDateWarningMsg)
        self.assertTrue(self.resultData.containsWarning(ResultData.WARNING_TYPE_FUTURE_DATE))


    def testOverwriteWarning(self):
        commValWarningMsgOne = "test warning command value one"
        futureDateWarningMsgOne = "test warning future date one"

        self.resultData.setWarning(ResultData.WARNING_TYPE_COMMAND_VALUE, commValWarningMsgOne)
        self.resultData.setWarning(ResultData.WARNING_TYPE_FUTURE_DATE, futureDateWarningMsgOne)

        commValWarningMsgTwo = "test warning command value two"
        futureDateWarningMsgTwo = "test warning future date two"

        self.resultData.setWarning(ResultData.WARNING_TYPE_COMMAND_VALUE, commValWarningMsgTwo)
        self.resultData.setWarning(ResultData.WARNING_TYPE_FUTURE_DATE, futureDateWarningMsgTwo)

        self.assertEqual(commValWarningMsgTwo, self.resultData.getWarningMessage(ResultData.WARNING_TYPE_COMMAND_VALUE))
        self.assertEqual(futureDateWarningMsgTwo, self.resultData.getWarningMessage(ResultData.WARNING_TYPE_FUTURE_DATE))
Esempio n. 5
0
	def getCryptoPrice(self,
					   crypto,
					   unit,
					   exchange,
					   day,
					   month,
					   year,
					   hour,
					   minute,
					   optionValueSymbol=None,
					   optionValueAmount=None,
					   optionValueSaveFlag=None,
					   optionFiatSymbol=None,
					   optionFiatExchange=None,
					   optionPriceAmount=None,
					   optionPriceSaveFlag=None,
					   optionResultStrAmount=None,
					   optionResultSaveFlag=None,
					   optionLimitSymbol=None,
					   optionLimitAmount=None,
					   optionLimitExchange=None,
					   optionLimitSaveFlag=None,
					   requestInputString=''):
		"""
		Ask the PriceRequester either a RT price or a historical price. Then,
		in case a fiat (-f) or/and a value option (-v) was specified, computes
		them and add the results to the returned ResultData.
		
		:param crypto:
		:param unit:
		:param exchange:
		:param day:
		:param month:
		:param year:
		:param hour:
		:param minute:
		:param optionValueSymbol: upper case currency value symbol. If == crypto, this means that optionValueAmount provided
								  is in crypto and must be converted into unit (counter party) at the rate returned by
								  the PriceRequester.

								  If the currency value symbol == unit, this means that optionValueAmount provided
								  is in the counter party (unit or an other crypto) and must be converted into crypto at
								  the rate returned by the PriceRequester.

								  Ex 1:  -v0.001btc
										crypto == BTC
										unit == USD
										optionValueSymbol == BTC
										optionValueAmount == 0.001

										if returned rate (stored in ResultData.RESULT_KEY_PRICE entry) is 20000,
										converted value will be 20000 USD * 0.001 BTC => 200 USD

								  Ex 2:  -v500usd
										crypto == BTC
										unit == USD
										optionValueSymbol == USD
										optionValueAmount == 500

										if returned rate (stored in ResultData.RESULT_KEY_PRICE entry) is 20000,
										converted value will be 1 / 20000 USD * 500 USD => 0.025 BTC

		:param optionValueAmount:   float specified value option amount
		:param optionValueSaveFlag: used to refine warning if value option not applicable
		:param optionFiatSymbol:    stores the fiat symbol, i.e. the fiat into which the returned
									unit amount is converted
		:param optionFiatExchange:
		:param optionPriceAmount:
		:param optionPriceSaveFlag: not sure if useful. May be used to refine warning if price option
									not applicable
		:param optionResultStrAmount: ex: '' means -1 or -2 or -1-3 or -2:-4
		:param optionResultSaveFlag:  not sure if useful. May be used to refine warning if result option
									  not applicable
		:param optionLimitSymbol:
		:param optionLimitAmount:
		:param optionLimitExchange:
		:param optionLimitSaveFlag: not sure if useful. May be used to refine warning if limit option
									not applicable
		:param requestInputString): used for to complete the error msg with the request
									causing problem!
		:seqdiag_return ResultData
		:return: a ResultData filled with result values
		"""
		
		# validating exchange, fiat exchange and limit exchange
		
		if exchange == None:
			resultData = ResultData()
			resultData.setError("ERROR - exchange could not be parsed due to an error in your request ({}).".format(requestInputString))
			return resultData
		else:
			try:
				validCryptoUnitExchangeSymbol = self.crypCompExchanges.getExchange(exchange)
			except(KeyError):
				resultData = ResultData()
				resultData.setError(MARKET_NOT_SUPPORTED_ERROR.format(exchange))
				return resultData

		validFiatExchangeSymbol = None

		if optionFiatExchange:
			try:
				validFiatExchangeSymbol = self.crypCompExchanges.getExchange(optionFiatExchange)
			except(KeyError):
				resultData = ResultData()
				resultData.setError(MARKET_NOT_SUPPORTED_ERROR.format(optionFiatExchange))
				return resultData

		validLimitExchangeSymbol = None

		if optionLimitExchange:
			try:
				validLimitExchangeSymbol = self.crypCompExchanges.getExchange(optionLimitExchange)
			except(KeyError):
				resultData = ResultData()
				resultData.setError(MARKET_NOT_SUPPORTED_ERROR.format(optionLimitExchange))
				return resultData

		localTz = self.configManager.localTimeZone
		dateTimeFormat = self.configManager.dateTimeFormat

		resultData = self._getPrice(crypto,
									unit,
									validCryptoUnitExchangeSymbol,
									year,
									month,
									day,
									hour,
									minute,
									dateTimeFormat,
									localTz,
									optionPriceAmount,
									optionPriceSaveFlag)


		if not resultData.noError():
			# since crypto/unit is not supported by the exchange, we try to request the unit/crypto inverted rate
			errorMsg = resultData.getErrorMessage()
			resultData = self._getPrice(unit,
										crypto,
										validCryptoUnitExchangeSymbol,
										year,
										month,
										day,
										hour,
										minute,
										dateTimeFormat,
										localTz,
										optionPriceAmount)

			resultData.setValue(resultData.RESULT_KEY_CRYPTO, crypto)
			resultData.setValue(resultData.RESULT_KEY_UNIT, unit)
			price = resultData.getValue(resultData.RESULT_KEY_PRICE)

			if price:
				resultData.setValue(resultData.RESULT_KEY_PRICE, 1 / price)
				resultData.setError(None)
			else:
				resultData.setError(errorMsg)
				
		if optionPriceAmount is not None and resultData.noError():
			resultData.setValue(resultData.RESULT_KEY_PRICE, optionPriceAmount)
			resultData.setValue(resultData.RESULT_KEY_PRICE_TYPE, resultData.PRICE_TYPE_EFFECTIVE)
		
		if optionFiatSymbol is not None and resultData.noError():
			resultData = self._computeOptionFiatAmount(resultData,
													   optionFiatSymbol,
													   validFiatExchangeSymbol,
													   crypto,
													   unit,
													   validCryptoUnitExchangeSymbol,
													   year,
													   month,
													   day,
													   hour,
													   minute,
													   dateTimeFormat,
													   localTz)

		if optionValueSymbol is not None and resultData.noError():
			resultData = self._computeOptionValueAmount(resultData,
														crypto,
														unit,
														optionFiatSymbol,
														optionValueSymbol,
														optionValueAmount,
														optionValueSaveFlag)

		return resultData
Esempio n. 6
0
    def getCryptoPrice(self,
                       crypto,
                       fiat,
                       exchange,
                       day,
                       month,
                       year,
                       hour,
                       minute,
                       priceValueSymbol = None,
                       priceValueAmount = None,
                       priceValueSaveFlag = None,
                       requestInputString = ''):
        '''
        Ask the PriceRequester either a RT price or a historical price. Then, in case a price value parm (-v)
        was specified, does the conversion and add its result to the returned ResultData
        :param crypto: upper case crypto symbol
        :param fiat: upper case fiat symbol
        :param exchange: exchange name
        :param day: int day number
        :param month: int month number
        :param year: int year number
        :param hour: int hour number
        :param minute: int minute number
        :param priceValueSymbol: upper case price value symbol. If == crypto, this means that priceValueAmount provided
                                 is in crypto and must be converted into fiat at the rate returned by the PriceRequester.

                                 If the price value symbol == fiat, this means that priceValueAmount provided
                                 is in fiat and must be converted into crypto at the rate returned by the PriceRequester.

                                 Ex 1:  -v0.001btc
                                        crypto == BTC
                                        fiat == USD
                                        priceValueSymbol == BTC
                                        priceValueAmount == 0.001

                                        if returned rate (stored in ResultData.RESULT_KEY_PRICE entry) is 20000,
                                        converted value will be 20000 USD * 0.001 BTC => 200 USD

                                 Ex 2:  -v500usd
                                        crypto == BTC
                                        fiat == USD
                                        priceValueSymbol == USD
                                        priceValueAmount == 500

                                        if returned rate (stored in ResultData.RESULT_KEY_PRICE entry) is 20000,
                                        converted value will be 1 / 20000 USD * 500 USD => 0.025 BTC

        :param priceValueAmount: float price value amount
        :param priceValueSaveFlag: used to refine warning if value command not applicable
        :param requestInputString): used for better error msg !

        :seqdiag_return ResultData
        :return: a ResultData filled with result values
        '''
        if exchange == None:
            resultData = ResultData()
            resultData.setValue(ResultData.RESULT_KEY_ERROR_MSG, "ERROR - exchange could not be parsed due to an error in your request ({})".format(requestInputString))
            return resultData
        else:
            #this responsability is specific to the PriceRequester and should be moved to it !
            try:
                validExchangeSymbol = self.crypCompExchanges.getExchange(exchange)
            except(KeyError):
                resultData = ResultData()
                resultData.setValue(ResultData.RESULT_KEY_ERROR_MSG, "ERROR - {} market does not exist for this coin pair ({}-{})".format(exchange, crypto, fiat))
                return resultData

        localTz = self.configManager.localTimeZone
        dateTimeFormat = self.configManager.dateTimeFormat

        if (day + month + year) == 0:
            # when the user specifies 0 for either the date,
            # this means current price is asked and date components
            # are set to zero !
            resultData = self.priceRequester.getCurrentPrice(crypto, fiat, validExchangeSymbol)

            if resultData.isEmpty(ResultData.RESULT_KEY_ERROR_MSG):
                #adding date time info if no error returned
                timeStamp = resultData.getValue(ResultData.RESULT_KEY_PRICE_TIME_STAMP)
                requestedPriceArrowLocalDateTime = DateTimeUtil.timeStampToArrowLocalDate(timeStamp, localTz)
                requestedDateTimeStr = requestedPriceArrowLocalDateTime.format(dateTimeFormat)
                resultData.setValue(ResultData.RESULT_KEY_PRICE_DATE_TIME_STRING, requestedDateTimeStr)
        else:
            #getting historical price, either histo day or histo minute
            timeStampLocal = DateTimeUtil.dateTimeComponentsToTimeStamp(day, month, year, hour, minute, 0, localTz)
            timeStampUtcNoHHMM = DateTimeUtil.dateTimeComponentsToTimeStamp(day, month, year, 0, 0, 0, 'UTC')
            resultData = self.priceRequester.getHistoricalPriceAtUTCTimeStamp(crypto, fiat, timeStampLocal, timeStampUtcNoHHMM, validExchangeSymbol)

            if resultData.isEmpty(ResultData.RESULT_KEY_ERROR_MSG):
                #adding date time info if no error returned
                if resultData.getValue(ResultData.RESULT_KEY_PRICE_TYPE) == ResultData.PRICE_TYPE_HISTO_DAY:
                    #histoday price returned
                    requestedPriceArrowUtcDateTime = DateTimeUtil.timeStampToArrowLocalDate(timeStampUtcNoHHMM, 'UTC')
                    requestedDateTimeStr = requestedPriceArrowUtcDateTime.format(self.configManager.dateTimeFormat)
                else:
                    requestedPriceArrowLocalDateTime = DateTimeUtil.timeStampToArrowLocalDate(timeStampLocal, localTz)
                    requestedDateTimeStr = requestedPriceArrowLocalDateTime.format(dateTimeFormat)

                resultData.setValue(ResultData.RESULT_KEY_PRICE_DATE_TIME_STRING, requestedDateTimeStr)
                
        if priceValueSymbol != None and not resultData.isError():
            resultData = self._computePriceValue(resultData, crypto, fiat, priceValueSymbol, priceValueAmount, priceValueSaveFlag)
            
        return resultData