def size_order(self, portfolio, initial_order):
     """
     Size the order to reflect the dollar-weighting of the
     current equity account size based on pre-specified
     ticker weights.
     """
     ticker = initial_order.ticker
     if initial_order.action == "EXIT":
         # Obtain current quantity and liquidate
         cur_quantity = portfolio.positions[ticker].quantity
         if cur_quantity > 0:
             initial_order.action = "SLD"
             initial_order.quantity = cur_quantity
         else:
             initial_order.action = "BOT"
             initial_order.quantity = cur_quantity
     else:
         weight = self.ticker_weights[ticker]
         # Determine total portfolio value, work out dollar weight
         # and finally determine integer quantity of shares to purchase
         price = portfolio.price_handler.tickers[ticker]["adj_close"]
         price = PriceParser.display(price)
         equity = PriceParser.display(portfolio.equity)
         dollar_weight = weight * equity
         weighted_quantity = int(floor(dollar_weight / price))
         initial_order.quantity = weighted_quantity
     return initial_order
Beispiel #2
0
    def test_calculate_round_trip(self):
        """
        Purchase/sell multiple lots of AMZN and GOOG
        at various prices/commissions to check the
        arithmetic and cost handling.
        """
        # Buy 300 of AMZN over two transactions
        self.portfolio.transact_position("BOT", "AMZN", 100,
                                         PriceParser.parse(566.56),
                                         PriceParser.parse(1.00))
        self.portfolio.transact_position("BOT", "AMZN", 200,
                                         PriceParser.parse(566.395),
                                         PriceParser.parse(1.00))
        # Buy 200 GOOG over one transaction
        self.portfolio.transact_position("BOT", "GOOG", 200,
                                         PriceParser.parse(707.50),
                                         PriceParser.parse(1.00))
        # Add to the AMZN position by 100 shares
        self.portfolio.transact_position("SLD", "AMZN", 100,
                                         PriceParser.parse(565.83),
                                         PriceParser.parse(1.00))
        # Add to the GOOG position by 200 shares
        self.portfolio.transact_position("BOT", "GOOG", 200,
                                         PriceParser.parse(705.545),
                                         PriceParser.parse(1.00))
        # Sell 200 of the AMZN shares
        self.portfolio.transact_position("SLD", "AMZN", 200,
                                         PriceParser.parse(565.59),
                                         PriceParser.parse(1.00))
        # Multiple transactions bundled into one (in IB)
        # Sell 300 GOOG from the portfolio
        self.portfolio.transact_position("SLD", "GOOG", 100,
                                         PriceParser.parse(704.92),
                                         PriceParser.parse(1.00))
        self.portfolio.transact_position("SLD", "GOOG", 100,
                                         PriceParser.parse(704.90),
                                         PriceParser.parse(0.00))
        self.portfolio.transact_position("SLD", "GOOG", 100,
                                         PriceParser.parse(704.92),
                                         PriceParser.parse(0.50))
        # Finally, sell the remaining GOOG 100 shares
        self.portfolio.transact_position("SLD", "GOOG", 100,
                                         PriceParser.parse(704.78),
                                         PriceParser.parse(1.00))

        # The figures below are derived from Interactive Brokers
        # demo account using the above trades with prices provided
        # by their demo feed.
        self.assertEqual(len(self.portfolio.positions), 0)
        self.assertEqual(len(self.portfolio.closed_positions), 2)
        self.assertEqual(PriceParser.display(self.portfolio.cur_cash),
                         499100.50)
        self.assertEqual(PriceParser.display(self.portfolio.equity), 499100.50)
        self.assertEqual(PriceParser.display(self.portfolio.unrealised_pnl),
                         0.00)
        self.assertEqual(PriceParser.display(self.portfolio.realised_pnl),
                         -899.50)
    def test_get_best_bid_ask(self):
        """
        Tests that the 'get_best_bid_ask' method produces the
        correct values depending upon validity of ticker.
        """
        bid, ask = self.price_handler.get_best_bid_ask("AMZN")
        self.assertEqual(PriceParser.display(bid, 5), 502.10001)
        self.assertEqual(PriceParser.display(ask, 5), 502.11999)

        bid, ask = self.price_handler.get_best_bid_ask("C")
    def test_get_best_bid_ask(self):
        """
        Tests that the 'get_best_bid_ask' method produces the
        correct values depending upon validity of ticker.
        """
        bid, ask = self.price_handler.get_best_bid_ask("AMZN")
        self.assertEqual(PriceParser.display(bid, 5), 502.10001)
        self.assertEqual(PriceParser.display(ask, 5), 502.11999)

        bid, ask = self.price_handler.get_best_bid_ask("C")
Beispiel #5
0
 def record_trade(self, fill):
     """
     Append all details about the FillEvent to the CSV trade log.
     """
     fname = os.path.expanduser(os.path.join(self.config.OUTPUT_DIR, self.csv_filename))
     with open(fname, 'a') as csvfile:
         writer = csv.writer(csvfile)
         writer.writerow([
             fill.timestamp, fill.ticker,
             fill.action, fill.quantity,
             fill.exchange, PriceParser.display(fill.price, 4),
             PriceParser.display(fill.commission, 4)
         ])
