def test_buy_fail(self): p = Portfolio(balance=13.0) p.update(ticker='TICK', price=12.3) p.set_shares('TICK', 3.0) cont = Controller(p) success = cont.process_receipt(('TICK',11.0, 2.0, 10.0)) self.assertFalse(success) # Trade failed
def test_update(self): p = Portfolio(balance=10.0) p.update(ticker='TICK', price=10.0) p.set_shares('TICK', 3.0) eps = 1e-7 self.assertTrue(abs(10.0 - p.balance) < eps) # Balance correct self.assertTrue( abs(3.0 - p.get_shares('TICK')) < eps) # Shares updated self.assertTrue( abs(40.0 - p.get_total_value()) < eps) # Shares updated
def test_update(self): p = Portfolio(balance=10.0) p.update(ticker='TICK', price=10.0) p.set_shares('TICK', 3.0) eps = 1e-7 self.assertTrue(abs(10.0 - p.balance) < eps) # Balance correct self.assertTrue(abs(3.0 - p.get_shares('TICK'))<eps) # Shares updated self.assertTrue(abs(40.0 - p.get_total_value()) < eps) # Shares updated
def __init__(self): self._logger = logging.getLogger(__name__) self._settings = {} self._default_settings = { 'Portfolio': Portfolio(), 'Algorithm': Algorithm(), 'Source': 'yahoo', 'Start_Day': dt.datetime(2016, 1, 1), 'End_Day': dt.datetime.today(), 'Tickers': ['AAPL', 'GOGL', 'MSFT', 'AA', 'APB'] }
def test_buy_fail(self): p = Portfolio(balance=13.0) p.update(ticker='TICK', price=12.3) p.set_shares('TICK', 3.0) cont = Controller(p) success = cont.process_receipt(('TICK', 11.0, 2.0, 10.0)) self.assertFalse(success) # Trade failed
def __init__(self): self._logger = logging.getLogger(__name__) self._settings = {} self._default_settings = { 'Source': 'tushare', 'Start_Day': dt.datetime(2018, 4, 1), 'End_Day': dt.datetime.today(), 'Tickers': ['601318', '601155', '000732', '600340'], 'ktype': 'D', 'atype': 'close', 'Portfolio': Portfolio(), 'Algorithm': Algorithm(), }
def test_sell(self): p = Portfolio(balance=13.0) p.update(ticker='TICK', price=12.3) p.set_shares('TICK', 3.0) cont = Controller(p) success = cont.process_receipt(('TICK', 11.0, -2.0, 10.0)) eps = 1e-4 self.assertTrue(success) # Trade went through self.assertTrue( abs(25.0 - p.balance) < eps) # Balance updated correctly self.assertTrue( abs(1.0 - p.get_shares('TICK')) < eps) # Shares updated
def test_liquidate(self): p = Portfolio(balance=13.0) p.update(ticker='TICK', price=12.3) p.set_shares('TICK', 3.0) cont = Controller(p) success = cont.process_receipt(('TICK', 11.0, -5.0, 10.0)) eps = 1e-4 updated_fee = cont._order_api._calculate_fee(11.0*3.0) self.assertTrue(success) # Trade went through self.assertTrue(abs(13.0 + (3*11.0) - updated_fee - p.balance) < eps) # Balance updated correctly self.assertTrue(abs(0.0 - p.get_shares('TICK')) < eps) # Shares updated self.assertTrue(abs(12.3 - p.get_price('TICK')) < eps) # Price not updated from slippage
def test_liquidate(self): p = Portfolio(balance=13.0) p.update(ticker='TICK', price=12.3) p.set_shares('TICK', 3.0) cont = Controller(p) success = cont.process_receipt(('TICK', 11.0, -5.0, 10.0)) eps = 1e-4 updated_fee = cont._order_api._calculate_fee(11.0 * 3.0) self.assertTrue(success) # Trade went through self.assertTrue( abs(13.0 + (3 * 11.0) - updated_fee - p.balance) < eps) # Balance updated correctly self.assertTrue( abs(0.0 - p.get_shares('TICK')) < eps) # Shares updated self.assertTrue(abs(12.3 - p.get_price('TICK')) < eps) # Price not updated from slippage
def test_sell(self): p = Portfolio(balance=13.0) p.update(ticker='TICK', price=12.3) p.set_shares('TICK', 3.0) cont = Controller(p) success = cont.process_receipt(('TICK', 11.0, -2.0, 10.0)) eps=1e-4 self.assertTrue(success) # Trade went through self.assertTrue(abs(25.0-p.balance)<eps) # Balance updated correctly self.assertTrue(abs(1.0 - p.get_shares('TICK'))<eps) # Shares updated
def test_stream(self): import datetime from multiprocessing import Queue p = Portfolio(balance=10.0) p.update(ticker='TICK', price=9.0) p.set_shares('TICK', 3.0) cur_time = lambda: datetime.datetime.now().strftime('%Y-%m-%d') q = Queue() q.put((cur_time(), 'TICK', 10.0)) q.put((cur_time(), 'TICK', 11.0)) q.put((cur_time(), 'TICK', 12.0)) q.put('POISON') #Stops simulation c = Controller(portfolio=p) Controller.backtest(q, controller=c) # Run backtest is the local version self.assertAlmostEqual(p.get_total_value(), 10. + 3. * 12., delta=1e-7) self.assertAlmostEqual(p.get_price('TICK'), 12., delta=1e-7)
def test_stream(self): import datetime from multiprocessing import Queue p = Portfolio(balance=10.0) p.update(ticker='TICK', price=9.0) p.set_shares('TICK', 3.0) cur_time = lambda : datetime.datetime.now().strftime('%Y-%m-%d') q = Queue() q.put((cur_time(), 'TICK', 10.0)) q.put((cur_time(), 'TICK', 11.0)) q.put((cur_time(), 'TICK', 12.0)) q.put('POISON') #Stops simulation c = Controller(portfolio=p) Controller.backtest(q, controller=c) # Run backtest is the local version self.assertAlmostEqual(p.get_total_value(), 10.+3.*12., delta=1e-7) self.assertAlmostEqual(p.get_price('TICK'), 12., delta=1e-7)
class Controller: def __init__(self, portfolio=None, algorithm=None): self._logger = logging.getLogger(__name__) self._portfolio = Portfolio() if portfolio is None else portfolio self._algorithm = Algorithm() if algorithm is None else algorithm self._order_api = OrderApi() @classmethod def backtest(cls, queue, controller=None): controller = cls() if controller is None else controller try: while True: if not queue.empty(): o = queue.get() controller._logger.debug(o) if o == 'POISON': break timestamp = o[0] ticker = o[1] price = o[2] vol = o[3] # Update pricing controller.process_pricing(ticker=ticker, price=price, vol=vol) # Generate Orders orders = controller._algorithm.generate_orders( ticker, timestamp, controller._portfolio) # Process orders if len(orders) > 0: print("Orders", orders) controller.process_order(orders) controller._logger.info( controller._portfolio.value_summary(timestamp)) except Exception as e: print(e) finally: controller._logger.info(controller._portfolio.value_summary(None)) def process_pricing(self, ticker, price, vol): self._portfolio.update(price=price, ticker=ticker) self._algorithm.update(stock=ticker, price=price, vol=vol) def process_order(self, order): success = False receipt = self._order_api.process_order( order[0]) #(stockID, actual_price, vol, fees) print("Recept: ", receipt) if receipt is not None: success = self.process_receipt(receipt) if order is None or success is False: self._logger.info( ('{order_type} failed: %s at $%s for %s shares' % order).format(order_type='Sell' if order[2] < 0 else 'Buy')) print("Order processing: done!") ####################### if success: print("Order completed") else: print("Order failed") def process_receipt(self, receipt): ticker = receipt[0] price = receipt[1] share_delta = receipt[2] fee = receipt[3] temp = self._portfolio.balance - (price * share_delta + fee) if temp > 0: if share_delta < 0 and -share_delta > self._portfolio.get_shares( ticker): share_delta = -self._portfolio.get_shares(ticker) self._portfolio.update_trade(ticker=ticker, price=price, share_delta=share_delta, fee=fee) self._logger.debug('Trade on %s for %s shares at %s with fee %s' % (ticker, share_delta, price, fee)) return True return False
class Controller: def __init__(self, portfolio = None, algorithm = None): self._logger = logging.getLogger(__name__) self._portfolio = Portfolio() if portfolio is None else portfolio self._algorithm = Algorithm() if algorithm is None else algorithm self._order_api = OrderApi() @classmethod def backtest(cls, queue, controller = None): controller = cls() if controller is None else controller try: while True: if not queue.empty(): o = queue.get() controller._logger.debug(o) if o == 'POISON': break timestamp = o[0] ticker = o[1] price = o[2] # Update pricing controller.process_pricing(ticker = ticker, price = price) # Generate Orders orders = controller._algorithm.generate_orders(timestamp, controller._portfolio) # Process orders if len(orders) > 0: # Randomize the order execution final_orders = [orders[k] for k in np.random.choice(len(orders), replace=False, size=len(orders))] for order in final_orders: controller.process_order(order) controller._logger.info(controller._portfolio.value_summary(timestamp)) except Exception as e: print(e) finally: controller._logger.info(controller._portfolio.value_summary(None)) def process_order(self, order): success = False receipt = self._order_api.process_order(order) if receipt is not None: success = self.process_receipt(receipt) if order is None or success is False: self._logger.info(('{order_type} failed: %s at $%s for %s shares' % order).format(order_type = 'Sell' if order[2] < 0 else 'Buy')) def process_receipt(self,receipt): ticker = receipt[0] price = receipt[1] share_delta = receipt[2] fee = receipt[3] temp = self._portfolio.balance - (price * share_delta + fee) if temp > 0: if share_delta < 0 and -share_delta > self._portfolio.get_shares(ticker): # Liquidate share_delta = -self._portfolio.get_shares(ticker) fee = self._order_api._calculate_fee(share_delta*price) if fee > abs(share_delta*price): return False self._portfolio.update_trade(ticker=ticker, price=price, share_delta=share_delta, fee=fee) self._logger.debug('Trade on %s for %s shares at %s with fee %s' % (ticker,share_delta,price, fee)) return True return False def process_pricing(self, ticker, price): self._portfolio.update(price=price, ticker = ticker) self._algorithm.update(stock=ticker, price = price)
class Controller: def __init__(self, portfolio=None, algorithm=None): self._logger = logging.getLogger(__name__) self._portfolio = Portfolio() if portfolio is None else portfolio self._algorithm = Algorithm() if algorithm is None else algorithm self._order_api = OrderApi() @classmethod def backtest(cls, queue, controller=None): controller = cls() if controller is None else controller try: while True: if not queue.empty(): o = queue.get() controller._logger.debug(o) if o == 'POISON': break timestamp = o[0] ticker = o[1] price = o[2] # Update pricing controller.process_pricing(ticker=ticker, price=price) # Generate Orders orders = controller._algorithm.generate_orders( timestamp, controller._portfolio) # Process orders if len(orders) > 0: # Randomize the order execution final_orders = [ orders[k] for k in np.random.choice( len(orders), replace=False, size=len(orders)) ] for order in final_orders: controller.process_order(order) controller._logger.info( controller._portfolio.value_summary(timestamp)) except Exception as e: print(e) finally: controller._logger.info(controller._portfolio.value_summary(None)) def process_order(self, order): success = False receipt = self._order_api.process_order(order) if receipt is not None: success = self.process_receipt(receipt) if order is None or success is False: self._logger.info( ('{order_type} failed: %s at $%s for %s shares' % order).format(order_type='Sell' if order[2] < 0 else 'Buy')) def process_receipt(self, receipt): ticker = receipt[0] price = receipt[1] share_delta = receipt[2] fee = receipt[3] temp = self._portfolio.balance - (price * share_delta + fee) if temp > 0: if share_delta < 0 and -share_delta > self._portfolio.get_shares( ticker): # Liquidate share_delta = -self._portfolio.get_shares(ticker) fee = self._order_api._calculate_fee(share_delta * price) if fee > abs(share_delta * price): return False self._portfolio.update_trade(ticker=ticker, price=price, share_delta=share_delta, fee=fee) self._logger.debug('Trade on %s for %s shares at %s with fee %s' % (ticker, share_delta, price, fee)) return True return False def process_pricing(self, ticker, price): self._portfolio.update(price=price, ticker=ticker) self._algorithm.update(stock=ticker, price=price)
def __init__(self, portfolio=None, algorithm=None): self._logger = logging.getLogger(__name__) self._portfolio = Portfolio() if portfolio is None else portfolio self._algorithm = Algorithm() if algorithm is None else algorithm self._order_api = OrderApi()
def __init__(self, portfolio = None, algorithm = None): self._logger = logging.getLogger(__name__) self._portfolio = Portfolio() if portfolio is None else portfolio self._algorithm = Algorithm() if algorithm is None else algorithm self._order_api = OrderApi()