from abc import ABC, abstractmethod

from op_futures.op_objects.tick_data import TickData
from op_futures.op_objects.order_data import OrderData
from tqz_extern.tqz_constant import OrderSide, OrderType

class TemplateStrategy(ABC):

    def __init__(self):
        self.profit_and_loss_detail = []

        self.pos = 0

    @abstractmethod
    def on_init(self):
        pass

    @abstractmethod
    def on_tick(self, tick: TickData):
        pass

    @abstractmethod
    def on_stop(self):
        pass

    def buy(self, symbol: str, lots: float, price: float, order_type: OrderType = OrderType.LIMIT) -> OrderData:
        assert lots > 0, f'Bad buy lots: {lots}.'
        order_data = OrderData(symbol=symbol, lots=lots, price=price, order_side=OrderSide.BUY, order_type=order_type)

        self.profit_and_loss_detail.append(order_data)
        self.pos += lots
        return order_data

    def sell(self, symbol: str, lots: float, price: float, order_type: OrderType = OrderType.LIMIT) -> OrderData:
        assert lots > 0, f'Bad sell lots: {lots}.'

        order_data = OrderData(symbol=symbol, lots=lots, price=price, order_side=OrderSide.SELL, order_type=order_type)
        self.profit_and_loss_detail.append(order_data)
        self.pos -= lots
        return order_data

    def short(self, symbol: str, lots: float, price: float, order_type: OrderType = OrderType.LIMIT) -> OrderData:
        assert lots > 0, f'Bad short lots: {lots}.'

        order_data = OrderData(symbol=symbol, lots=lots, price=price, order_side=OrderSide.SHORT, order_type=order_type)
        self.profit_and_loss_detail.append(order_data)
        self.pos -= lots
        return order_data

    def cover(self, symbol: str, lots: float, price: float, order_type: OrderType = OrderType.LIMIT) -> OrderData:
        assert lots > 0, f'Bad cover lots: {lots}.'

        order_data = OrderData(symbol=symbol, lots=lots, price=price, order_side=OrderSide.COVER, order_type=order_type)
        self.profit_and_loss_detail.append(order_data)
        self.pos += lots
        return order_data