Beispiel #6
0
 def record_trade(self, fill):
     """
     Append all details about the FillEvent to the CSV trade log.
     """
     fname = os.path.expanduser(os.path.join(self.config.OUTPUT_DIR, self.csv_filename))
     with open( fname, 'a') as csvfile:
         writer = csv.writer(csvfile)
         writer.writerow([
             fill.timestamp, fill.ticker,
             fill.action, fill.quantity,
             fill.exchange, PriceParser.display(fill.price, 4),
             PriceParser.display(fill.commission, 4)
         ])
Beispiel #7
0
    def test_realised_unrealised_calcs(self):
        self.assertEqual(
            PriceParser.display(self.position.unrealised_pnl), -1.00
        )
        self.assertEqual(
            PriceParser.display(self.position.realised_pnl), 0.00
        )

        self.position.update_market_value(
            PriceParser.parse(75.77), PriceParser.parse(75.79)
        )
        self.assertEqual(
            PriceParser.display(self.position.unrealised_pnl), 99.00
        )
        self.position.transact_shares(
            "SLD", 100,
            PriceParser.parse(75.78), PriceParser.parse(1.00)
        )
        self.assertEqual(
            PriceParser.display(self.position.unrealised_pnl), 99.00
        )  # still high
        self.assertEqual(
            PriceParser.display(self.position.realised_pnl), 98.00
        )

        self.position.update_market_value(
            PriceParser.parse(75.77), PriceParser.parse(75.79)
        )
        self.assertEqual(
            PriceParser.display(self.position.unrealised_pnl), 0.00
        )
Beispiel #8
0
    def test_open_short_position(self):
        self.assertEqual(PriceParser.display(self.position.cost_basis), -7768.00)
        self.assertEqual(PriceParser.display(self.position.market_value), -7769.00)
        self.assertEqual(PriceParser.display(self.position.unrealised_pnl), -1.00)
        self.assertEqual(PriceParser.display(self.position.realised_pnl), -1.0)

        self.position.update_market_value(
            PriceParser.parse(77.72), PriceParser.parse(77.72)
        )

        self.assertEqual(PriceParser.display(self.position.cost_basis), -7768.00)
        self.assertEqual(PriceParser.display(self.position.market_value), -7772.00)
        self.assertEqual(PriceParser.display(self.position.unrealised_pnl), -4.00)
        self.assertEqual(PriceParser.display(self.position.realised_pnl), -4.0)
    def test_open_short_position(self):
        self.assertEqual(PriceParser.display(self.position.cost_basis),
                         -7768.00)
        self.assertEqual(PriceParser.display(self.position.market_value),
                         -7769.00)
        self.assertEqual(PriceParser.display(self.position.unrealised_pnl),
                         -1.00)
        self.assertEqual(PriceParser.display(self.position.realised_pnl), -1.0)

        self.position.update_market_value(PriceParser.parse(77.72),
                                          PriceParser.parse(77.72))

        self.assertEqual(PriceParser.display(self.position.cost_basis),
                         -7768.00)
        self.assertEqual(PriceParser.display(self.position.market_value),
                         -7772.00)
        self.assertEqual(PriceParser.display(self.position.unrealised_pnl),
                         -4.00)
        self.assertEqual(PriceParser.display(self.position.realised_pnl), -4.0)
    def test_realised_unrealised_calcs(self):
        self.assertEqual(PriceParser.display(self.position.unrealised_pnl),
                         -1.00)
        self.assertEqual(PriceParser.display(self.position.realised_pnl), 0.00)

        self.position.update_market_value(PriceParser.parse(75.77),
                                          PriceParser.parse(75.79))
        self.assertEqual(PriceParser.display(self.position.unrealised_pnl),
                         99.00)
        self.position.transact_shares("SLD", 100, PriceParser.parse(75.78),
                                      PriceParser.parse(1.00))
        self.assertEqual(PriceParser.display(self.position.unrealised_pnl),
                         99.00)  # still high
        self.assertEqual(PriceParser.display(self.position.realised_pnl),
                         98.00)

        self.position.update_market_value(PriceParser.parse(75.77),
                                          PriceParser.parse(75.79))
        self.assertEqual(PriceParser.display(self.position.unrealised_pnl),
                         0.00)
