import unittest
import sys, os
sys.path.append(os.path.join(os.path.dirname(__file__), '../..'))
from optrabot.broker.order import Order, Leg, OrderAction, OrderType, PriceEffect, OptionRight

class OrderTests(unittest.TestCase):
	def setUp(self):
		self._cut = Order()
		pass

	def test_price_effect_long_call(self):
		"""
		Test the price effect of an order based on its legs.
		"""
		
		# Test a Long Call Debit order
		leg1 = Leg(action=OrderAction.BUY_TO_OPEN, symbol='SPX', strike=6660.0, right=OptionRight.CALL, expiration=None, quantity=1)
		leg1.midPrice = 5.0
		self._cut.legs = [leg1]
		self._cut.action = OrderAction.BUY_TO_OPEN
		self._cut.type = OrderType.LIMIT
		self._cut.quantity = 1
		self._cut.price = 5.0
		self._cut.determine_price_effect()
		self.assertEqual(self._cut.price_effect, PriceEffect.DEBIT)

	def test_price_effect_bcs(self):
		"""
		Test the price effect of a Bull Call Spread order based on its legs
		"""
		leg1 = Leg(action=OrderAction.SELL_TO_OPEN, symbol='SPX', strike=6640.0, right=OptionRight.CALL, expiration=None, quantity=1)
		leg1.midPrice = 1.0
		leg2 = Leg(action=OrderAction.BUY_TO_OPEN, symbol='SPX', strike=6670.0, right=OptionRight.CALL, expiration=None, quantity=1)
		leg2.midPrice = 0.25
		self._cut.legs = [leg1, leg2]
		self._cut.action = OrderAction.BUY_TO_OPEN
		self._cut.type = OrderType.LIMIT
		self._cut.quantity = 1
		self._cut.price = 0.75
		self._cut.determine_price_effect()
		self.assertEqual(self._cut.price_effect, PriceEffect.CREDIT)

	def test_price_effect_bps(self):
		"""
		Test the price effect of a Bull Put Spread order based on its legs
		"""
		leg1 = Leg(action=OrderAction.SELL_TO_OPEN, symbol='SPX', strike=6640.0, right=OptionRight.PUT, expiration=None, quantity=1)
		leg1.midPrice = 1.0
		leg2 = Leg(action=OrderAction.BUY_TO_OPEN, symbol='SPX', strike=6610.0, right=OptionRight.PUT, expiration=None, quantity=1)
		leg2.midPrice = 0.25
		self._cut.legs = [leg1, leg2]
		self._cut.action = OrderAction.BUY_TO_OPEN
		self._cut.type = OrderType.LIMIT
		self._cut.quantity = 1
		self._cut.price = 0.75
		self._cut.determine_price_effect()
		self.assertEqual(self._cut.price_effect, PriceEffect.CREDIT)

	def test_calculate_price_for_credit(self):
		"""
		Test the calculation of the order price based on its legs
		"""
		leg1 = Leg(action=OrderAction.SELL_TO_OPEN, symbol='SPX', strike=6640.0, right=OptionRight.PUT, expiration=None, quantity=1)
		leg1.midPrice = 1.0
		leg2 = Leg(action=OrderAction.BUY_TO_OPEN, symbol='SPX', strike=6610.0, right=OptionRight.PUT, expiration=None, quantity=1)
		leg2.midPrice = 0.25
		self._cut.legs = [leg1, leg2]
		self._cut.action = OrderAction.BUY_TO_OPEN
		self._cut.type = OrderType.LIMIT
		self._cut.quantity = 1
		calculated_price = self._cut.calculate_price()
		self.assertEqual(calculated_price, -0.75)
	
	def test_calculate_price_for_debit(self):
		"""
		Test the calculation of the order price based on its legs
		"""
		leg1 = Leg(action=OrderAction.BUY_TO_OPEN, symbol='SPX', strike=6640.0, right=OptionRight.PUT, expiration=None, quantity=1)
		leg1.midPrice = 1.0
		leg2 = Leg(action=OrderAction.SELL_TO_OPEN, symbol='SPX', strike=6610.0, right=OptionRight.PUT, expiration=None, quantity=1)
		leg2.midPrice = 0.25
		self._cut.legs = [leg1, leg2]
		self._cut.action = OrderAction.BUY_TO_OPEN
		self._cut.type = OrderType.LIMIT
		self._cut.quantity = 1
		calculated_price = self._cut.calculate_price()
		self.assertEqual(calculated_price, 0.75)