# Path: speculator/features/OBV.py
# class OBV(TechnicalAnalysis):
#     """
#     On Balance Volume:
#     OBV = OBV_prev + v
#         such that,
#             v = volume  if close >  close_prev
#             v = 0       if close == close_prev
#             v = -volume if close <  close_prev
#     """
# 
#     def eval_algorithm(curr, prev):
#         """ Evaluates OBV
# 
#         Args:
#             curr: Dict of current volume and close
#             prev: Dict of previous OBV and close
# 
#         Returns:
#             Float of OBV
#         """
#         if curr['close'] > prev['close']:
#             v = curr['volume']
#         elif curr['close'] < prev['close']:
#             v = curr['volume'] * -1
#         else:
#             v = 0
#         return prev['obv'] + v
# 
#     def eval_from_json(json):
#         """ Evaluates OBV from JSON (typically Poloniex API response)
# 
#         Args:
#             json: List of dates where each entry is a dict of raw market data.
# 
#         Returns:
#             Float of OBV
#         """
#         closes = poloniex.get_attribute(json, 'close')
#         volumes = poloniex.get_attribute(json, 'volume')
#         obv = 0
#         for date in range(1, len(json)):
#             curr = {'close': closes[date], 'volume': volumes[date]}
#             prev = {'close': closes[date - 1], 'obv': obv}
#             obv = OBV.eval_algorithm(curr, prev)
#         return obv


from speculator.features.OBV import OBV
import unittest

class OBVTest(unittest.TestCase):
    def test_eval_algorithm_case1(self):
        # Case 1: close > close_prev, return obv + volume
        curr = {'close': 5, 'volume': 1}
        prev = {'close': 4, 'obv': 2}
        self.assertEqual(OBV.eval_algorithm(curr, prev), 3)

    def test_eval_algorithm_case2(self):
        # Case 2: close == close_prev, return obv
        curr = {'close': 5, 'volume': 1}
        prev = {'close': 5, 'obv': 2}
        self.assertEqual(OBV.eval_algorithm(curr, prev), 2)

    def test_eval_algorithm_case3(self):
        # Case 3: close < close_prev, return obv - volume
        curr = {'close': 5, 'volume': 1}
        prev = {'close': 6, 'obv': 2}

# Path: speculator/features/OBV.py
# class OBV(TechnicalAnalysis):
#     """
#     On Balance Volume:
#     OBV = OBV_prev + v
#         such that,
#             v = volume  if close >  close_prev
#             v = 0       if close == close_prev
#             v = -volume if close <  close_prev
#     """
# 
#     def eval_algorithm(curr, prev):
#         """ Evaluates OBV
# 
#         Args:
#             curr: Dict of current volume and close
#             prev: Dict of previous OBV and close
# 
#         Returns:
#             Float of OBV
#         """
#         if curr['close'] > prev['close']:
#             v = curr['volume']
#         elif curr['close'] < prev['close']:
#             v = curr['volume'] * -1
#         else:
#             v = 0
#         return prev['obv'] + v
# 
#     def eval_from_json(json):
#         """ Evaluates OBV from JSON (typically Poloniex API response)
# 
#         Args:
#             json: List of dates where each entry is a dict of raw market data.
# 
#         Returns:
#             Float of OBV
#         """
#         closes = poloniex.get_attribute(json, 'close')
#         volumes = poloniex.get_attribute(json, 'volume')
#         obv = 0
#         for date in range(1, len(json)):
#             curr = {'close': closes[date], 'volume': volumes[date]}
#             prev = {'close': closes[date - 1], 'obv': obv}
#             obv = OBV.eval_algorithm(curr, prev)
#         return obv


# Path: speculator/tests/unit/test_obv.py
from speculator.features.OBV import OBV
import unittest


class OBVTest(unittest.TestCase):
    def test_eval_algorithm_case1(self):
        # Case 1: close > close_prev, return obv + volume
        curr = {'close': 5, 'volume': 1}
        prev = {'close': 4, 'obv': 2}
        self.assertEqual(OBV.eval_algorithm(curr, prev), 3)

    def test_eval_algorithm_case2(self):
        # Case 2: close == close_prev, return obv
        curr = {'close': 5, 'volume': 1}
        prev = {'close': 5, 'obv': 2}
        self.assertEqual(OBV.eval_algorithm(curr, prev), 2)

    def test_eval_algorithm_case3(self):
        # Case 3: close < close_prev, return obv - volume
        curr = {'close': 5, 'volume': 1}
        prev = {'close': 6, 'obv': 2}

        self.assertEqual(OBV.eval_algorithm(curr, prev), 1)