Beispiel #11
0
    def test_calculate_round_trip(self):
        """
        After the subsequent purchase, carry out two more buys/longs
        and then close the position out with two additional sells/shorts.

        The following prices have been tested against those calculated
        via Interactive Brokers' Trader Workstation (TWS).
        """
        self.position.transact_shares("BOT", 100, PriceParser.parse(74.63),
                                      PriceParser.parse(1.00))
        self.position.transact_shares("BOT", 250, PriceParser.parse(74.620),
                                      PriceParser.parse(1.25))
        self.position.transact_shares("SLD", 200, PriceParser.parse(74.58),
                                      PriceParser.parse(1.00))
        self.position.transact_shares("SLD", 250, PriceParser.parse(75.26),
                                      PriceParser.parse(1.25))
        self.position.update_market_value(PriceParser.parse(77.75),
                                          PriceParser.parse(77.77))

        self.assertEqual(self.position.action, "BOT")
        self.assertEqual(self.position.ticker, "XOM")
        self.assertEqual(self.position.quantity, 0)

        self.assertEqual(self.position.buys, 450)
        self.assertEqual(self.position.sells, 450)
        self.assertEqual(self.position.net, 0)
        self.assertEqual(PriceParser.display(self.position.avg_bot, 5),
                         74.65778)
        self.assertEqual(PriceParser.display(self.position.avg_sld, 5),
                         74.95778)
        self.assertEqual(PriceParser.display(self.position.total_bot),
                         33596.00)
        self.assertEqual(PriceParser.display(self.position.total_sld),
                         33731.00)
        self.assertEqual(PriceParser.display(self.position.net_total), 135.00)
        self.assertEqual(PriceParser.display(self.position.total_commission),
                         5.50)
        self.assertEqual(PriceParser.display(self.position.net_incl_comm),
                         129.50)

        self.assertEqual(PriceParser.display(self.position.avg_price, 3),
                         74.665)
        self.assertEqual(PriceParser.display(self.position.cost_basis), 0.00)
        self.assertEqual(PriceParser.display(self.position.market_value), 0.00)
        self.assertEqual(PriceParser.display(self.position.unrealised_pnl),
                         0.00)
        self.assertEqual(PriceParser.display(self.position.realised_pnl),
                         129.50)
