예제 #1
0
파일: tests.py 프로젝트: srome/pybacktester
    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
예제 #2
0
    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
예제 #3
0
파일: tests.py 프로젝트: srome/pybacktester
    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
예제 #4
0
    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']
        }
예제 #5
0
    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
예제 #6
0
    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(),
        }
예제 #7
0
    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
예제 #8
0
파일: tests.py 프로젝트: srome/pybacktester
    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
예제 #9
0
    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
예제 #10
0
파일: tests.py 프로젝트: srome/pybacktester
    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
예제 #11
0
    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)
예제 #12
0
파일: tests.py 프로젝트: srome/pybacktester
    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)
예제 #13
0
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
예제 #14
0
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)
예제 #15
0
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)
예제 #16
0
 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()
예제 #17
0
 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()