import math from enum import Enum, auto from typing import override from internal_types.types import Instrument, Position, Quote from strategy.strategy import Strategy from utils.utils import Portfolio class State(Enum): POS_0 = auto() POS_1 = auto() class BuyAndHold(Strategy): def __init__(self, init_balance, instr: Instrument): self.state = State.POS_0 self.balance = init_balance self.instr = instr self.portfolio = Portfolio() self.desired_pos = 0 @override def curr_position(self) -> int: return self.portfolio.curr_position(self.instr) @override def desired_position(self) -> int: return self.desired_pos @override def order_filled(self, new_pos: Position): self.portfolio.add_pos(new_pos) @override def process_quote(self, quote: Quote): match self.state: case State.POS_0: self.desired_pos = math.floor(self.balance / quote.close / self.instr.multiplier) self.state = State.POS_1 case State.POS_1: pass case _: raise RuntimeError('invalid state') @override def net_liquid_value(self, closing_price: float) -> float: return self.balance + self.portfolio.total_gains(self.instr, closing_price)