Beispiel #12
0
    def test_calculating_statistics(self):
        """
        Purchase/sell multiple lots of AMZN, GOOG
        at various prices/commissions to ensure
        the arithmetic in calculating equity, drawdowns
        and sharpe ratio is correct.
        """
        # Create Statistics object
        price_handler = PriceHandlerMock()
        self.portfolio = Portfolio(price_handler, PriceParser.parse(500000.00))

        portfolio_handler = PortfolioHandlerMock(self.portfolio)
        statistics = SimpleStatistics(self.config, portfolio_handler)

        # Check initialization was correct
        self.assertEqual(PriceParser.display(statistics.equity[0]), 500000.00)
        self.assertEqual(PriceParser.display(statistics.drawdowns[0]), 00)
        self.assertEqual(statistics.equity_returns[0], 0.0)

        # Perform transaction and test statistics at this tick
        self.portfolio.transact_position(
            "BOT", "AMZN", 100,
            PriceParser.parse(566.56), PriceParser.parse(1.00)
        )
        t = "2000-01-01 00:00:00"
        statistics.update(t, portfolio_handler)
        self.assertEqual(PriceParser.display(statistics.equity[1]), 499807.00)
        self.assertEqual(PriceParser.display(statistics.drawdowns[1]), 193.00)
        self.assertEqual(statistics.equity_returns[1], -0.0386)

        # Perform transaction and test statistics at this tick
        self.portfolio.transact_position(
            "BOT", "AMZN", 200,
            PriceParser.parse(566.395), PriceParser.parse(1.00)
        )
        t = "2000-01-02 00:00:00"
        statistics.update(t, portfolio_handler)
        self.assertEqual(PriceParser.display(statistics.equity[2]), 499455.00)
        self.assertEqual(PriceParser.display(statistics.drawdowns[2]), 545.00)
        self.assertEqual(statistics.equity_returns[2], -0.0705)

        # Perform transaction and test statistics at this tick
        self.portfolio.transact_position(
            "BOT", "GOOG", 200,
            PriceParser.parse(707.50), PriceParser.parse(1.00)
        )
        t = "2000-01-03 00:00:00"
        statistics.update(t, portfolio_handler)
        self.assertEqual(PriceParser.display(statistics.equity[3]), 499046.00)
        self.assertEqual(PriceParser.display(statistics.drawdowns[3]), 954.00)
        self.assertEqual(statistics.equity_returns[3], -0.0820)

        # Perform transaction and test statistics at this tick
        self.portfolio.transact_position(
            "SLD", "AMZN", 100,
            PriceParser.parse(565.83), PriceParser.parse(1.00)
        )
        t = "2000-01-04 00:00:00"
        statistics.update(t, portfolio_handler)
        self.assertEqual(PriceParser.display(statistics.equity[4]), 499164.00)
        self.assertEqual(PriceParser.display(statistics.drawdowns[4]), 836.00)
        self.assertEqual(statistics.equity_returns[4], 0.0236)

        # Perform transaction and test statistics at this tick
        self.portfolio.transact_position(
            "BOT", "GOOG", 200,
            PriceParser.parse(705.545), PriceParser.parse(1.00)
        )
        t = "2000-01-05 00:00:00"
        statistics.update(t, portfolio_handler)
        self.assertEqual(PriceParser.display(statistics.equity[5]), 499146.00)
        self.assertEqual(PriceParser.display(statistics.drawdowns[5]), 854.00)
        self.assertEqual(statistics.equity_returns[5], -0.0036)

        # Perform transaction and test statistics at this tick
        self.portfolio.transact_position(
            "SLD", "AMZN", 200,
            PriceParser.parse(565.59), PriceParser.parse(1.00)
        )
        t = "2000-01-06 00:00:00"
        statistics.update(t, portfolio_handler)
        self.assertEqual(PriceParser.display(statistics.equity[6]), 499335.00)
        self.assertEqual(PriceParser.display(statistics.drawdowns[6]), 665.00)
        self.assertEqual(statistics.equity_returns[6], 0.0379)

        # Perform transaction and test statistics at this tick
        self.portfolio.transact_position(
            "SLD", "GOOG", 100,
            PriceParser.parse(707.92), PriceParser.parse(1.00)
        )
        t = "2000-01-07 00:00:00"
        statistics.update(t, portfolio_handler)
        self.assertEqual(PriceParser.display(statistics.equity[7]), 499580.00)
        self.assertEqual(PriceParser.display(statistics.drawdowns[7]), 420.00)
        self.assertEqual(statistics.equity_returns[7], 0.0490)

        # Perform transaction and test statistics at this tick
        self.portfolio.transact_position(
            "SLD", "GOOG", 100,
            PriceParser.parse(707.90), PriceParser.parse(0.00)
        )
        t = "2000-01-08 00:00:00"
        statistics.update(t, portfolio_handler)
        self.assertEqual(PriceParser.display(statistics.equity[8]), 499824.00)
        self.assertEqual(PriceParser.display(statistics.drawdowns[8]), 176.00)
        self.assertEqual(statistics.equity_returns[8], 0.0488)

        # Perform transaction and test statistics at this tick
        self.portfolio.transact_position(
            "SLD", "GOOG", 100,
            PriceParser.parse(707.92), PriceParser.parse(0.50)
        )
        t = "2000-01-09 00:00:00"
        statistics.update(t, portfolio_handler)
        self.assertEqual(PriceParser.display(statistics.equity[9]), 500069.50)
        self.assertEqual(PriceParser.display(statistics.drawdowns[9]), 00.00)
        self.assertEqual(statistics.equity_returns[9], 0.0491)

        # Perform transaction and test statistics at this tick
        self.portfolio.transact_position(
            "SLD", "GOOG", 100,
            PriceParser.parse(707.78), PriceParser.parse(1.00)
        )
        t = "2000-01-10 00:00:00"
        statistics.update(t, portfolio_handler)
        self.assertEqual(PriceParser.display(statistics.equity[10]), 500300.50)
        self.assertEqual(PriceParser.display(statistics.drawdowns[10]), 00.00)
        self.assertEqual(statistics.equity_returns[10], 0.0462)

        # Test that results are calculated correctly.
        results = statistics.get_results()
        self.assertEqual(results["max_drawdown"], 954.00)
        self.assertEqual(results["max_drawdown_pct"], 0.1908)
        self.assertAlmostEqual(float(results["sharpe"]), 1.7575)
    def test_stream_all_ticks(self):
        """
        The initialisation of the class will open the three
        test CSV files, then merge and sort them. They will
        then be stored in a member "tick_stream". This will
        be used for streaming the ticks.
        """
        # Stream to Tick #1 (GOOG)
        self.price_handler.stream_next()
        self.assertEqual(
            self.price_handler.tickers["GOOG"]["timestamp"].strftime(
                "%d-%m-%Y %H:%M:%S.%f"), "01-02-2016 00:00:01.358000")
        self.assertEqual(
            PriceParser.display(self.price_handler.tickers["GOOG"]["bid"], 5),
            683.56000)
        self.assertEqual(
            PriceParser.display(self.price_handler.tickers["GOOG"]["ask"], 5),
            683.58000)

        # Stream to Tick #2 (AMZN)
        self.price_handler.stream_next()
        self.assertEqual(
            self.price_handler.tickers["AMZN"]["timestamp"].strftime(
                "%d-%m-%Y %H:%M:%S.%f"), "01-02-2016 00:00:01.562000")
        self.assertEqual(
            PriceParser.display(self.price_handler.tickers["AMZN"]["bid"], 5),
            502.10001)
        self.assertEqual(
            PriceParser.display(self.price_handler.tickers["AMZN"]["ask"], 5),
            502.11999)

        # Stream to Tick #3 (MSFT)
        self.price_handler.stream_next()
        self.assertEqual(
            self.price_handler.tickers["MSFT"]["timestamp"].strftime(
                "%d-%m-%Y %H:%M:%S.%f"), "01-02-2016 00:00:01.578000")
        self.assertEqual(
            PriceParser.display(self.price_handler.tickers["MSFT"]["bid"], 5),
            50.14999)
        self.assertEqual(
            PriceParser.display(self.price_handler.tickers["MSFT"]["ask"], 5),
            50.17001)

        # Stream to Tick #10 (GOOG)
        for i in range(4, 11):
            self.price_handler.stream_next()
        self.assertEqual(
            self.price_handler.tickers["GOOG"]["timestamp"].strftime(
                "%d-%m-%Y %H:%M:%S.%f"), "01-02-2016 00:00:05.215000")
        self.assertEqual(
            PriceParser.display(self.price_handler.tickers["GOOG"]["bid"], 5),
            683.56001)
        self.assertEqual(
            PriceParser.display(self.price_handler.tickers["GOOG"]["ask"], 5),
            683.57999)

        # Stream to Tick #20 (GOOG)
        for i in range(11, 21):
            self.price_handler.stream_next()
        self.assertEqual(
            self.price_handler.tickers["MSFT"]["timestamp"].strftime(
                "%d-%m-%Y %H:%M:%S.%f"), "01-02-2016 00:00:09.904000")
        self.assertEqual(
            PriceParser.display(self.price_handler.tickers["MSFT"]["bid"], 5),
            50.15000)
        self.assertEqual(
            PriceParser.display(self.price_handler.tickers["MSFT"]["ask"], 5),
            50.17000)

        # Stream to Tick #30 (final tick, AMZN)
        for i in range(21, 31):
            self.price_handler.stream_next()
        self.assertEqual(
            self.price_handler.tickers["AMZN"]["timestamp"].strftime(
                "%d-%m-%Y %H:%M:%S.%f"), "01-02-2016 00:00:14.616000")
        self.assertEqual(
            PriceParser.display(self.price_handler.tickers["AMZN"]["bid"], 5),
            502.10015)
        self.assertEqual(
            PriceParser.display(self.price_handler.tickers["AMZN"]["ask"], 5),
            502.11985)
Beispiel #14
0
 def test_display(self):
     parsed = PriceParser.parse(self.float)
     displayed = PriceParser.display(parsed)
     self.assertEqual(displayed, 10.12)
    def test_calculating_statistics(self):
        """
        Purchase/sell multiple lots of AMZN, GOOG
        at various prices/commissions to ensure
        the arithmetic in calculating equity, drawdowns
        and sharpe ratio is correct.
        """
        # Create Statistics object
        price_handler = PriceHandlerMock()
        self.portfolio = Portfolio(price_handler, PriceParser.parse(500000.00))

        portfolio_handler = PortfolioHandlerMock(self.portfolio)
        statistics = SimpleStatistics(self.config, portfolio_handler)

        # Check initialization was correct
        self.assertEqual(PriceParser.display(statistics.equity[0]), 500000.00)
        self.assertEqual(PriceParser.display(statistics.drawdowns[0]), 00)
        self.assertEqual(statistics.equity_returns[0], 0.0)

        # Perform transaction and test statistics at this tick
        self.portfolio.transact_position("BOT", "AMZN", 100,
                                         PriceParser.parse(566.56),
                                         PriceParser.parse(1.00))
        t = "2000-01-01 00:00:00"
        statistics.update(t, portfolio_handler)
        self.assertEqual(PriceParser.display(statistics.equity[1]), 499807.00)
        self.assertEqual(PriceParser.display(statistics.drawdowns[1]), 193.00)
        self.assertEqual(statistics.equity_returns[1], -0.0386)

        # Perform transaction and test statistics at this tick
        self.portfolio.transact_position("BOT", "AMZN", 200,
                                         PriceParser.parse(566.395),
                                         PriceParser.parse(1.00))
        t = "2000-01-02 00:00:00"
        statistics.update(t, portfolio_handler)
        self.assertEqual(PriceParser.display(statistics.equity[2]), 499455.00)
        self.assertEqual(PriceParser.display(statistics.drawdowns[2]), 545.00)
        self.assertEqual(statistics.equity_returns[2], -0.0705)

        # Perform transaction and test statistics at this tick
        self.portfolio.transact_position("BOT", "GOOG", 200,
                                         PriceParser.parse(707.50),
                                         PriceParser.parse(1.00))
        t = "2000-01-03 00:00:00"
        statistics.update(t, portfolio_handler)
        self.assertEqual(PriceParser.display(statistics.equity[3]), 499046.00)
        self.assertEqual(PriceParser.display(statistics.drawdowns[3]), 954.00)
        self.assertEqual(statistics.equity_returns[3], -0.0820)

        # Perform transaction and test statistics at this tick
        self.portfolio.transact_position("SLD", "AMZN", 100,
                                         PriceParser.parse(565.83),
                                         PriceParser.parse(1.00))
        t = "2000-01-04 00:00:00"
        statistics.update(t, portfolio_handler)
        self.assertEqual(PriceParser.display(statistics.equity[4]), 499164.00)
        self.assertEqual(PriceParser.display(statistics.drawdowns[4]), 836.00)
        self.assertEqual(statistics.equity_returns[4], 0.0236)

        # Perform transaction and test statistics at this tick
        self.portfolio.transact_position("BOT", "GOOG", 200,
                                         PriceParser.parse(705.545),
                                         PriceParser.parse(1.00))
        t = "2000-01-05 00:00:00"
        statistics.update(t, portfolio_handler)
        self.assertEqual(PriceParser.display(statistics.equity[5]), 499146.00)
        self.assertEqual(PriceParser.display(statistics.drawdowns[5]), 854.00)
        self.assertEqual(statistics.equity_returns[5], -0.0036)

        # Perform transaction and test statistics at this tick
        self.portfolio.transact_position("SLD", "AMZN", 200,
                                         PriceParser.parse(565.59),
                                         PriceParser.parse(1.00))
        t = "2000-01-06 00:00:00"
        statistics.update(t, portfolio_handler)
        self.assertEqual(PriceParser.display(statistics.equity[6]), 499335.00)
        self.assertEqual(PriceParser.display(statistics.drawdowns[6]), 665.00)
        self.assertEqual(statistics.equity_returns[6], 0.0379)

        # Perform transaction and test statistics at this tick
        self.portfolio.transact_position("SLD", "GOOG", 100,
                                         PriceParser.parse(707.92),
                                         PriceParser.parse(1.00))
        t = "2000-01-07 00:00:00"
        statistics.update(t, portfolio_handler)
        self.assertEqual(PriceParser.display(statistics.equity[7]), 499580.00)
        self.assertEqual(PriceParser.display(statistics.drawdowns[7]), 420.00)
        self.assertEqual(statistics.equity_returns[7], 0.0490)

        # Perform transaction and test statistics at this tick
        self.portfolio.transact_position("SLD", "GOOG", 100,
                                         PriceParser.parse(707.90),
                                         PriceParser.parse(0.00))
        t = "2000-01-08 00:00:00"
        statistics.update(t, portfolio_handler)
        self.assertEqual(PriceParser.display(statistics.equity[8]), 499824.00)
        self.assertEqual(PriceParser.display(statistics.drawdowns[8]), 176.00)
        self.assertEqual(statistics.equity_returns[8], 0.0488)

        # Perform transaction and test statistics at this tick
        self.portfolio.transact_position("SLD", "GOOG", 100,
                                         PriceParser.parse(707.92),
                                         PriceParser.parse(0.50))
        t = "2000-01-09 00:00:00"
        statistics.update(t, portfolio_handler)
        self.assertEqual(PriceParser.display(statistics.equity[9]), 500069.50)
        self.assertEqual(PriceParser.display(statistics.drawdowns[9]), 00.00)
        self.assertEqual(statistics.equity_returns[9], 0.0491)

        # Perform transaction and test statistics at this tick
        self.portfolio.transact_position("SLD", "GOOG", 100,
                                         PriceParser.parse(707.78),
                                         PriceParser.parse(1.00))
        t = "2000-01-10 00:00:00"
        statistics.update(t, portfolio_handler)
        self.assertEqual(PriceParser.display(statistics.equity[10]), 500300.50)
        self.assertEqual(PriceParser.display(statistics.drawdowns[10]), 00.00)
        self.assertEqual(statistics.equity_returns[10], 0.0462)

        # Test that results are calculated correctly.
        results = statistics.get_results()
        self.assertEqual(results["max_drawdown"], 954.00)
        self.assertEqual(results["max_drawdown_pct"], 0.1908)
        self.assertAlmostEqual(float(results["sharpe"]), 1.7575)
Beispiel #16
0
 def test_unparsed_display(self):
     displayed = PriceParser.display(self.float)
     self.assertEqual(displayed, 10.12)
Beispiel #17
0
 def test_unparsed_display(self):
     displayed = PriceParser.display(self.float)
     self.assertEqual(displayed, 10.12)
Beispiel #18
0
    def test_calculate_round_trip(self):
        """
        After the subsequent sale, carry out two more sells/shorts
        and then close the position out with two additional buys/longs.

        The following prices have been tested against those calculated
        via Interactive Brokers' Trader Workstation (TWS).
        """
        self.position.transact_shares(
            "SLD", 100, PriceParser.parse(77.68), PriceParser.parse(1.00)
        )
        self.position.transact_shares(
            "SLD", 50, PriceParser.parse(77.70), PriceParser.parse(1.00)
        )
        self.position.transact_shares(
            "BOT", 100, PriceParser.parse(77.77), PriceParser.parse(1.00)
        )
        self.position.transact_shares(
            "BOT", 150, PriceParser.parse(77.73), PriceParser.parse(1.00)
        )
        self.position.update_market_value(
            PriceParser.parse(77.72), PriceParser.parse(77.72)
        )

        self.assertEqual(self.position.action, "SLD")
        self.assertEqual(self.position.ticker, "PG")
        self.assertEqual(self.position.quantity, 0)

        self.assertEqual(self.position.buys, 250)
        self.assertEqual(self.position.sells, 250)
        self.assertEqual(self.position.net, 0)
        self.assertEqual(
            PriceParser.display(self.position.avg_bot, 3), 77.746
        )
        self.assertEqual(
            PriceParser.display(self.position.avg_sld, 3), 77.688
        )
        self.assertEqual(PriceParser.display(self.position.total_bot), 19436.50)
        self.assertEqual(PriceParser.display(self.position.total_sld), 19422.00)
        self.assertEqual(PriceParser.display(self.position.net_total), -14.50)
        self.assertEqual(PriceParser.display(self.position.total_commission), 5.00)
        self.assertEqual(PriceParser.display(self.position.net_incl_comm), -19.50)

        self.assertEqual(
            PriceParser.display(self.position.avg_price, 5), 77.67600
        )
        self.assertEqual(PriceParser.display(self.position.cost_basis), 0.00)
        self.assertEqual(PriceParser.display(self.position.market_value), 0.00)
        self.assertEqual(PriceParser.display(self.position.unrealised_pnl), 0.00)
        self.assertEqual(PriceParser.display(self.position.realised_pnl), -19.50)
Beispiel #19
0
    def test_calculate_round_trip(self):
        """
        After the subsequent purchase, carry out two more buys/longs
        and then close the position out with two additional sells/shorts.

        The following prices have been tested against those calculated
        via Interactive Brokers' Trader Workstation (TWS).
        """
        self.position.transact_shares(
            "BOT", 100, PriceParser.parse(74.63), PriceParser.parse(1.00)
        )
        self.position.transact_shares(
            "BOT", 250, PriceParser.parse(74.620), PriceParser.parse(1.25)
        )
        self.position.transact_shares(
            "SLD", 200, PriceParser.parse(74.58), PriceParser.parse(1.00)
        )
        self.position.transact_shares(
            "SLD", 250, PriceParser.parse(75.26), PriceParser.parse(1.25)
        )
        self.position.update_market_value(
            PriceParser.parse(77.75), PriceParser.parse(77.77)
        )

        self.assertEqual(self.position.action, "BOT")
        self.assertEqual(self.position.ticker, "XOM")
        self.assertEqual(self.position.quantity, 0)

        self.assertEqual(self.position.buys, 450)
        self.assertEqual(self.position.sells, 450)
        self.assertEqual(self.position.net, 0)
        self.assertEqual(
            PriceParser.display(self.position.avg_bot, 5), 74.65778
        )
        self.assertEqual(
            PriceParser.display(self.position.avg_sld, 5), 74.95778
        )
        self.assertEqual(PriceParser.display(self.position.total_bot), 33596.00)
        self.assertEqual(PriceParser.display(self.position.total_sld), 33731.00)
        self.assertEqual(PriceParser.display(self.position.net_total), 135.00)
        self.assertEqual(PriceParser.display(self.position.total_commission), 5.50)
        self.assertEqual(PriceParser.display(self.position.net_incl_comm), 129.50)

        self.assertEqual(
            PriceParser.display(self.position.avg_price, 3), 74.665
        )
        self.assertEqual(PriceParser.display(self.position.cost_basis), 0.00)
        self.assertEqual(PriceParser.display(self.position.market_value), 0.00)
        self.assertEqual(PriceParser.display(self.position.unrealised_pnl), 0.00)
        self.assertEqual(PriceParser.display(self.position.realised_pnl), 129.50)
Beispiel #20
0
    def test_calculate_round_trip(self):
        """
        After the subsequent sale, carry out two more sells/shorts
        and then close the position out with two additional buys/longs.

        The following prices have been tested against those calculated
        via Interactive Brokers' Trader Workstation (TWS).
        """
        self.position.transact_shares("SLD", 100, PriceParser.parse(77.68),
                                      PriceParser.parse(1.00))
        self.position.transact_shares("SLD", 50, PriceParser.parse(77.70),
                                      PriceParser.parse(1.00))
        self.position.transact_shares("BOT", 100, PriceParser.parse(77.77),
                                      PriceParser.parse(1.00))
        self.position.transact_shares("BOT", 150, PriceParser.parse(77.73),
                                      PriceParser.parse(1.00))
        self.position.update_market_value(PriceParser.parse(77.72),
                                          PriceParser.parse(77.72))

        self.assertEqual(self.position.action, "SLD")
        self.assertEqual(self.position.ticker, "PG")
        self.assertEqual(self.position.quantity, 0)

        self.assertEqual(self.position.buys, 250)
        self.assertEqual(self.position.sells, 250)
        self.assertEqual(self.position.net, 0)
        self.assertEqual(PriceParser.display(self.position.avg_bot, 3), 77.746)
        self.assertEqual(PriceParser.display(self.position.avg_sld, 3), 77.688)
        self.assertEqual(PriceParser.display(self.position.total_bot),
                         19436.50)
        self.assertEqual(PriceParser.display(self.position.total_sld),
                         19422.00)
        self.assertEqual(PriceParser.display(self.position.net_total), -14.50)
        self.assertEqual(PriceParser.display(self.position.total_commission),
                         5.00)
        self.assertEqual(PriceParser.display(self.position.net_incl_comm),
                         -19.50)

        self.assertEqual(PriceParser.display(self.position.avg_price, 5),
                         77.67600)
        self.assertEqual(PriceParser.display(self.position.cost_basis), 0.00)
        self.assertEqual(PriceParser.display(self.position.market_value), 0.00)
        self.assertEqual(PriceParser.display(self.position.unrealised_pnl),
                         0.00)
        self.assertEqual(PriceParser.display(self.position.realised_pnl),
                         -19.50)
    def test_stream_all_ticks(self):
        """
        The initialisation of the class will open the three
        test CSV files, then merge and sort them. They will
        then be stored in a member "tick_stream". This will
        be used for streaming the ticks.
        """
        # Stream to Tick #1 (GOOG)
        self.price_handler.stream_next()
        self.assertEqual(
            self.price_handler.tickers["GOOG"]["timestamp"].strftime(
                "%d-%m-%Y %H:%M:%S.%f"
            ),
            "01-02-2016 00:00:01.358000"
        )
        self.assertEqual(
            PriceParser.display(self.price_handler.tickers["GOOG"]["bid"], 5),
            683.56000
        )
        self.assertEqual(
            PriceParser.display(self.price_handler.tickers["GOOG"]["ask"], 5),
            683.58000
        )

        # Stream to Tick #2 (AMZN)
        self.price_handler.stream_next()
        self.assertEqual(
            self.price_handler.tickers["AMZN"]["timestamp"].strftime(
                "%d-%m-%Y %H:%M:%S.%f"
            ),
            "01-02-2016 00:00:01.562000"
        )
        self.assertEqual(
            PriceParser.display(self.price_handler.tickers["AMZN"]["bid"], 5),
            502.10001
        )
        self.assertEqual(
            PriceParser.display(self.price_handler.tickers["AMZN"]["ask"], 5),
            502.11999
        )

        # Stream to Tick #3 (MSFT)
        self.price_handler.stream_next()
        self.assertEqual(
            self.price_handler.tickers["MSFT"]["timestamp"].strftime(
                "%d-%m-%Y %H:%M:%S.%f"
            ),
            "01-02-2016 00:00:01.578000"
        )
        self.assertEqual(
            PriceParser.display(self.price_handler.tickers["MSFT"]["bid"], 5),
            50.14999
        )
        self.assertEqual(
            PriceParser.display(self.price_handler.tickers["MSFT"]["ask"], 5),
            50.17001
        )

        # Stream to Tick #10 (GOOG)
        for i in range(4, 11):
            self.price_handler.stream_next()
        self.assertEqual(
            self.price_handler.tickers["GOOG"]["timestamp"].strftime(
                "%d-%m-%Y %H:%M:%S.%f"
            ),
            "01-02-2016 00:00:05.215000"
        )
        self.assertEqual(
            PriceParser.display(self.price_handler.tickers["GOOG"]["bid"], 5),
            683.56001
        )
        self.assertEqual(
            PriceParser.display(self.price_handler.tickers["GOOG"]["ask"], 5),
            683.57999
        )

        # Stream to Tick #20 (GOOG)
        for i in range(11, 21):
            self.price_handler.stream_next()
        self.assertEqual(
            self.price_handler.tickers["MSFT"]["timestamp"].strftime(
                "%d-%m-%Y %H:%M:%S.%f"
            ),
            "01-02-2016 00:00:09.904000"
        )
        self.assertEqual(
            PriceParser.display(self.price_handler.tickers["MSFT"]["bid"], 5),
            50.15000
        )
        self.assertEqual(
            PriceParser.display(self.price_handler.tickers["MSFT"]["ask"], 5),
            50.17000
        )

        # Stream to Tick #30 (final tick, AMZN)
        for i in range(21, 31):
            self.price_handler.stream_next()
        self.assertEqual(
            self.price_handler.tickers["AMZN"]["timestamp"].strftime(
                "%d-%m-%Y %H:%M:%S.%f"
            ),
            "01-02-2016 00:00:14.616000"
        )
        self.assertEqual(
            PriceParser.display(self.price_handler.tickers["AMZN"]["bid"], 5),
            502.10015
        )
        self.assertEqual(
            PriceParser.display(self.price_handler.tickers["AMZN"]["ask"], 5),
            502.11985
        )
Beispiel #22
0
 def test_display(self):
     parsed = PriceParser.parse(self.float)
     displayed = PriceParser.display(parsed)
     self.assertEqual(displayed, 10.12)
Beispiel #23
0
    def test_calculate_round_trip(self):
        """
        Purchase/sell multiple lots of AMZN and GOOG
        at various prices/commissions to check the
        arithmetic and cost handling.
        """
        # Buy 300 of AMZN over two transactions
        self.portfolio.transact_position(
            "BOT", "AMZN", 100,
            PriceParser.parse(566.56), PriceParser.parse(1.00)
        )
        self.portfolio.transact_position(
            "BOT", "AMZN", 200,
            PriceParser.parse(566.395), PriceParser.parse(1.00)
        )
        # Buy 200 GOOG over one transaction
        self.portfolio.transact_position(
            "BOT", "GOOG", 200,
            PriceParser.parse(707.50), PriceParser.parse(1.00)
        )
        # Add to the AMZN position by 100 shares
        self.portfolio.transact_position(
            "SLD", "AMZN", 100,
            PriceParser.parse(565.83), PriceParser.parse(1.00)
        )
        # Add to the GOOG position by 200 shares
        self.portfolio.transact_position(
            "BOT", "GOOG", 200,
            PriceParser.parse(705.545), PriceParser.parse(1.00)
        )
        # Sell 200 of the AMZN shares
        self.portfolio.transact_position(
            "SLD", "AMZN", 200,
            PriceParser.parse(565.59), PriceParser.parse(1.00)
        )
        # Multiple transactions bundled into one (in IB)
        # Sell 300 GOOG from the portfolio
        self.portfolio.transact_position(
            "SLD", "GOOG", 100,
            PriceParser.parse(704.92), PriceParser.parse(1.00)
        )
        self.portfolio.transact_position(
            "SLD", "GOOG", 100,
            PriceParser.parse(704.90), PriceParser.parse(0.00)
        )
        self.portfolio.transact_position(
            "SLD", "GOOG", 100,
            PriceParser.parse(704.92), PriceParser.parse(0.50)
        )
        # Finally, sell the remaining GOOG 100 shares
        self.portfolio.transact_position(
            "SLD", "GOOG", 100,
            PriceParser.parse(704.78), PriceParser.parse(1.00)
        )

        # The figures below are derived from Interactive Brokers
        # demo account using the above trades with prices provided
        # by their demo feed.
        self.assertEqual(len(self.portfolio.positions), 0)
        self.assertEqual(len(self.portfolio.closed_positions), 2)
        self.assertEqual(PriceParser.display(self.portfolio.cur_cash), 499100.50)
        self.assertEqual(PriceParser.display(self.portfolio.equity), 499100.50)
        self.assertEqual(PriceParser.display(self.portfolio.unrealised_pnl), 0.00)
        self.assertEqual(PriceParser.display(self.portfolio.realised_pnl), -899.50)