{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(5,) (5, 3)\n", "(1000, 1) (1000, 1000)\n" ] } ], "source": [ "import vectorbt as vbt\n", "from vectorbt.portfolio.enums import *\n", "\n", "import numpy as np\n", "import pandas as pd\n", "from numba import njit\n", "from datetime import datetime, timedelta\n", "\n", "seed = 42\n", "\n", "price = pd.Series([1., 2., 3., 4., 5.], index=pd.Index([\n", " datetime(2020, 1, 1),\n", " datetime(2020, 1, 2),\n", " datetime(2020, 1, 3),\n", " datetime(2020, 1, 4),\n", " datetime(2020, 1, 5)\n", "]))\n", "price_wide = price.vbt.tile(3, keys=['a', 'b', 'c'])\n", "print(price.shape, price_wide.shape)\n", "\n", "big_price = pd.DataFrame(np.random.uniform(0.9, 1.1, size=(1000,)))\n", "big_price.index = [datetime(2018, 1, 1) + timedelta(days=i) for i in range(1000)]\n", "big_price_wide = big_price.vbt.tile(1000)\n", "print(big_price.shape, big_price_wide.shape)\n", "\n", "# Disable caching for performance testing\n", "# NOTE: Expect waterfall of executions, since some attributes depend on other attributes \n", "# that have to be calculated again and again\n", "vbt.settings.caching['enabled'] = False\n", "vbt.settings.portfolio['attach_call_seq'] = True" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## from_orders" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "order_size = pd.Series([np.inf, -np.inf, np.nan, np.inf, -np.inf], index=price.index)\n", "order_size_wide = order_size.vbt.tile(3, keys=['a', 'b', 'c'])\n", "\n", "big_order_size = pd.DataFrame.vbt.empty((1000,), 1, dtype=np.float64)\n", "big_order_size.iloc[1::2] = -1\n", "big_order_size_wide = big_order_size.vbt.tile(1000)" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2.24 ms ± 179 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" ] } ], "source": [ "%timeit vbt.Portfolio.from_orders(big_price, big_order_size, init_cash=np.inf)" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "67 ms ± 2.3 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" ] } ], "source": [ "%timeit vbt.Portfolio.from_orders(big_price_wide, big_order_size_wide, init_cash=np.inf)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "64.3 ms ± 1.05 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" ] } ], "source": [ "%timeit vbt.Portfolio.from_orders(\\\n", " big_price_wide, big_order_size_wide, init_cash=np.inf, \\\n", " group_by=np.repeat(np.arange(500), 2))" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "65.9 ms ± 1.68 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" ] } ], "source": [ "%timeit vbt.Portfolio.from_orders(\\\n", " big_price_wide, big_order_size_wide, init_cash=np.inf, \\\n", " group_by=np.repeat(np.arange(500), 2), cash_sharing=True)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "71.7 ms ± 510 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" ] } ], "source": [ "%timeit vbt.Portfolio.from_orders(\\\n", " big_price_wide, big_order_size_wide, init_cash=np.inf, \\\n", " group_by=np.repeat(np.arange(500), 2), cash_sharing=True, call_seq=CallSeqType.Auto)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "66.3 ms ± 285 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" ] } ], "source": [ "%timeit vbt.Portfolio.from_orders(\\\n", " big_price_wide, big_order_size_wide, init_cash=np.inf, \\\n", " group_by=np.full(1000, 0))" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "63.7 ms ± 728 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" ] } ], "source": [ "%timeit vbt.Portfolio.from_orders(\\\n", " big_price_wide, big_order_size_wide, init_cash=np.inf, \\\n", " group_by=np.full(1000, 0), cash_sharing=True)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "68.3 ms ± 443 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" ] } ], "source": [ "%timeit vbt.Portfolio.from_orders(\\\n", " big_price_wide, big_order_size_wide, init_cash=np.inf, \\\n", " group_by=np.full(1000, 0), cash_sharing=True, call_seq=CallSeqType.Auto)" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [], "source": [ "def test_per_direction(price=price, size=order_size, **kwargs):\n", " print('Both')\n", " try:\n", " portfolio = vbt.Portfolio.from_orders(price, size, direction='both', **kwargs)\n", " print(portfolio.orders.records)\n", " except Exception as e:\n", " print(e)\n", " print('LongOnly')\n", " try:\n", " portfolio = vbt.Portfolio.from_orders(price, size, direction='longonly', **kwargs)\n", " print(portfolio.orders.records)\n", " except Exception as e:\n", " print(e)\n", " print('ShortOnly')\n", " try:\n", " portfolio = vbt.Portfolio.from_orders(price, size, direction='shortonly', **kwargs)\n", " print(portfolio.orders.records)\n", " except Exception as e:\n", " print(e)" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "All\n", " id idx col size price fees side\n", "0 0 0 0 100.0 1.0 0.0 0\n", "1 1 1 0 200.0 2.0 0.0 1\n", "2 2 3 0 100.0 4.0 0.0 0\n", "LongOnly\n", " id idx col size price fees side\n", "0 0 0 0 100.0 1.0 0.0 0\n", "1 1 1 0 100.0 2.0 0.0 1\n", "2 2 3 0 50.0 4.0 0.0 0\n", "3 3 4 0 50.0 5.0 0.0 1\n", "ShortOnly\n", " id idx col size price fees side\n", "0 0 0 0 100.0 1.0 0.0 1\n", "1 1 1 0 100.0 2.0 0.0 0\n" ] } ], "source": [ "test_per_direction()" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "All\n", " id idx col size price fees side\n", "0 0 0 0 100.0 1.0 0.0 0\n", "1 1 1 0 200.0 2.0 0.0 1\n", "2 2 3 0 100.0 4.0 0.0 0\n", "3 3 0 1 100.0 1.0 0.0 0\n", "4 4 1 1 200.0 2.0 0.0 1\n", "5 5 3 1 100.0 4.0 0.0 0\n", "6 6 0 2 100.0 1.0 0.0 0\n", "7 7 1 2 200.0 2.0 0.0 1\n", "8 8 3 2 100.0 4.0 0.0 0\n", "LongOnly\n", " id idx col size price fees side\n", "0 0 0 0 100.0 1.0 0.0 0\n", "1 1 1 0 100.0 2.0 0.0 1\n", "2 2 3 0 50.0 4.0 0.0 0\n", "3 3 4 0 50.0 5.0 0.0 1\n", "4 4 0 1 100.0 1.0 0.0 0\n", "5 5 1 1 100.0 2.0 0.0 1\n", "6 6 3 1 50.0 4.0 0.0 0\n", "7 7 4 1 50.0 5.0 0.0 1\n", "8 8 0 2 100.0 1.0 0.0 0\n", "9 9 1 2 100.0 2.0 0.0 1\n", "10 10 3 2 50.0 4.0 0.0 0\n", "11 11 4 2 50.0 5.0 0.0 1\n", "ShortOnly\n", " id idx col size price fees side\n", "0 0 0 0 100.0 1.0 0.0 1\n", "1 1 1 0 100.0 2.0 0.0 0\n", "2 2 0 1 100.0 1.0 0.0 1\n", "3 3 1 1 100.0 2.0 0.0 0\n", "4 4 0 2 100.0 1.0 0.0 1\n", "5 5 1 2 100.0 2.0 0.0 0\n" ] } ], "source": [ "test_per_direction(price=price_wide)" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "All\n", " id idx col size price fees side\n", "0 0 0 0 100.0 1.0 0.0 0\n", "1 1 0 1 100.0 1.0 0.0 1\n", "LongOnly\n", " id idx col size price fees side\n", "0 0 0 0 100.0 1.0 0.0 0\n", "ShortOnly\n", " id idx col size price fees side\n", "0 0 0 0 100.0 1.0 0.0 1\n" ] } ], "source": [ "test_per_direction(size=[[np.inf, -np.inf]])" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [], "source": [ "order_size_one = pd.Series([1, -1, np.nan, 1, -1], index=price.index)" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "All\n", " id idx col size price fees side\n", "0 0 0 0 99.009901 1.01 0.0 0\n", "1 1 1 0 198.019802 2.02 0.0 1\n", "2 2 3 0 99.009901 4.04 0.0 0\n", "LongOnly\n", " id idx col size price fees side\n", "0 0 0 0 99.009901 1.01 0.0 0\n", "1 1 1 0 99.009901 2.02 0.0 1\n", "2 2 3 0 49.504950 4.04 0.0 0\n", "3 3 4 0 49.504950 5.05 0.0 1\n", "ShortOnly\n", " id idx col size price fees side\n", "0 0 0 0 99.009901 1.01 0.0 1\n", "1 1 1 0 99.009901 2.02 0.0 0\n" ] } ], "source": [ "test_per_direction(price=price * 1.01)" ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "All\n", " id idx col size price fees side\n", "0 0 0 0 1.0 1.0 0.0 0\n", "1 1 1 0 1.0 2.0 0.0 1\n", "2 2 3 0 1.0 4.0 0.0 0\n", "3 3 4 0 1.0 5.0 0.0 1\n", "4 4 0 1 1.0 1.0 0.1 0\n", "5 5 1 1 1.0 2.0 0.2 1\n", "6 6 3 1 1.0 4.0 0.4 0\n", "7 7 4 1 1.0 5.0 0.5 1\n", "8 8 0 2 1.0 1.0 1.0 0\n", "9 9 1 2 1.0 2.0 2.0 1\n", "10 10 3 2 1.0 4.0 4.0 0\n", "11 11 4 2 1.0 5.0 5.0 1\n", "LongOnly\n", " id idx col size price fees side\n", "0 0 0 0 1.0 1.0 0.0 0\n", "1 1 1 0 1.0 2.0 0.0 1\n", "2 2 3 0 1.0 4.0 0.0 0\n", "3 3 4 0 1.0 5.0 0.0 1\n", "4 4 0 1 1.0 1.0 0.1 0\n", "5 5 1 1 1.0 2.0 0.2 1\n", "6 6 3 1 1.0 4.0 0.4 0\n", "7 7 4 1 1.0 5.0 0.5 1\n", "8 8 0 2 1.0 1.0 1.0 0\n", "9 9 1 2 1.0 2.0 2.0 1\n", "10 10 3 2 1.0 4.0 4.0 0\n", "11 11 4 2 1.0 5.0 5.0 1\n", "ShortOnly\n", " id idx col size price fees side\n", "0 0 0 0 1.0 1.0 0.0 1\n", "1 1 1 0 1.0 2.0 0.0 0\n", "2 2 3 0 1.0 4.0 0.0 1\n", "3 3 4 0 1.0 5.0 0.0 0\n", "4 4 0 1 1.0 1.0 0.1 1\n", "5 5 1 1 1.0 2.0 0.2 0\n", "6 6 3 1 1.0 4.0 0.4 1\n", "7 7 4 1 1.0 5.0 0.5 0\n", "8 8 0 2 1.0 1.0 1.0 1\n", "9 9 1 2 1.0 2.0 2.0 0\n", "10 10 3 2 1.0 4.0 4.0 1\n", "11 11 4 2 1.0 5.0 5.0 0\n" ] } ], "source": [ "test_per_direction(size=order_size_one, fees=[[0., 0.1, 1.]])" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "All\n", " id idx col size price fees side\n", "0 0 0 0 1.0 1.0 0.0 0\n", "1 1 1 0 1.0 2.0 0.0 1\n", "2 2 3 0 1.0 4.0 0.0 0\n", "3 3 4 0 1.0 5.0 0.0 1\n", "4 4 0 1 1.0 1.0 0.1 0\n", "5 5 1 1 1.0 2.0 0.1 1\n", "6 6 3 1 1.0 4.0 0.1 0\n", "7 7 4 1 1.0 5.0 0.1 1\n", "8 8 0 2 1.0 1.0 1.0 0\n", "9 9 1 2 1.0 2.0 1.0 1\n", "10 10 3 2 1.0 4.0 1.0 0\n", "11 11 4 2 1.0 5.0 1.0 1\n", "LongOnly\n", " id idx col size price fees side\n", "0 0 0 0 1.0 1.0 0.0 0\n", "1 1 1 0 1.0 2.0 0.0 1\n", "2 2 3 0 1.0 4.0 0.0 0\n", "3 3 4 0 1.0 5.0 0.0 1\n", "4 4 0 1 1.0 1.0 0.1 0\n", "5 5 1 1 1.0 2.0 0.1 1\n", "6 6 3 1 1.0 4.0 0.1 0\n", "7 7 4 1 1.0 5.0 0.1 1\n", "8 8 0 2 1.0 1.0 1.0 0\n", "9 9 1 2 1.0 2.0 1.0 1\n", "10 10 3 2 1.0 4.0 1.0 0\n", "11 11 4 2 1.0 5.0 1.0 1\n", "ShortOnly\n", " id idx col size price fees side\n", "0 0 0 0 1.0 1.0 0.0 1\n", "1 1 1 0 1.0 2.0 0.0 0\n", "2 2 3 0 1.0 4.0 0.0 1\n", "3 3 4 0 1.0 5.0 0.0 0\n", "4 4 0 1 1.0 1.0 0.1 1\n", "5 5 1 1 1.0 2.0 0.1 0\n", "6 6 3 1 1.0 4.0 0.1 1\n", "7 7 4 1 1.0 5.0 0.1 0\n", "8 8 0 2 1.0 1.0 1.0 1\n", "9 9 1 2 1.0 2.0 1.0 0\n", "10 10 3 2 1.0 4.0 1.0 1\n", "11 11 4 2 1.0 5.0 1.0 0\n" ] } ], "source": [ "test_per_direction(size=order_size_one, fixed_fees=[[0., 0.1, 1.]])" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "All\n", " id idx col size price fees side\n", "0 0 0 0 1.0 1.0 0.0 0\n", "1 1 1 0 1.0 2.0 0.0 1\n", "2 2 3 0 1.0 4.0 0.0 0\n", "3 3 4 0 1.0 5.0 0.0 1\n", "4 4 0 1 1.0 1.1 0.0 0\n", "5 5 1 1 1.0 1.8 0.0 1\n", "6 6 3 1 1.0 4.4 0.0 0\n", "7 7 4 1 1.0 4.5 0.0 1\n", "8 8 0 2 1.0 2.0 0.0 0\n", "9 9 1 2 1.0 0.0 0.0 1\n", "10 10 3 2 1.0 8.0 0.0 0\n", "11 11 4 2 1.0 0.0 0.0 1\n", "LongOnly\n", " id idx col size price fees side\n", "0 0 0 0 1.0 1.0 0.0 0\n", "1 1 1 0 1.0 2.0 0.0 1\n", "2 2 3 0 1.0 4.0 0.0 0\n", "3 3 4 0 1.0 5.0 0.0 1\n", "4 4 0 1 1.0 1.1 0.0 0\n", "5 5 1 1 1.0 1.8 0.0 1\n", "6 6 3 1 1.0 4.4 0.0 0\n", "7 7 4 1 1.0 4.5 0.0 1\n", "8 8 0 2 1.0 2.0 0.0 0\n", "9 9 1 2 1.0 0.0 0.0 1\n", "10 10 3 2 1.0 8.0 0.0 0\n", "11 11 4 2 1.0 0.0 0.0 1\n", "ShortOnly\n", " id idx col size price fees side\n", "0 0 0 0 1.0 1.0 0.0 1\n", "1 1 1 0 1.0 2.0 0.0 0\n", "2 2 3 0 1.0 4.0 0.0 1\n", "3 3 4 0 1.0 5.0 0.0 0\n", "4 4 0 1 1.0 0.9 0.0 1\n", "5 5 1 1 1.0 2.2 0.0 0\n", "6 6 3 1 1.0 3.6 0.0 1\n", "7 7 4 1 1.0 5.5 0.0 0\n", "8 8 0 2 1.0 0.0 0.0 1\n", "9 9 1 2 1.0 4.0 0.0 0\n", "10 10 3 2 1.0 0.0 0.0 1\n", "11 11 4 2 1.0 10.0 0.0 0\n" ] } ], "source": [ "test_per_direction(size=order_size_one, slippage=[[0., 0.1, 1.]])" ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "All\n", " id idx col size price fees side\n", "0 0 0 0 1.0 1.0 0.0 0\n", "1 1 1 0 1.0 2.0 0.0 1\n", "2 2 3 0 1.0 4.0 0.0 0\n", "3 3 4 0 1.0 5.0 0.0 1\n", "4 4 0 1 1.0 1.0 0.0 0\n", "5 5 1 1 1.0 2.0 0.0 1\n", "6 6 3 1 1.0 4.0 0.0 0\n", "7 7 4 1 1.0 5.0 0.0 1\n", "LongOnly\n", " id idx col size price fees side\n", "0 0 0 0 1.0 1.0 0.0 0\n", "1 1 1 0 1.0 2.0 0.0 1\n", "2 2 3 0 1.0 4.0 0.0 0\n", "3 3 4 0 1.0 5.0 0.0 1\n", "4 4 0 1 1.0 1.0 0.0 0\n", "5 5 1 1 1.0 2.0 0.0 1\n", "6 6 3 1 1.0 4.0 0.0 0\n", "7 7 4 1 1.0 5.0 0.0 1\n", "ShortOnly\n", " id idx col size price fees side\n", "0 0 0 0 1.0 1.0 0.0 1\n", "1 1 1 0 1.0 2.0 0.0 0\n", "2 2 3 0 1.0 4.0 0.0 1\n", "3 3 4 0 1.0 5.0 0.0 0\n", "4 4 0 1 1.0 1.0 0.0 1\n", "5 5 1 1 1.0 2.0 0.0 0\n", "6 6 3 1 1.0 4.0 0.0 1\n", "7 7 4 1 1.0 5.0 0.0 0\n" ] } ], "source": [ "test_per_direction(size=order_size_one, min_size=[[0., 1., 2.]])" ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "All\n", " id idx col size price fees side\n", "0 0 0 0 0.5 1.0 0.0 0\n", "1 1 1 0 0.5 2.0 0.0 1\n", "2 2 3 0 0.5 4.0 0.0 0\n", "3 3 4 0 0.5 5.0 0.0 1\n", "4 4 0 1 1.0 1.0 0.0 0\n", "5 5 1 1 1.0 2.0 0.0 1\n", "6 6 3 1 1.0 4.0 0.0 0\n", "7 7 4 1 1.0 5.0 0.0 1\n", "8 8 0 2 1.0 1.0 0.0 0\n", "9 9 1 2 1.0 2.0 0.0 1\n", "10 10 3 2 1.0 4.0 0.0 0\n", "11 11 4 2 1.0 5.0 0.0 1\n", "LongOnly\n", " id idx col size price fees side\n", "0 0 0 0 0.5 1.0 0.0 0\n", "1 1 1 0 0.5 2.0 0.0 1\n", "2 2 3 0 0.5 4.0 0.0 0\n", "3 3 4 0 0.5 5.0 0.0 1\n", "4 4 0 1 1.0 1.0 0.0 0\n", "5 5 1 1 1.0 2.0 0.0 1\n", "6 6 3 1 1.0 4.0 0.0 0\n", "7 7 4 1 1.0 5.0 0.0 1\n", "8 8 0 2 1.0 1.0 0.0 0\n", "9 9 1 2 1.0 2.0 0.0 1\n", "10 10 3 2 1.0 4.0 0.0 0\n", "11 11 4 2 1.0 5.0 0.0 1\n", "ShortOnly\n", " id idx col size price fees side\n", "0 0 0 0 0.5 1.0 0.0 1\n", "1 1 1 0 0.5 2.0 0.0 0\n", "2 2 3 0 0.5 4.0 0.0 1\n", "3 3 4 0 0.5 5.0 0.0 0\n", "4 4 0 1 1.0 1.0 0.0 1\n", "5 5 1 1 1.0 2.0 0.0 0\n", "6 6 3 1 1.0 4.0 0.0 1\n", "7 7 4 1 1.0 5.0 0.0 0\n", "8 8 0 2 1.0 1.0 0.0 1\n", "9 9 1 2 1.0 2.0 0.0 0\n", "10 10 3 2 1.0 4.0 0.0 1\n", "11 11 4 2 1.0 5.0 0.0 0\n" ] } ], "source": [ "test_per_direction(size=order_size_one, max_size=[[0.5, 1., np.inf]])" ] }, { "cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "All\n", " id idx col size price fees side\n", "0 0 0 0 1.0 1.0 0.0 0\n", "1 1 1 0 1.0 2.0 0.0 1\n", "2 2 3 0 1.0 4.0 0.0 0\n", "3 3 4 0 1.0 5.0 0.0 1\n", "4 4 1 1 1.0 2.0 0.0 1\n", "5 5 3 1 1.0 4.0 0.0 0\n", "6 6 4 1 1.0 5.0 0.0 1\n", "LongOnly\n", " id idx col size price fees side\n", "0 0 0 0 1.0 1.0 0.0 0\n", "1 1 1 0 1.0 2.0 0.0 1\n", "2 2 3 0 1.0 4.0 0.0 0\n", "3 3 4 0 1.0 5.0 0.0 1\n", "4 4 3 1 1.0 4.0 0.0 0\n", "5 5 4 1 1.0 5.0 0.0 1\n", "ShortOnly\n", " id idx col size price fees side\n", "0 0 0 0 1.0 1.0 0.0 1\n", "1 1 1 0 1.0 2.0 0.0 0\n", "2 2 3 0 1.0 4.0 0.0 1\n", "3 3 4 0 1.0 5.0 0.0 0\n", "4 4 3 1 1.0 4.0 0.0 1\n", "5 5 4 1 1.0 5.0 0.0 0\n" ] } ], "source": [ "test_per_direction(size=order_size_one, reject_prob=[[0., 0.5, 1.]], seed=42)" ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "All\n", "__init__() got an unexpected keyword argument 'close_first'\n", "LongOnly\n", "__init__() got an unexpected keyword argument 'close_first'\n", "ShortOnly\n", "__init__() got an unexpected keyword argument 'close_first'\n" ] } ], "source": [ "test_per_direction(size=pd.Series([np.inf, -np.inf, -np.inf, np.inf, np.inf]), close_first=[[False, True]])" ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "All\n", " id idx col size price fees side\n", "0 0 0 0 100.0 1.0 0.0 0\n", "1 1 1 0 1000.0 2.0 0.0 1\n", "2 2 3 0 500.0 4.0 0.0 0\n", "3 3 4 0 1000.0 5.0 0.0 1\n", "4 4 1 1 1000.0 2.0 0.0 1\n", "5 5 4 1 1000.0 5.0 0.0 1\n", "LongOnly\n", " id idx col size price fees side\n", "0 0 0 0 100.0 1.0 0.0 0\n", "1 1 1 0 100.0 2.0 0.0 1\n", "2 2 3 0 50.0 4.0 0.0 0\n", "3 3 4 0 50.0 5.0 0.0 1\n", "ShortOnly\n", " id idx col size price fees side\n", "0 0 0 0 1000.0 1.0 0.0 1\n", "1 1 1 0 550.0 2.0 0.0 0\n", "2 2 3 0 1000.0 4.0 0.0 1\n", "3 3 4 0 800.0 5.0 0.0 0\n", "4 4 0 1 1000.0 1.0 0.0 1\n", "5 5 3 1 1000.0 4.0 0.0 1\n", "6 6 4 1 1000.0 5.0 0.0 0\n", "All\n", " id idx col size price fees side\n", "0 0 0 0 100.0 1.0 0.0 0\n", "1 1 1 0 200.0 2.0 0.0 1\n", "2 2 3 0 100.0 4.0 0.0 0\n", "3 3 0 1 100.0 1.0 0.0 0\n", "4 4 1 1 200.0 2.0 0.0 1\n", "5 5 3 1 100.0 4.0 0.0 0\n", "LongOnly\n", " id idx col size price fees side\n", "0 0 0 0 100.0 1.0 0.0 0\n", "1 1 1 0 100.0 2.0 0.0 1\n", "2 2 3 0 50.0 4.0 0.0 0\n", "3 3 4 0 50.0 5.0 0.0 1\n", "4 4 0 1 100.0 1.0 0.0 0\n", "5 5 1 1 100.0 2.0 0.0 1\n", "6 6 3 1 50.0 4.0 0.0 0\n", "7 7 4 1 50.0 5.0 0.0 1\n", "ShortOnly\n", " id idx col size price fees side\n", "0 0 0 0 100.0 1.0 0.0 1\n", "1 1 1 0 100.0 2.0 0.0 0\n", "2 2 0 1 100.0 1.0 0.0 1\n", "3 3 1 1 100.0 2.0 0.0 0\n" ] } ], "source": [ "test_per_direction(size=order_size_one * 1000, allow_partial=[[True, False]])\n", "test_per_direction(size=order_size, allow_partial=[[True, False]])" ] }, { "cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "All\n", " id idx col size price fees side\n", "0 0 0 0 100.0 1.0 0.0 0\n", "1 1 1 0 1000.0 2.0 0.0 1\n", "2 2 3 0 500.0 4.0 0.0 0\n", "3 3 4 0 1000.0 5.0 0.0 1\n", "LongOnly\n", " id idx col size price fees side\n", "0 0 0 0 100.0 1.0 0.0 0\n", "1 1 1 0 100.0 2.0 0.0 1\n", "2 2 3 0 50.0 4.0 0.0 0\n", "3 3 4 0 50.0 5.0 0.0 1\n", "ShortOnly\n", " id idx col size price fees side\n", "0 0 0 0 1000.0 1.0 0.0 1\n", "1 1 1 0 550.0 2.0 0.0 0\n", "2 2 3 0 1000.0 4.0 0.0 1\n", "3 3 4 0 800.0 5.0 0.0 0\n", "All\n", "Final size is less than requested\n", "LongOnly\n", "Final size is less than requested\n", "ShortOnly\n", "Final size is less than requested\n" ] } ], "source": [ "test_per_direction(size=order_size_one * 1000, allow_partial=True, raise_reject=True)\n", "test_per_direction(size=order_size_one * 1000, allow_partial=False, raise_reject=True)" ] }, { "cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " id idx col group cash position debt free_cash val_price value \\\n", "0 0 0 0 0 100.0 0.0 0.0 100.0 1.0 100.0 \n", "1 1 1 0 0 0.0 100.0 0.0 0.0 2.0 200.0 \n", "2 2 2 0 0 400.0 -100.0 200.0 0.0 3.0 100.0 \n", "3 3 3 0 0 400.0 -100.0 200.0 0.0 4.0 0.0 \n", "4 4 4 0 0 0.0 0.0 0.0 0.0 5.0 0.0 \n", "\n", " ... new_free_cash new_val_price new_value res_size res_price \\\n", "0 ... 0.0 1.0 100.0 100.0 1.0 \n", "1 ... 0.0 2.0 200.0 200.0 2.0 \n", "2 ... 0.0 3.0 100.0 NaN NaN \n", "3 ... 0.0 4.0 0.0 100.0 4.0 \n", "4 ... 0.0 5.0 0.0 NaN NaN \n", "\n", " res_fees res_side res_status res_status_info order_id \n", "0 0.0 0 0 -1 0 \n", "1 0.0 1 0 -1 1 \n", "2 NaN -1 1 0 -1 \n", "3 0.0 0 0 -1 2 \n", "4 NaN -1 2 6 -1 \n", "\n", "[5 rows x 37 columns]\n" ] } ], "source": [ "portfolio = vbt.Portfolio.from_orders(price, order_size, log=True, direction='both')\n", "\n", "print(portfolio.logs.records)" ] }, { "cell_type": "code", "execution_count": 64, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " id idx col size price fees side\n", "0 0 0 0 100.0 1.0 0.0 0\n", "1 1 1 0 200.0 2.0 0.0 1\n", "2 2 3 0 100.0 4.0 0.0 0\n", "3 3 0 1 100.0 1.0 0.0 0\n", "4 4 1 1 200.0 2.0 0.0 1\n", "5 5 3 1 100.0 4.0 0.0 0\n", "6 6 0 2 100.0 1.0 0.0 0\n", "7 7 1 2 200.0 2.0 0.0 1\n", "8 8 3 2 100.0 4.0 0.0 0\n" ] } ], "source": [ "portfolio = vbt.Portfolio.from_orders(\n", " price_wide, order_size, \n", " group_by=np.array([0, 0, 1]), direction='both')\n", "\n", "print(portfolio.orders.records)" ] }, { "cell_type": "code", "execution_count": 65, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " id idx col size price fees side\n", "0 0 0 0 100.0 1.0 0.0 0\n", "1 1 1 0 200.0 2.0 0.0 1\n", "2 2 3 0 100.0 4.0 0.0 0\n", "3 3 0 2 100.0 1.0 0.0 0\n", "4 4 1 2 200.0 2.0 0.0 1\n", "5 5 3 2 100.0 4.0 0.0 0\n", " a b c\n", "2020-01-01 0 1 0\n", "2020-01-02 0 1 0\n", "2020-01-03 0 1 0\n", "2020-01-04 0 1 0\n", "2020-01-05 0 1 0\n" ] } ], "source": [ "portfolio = vbt.Portfolio.from_orders(\n", " price_wide, order_size, \n", " group_by=np.array([0, 0, 1]), cash_sharing=True, direction='both')\n", "\n", "print(portfolio.orders.records)\n", "print(portfolio.call_seq)" ] }, { "cell_type": "code", "execution_count": 66, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " id idx col size price fees side\n", "0 0 0 1 100.0 1.0 0.0 0\n", "1 1 1 1 200.0 2.0 0.0 1\n", "2 2 3 1 100.0 4.0 0.0 0\n", "3 3 0 2 100.0 1.0 0.0 0\n", "4 4 1 2 200.0 2.0 0.0 1\n", "5 5 3 2 100.0 4.0 0.0 0\n", " a b c\n", "2020-01-01 1 0 0\n", "2020-01-02 1 0 0\n", "2020-01-03 1 0 0\n", "2020-01-04 1 0 0\n", "2020-01-05 1 0 0\n" ] } ], "source": [ "portfolio = vbt.Portfolio.from_orders(\n", " price_wide, order_size, \n", " group_by=np.array([0, 0, 1]), cash_sharing=True, direction='both', call_seq='reversed')\n", "\n", "print(portfolio.orders.records)\n", "print(portfolio.call_seq)" ] }, { "cell_type": "code", "execution_count": 67, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " id idx col size price fees side\n", "0 0 0 0 100.0 1.0 0.0 0\n", "1 1 1 0 200.0 2.0 0.0 1\n", "2 2 3 1 100.0 4.0 0.0 0\n", "3 3 4 1 120.0 5.0 0.0 1\n", "4 4 0 2 100.0 1.0 0.0 0\n", "5 5 1 2 200.0 2.0 0.0 1\n", "6 6 3 2 100.0 4.0 0.0 0\n", " a b c\n", "2020-01-01 0 1 0\n", "2020-01-02 0 1 0\n", "2020-01-03 0 1 0\n", "2020-01-04 1 0 0\n", "2020-01-05 0 1 0\n", " id idx col size price fees side\n", "0 0 0 1 100.0 1.0 0.0 0\n", "1 1 1 1 200.0 2.0 0.0 1\n", "2 2 3 1 100.0 4.0 0.0 0\n", "3 3 0 2 100.0 1.0 0.0 0\n", "4 4 1 2 200.0 2.0 0.0 1\n", "5 5 3 2 100.0 4.0 0.0 0\n", " a b c\n", "2020-01-01 1 0 0\n", "2020-01-02 0 1 0\n", "2020-01-03 1 0 0\n", "2020-01-04 1 0 0\n", "2020-01-05 1 0 0\n" ] } ], "source": [ "portfolio = vbt.Portfolio.from_orders(\n", " price_wide, order_size, \n", " group_by=np.array([0, 0, 1]), cash_sharing=True, direction='both', call_seq='random')\n", "\n", "print(portfolio.orders.records)\n", "print(portfolio.call_seq)\n", "\n", "portfolio = vbt.Portfolio.from_orders(\n", " price_wide, order_size, \n", " group_by=np.array([0, 0, 1]), cash_sharing=True, direction='both', call_seq='random', seed=42)\n", "\n", "print(portfolio.orders.records)\n", "print(portfolio.call_seq)" ] }, { "cell_type": "code", "execution_count": 68, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "All\n", " id idx col size price fees side\n", "0 0 0 2 100.0 1.0 0.0 0\n", "1 1 1 2 200.0 1.0 0.0 1\n", "2 2 1 1 200.0 1.0 0.0 0\n", "3 3 2 1 200.0 1.0 0.0 1\n", "4 4 2 0 200.0 1.0 0.0 0\n", "5 5 3 0 200.0 1.0 0.0 1\n", "6 6 3 2 200.0 1.0 0.0 0\n", "7 7 4 2 200.0 1.0 0.0 1\n", "8 8 4 1 200.0 1.0 0.0 0\n", " 0 1 2\n", "0 0 1 2\n", "1 2 0 1\n", "2 1 2 0\n", "3 0 1 2\n", "4 2 0 1\n", " 0 1 2\n", "0 0.0 0.0 100.0\n", "1 0.0 200.0 -100.0\n", "2 200.0 0.0 -100.0\n", "3 0.0 0.0 100.0\n", "4 0.0 200.0 -100.0\n", "0 100.0\n", "1 100.0\n", "2 100.0\n", "3 100.0\n", "4 100.0\n", "dtype: float64\n", "LongOnly\n", " id idx col size price fees side\n", "0 0 0 2 100.0 1.0 0.0 0\n", "1 1 1 2 100.0 1.0 0.0 1\n", "2 2 1 1 100.0 1.0 0.0 0\n", "3 3 2 1 100.0 1.0 0.0 1\n", "4 4 2 0 100.0 1.0 0.0 0\n", "5 5 3 0 100.0 1.0 0.0 1\n", "6 6 3 2 100.0 1.0 0.0 0\n", "7 7 4 2 100.0 1.0 0.0 1\n", "8 8 4 1 100.0 1.0 0.0 0\n", " 0 1 2\n", "0 0 1 2\n", "1 2 0 1\n", "2 1 2 0\n", "3 0 1 2\n", "4 2 0 1\n", " 0 1 2\n", "0 0.0 0.0 100.0\n", "1 0.0 100.0 0.0\n", "2 100.0 0.0 0.0\n", "3 0.0 0.0 100.0\n", "4 0.0 100.0 0.0\n", "0 100.0\n", "1 100.0\n", "2 100.0\n", "3 100.0\n", "4 100.0\n", "dtype: float64\n", "ShortOnly\n", " id idx col size price fees side\n", "0 0 0 2 100.0 1.0 0.0 1\n", "1 1 1 2 100.0 1.0 0.0 0\n", "2 2 2 0 100.0 1.0 0.0 1\n", "3 3 3 0 100.0 1.0 0.0 0\n", "4 4 4 1 100.0 1.0 0.0 1\n", " 0 1 2\n", "0 2 0 1\n", "1 1 0 2\n", "2 0 2 1\n", "3 2 1 0\n", "4 1 0 2\n", " 0 1 2\n", "0 0.0 0.0 -100.0\n", "1 0.0 0.0 0.0\n", "2 -100.0 0.0 0.0\n", "3 0.0 0.0 0.0\n", "4 0.0 -100.0 0.0\n", "0 100.0\n", "1 100.0\n", "2 100.0\n", "3 100.0\n", "4 100.0\n", "dtype: float64\n" ] } ], "source": [ "for direction in ('Both', 'LongOnly', 'ShortOnly'):\n", " print(direction)\n", " portfolio = vbt.Portfolio.from_orders(1., pd.DataFrame([\n", " [0., 0., np.inf],\n", " [0., np.inf, -np.inf],\n", " [np.inf, -np.inf, 0.],\n", " [-np.inf, 0., np.inf],\n", " [0., np.inf, -np.inf],\n", " ]), group_by=np.array([0, 0, 0]), \n", " cash_sharing=True, call_seq='auto', direction=direction)\n", "\n", " print(portfolio.orders.records)\n", " print(portfolio.call_seq)\n", " print(portfolio.assets())\n", " print(portfolio.value())\n", " # notice how shorting with np.inf only accounts for current cash, not for other assets!" ] }, { "cell_type": "code", "execution_count": 69, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "All\n", " id idx col size price fees side\n", "0 0 0 0 75.0 1.0 0.0 0\n", "1 1 0 1 75.0 1.0 0.0 1\n", "LongOnly\n", " id idx col size price fees side\n", "0 0 0 0 75.0 1.0 0.0 0\n", "ShortOnly\n", " id idx col size price fees side\n", "0 0 0 0 75.0 1.0 0.0 1\n", " 0 1\n", "2020-01-01 75.0 -75.0\n", "2020-01-02 75.0 -75.0\n", "2020-01-03 75.0 -75.0\n", "2020-01-04 75.0 -75.0\n", "2020-01-05 75.0 -75.0\n", " id idx col size price fees side\n", "0 0 0 0 75.0 1.0 0.0 0\n", "1 1 0 1 25.0 1.0 0.0 0\n", " a b c\n", "2020-01-01 75.0 25.0 0.0\n", "2020-01-02 75.0 25.0 0.0\n", "2020-01-03 75.0 25.0 0.0\n", "2020-01-04 75.0 25.0 0.0\n", "2020-01-05 75.0 25.0 0.0\n" ] } ], "source": [ "test_per_direction(size=[[75., -75.]], size_type=SizeType.TargetAmount)\n", "\n", "portfolio = vbt.Portfolio.from_orders(\n", " price, [[75., -75.]], size_type=SizeType.TargetAmount, direction='both')\n", "print(portfolio.assets())\n", "\n", "portfolio = vbt.Portfolio.from_orders(\n", " price_wide, 75., size_type=SizeType.TargetAmount, \n", " group_by=np.array([0, 0, 0]), cash_sharing=True, direction='both')\n", "print(portfolio.orders.records)\n", "print(portfolio.assets())" ] }, { "cell_type": "code", "execution_count": 70, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "All\n", " id idx col size price fees side\n", "0 0 0 0 50.000000 1.0 0.0 0\n", "1 1 1 0 25.000000 2.0 0.0 1\n", "2 2 2 0 8.333333 3.0 0.0 1\n", "3 3 3 0 4.166667 4.0 0.0 1\n", "4 4 4 0 2.500000 5.0 0.0 1\n", "5 5 0 1 50.000000 1.0 0.0 1\n", "6 6 1 1 25.000000 2.0 0.0 0\n", "7 7 2 1 8.333333 3.0 0.0 0\n", "8 8 3 1 4.166667 4.0 0.0 0\n", "9 9 4 1 2.500000 5.0 0.0 0\n", "LongOnly\n", " id idx col size price fees side\n", "0 0 0 0 50.000000 1.0 0.0 0\n", "1 1 1 0 25.000000 2.0 0.0 1\n", "2 2 2 0 8.333333 3.0 0.0 1\n", "3 3 3 0 4.166667 4.0 0.0 1\n", "4 4 4 0 2.500000 5.0 0.0 1\n", "ShortOnly\n", " id idx col size price fees side\n", "0 0 0 0 50.000000 1.0 0.0 1\n", "1 1 1 0 25.000000 2.0 0.0 0\n", "2 2 2 0 8.333333 3.0 0.0 0\n", "3 3 3 0 4.166667 4.0 0.0 0\n", "4 4 4 0 2.500000 5.0 0.0 0\n", " 0 1\n", "2020-01-01 50.0 -50.0\n", "2020-01-02 50.0 -50.0\n", "2020-01-03 50.0 -50.0\n", "2020-01-04 50.0 -50.0\n", "2020-01-05 50.0 -50.0\n", " id idx col size price fees side\n", "0 0 0 0 50.000000 1.0 0.0 0\n", "1 1 0 1 50.000000 1.0 0.0 0\n", "2 2 1 0 25.000000 2.0 0.0 1\n", "3 3 1 1 25.000000 2.0 0.0 1\n", "4 4 1 2 25.000000 2.0 0.0 0\n", "5 5 2 0 8.333333 3.0 0.0 1\n", "6 6 2 1 8.333333 3.0 0.0 1\n", "7 7 2 2 8.333333 3.0 0.0 1\n", "8 8 3 0 4.166667 4.0 0.0 1\n", "9 9 3 1 4.166667 4.0 0.0 1\n", "10 10 3 2 4.166667 4.0 0.0 1\n", "11 11 4 0 2.500000 5.0 0.0 1\n", "12 12 4 1 2.500000 5.0 0.0 1\n", "13 13 4 2 2.500000 5.0 0.0 1\n", " a b c\n", "2020-01-01 50.0 50.0 0.0\n", "2020-01-02 50.0 50.0 50.0\n", "2020-01-03 50.0 50.0 50.0\n", "2020-01-04 50.0 50.0 50.0\n", "2020-01-05 50.0 50.0 50.0\n" ] } ], "source": [ "test_per_direction(size=[[50., -50.]], size_type=SizeType.TargetValue)\n", "\n", "portfolio = vbt.Portfolio.from_orders(\n", " price, [[50., -50.]], size_type=SizeType.TargetValue, direction='both')\n", "print(portfolio.asset_value())\n", "\n", "portfolio = vbt.Portfolio.from_orders(\n", " price_wide, 50., size_type=SizeType.TargetValue, \n", " group_by=np.array([0, 0, 0]), cash_sharing=True, direction='both')\n", "print(portfolio.orders.records)\n", "print(portfolio.asset_value(group_by=False))" ] }, { "cell_type": "code", "execution_count": 71, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "All\n", " id idx col size price fees side\n", "0 0 0 0 50.000000 1.0 0.0 0\n", "1 1 1 0 12.500000 2.0 0.0 1\n", "2 2 2 0 6.250000 3.0 0.0 1\n", "3 3 3 0 3.906250 4.0 0.0 1\n", "4 4 4 0 2.734375 5.0 0.0 1\n", "5 5 0 1 50.000000 1.0 0.0 1\n", "6 6 1 1 37.500000 2.0 0.0 0\n", "7 7 2 1 6.250000 3.0 0.0 0\n", "8 8 3 1 2.343750 4.0 0.0 0\n", "9 9 4 1 1.171875 5.0 0.0 0\n", "LongOnly\n", " id idx col size price fees side\n", "0 0 0 0 50.000000 1.0 0.0 0\n", "1 1 1 0 12.500000 2.0 0.0 1\n", "2 2 2 0 6.250000 3.0 0.0 1\n", "3 3 3 0 3.906250 4.0 0.0 1\n", "4 4 4 0 2.734375 5.0 0.0 1\n", "ShortOnly\n", " id idx col size price fees side\n", "0 0 0 0 50.000000 1.0 0.0 1\n", "1 1 1 0 37.500000 2.0 0.0 0\n", "2 2 2 0 6.250000 3.0 0.0 0\n", "3 3 3 0 2.343750 4.0 0.0 0\n", "4 4 4 0 1.171875 5.0 0.0 0\n", " 0 1\n", "2020-01-01 0.5 -0.5\n", "2020-01-02 0.5 -0.5\n", "2020-01-03 0.5 -0.5\n", "2020-01-04 0.5 -0.5\n", "2020-01-05 0.5 -0.5\n", " id idx col size price fees side\n", "0 0 0 0 50.0 1.0 0.0 0\n", "1 1 0 1 50.0 1.0 0.0 0\n", " a b c\n", "2020-01-01 0.500000 0.500000 0.0\n", "2020-01-02 0.666667 0.666667 0.0\n", "2020-01-03 0.750000 0.750000 0.0\n", "2020-01-04 0.800000 0.800000 0.0\n", "2020-01-05 0.833333 0.833333 0.0\n" ] } ], "source": [ "test_per_direction(size=[[0.5, -0.5]], size_type=SizeType.TargetPercent)\n", "\n", "portfolio = vbt.Portfolio.from_orders(\n", " price, [[0.5, -0.5]], size_type=SizeType.TargetPercent, direction='both')\n", "print(portfolio.asset_value() / portfolio.value())\n", "\n", "portfolio = vbt.Portfolio.from_orders(\n", " price_wide, 0.5, size_type=SizeType.TargetPercent, \n", " group_by=np.array([0, 0, 0]), cash_sharing=True, direction='both')\n", "print(portfolio.orders.records)\n", "print(portfolio.asset_value(group_by=False) / portfolio.value(group_by=False))" ] }, { "cell_type": "code", "execution_count": 72, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " a b c\n", "2020-01-01 0.0 30.0 70.0\n", "2020-01-02 70.0 0.0 30.0\n", "2020-01-03 30.0 70.0 0.0\n", "2020-01-04 0.0 30.0 70.0\n", "2020-01-05 70.0 30.0 0.0\n" ] } ], "source": [ "price_one = pd.Series([1., 1., 1., 1., 1.], index=price.index)\n", "target_hold_value = pd.DataFrame({\n", " 'a': [0., 70., 30., 0., 70.],\n", " 'b': [30., 0., 70., 30., 30.],\n", " 'c': [70., 30., 0., 70., 0.]\n", "}, index=price.index)\n", "print(target_hold_value)" ] }, { "cell_type": "code", "execution_count": 75, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " id idx col size price fees side\n", "0 0 0 1 30.0 1.0 0.0 0\n", "1 1 0 2 70.0 1.0 0.0 0\n", "2 2 1 2 40.0 1.0 0.0 1\n", "3 3 1 1 30.0 1.0 0.0 1\n", "4 4 2 1 70.0 1.0 0.0 0\n", "5 5 2 2 30.0 1.0 0.0 1\n", "6 6 3 2 30.0 1.0 0.0 0\n", "7 7 3 1 40.0 1.0 0.0 1\n", "8 8 4 0 40.0 1.0 0.0 0\n", "9 9 4 2 30.0 1.0 0.0 1\n", " a b c\n", "2020-01-01 0.0 30.0 70.0\n", "2020-01-02 0.0 -30.0 -40.0\n", "2020-01-03 0.0 70.0 -30.0\n", "2020-01-04 0.0 -40.0 30.0\n", "2020-01-05 40.0 0.0 -30.0\n", " a b c\n", "2020-01-01 0.0 30.0 70.0\n", "2020-01-02 0.0 0.0 30.0\n", "2020-01-03 0.0 70.0 0.0\n", "2020-01-04 0.0 30.0 30.0\n", "2020-01-05 40.0 30.0 0.0\n", " a b c\n", "2020-01-01 1 2 0\n", "2020-01-02 0 2 1\n", "2020-01-03 1 0 2\n", "2020-01-04 0 2 1\n", "2020-01-05 1 0 2\n" ] } ], "source": [ "portfolio = vbt.Portfolio.from_orders(\n", " price_one, target_hold_value, size_type=SizeType.TargetValue,\n", " group_by=np.array([0, 0, 0]), cash_sharing=True,\n", " call_seq='random', seed=43)\n", "\n", "print(portfolio.orders.records)\n", "print(portfolio.asset_flow())\n", "print(portfolio.asset_value(group_by=False)) # order fixed -> cannot rebalance properly\n", "print(portfolio.call_seq)" ] }, { "cell_type": "code", "execution_count": 76, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " id idx col size price fees side\n", "0 0 0 1 30.0 1.0 0.0 0\n", "1 1 0 2 70.0 1.0 0.0 0\n", "2 2 1 2 40.0 1.0 0.0 1\n", "3 3 1 1 30.0 1.0 0.0 1\n", "4 4 1 0 70.0 1.0 0.0 0\n", "5 5 2 0 40.0 1.0 0.0 1\n", "6 6 2 2 30.0 1.0 0.0 1\n", "7 7 2 1 70.0 1.0 0.0 0\n", "8 8 3 1 40.0 1.0 0.0 1\n", "9 9 3 0 30.0 1.0 0.0 1\n", "10 10 3 2 70.0 1.0 0.0 0\n", "11 11 4 2 70.0 1.0 0.0 1\n", "12 12 4 0 70.0 1.0 0.0 0\n", " a b c\n", "2020-01-01 0.0 30.0 70.0\n", "2020-01-02 70.0 -30.0 -40.0\n", "2020-01-03 -40.0 70.0 -30.0\n", "2020-01-04 -30.0 -40.0 70.0\n", "2020-01-05 70.0 0.0 -70.0\n", " a b c\n", "2020-01-01 0.0 30.0 70.0\n", "2020-01-02 70.0 0.0 30.0\n", "2020-01-03 30.0 70.0 0.0\n", "2020-01-04 0.0 30.0 70.0\n", "2020-01-05 70.0 30.0 0.0\n", " a b c\n", "2020-01-01 0 1 2\n", "2020-01-02 2 1 0\n", "2020-01-03 0 2 1\n", "2020-01-04 1 0 2\n", "2020-01-05 2 1 0\n" ] } ], "source": [ "portfolio = vbt.Portfolio.from_orders(\n", " price_one, target_hold_value, size_type=SizeType.TargetValue, \n", " group_by=np.array([0, 0, 0]), cash_sharing=True,\n", " call_seq='auto')\n", "\n", "print(portfolio.orders.records)\n", "print(portfolio.asset_flow())\n", "print(portfolio.asset_value(group_by=False)) # order dynamic -> can rebalance\n", "print(portfolio.call_seq)" ] }, { "cell_type": "code", "execution_count": 77, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " id idx col size price fees side\n", "0 0 0 1 30.0 1.0 0.0 0\n", "1 1 0 2 70.0 1.0 0.0 0\n", "2 2 1 2 40.0 1.0 0.0 1\n", "3 3 1 1 30.0 1.0 0.0 1\n", "4 4 1 0 70.0 1.0 0.0 0\n", "5 5 2 0 40.0 1.0 0.0 1\n", "6 6 2 2 30.0 1.0 0.0 1\n", "7 7 2 1 70.0 1.0 0.0 0\n", "8 8 3 1 40.0 1.0 0.0 1\n", "9 9 3 0 30.0 1.0 0.0 1\n", "10 10 3 2 70.0 1.0 0.0 0\n", "11 11 4 2 70.0 1.0 0.0 1\n", "12 12 4 0 70.0 1.0 0.0 0\n", " a b c\n", "2020-01-01 0.0 30.0 70.0\n", "2020-01-02 70.0 -30.0 -40.0\n", "2020-01-03 -40.0 70.0 -30.0\n", "2020-01-04 -30.0 -40.0 70.0\n", "2020-01-05 70.0 0.0 -70.0\n", " a b c\n", "2020-01-01 0.0 30.0 70.0\n", "2020-01-02 70.0 0.0 30.0\n", "2020-01-03 30.0 70.0 0.0\n", "2020-01-04 0.0 30.0 70.0\n", "2020-01-05 70.0 30.0 0.0\n", " a b c\n", "2020-01-01 0 1 2\n", "2020-01-02 2 1 0\n", "2020-01-03 0 2 1\n", "2020-01-04 1 0 2\n", "2020-01-05 2 1 0\n" ] } ], "source": [ "portfolio = vbt.Portfolio.from_orders(\n", " price_one, target_hold_value / 100., size_type=SizeType.TargetPercent, \n", " group_by=np.array([0, 0, 0]), cash_sharing=True,\n", " call_seq='auto')\n", "\n", "print(portfolio.orders.records)\n", "print(portfolio.asset_flow())\n", "print(portfolio.asset_value(group_by=False))\n", "print(portfolio.call_seq)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## from_signals" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(5,) (5, 3)\n", "(5,) (5, 3)\n", "(1000,) (1000, 1000)\n", "(1000,) (1000, 1000)\n" ] } ], "source": [ "entries = pd.Series([True, True, True, False, False], index=price.index)\n", "entries_wide = entries.vbt.tile(3, keys=['a', 'b', 'c'])\n", "print(entries.shape, entries_wide.shape)\n", "\n", "exits = pd.Series([False, False, True, True, True], index=price.index)\n", "exits_wide = exits.vbt.tile(3, keys=['a', 'b', 'c'])\n", "print(exits.shape, exits_wide.shape)\n", "\n", "big_entries = pd.DataFrame.vbt.signals.empty((1000,), index=big_price.index)\n", "big_entries.iloc[0::2] = True\n", "big_entries_wide = big_entries.vbt.tile(1000)\n", "print(big_entries.shape, big_entries_wide.shape)\n", "\n", "big_exits = pd.DataFrame.vbt.signals.empty((1000,), index=big_price.index)\n", "big_exits.iloc[1::2] = True\n", "big_exits_wide = big_exits.vbt.tile(1000)\n", "print(big_exits.shape, big_exits_wide.shape)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2.72 ms ± 238 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" ] } ], "source": [ "%timeit vbt.Portfolio.from_signals(\\\n", " big_price, big_entries, big_exits,\\\n", " size=1., init_cash=np.inf, accumulate=True)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "95.1 ms ± 2.6 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" ] } ], "source": [ "%timeit vbt.Portfolio.from_signals(\\\n", " big_price_wide, big_entries_wide, big_exits_wide,\\\n", " size=1., init_cash=np.inf, accumulate=True)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "104 ms ± 1.87 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" ] } ], "source": [ "%timeit vbt.Portfolio.from_signals(\\\n", " big_price_wide, big_entries_wide, big_exits_wide,\\\n", " size=1., init_cash=np.inf, sl_stop=np.inf, tp_stop=np.inf, accumulate=True)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "171 ms ± 6.43 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" ] } ], "source": [ "%timeit vbt.Portfolio.from_signals(\\\n", " big_price_wide, big_entries_wide, big_exits_wide,\\\n", " size=1., init_cash=np.inf, accumulate=True, log=True)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "98.4 ms ± 250 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" ] } ], "source": [ "%timeit vbt.Portfolio.from_signals(\\\n", " big_price_wide, big_entries_wide, big_exits_wide,\\\n", " size=1., init_cash=np.inf, accumulate=True,\\\n", " group_by=np.repeat(np.arange(500), 2))" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "100 ms ± 564 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" ] } ], "source": [ "%timeit vbt.Portfolio.from_signals(\\\n", " big_price_wide, big_entries_wide, big_exits_wide,\\\n", " size=1., init_cash=np.inf, accumulate=True,\\\n", " group_by=np.repeat(np.arange(500), 2), cash_sharing=True)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "101 ms ± 191 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" ] } ], "source": [ "# worst case\n", "%timeit vbt.Portfolio.from_signals(\\\n", " big_price_wide, big_entries_wide, big_exits_wide,\\\n", " size=np.arange(1000)[::-1], init_cash=np.inf, accumulate=True,\\\n", " group_by=np.repeat(np.arange(500), 2), cash_sharing=True, call_seq=CallSeqType.Auto)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "98.6 ms ± 848 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" ] } ], "source": [ "%timeit vbt.Portfolio.from_signals(\\\n", " big_price_wide, big_entries_wide, big_exits_wide,\\\n", " size=1., init_cash=np.inf, accumulate=True,\\\n", " group_by=np.full(1000, 0))" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "96 ms ± 501 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" ] } ], "source": [ "%timeit vbt.Portfolio.from_signals(\\\n", " big_price_wide, big_entries_wide, big_exits_wide,\\\n", " size=1., init_cash=np.inf, accumulate=True,\\\n", " group_by=np.full(1000, 0), cash_sharing=True)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "279 ms ± 1.83 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" ] } ], "source": [ "# worst case\n", "%timeit vbt.Portfolio.from_signals(\\\n", " big_price_wide, big_entries_wide, big_exits_wide,\\\n", " size=np.arange(1000)[::-1], init_cash=np.inf, accumulate=True,\\\n", " group_by=np.full(1000, 0), cash_sharing=True, call_seq=CallSeqType.Auto)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "def test_per_direction(price=price, entries=entries, exits=exits, **kwargs):\n", " print('Both')\n", " try:\n", " portfolio = vbt.Portfolio.from_signals(price, entries, exits, direction='both', **kwargs)\n", " print(portfolio.orders.records)\n", " except Exception as e:\n", " print(e)\n", " print('LongOnly')\n", " try:\n", " portfolio = vbt.Portfolio.from_signals(price, entries, exits, direction='longonly', **kwargs)\n", " print(portfolio.orders.records)\n", " except Exception as e:\n", " print(e)\n", " print('ShortOnly')\n", " try:\n", " portfolio = vbt.Portfolio.from_signals(price, entries, exits, direction='shortonly', **kwargs)\n", " print(portfolio.orders.records)\n", " except Exception as e:\n", " print(e)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Both\n", " id col idx size price fees side\n", "0 0 0 0 100.0 1.0 0.0 0\n", "1 1 0 3 200.0 4.0 0.0 1\n", "LongOnly\n", " id col idx size price fees side\n", "0 0 0 0 100.0 1.0 0.0 0\n", "1 1 0 3 100.0 4.0 0.0 1\n", "ShortOnly\n", " id col idx size price fees side\n", "0 0 0 0 100.0 1.0 0.0 1\n", "1 1 0 3 50.0 4.0 0.0 0\n" ] } ], "source": [ "test_per_direction()" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Both\n", " id col idx size price fees side\n", "0 0 1 0 1.0 1.0 0.0 0\n", "1 1 1 3 2.0 4.0 0.0 1\n", "2 2 2 0 100.0 1.0 0.0 0\n", "3 3 2 3 200.0 4.0 0.0 1\n", "LongOnly\n", " id col idx size price fees side\n", "0 0 1 0 1.0 1.0 0.0 0\n", "1 1 1 3 1.0 4.0 0.0 1\n", "2 2 2 0 100.0 1.0 0.0 0\n", "3 3 2 3 100.0 4.0 0.0 1\n", "ShortOnly\n", " id col idx size price fees side\n", "0 0 1 0 1.0 1.0 0.0 1\n", "1 1 1 3 1.0 4.0 0.0 0\n", "2 2 2 0 100.0 1.0 0.0 1\n", "3 3 2 3 50.0 4.0 0.0 0\n" ] } ], "source": [ "test_per_direction(size=[[0, 1, np.inf]])" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Both\n", "SizeType.Percent does not support position reversal using signals\n", "LongOnly\n", " id col idx size price fees side\n", "0 0 0 0 50.0 1.0 0.0 0\n", "1 1 0 3 50.0 4.0 0.0 1\n", "ShortOnly\n", " id col idx size price fees side\n", "0 0 0 0 50.0 1.0 0.0 1\n", "1 1 0 3 37.5 4.0 0.0 0\n" ] } ], "source": [ "test_per_direction(size=0.5, size_type='percent')" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Both\n", " id col idx size price fees side\n", "0 0 0 0 50.000 1.0 0.0 0\n", "1 1 0 1 12.500 2.0 0.0 0\n", "2 2 0 3 65.625 4.0 0.0 1\n", "3 3 0 4 26.250 5.0 0.0 1\n", "LongOnly\n", " id col idx size price fees side\n", "0 0 0 0 50.000 1.0 0.0 0\n", "1 1 0 1 12.500 2.0 0.0 0\n", "2 2 0 3 31.250 4.0 0.0 1\n", "3 3 0 4 15.625 5.0 0.0 1\n", "ShortOnly\n", " id col idx size price fees side\n", "0 0 0 0 50.000 1.0 0.0 1\n", "1 1 0 1 12.500 2.0 0.0 1\n", "2 2 0 3 21.875 4.0 0.0 0\n", "3 3 0 4 8.750 5.0 0.0 0\n" ] } ], "source": [ "test_per_direction(size=0.5, size_type='percent', accumulate=True)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Both\n", " id col idx size price fees side\n", "0 0 0 0 99.009901 1.01 0.0 0\n", "1 1 0 3 198.019802 4.04 0.0 1\n", "LongOnly\n", " id col idx size price fees side\n", "0 0 0 0 99.009901 1.01 0.0 0\n", "1 1 0 3 99.009901 4.04 0.0 1\n", "ShortOnly\n", " id col idx size price fees side\n", "0 0 0 0 99.009901 1.01 0.0 1\n", "1 1 0 3 49.504950 4.04 0.0 0\n" ] } ], "source": [ "test_per_direction(price=price * 1.01)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Both\n", " id col idx size price fees side\n", "0 0 0 0 1.0 1.0 0.0 0\n", "1 1 0 3 2.0 4.0 0.0 1\n", "2 2 1 0 1.0 1.0 0.1 0\n", "3 3 1 3 2.0 4.0 0.8 1\n", "4 4 2 0 1.0 1.0 1.0 0\n", "5 5 2 3 2.0 4.0 8.0 1\n", "LongOnly\n", " id col idx size price fees side\n", "0 0 0 0 1.0 1.0 0.0 0\n", "1 1 0 3 1.0 4.0 0.0 1\n", "2 2 1 0 1.0 1.0 0.1 0\n", "3 3 1 3 1.0 4.0 0.4 1\n", "4 4 2 0 1.0 1.0 1.0 0\n", "5 5 2 3 1.0 4.0 4.0 1\n", "ShortOnly\n", " id col idx size price fees side\n", "0 0 0 0 1.0 1.0 0.0 1\n", "1 1 0 3 1.0 4.0 0.0 0\n", "2 2 1 0 1.0 1.0 0.1 1\n", "3 3 1 3 1.0 4.0 0.4 0\n", "4 4 2 0 1.0 1.0 1.0 1\n", "5 5 2 3 1.0 4.0 4.0 0\n" ] } ], "source": [ "test_per_direction(size=1, fees=[[0., 0.1, 1.]])" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Both\n", " id col idx size price fees side\n", "0 0 0 0 1.0 1.0 0.0 0\n", "1 1 0 3 2.0 4.0 0.0 1\n", "2 2 1 0 1.0 1.0 0.1 0\n", "3 3 1 3 2.0 4.0 0.1 1\n", "4 4 2 0 1.0 1.0 1.0 0\n", "5 5 2 3 2.0 4.0 1.0 1\n", "LongOnly\n", " id col idx size price fees side\n", "0 0 0 0 1.0 1.0 0.0 0\n", "1 1 0 3 1.0 4.0 0.0 1\n", "2 2 1 0 1.0 1.0 0.1 0\n", "3 3 1 3 1.0 4.0 0.1 1\n", "4 4 2 0 1.0 1.0 1.0 0\n", "5 5 2 3 1.0 4.0 1.0 1\n", "ShortOnly\n", " id col idx size price fees side\n", "0 0 0 0 1.0 1.0 0.0 1\n", "1 1 0 3 1.0 4.0 0.0 0\n", "2 2 1 0 1.0 1.0 0.1 1\n", "3 3 1 3 1.0 4.0 0.1 0\n", "4 4 2 0 1.0 1.0 1.0 1\n", "5 5 2 3 1.0 4.0 1.0 0\n" ] } ], "source": [ "test_per_direction(size=1, fixed_fees=[[0., 0.1, 1.]])" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Both\n", " id col idx size price fees side\n", "0 0 0 0 1.0 1.0 0.0 0\n", "1 1 0 3 2.0 4.0 0.0 1\n", "2 2 1 0 1.0 1.1 0.0 0\n", "3 3 1 3 2.0 3.6 0.0 1\n", "4 4 2 0 1.0 2.0 0.0 0\n", "5 5 2 3 2.0 0.0 0.0 1\n", "LongOnly\n", " id col idx size price fees side\n", "0 0 0 0 1.0 1.0 0.0 0\n", "1 1 0 3 1.0 4.0 0.0 1\n", "2 2 1 0 1.0 1.1 0.0 0\n", "3 3 1 3 1.0 3.6 0.0 1\n", "4 4 2 0 1.0 2.0 0.0 0\n", "5 5 2 3 1.0 0.0 0.0 1\n", "ShortOnly\n", " id col idx size price fees side\n", "0 0 0 0 1.0 1.0 0.0 1\n", "1 1 0 3 1.0 4.0 0.0 0\n", "2 2 1 0 1.0 0.9 0.0 1\n", "3 3 1 3 1.0 4.4 0.0 0\n", "4 4 2 0 1.0 0.0 0.0 1\n", "5 5 2 3 1.0 8.0 0.0 0\n" ] } ], "source": [ "test_per_direction(size=1, slippage=[[0., 0.1, 1.]])" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Both\n", " id col idx size price fees side\n", "0 0 0 0 1.0 1.0 0.0 0\n", "1 1 0 3 2.0 4.0 0.0 1\n", "2 2 1 0 1.0 1.0 0.0 0\n", "3 3 1 3 2.0 4.0 0.0 1\n", "LongOnly\n", " id col idx size price fees side\n", "0 0 0 0 1.0 1.0 0.0 0\n", "1 1 0 3 1.0 4.0 0.0 1\n", "2 2 1 0 1.0 1.0 0.0 0\n", "3 3 1 3 1.0 4.0 0.0 1\n", "ShortOnly\n", " id col idx size price fees side\n", "0 0 0 0 1.0 1.0 0.0 1\n", "1 1 0 3 1.0 4.0 0.0 0\n", "2 2 1 0 1.0 1.0 0.0 1\n", "3 3 1 3 1.0 4.0 0.0 0\n" ] } ], "source": [ "test_per_direction(size=1, min_size=[[0., 1., 2.]])" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Both\n", " id col idx size price fees side\n", "0 0 0 0 0.5 1.0 0.0 0\n", "1 1 0 3 0.5 4.0 0.0 1\n", "2 2 0 4 0.5 5.0 0.0 1\n", "3 3 1 0 1.0 1.0 0.0 0\n", "4 4 1 3 1.0 4.0 0.0 1\n", "5 5 1 4 1.0 5.0 0.0 1\n", "6 6 2 0 1.0 1.0 0.0 0\n", "7 7 2 3 2.0 4.0 0.0 1\n", "LongOnly\n", " id col idx size price fees side\n", "0 0 0 0 0.5 1.0 0.0 0\n", "1 1 0 3 0.5 4.0 0.0 1\n", "2 2 1 0 1.0 1.0 0.0 0\n", "3 3 1 3 1.0 4.0 0.0 1\n", "4 4 2 0 1.0 1.0 0.0 0\n", "5 5 2 3 1.0 4.0 0.0 1\n", "ShortOnly\n", " id col idx size price fees side\n", "0 0 0 0 0.5 1.0 0.0 1\n", "1 1 0 3 0.5 4.0 0.0 0\n", "2 2 1 0 1.0 1.0 0.0 1\n", "3 3 1 3 1.0 4.0 0.0 0\n", "4 4 2 0 1.0 1.0 0.0 1\n", "5 5 2 3 1.0 4.0 0.0 0\n" ] } ], "source": [ "test_per_direction(size=1, max_size=[[0.5, 1., np.inf]])" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Both\n", " id col idx size price fees side\n", "0 0 0 0 1.0 1.0 0.0 0\n", "1 1 0 3 2.0 4.0 0.0 1\n", "2 2 1 1 1.0 2.0 0.0 0\n", "3 3 1 3 2.0 4.0 0.0 1\n", "LongOnly\n", " id col idx size price fees side\n", "0 0 0 0 1.0 1.0 0.0 0\n", "1 1 0 3 1.0 4.0 0.0 1\n", "2 2 1 1 1.0 2.0 0.0 0\n", "3 3 1 3 1.0 4.0 0.0 1\n", "ShortOnly\n", " id col idx size price fees side\n", "0 0 0 0 1.0 1.0 0.0 1\n", "1 1 0 3 1.0 4.0 0.0 0\n", "2 2 1 1 1.0 2.0 0.0 1\n", "3 3 1 3 1.0 4.0 0.0 0\n" ] } ], "source": [ "test_per_direction(size=1., reject_prob=[[0., 0.5, 1.]], seed=42)" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " id col idx size price fees side\n", "0 0 0 0 100.0 1.0 0.0 0\n", "1 1 0 3 200.0 4.0 0.0 1\n", "2 2 1 0 100.0 1.0 0.0 0\n", "3 3 1 3 100.0 4.0 0.0 1\n", "4 4 1 4 80.0 5.0 0.0 1\n", " id col idx size price fees side\n", "0 0 0 0 20.0 5.0 0.0 1\n", "1 1 0 3 100.0 2.0 0.0 0\n", "2 2 1 0 20.0 5.0 0.0 1\n", "3 3 1 3 20.0 2.0 0.0 0\n", "4 4 1 4 160.0 1.0 0.0 0\n" ] } ], "source": [ "portfolio = vbt.Portfolio.from_signals(\n", " price, entries, exits, direction='both',\n", " upon_opposite_entry=[['reverse', 'close']]\n", ")\n", "print(portfolio.orders.records)\n", "\n", "portfolio = vbt.Portfolio.from_signals(\n", " pd.Series(price.values[::-1], index=price.index),\n", " pd.Series(entries.values[::-1], index=price.index),\n", " pd.Series(exits.values[::-1], index=price.index), \n", " direction='both',\n", " upon_opposite_entry=[['reverse', 'close']]\n", ")\n", "print(portfolio.orders.records)" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Both\n", " id col idx size price fees side\n", "0 0 0 0 100.0 1.0 0.0 0\n", "1 1 0 3 1100.0 4.0 0.0 1\n", "2 2 1 3 1000.0 4.0 0.0 1\n", "LongOnly\n", " id col idx size price fees side\n", "0 0 0 0 100.0 1.0 0.0 0\n", "1 1 0 3 100.0 4.0 0.0 1\n", "ShortOnly\n", " id col idx size price fees side\n", "0 0 0 0 1000.0 1.0 0.0 1\n", "1 1 0 3 275.0 4.0 0.0 0\n", "2 2 1 0 1000.0 1.0 0.0 1\n", "Both\n", " id col idx size price fees side\n", "0 0 0 0 100.0 1.0 0.0 0\n", "1 1 0 3 200.0 4.0 0.0 1\n", "2 2 1 0 100.0 1.0 0.0 0\n", "3 3 1 3 200.0 4.0 0.0 1\n", "LongOnly\n", " id col idx size price fees side\n", "0 0 0 0 100.0 1.0 0.0 0\n", "1 1 0 3 100.0 4.0 0.0 1\n", "2 2 1 0 100.0 1.0 0.0 0\n", "3 3 1 3 100.0 4.0 0.0 1\n", "ShortOnly\n", " id col idx size price fees side\n", "0 0 0 0 100.0 1.0 0.0 1\n", "1 1 0 3 50.0 4.0 0.0 0\n", "2 2 1 0 100.0 1.0 0.0 1\n" ] } ], "source": [ "test_per_direction(size=1000, allow_partial=[[True, False]])\n", "test_per_direction(size=np.inf, allow_partial=[[True, False]])" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Both\n", " id col idx size price fees side\n", "0 0 0 0 100.0 1.0 0.0 0\n", "1 1 0 3 1100.0 4.0 0.0 1\n", "LongOnly\n", " id col idx size price fees side\n", "0 0 0 0 100.0 1.0 0.0 0\n", "1 1 0 3 100.0 4.0 0.0 1\n", "ShortOnly\n", "Not enough cash to cover fees\n", "Both\n", "Final size is less than requested\n", "LongOnly\n", "Final size is less than requested\n", "ShortOnly\n", "Final size is less than requested\n" ] } ], "source": [ "test_per_direction(size=1000, allow_partial=True, raise_reject=True)\n", "test_per_direction(size=1000, allow_partial=False, raise_reject=True)" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Both\n", " id col idx size price fees side\n", "0 0 0 0 1.0 1.0 0.0 0\n", "1 1 0 1 1.0 2.0 0.0 0\n", "2 2 0 3 1.0 4.0 0.0 1\n", "3 3 0 4 1.0 5.0 0.0 1\n", "LongOnly\n", " id col idx size price fees side\n", "0 0 0 0 1.0 1.0 0.0 0\n", "1 1 0 1 1.0 2.0 0.0 0\n", "2 2 0 3 1.0 4.0 0.0 1\n", "3 3 0 4 1.0 5.0 0.0 1\n", "ShortOnly\n", " id col idx size price fees side\n", "0 0 0 0 1.0 1.0 0.0 1\n", "1 1 0 1 1.0 2.0 0.0 1\n", "2 2 0 3 1.0 4.0 0.0 0\n", "3 3 0 4 1.0 5.0 0.0 0\n" ] } ], "source": [ "test_per_direction(size=1, accumulate=True)" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " id col idx size price fees side\n", "0 0 0 0 100.0 1.0 0.0 0\n", "1 1 0 3 200.0 4.0 0.0 1\n", " id group col idx cash position debt free_cash val_price value \\\n", "0 0 0 0 0 100.0 0.0 0.0 100.0 1.0 100.0 \n", "1 1 0 0 3 0.0 100.0 0.0 0.0 4.0 400.0 \n", "\n", " ... new_free_cash new_val_price new_value res_size res_price \\\n", "0 ... 0.0 1.0 100.0 100.0 1.0 \n", "1 ... 0.0 4.0 400.0 200.0 4.0 \n", "\n", " res_fees res_side res_status res_status_info order_id \n", "0 0.0 0 0 -1 0 \n", "1 0.0 1 0 -1 1 \n", "\n", "[2 rows x 37 columns]\n" ] } ], "source": [ "portfolio = vbt.Portfolio.from_signals(price, entries, exits, log=True, direction='both')\n", "print(portfolio.orders.records)\n", "print(portfolio.logs.records)" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Both\n", " id col idx size price fees side\n", "0 0 0 1 1.0 2.0 0.0 0\n", "1 1 1 1 1.0 2.0 0.0 0\n", "2 2 2 1 1.0 2.0 0.0 0\n", "3 3 3 1 1.0 2.0 0.0 0\n", "4 4 4 1 1.0 2.0 0.0 1\n", "LongOnly\n", " id col idx size price fees side\n", "0 0 0 1 1.0 2.0 0.0 0\n", "1 1 1 0 1.0 1.0 0.0 0\n", "2 2 2 1 1.0 2.0 0.0 0\n", "3 3 2 2 1.0 3.0 0.0 1\n", "4 4 3 1 1.0 2.0 0.0 0\n", "5 5 3 2 1.0 3.0 0.0 1\n", "ShortOnly\n", " id col idx size price fees side\n", "0 0 0 1 1.0 2.0 0.0 1\n", "1 1 1 0 1.0 1.0 0.0 1\n", "2 2 2 1 1.0 2.0 0.0 1\n", "3 3 2 2 1.0 3.0 0.0 0\n", "4 4 3 1 1.0 2.0 0.0 1\n", "5 5 3 2 1.0 3.0 0.0 0\n" ] } ], "source": [ "test_per_direction(price=price.iloc[:3], entries=pd.DataFrame([\n", " [True, True, True, True, True],\n", " [True, True, True, True, False],\n", " [True, True, True, True, True]\n", "]), exits=pd.DataFrame([\n", " [True, True, True, True, True],\n", " [False, False, False, False, True],\n", " [True, True, True, True, True]\n", "]), size=1., upon_long_conflict=[[\n", " 'ignore', \n", " 'entry', \n", " 'exit', \n", " 'opposite',\n", " 'opposite'\n", "]], upon_short_conflict=[[\n", " 'ignore', \n", " 'entry', \n", " 'exit', \n", " 'opposite',\n", " 'opposite'\n", "]])" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Both\n", " id col idx size price fees side\n", "0 0 0 1 1.0 2.0 0.0 0\n", "1 1 1 0 1.0 1.0 0.0 0\n", "2 2 2 0 1.0 1.0 0.0 1\n", "3 3 2 1 2.0 2.0 0.0 0\n", "4 4 2 2 2.0 3.0 0.0 1\n", "5 5 3 1 1.0 2.0 0.0 0\n", "6 6 3 2 2.0 3.0 0.0 1\n", "7 7 4 1 1.0 2.0 0.0 1\n", "8 8 4 2 2.0 3.0 0.0 0\n", "LongOnly\n", " id col idx size price fees side\n", "0 0 0 1 1.0 2.0 0.0 0\n", "1 1 1 1 1.0 2.0 0.0 0\n", "2 2 2 1 1.0 2.0 0.0 0\n", "3 3 3 1 1.0 2.0 0.0 0\n", "ShortOnly\n", " id col idx size price fees side\n", "0 0 0 1 1.0 2.0 0.0 1\n", "1 1 1 1 1.0 2.0 0.0 1\n", "2 2 2 1 1.0 2.0 0.0 1\n", "3 3 3 1 1.0 2.0 0.0 1\n" ] } ], "source": [ "test_per_direction(price=price.iloc[:3], entries=pd.DataFrame([\n", " [True, True, True, True, True],\n", " [True, True, True, True, False],\n", " [True, True, True, True, True]\n", "]), exits=pd.DataFrame([\n", " [True, True, True, True, True],\n", " [False, False, False, False, True],\n", " [True, True, True, True, True]\n", "]), size=1., upon_dir_conflict=[[\n", " 'ignore', \n", " 'long', \n", " 'short', \n", " 'opposite',\n", " 'opposite'\n", "]])" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Both\n", " id col idx size price fees side\n", "0 0 0 3 1.0 4.0 0.0 1\n", "1 1 1 0 1.0 1.0 0.0 0\n", "2 2 1 3 2.0 4.0 0.0 1\n", "3 3 2 0 1.0 1.0 0.0 0\n", "4 4 2 3 2.0 4.0 0.0 1\n", "LongOnly\n", " id col idx size price fees side\n", "0 0 1 0 1.0 1.0 0.0 0\n", "1 1 1 3 1.0 4.0 0.0 1\n", "2 2 2 0 1.0 1.0 0.0 0\n", "3 3 2 3 1.0 4.0 0.0 1\n", "ShortOnly\n", " id col idx size price fees side\n", "0 0 0 0 1.00 1.0 0.0 1\n", "1 1 0 3 0.25 4.0 0.0 0\n", "2 2 1 0 1.00 1.0 0.0 1\n", "3 3 1 3 0.50 4.0 0.0 0\n", "4 4 2 0 1.00 1.0 0.0 1\n", "5 5 2 3 1.00 4.0 0.0 0\n", "Both\n", "Attempt to go in long direction infinitely\n", "LongOnly\n", "Attempt to go in long direction infinitely\n", "ShortOnly\n", "Attempt to go in short direction infinitely\n" ] } ], "source": [ "test_per_direction(price=price_wide, size=1., init_cash=[0., 1., 100.])\n", "test_per_direction(init_cash=np.inf)" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " id col idx size price fees side\n", "0 0 0 0 100.0 1.0 0.0 0\n", "1 1 0 3 200.0 4.0 0.0 1\n", "2 2 1 0 100.0 1.0 0.0 0\n", "3 3 1 3 200.0 4.0 0.0 1\n", "4 4 2 0 100.0 1.0 0.0 0\n", "5 5 2 3 200.0 4.0 0.0 1\n" ] } ], "source": [ "portfolio = vbt.Portfolio.from_signals(\n", " price_wide, entries, exits, \n", " group_by=np.array([0, 0, 1]), direction='both')\n", "\n", "print(portfolio.orders.records)" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " id col idx size price fees side\n", "0 0 0 0 100.0 1.0 0.0 0\n", "1 1 0 3 200.0 4.0 0.0 1\n", "2 2 2 0 100.0 1.0 0.0 0\n", "3 3 2 3 200.0 4.0 0.0 1\n", " a b c\n", "2020-01-01 0 1 0\n", "2020-01-02 0 1 0\n", "2020-01-03 0 1 0\n", "2020-01-04 0 1 0\n", "2020-01-05 0 1 0\n", "Cannot modify grouping globally when cash_sharing=True\n" ] } ], "source": [ "portfolio = vbt.Portfolio.from_signals(\n", " price_wide, entries, exits, \n", " group_by=np.array([0, 0, 1]), cash_sharing=True, direction='both')\n", "\n", "print(portfolio.orders.records)\n", "print(portfolio.call_seq)\n", "try:\n", " print(portfolio.regroup(group_by=False))\n", "except Exception as e:\n", " print(e)" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " id col idx size price fees side\n", "0 0 1 0 100.0 1.0 0.0 0\n", "1 1 1 3 200.0 4.0 0.0 1\n", "2 2 2 0 100.0 1.0 0.0 0\n", "3 3 2 3 200.0 4.0 0.0 1\n", " a b c\n", "2020-01-01 1 0 0\n", "2020-01-02 1 0 0\n", "2020-01-03 1 0 0\n", "2020-01-04 1 0 0\n", "2020-01-05 1 0 0\n" ] } ], "source": [ "portfolio = vbt.Portfolio.from_signals(\n", " price_wide, entries, exits, \n", " group_by=np.array([0, 0, 1]), cash_sharing=True, direction='both', call_seq='reversed')\n", "\n", "print(portfolio.orders.records)\n", "print(portfolio.call_seq)" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " id col idx size price fees side\n", "0 0 1 0 100.0 1.0 0.0 0\n", "1 1 1 3 200.0 4.0 0.0 1\n", "2 2 2 0 100.0 1.0 0.0 0\n", "3 3 2 3 200.0 4.0 0.0 1\n", " a b c\n", "2020-01-01 1 0 0\n", "2020-01-02 1 0 0\n", "2020-01-03 1 0 0\n", "2020-01-04 1 0 0\n", "2020-01-05 0 1 0\n", " id col idx size price fees side\n", "0 0 1 0 100.0 1.0 0.0 0\n", "1 1 1 3 200.0 4.0 0.0 1\n", "2 2 2 0 100.0 1.0 0.0 0\n", "3 3 2 3 200.0 4.0 0.0 1\n", " a b c\n", "2020-01-01 1 0 0\n", "2020-01-02 0 1 0\n", "2020-01-03 1 0 0\n", "2020-01-04 1 0 0\n", "2020-01-05 1 0 0\n" ] } ], "source": [ "portfolio = vbt.Portfolio.from_signals(\n", " price_wide, entries, exits, \n", " group_by=np.array([0, 0, 1]), cash_sharing=True, direction='both', call_seq='random')\n", "\n", "print(portfolio.orders.records)\n", "print(portfolio.call_seq)\n", "\n", "portfolio = vbt.Portfolio.from_signals(\n", " price_wide, entries, exits, \n", " group_by=np.array([0, 0, 1]), cash_sharing=True, direction='both', call_seq='random', seed=42)\n", "\n", "print(portfolio.orders.records)\n", "print(portfolio.call_seq)" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Both\n", " id col idx size price fees side\n", "0 0 2 0 100.0 1.0 0.0 0\n", "1 1 2 1 200.0 1.0 0.0 1\n", "2 2 1 1 200.0 1.0 0.0 0\n", "3 3 1 2 200.0 1.0 0.0 1\n", "4 4 0 2 200.0 1.0 0.0 0\n", "5 5 0 3 200.0 1.0 0.0 1\n", "6 6 2 3 200.0 1.0 0.0 0\n", "7 7 2 4 200.0 1.0 0.0 1\n", "8 8 1 4 200.0 1.0 0.0 0\n", " 0 1 2\n", "0 0 1 2\n", "1 2 0 1\n", "2 1 2 0\n", "3 0 1 2\n", "4 2 0 1\n", " 0 1 2\n", "0 0.0 0.0 100.0\n", "1 0.0 200.0 -100.0\n", "2 200.0 0.0 -100.0\n", "3 0.0 0.0 100.0\n", "4 0.0 200.0 -100.0\n", "0 100.0\n", "1 100.0\n", "2 100.0\n", "3 100.0\n", "4 100.0\n", "dtype: float64\n", "LongOnly\n", " id col idx size price fees side\n", "0 0 2 0 100.0 1.0 0.0 0\n", "1 1 2 1 100.0 1.0 0.0 1\n", "2 2 1 1 100.0 1.0 0.0 0\n", "3 3 1 2 100.0 1.0 0.0 1\n", "4 4 0 2 100.0 1.0 0.0 0\n", "5 5 0 3 100.0 1.0 0.0 1\n", "6 6 2 3 100.0 1.0 0.0 0\n", "7 7 2 4 100.0 1.0 0.0 1\n", "8 8 1 4 100.0 1.0 0.0 0\n", " 0 1 2\n", "0 0 1 2\n", "1 2 0 1\n", "2 1 2 0\n", "3 0 1 2\n", "4 2 0 1\n", " 0 1 2\n", "0 0.0 0.0 100.0\n", "1 0.0 100.0 0.0\n", "2 100.0 0.0 0.0\n", "3 0.0 0.0 100.0\n", "4 0.0 100.0 0.0\n", "0 100.0\n", "1 100.0\n", "2 100.0\n", "3 100.0\n", "4 100.0\n", "dtype: float64\n", "ShortOnly\n", " id col idx size price fees side\n", "0 0 2 0 100.0 1.0 0.0 1\n", "1 1 2 1 100.0 1.0 0.0 0\n", "2 2 0 2 100.0 1.0 0.0 1\n", "3 3 0 3 100.0 1.0 0.0 0\n", "4 4 1 4 100.0 1.0 0.0 1\n", " 0 1 2\n", "0 2 0 1\n", "1 1 0 2\n", "2 0 1 2\n", "3 2 1 0\n", "4 1 0 2\n", " 0 1 2\n", "0 0.0 0.0 -100.0\n", "1 0.0 0.0 0.0\n", "2 -100.0 0.0 0.0\n", "3 0.0 0.0 0.0\n", "4 0.0 -100.0 0.0\n", "0 100.0\n", "1 100.0\n", "2 100.0\n", "3 100.0\n", "4 100.0\n", "dtype: float64\n" ] } ], "source": [ "for direction in ('Both', 'LongOnly', 'ShortOnly'):\n", " print(direction)\n", " portfolio = vbt.Portfolio.from_signals(1., pd.DataFrame([\n", " [False, False, True],\n", " [False, True, False],\n", " [True, False, False],\n", " [False, False, True],\n", " [False, True, False],\n", " ]), pd.DataFrame([\n", " [False, False, False],\n", " [False, False, True],\n", " [False, True, False],\n", " [True, False, False],\n", " [False, False, True],\n", " ]), group_by=np.array([0, 0, 0]), \n", " cash_sharing=True, call_seq='auto', direction=direction)\n", "\n", " print(portfolio.orders.records)\n", " print(portfolio.call_seq)\n", " print(portfolio.assets())\n", " print(portfolio.value())\n", " # notice how shorting with np.inf only accounts for current cash, not for other assets!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## from_order_func" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "from vectorbt.portfolio.nb import order_nb, order_nothing_nb\n", "\n", "@njit\n", "def order_func_nb(c, size):\n", " return order_nb(size if c.i % 2 == 0 else -size)\n", "\n", "@njit\n", "def flex_order_func_nb(c, size):\n", " if c.call_idx < c.group_len:\n", " return c.from_col + c.call_idx, order_nb(size if c.i % 2 == 0 else -size)\n", " return -1, order_nothing_nb()" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1.92 ms ± 156 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n", "2.02 ms ± 189 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n", "1.85 ms ± 140 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n", "1.85 ms ± 145 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" ] } ], "source": [ "%timeit vbt.Portfolio.from_order_func(\\\n", " big_price, order_func_nb, 1., init_cash=np.inf)\n", "%timeit vbt.Portfolio.from_order_func(\\\n", " big_price, order_func_nb, 1., init_cash=np.inf, row_wise=True)\n", "%timeit vbt.Portfolio.from_order_func(\\\n", " big_price, flex_order_func_nb, 1., init_cash=np.inf, flexible=True)\n", "%timeit vbt.Portfolio.from_order_func(\\\n", " big_price, flex_order_func_nb, 1., init_cash=np.inf, row_wise=True, flexible=True)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "95 ms ± 181 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n", "101 ms ± 2.48 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n", "90.9 ms ± 489 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n", "89.1 ms ± 1.69 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" ] } ], "source": [ "%timeit vbt.Portfolio.from_order_func(\\\n", " big_price_wide, order_func_nb, 1., init_cash=np.inf)\n", "%timeit vbt.Portfolio.from_order_func(\\\n", " big_price_wide, order_func_nb, 1., init_cash=np.inf, row_wise=True)\n", "%timeit vbt.Portfolio.from_order_func(\\\n", " big_price_wide, flex_order_func_nb, 1., init_cash=np.inf, flexible=True)\n", "%timeit vbt.Portfolio.from_order_func(\\\n", " big_price_wide, flex_order_func_nb, 1., init_cash=np.inf, row_wise=True, flexible=True)" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "76.4 ms ± 217 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n", "84.2 ms ± 284 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n", "71.5 ms ± 1.39 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "71.1 ms ± 101 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" ] } ], "source": [ "%timeit vbt.Portfolio.from_order_func(\\\n", " big_price_wide, order_func_nb, 1., init_cash=np.inf, fill_pos_record=False)\n", "%timeit vbt.Portfolio.from_order_func(\\\n", " big_price_wide, order_func_nb, 1., init_cash=np.inf, row_wise=True, fill_pos_record=False)\n", "%timeit vbt.Portfolio.from_order_func(\\\n", " big_price_wide, flex_order_func_nb, 1., init_cash=np.inf, fill_pos_record=False, flexible=True)\n", "%timeit vbt.Portfolio.from_order_func(\\\n", " big_price_wide, flex_order_func_nb, 1., init_cash=np.inf, row_wise=True, fill_pos_record=False, flexible=True)" ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "89.1 ms ± 851 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "93.5 ms ± 692 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "86.2 ms ± 287 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "86.3 ms ± 131 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" ] } ], "source": [ "%timeit vbt.Portfolio.from_order_func(\\\n", " big_price_wide, order_func_nb, 1., \\\n", " group_by=np.repeat(np.arange(500), 2), init_cash=np.inf)\n", "%timeit vbt.Portfolio.from_order_func(\\\n", " big_price_wide, order_func_nb, 1., \\\n", " group_by=np.repeat(np.arange(500), 2), init_cash=np.inf, row_wise=True)\n", "%timeit vbt.Portfolio.from_order_func(\\\n", " big_price_wide, flex_order_func_nb, 1., \\\n", " group_by=np.repeat(np.arange(500), 2), init_cash=np.inf, flexible=True)\n", "%timeit vbt.Portfolio.from_order_func(\\\n", " big_price_wide, flex_order_func_nb, 1., \\\n", " group_by=np.repeat(np.arange(500), 2), init_cash=np.inf, row_wise=True, flexible=True)" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "88.7 ms ± 763 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "93 ms ± 686 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "85.4 ms ± 39.1 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "85.7 ms ± 140 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" ] } ], "source": [ "%timeit vbt.Portfolio.from_order_func(\\\n", " big_price_wide, order_func_nb, 1., \\\n", " group_by=np.repeat(np.arange(500), 2), cash_sharing=True, init_cash=np.inf)\n", "%timeit vbt.Portfolio.from_order_func(\\\n", " big_price_wide, order_func_nb, 1., \\\n", " group_by=np.repeat(np.arange(500), 2), cash_sharing=True, init_cash=np.inf, row_wise=True)\n", "%timeit vbt.Portfolio.from_order_func(\\\n", " big_price_wide, flex_order_func_nb, 1., \\\n", " group_by=np.repeat(np.arange(500), 2), cash_sharing=True, init_cash=np.inf, flexible=True)\n", "%timeit vbt.Portfolio.from_order_func(\\\n", " big_price_wide, flex_order_func_nb, 1., \\\n", " group_by=np.repeat(np.arange(500), 2), cash_sharing=True, init_cash=np.inf, row_wise=True, flexible=True)" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "87 ms ± 487 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "86.2 ms ± 369 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "83.4 ms ± 151 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "83.3 ms ± 153 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" ] } ], "source": [ "%timeit vbt.Portfolio.from_order_func(\\\n", " big_price_wide, order_func_nb, 1., init_cash=np.inf, \\\n", " group_by=np.full(1000, 0))\n", "%timeit vbt.Portfolio.from_order_func(\\\n", " big_price_wide, order_func_nb, 1., init_cash=np.inf, \\\n", " group_by=np.full(1000, 0), row_wise=True)\n", "%timeit vbt.Portfolio.from_order_func(\\\n", " big_price_wide, flex_order_func_nb, 1., init_cash=np.inf, \\\n", " group_by=np.full(1000, 0), flexible=True)\n", "%timeit vbt.Portfolio.from_order_func(\\\n", " big_price_wide, flex_order_func_nb, 1., init_cash=np.inf, \\\n", " group_by=np.full(1000, 0), row_wise=True, flexible=True)" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "83.6 ms ± 622 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n", "82.7 ms ± 192 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n", "82.3 ms ± 927 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n", "82 ms ± 680 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" ] } ], "source": [ "%timeit vbt.Portfolio.from_order_func(\\\n", " big_price_wide, order_func_nb, 1., init_cash=np.inf, \\\n", " group_by=np.full(1000, 0), cash_sharing=True)\n", "%timeit vbt.Portfolio.from_order_func(\\\n", " big_price_wide, order_func_nb, 1., init_cash=np.inf, \\\n", " group_by=np.full(1000, 0), cash_sharing=True, row_wise=True)\n", "%timeit vbt.Portfolio.from_order_func(\\\n", " big_price_wide, flex_order_func_nb, 1., init_cash=np.inf, \\\n", " group_by=np.full(1000, 0), cash_sharing=True, flexible=True)\n", "%timeit vbt.Portfolio.from_order_func(\\\n", " big_price_wide, flex_order_func_nb, 1., init_cash=np.inf, \\\n", " group_by=np.full(1000, 0), cash_sharing=True, row_wise=True, flexible=True)" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [], "source": [ "def test_call_seq(call_seq, **kwargs):\n", " return vbt.Portfolio.from_order_func(\n", " price_wide, \n", " order_func_nb, \n", " 1.,\n", " group_by=np.array([0, 0, 0]),\n", " call_seq=call_seq, **kwargs\n", " ).call_seq\n", "\n", "def big_test_call_seq(call_seq, **kwargs):\n", " return vbt.Portfolio.from_order_func(\n", " big_price_wide, \n", " order_func_nb, \n", " 1.,\n", " group_by=np.repeat(np.arange(500), 2),\n", " call_seq=call_seq, **kwargs\n", " ).call_seq" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " a b c\n", "2020-01-01 0 1 2\n", "2020-01-02 0 1 2\n", "2020-01-03 0 1 2\n", "2020-01-04 0 1 2\n", "2020-01-05 0 1 2\n", "46.2 ms ± 838 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", " a b c\n", "2020-01-01 2 1 0\n", "2020-01-02 2 1 0\n", "2020-01-03 2 1 0\n", "2020-01-04 2 1 0\n", "2020-01-05 2 1 0\n", "46.4 ms ± 683 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", " a b c\n", "2020-01-01 0 1 2\n", "2020-01-02 2 1 0\n", "2020-01-03 1 0 2\n", "2020-01-04 2 0 1\n", "2020-01-05 2 1 0\n", "55.1 ms ± 849 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" ] } ], "source": [ "print(test_call_seq(CallSeqType.Default))\n", "%timeit big_test_call_seq(CallSeqType.Default)\n", "\n", "print(test_call_seq(CallSeqType.Reversed))\n", "%timeit big_test_call_seq(CallSeqType.Reversed)\n", "\n", "print(test_call_seq(CallSeqType.Random))\n", "%timeit big_test_call_seq(CallSeqType.Random)" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [], "source": [ "@njit\n", "def pre_segment_func1_nb(c, *args):\n", " c.call_seq_now[:] = np.arange(c.to_col - c.from_col - 1, -1, -1)\n", " return ()\n", "\n", "@njit\n", "def pre_segment_func2_nb(c, *args):\n", " c.call_seq_now[:] = np.copy(c.call_seq_now[::-1])\n", " return ()\n", "\n", "@njit\n", "def pre_segment_func3_nb(c, *args):\n", " call_seq_now = c.call_seq_now\n", " n_cols = c.to_col - c.from_col\n", " for k in range(n_cols):\n", " call_seq_now[k] = n_cols - k - 1\n", " return ()\n", "\n", "@njit\n", "def pre_segment_func4_nb(c, *args):\n", " np.random.shuffle(c.call_seq_now)\n", " return ()" ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " a b c\n", "2020-01-01 2 1 0\n", "2020-01-02 2 1 0\n", "2020-01-03 2 1 0\n", "2020-01-04 2 1 0\n", "2020-01-05 2 1 0\n", "262 ms ± 109 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n", "206 ms ± 2.16 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n", " a b c\n", "2020-01-01 2 1 0\n", "2020-01-02 2 1 0\n", "2020-01-03 2 1 0\n", "2020-01-04 2 1 0\n", "2020-01-05 2 1 0\n", "209 ms ± 1.67 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n", "211 ms ± 1.97 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n", " a b c\n", "2020-01-01 2 1 0\n", "2020-01-02 2 1 0\n", "2020-01-03 2 1 0\n", "2020-01-04 2 1 0\n", "2020-01-05 2 1 0\n", "94.2 ms ± 1.26 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "99.2 ms ± 394 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n", " a b c\n", "2020-01-01 1 2 0\n", "2020-01-02 0 1 2\n", "2020-01-03 1 0 2\n", "2020-01-04 1 0 2\n", "2020-01-05 2 1 0\n", "148 ms ± 2.78 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "148 ms ± 3.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" ] } ], "source": [ "print(test_call_seq(CallSeqType.Default, pre_segment_func_nb=pre_segment_func1_nb))\n", "%timeit big_test_call_seq(CallSeqType.Default, pre_segment_func_nb=pre_segment_func1_nb)\n", "%timeit big_test_call_seq(CallSeqType.Default, pre_segment_func_nb=pre_segment_func1_nb, row_wise=True)\n", "\n", "print(test_call_seq(CallSeqType.Default, pre_segment_func_nb=pre_segment_func2_nb))\n", "%timeit big_test_call_seq(CallSeqType.Default, pre_segment_func_nb=pre_segment_func2_nb)\n", "%timeit big_test_call_seq(CallSeqType.Default, pre_segment_func_nb=pre_segment_func2_nb, row_wise=True)\n", "\n", "print(test_call_seq(CallSeqType.Default, pre_segment_func_nb=pre_segment_func3_nb))\n", "%timeit big_test_call_seq(CallSeqType.Default, pre_segment_func_nb=pre_segment_func3_nb)\n", "%timeit big_test_call_seq(CallSeqType.Default, pre_segment_func_nb=pre_segment_func3_nb, row_wise=True)\n", "\n", "print(test_call_seq(CallSeqType.Default, pre_segment_func_nb=pre_segment_func4_nb))\n", "%timeit big_test_call_seq(CallSeqType.Default, pre_segment_func_nb=pre_segment_func4_nb) # in-place fastest\n", "%timeit big_test_call_seq(CallSeqType.Default, pre_segment_func_nb=pre_segment_func4_nb, row_wise=True)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Index([0], dtype='int64')\n", "1\n", "Index([0], dtype='int64', name='iteration_idx')\n", "2\n", "Index(['first'], dtype='object', name='custom')\n", "2\n", "Index([0, 1, 2], dtype='int64', name='iteration_idx')\n", "2\n", "Index(['first', 'second', 'third'], dtype='object', name='custom')\n", "2\n" ] } ], "source": [ "portfolio = vbt.Portfolio.from_order_func(\n", " price, order_func_nb, np.inf,\n", " target_shape=(5,))\n", "print(portfolio.wrapper.columns)\n", "print(portfolio.wrapper.ndim)\n", "\n", "portfolio = vbt.Portfolio.from_order_func(\n", " price, order_func_nb, np.inf,\n", " target_shape=(5, 1))\n", "print(portfolio.wrapper.columns)\n", "print(portfolio.wrapper.ndim)\n", "\n", "portfolio = vbt.Portfolio.from_order_func(\n", " price, order_func_nb, np.inf,\n", " target_shape=(5, 1), keys=pd.Index(['first'], name='custom'))\n", "print(portfolio.wrapper.columns)\n", "print(portfolio.wrapper.ndim)\n", "\n", "portfolio = vbt.Portfolio.from_order_func(\n", " price, order_func_nb, np.inf,\n", " target_shape=(5, 3))\n", "print(portfolio.wrapper.columns)\n", "print(portfolio.wrapper.ndim)\n", "\n", "portfolio = vbt.Portfolio.from_order_func(\n", " price, order_func_nb, np.inf,\n", " target_shape=(5, 3), keys=pd.Index(['first', 'second', 'third'], name='custom'))\n", "print(portfolio.wrapper.columns)\n", "print(portfolio.wrapper.ndim)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " id idx col size price fees side\n", "0 0 0 0 100.000000 1.0 0.0 0\n", "1 1 1 0 200.000000 2.0 0.0 1\n", "2 2 2 0 133.333333 3.0 0.0 0\n", "3 3 3 0 66.666667 4.0 0.0 1\n", "4 4 4 0 53.333333 5.0 0.0 0\n", " id idx col size price fees side\n", "0 0 0 0 100.000000 1.0 0.0 0\n", "1 1 1 0 200.000000 2.0 0.0 1\n", "2 2 2 0 133.333333 3.0 0.0 0\n", "3 3 3 0 66.666667 4.0 0.0 1\n", "4 4 4 0 53.333333 5.0 0.0 0\n" ] } ], "source": [ "portfolio = vbt.Portfolio.from_order_func(price, order_func_nb, np.inf)\n", "print(portfolio.orders.records)\n", "\n", "portfolio = vbt.Portfolio.from_order_func(price, order_func_nb, np.inf, row_wise=True)\n", "print(portfolio.orders.records)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " id idx col size price fees side\n", "0 0 0 0 100.000000 1.0 0.0 0\n", "1 1 1 0 200.000000 2.0 0.0 1\n", "2 2 2 0 133.333333 3.0 0.0 0\n", "3 3 3 0 66.666667 4.0 0.0 1\n", "4 4 4 0 53.333333 5.0 0.0 0\n", "5 5 0 1 100.000000 1.0 0.0 0\n", "6 6 1 1 200.000000 2.0 0.0 1\n", "7 7 2 1 133.333333 3.0 0.0 0\n", "8 8 3 1 66.666667 4.0 0.0 1\n", "9 9 4 1 53.333333 5.0 0.0 0\n", "10 10 0 2 100.000000 1.0 0.0 0\n", "11 11 1 2 200.000000 2.0 0.0 1\n", "12 12 2 2 133.333333 3.0 0.0 0\n", "13 13 3 2 66.666667 4.0 0.0 1\n", "14 14 4 2 53.333333 5.0 0.0 0\n", " id idx col size price fees side\n", "0 0 0 0 100.000000 1.0 0.0 0\n", "1 1 0 1 100.000000 1.0 0.0 0\n", "2 2 0 2 100.000000 1.0 0.0 0\n", "3 3 1 0 200.000000 2.0 0.0 1\n", "4 4 1 1 200.000000 2.0 0.0 1\n", "5 5 1 2 200.000000 2.0 0.0 1\n", "6 6 2 0 133.333333 3.0 0.0 0\n", "7 7 2 1 133.333333 3.0 0.0 0\n", "8 8 2 2 133.333333 3.0 0.0 0\n", "9 9 3 0 66.666667 4.0 0.0 1\n", "10 10 3 1 66.666667 4.0 0.0 1\n", "11 11 3 2 66.666667 4.0 0.0 1\n", "12 12 4 0 53.333333 5.0 0.0 0\n", "13 13 4 1 53.333333 5.0 0.0 0\n", "14 14 4 2 53.333333 5.0 0.0 0\n" ] } ], "source": [ "portfolio = vbt.Portfolio.from_order_func(price_wide, order_func_nb, np.inf)\n", "print(portfolio.orders.records)\n", "\n", "portfolio = vbt.Portfolio.from_order_func(price_wide, order_func_nb, np.inf, row_wise=True)\n", "print(portfolio.orders.records)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " id idx col size price fees side\n", "0 0 0 0 100.000000 1.0 0.0 0\n", "1 1 0 1 100.000000 1.0 0.0 0\n", "2 2 1 0 200.000000 2.0 0.0 1\n", "3 3 1 1 200.000000 2.0 0.0 1\n", "4 4 2 0 133.333333 3.0 0.0 0\n", "5 5 2 1 133.333333 3.0 0.0 0\n", "6 6 3 0 66.666667 4.0 0.0 1\n", "7 7 3 1 66.666667 4.0 0.0 1\n", "8 8 4 0 53.333333 5.0 0.0 0\n", "9 9 4 1 53.333333 5.0 0.0 0\n", "10 10 0 2 100.000000 1.0 0.0 0\n", "11 11 1 2 200.000000 2.0 0.0 1\n", "12 12 2 2 133.333333 3.0 0.0 0\n", "13 13 3 2 66.666667 4.0 0.0 1\n", "14 14 4 2 53.333333 5.0 0.0 0\n", " id idx col size price fees side\n", "0 0 0 0 100.000000 1.0 0.0 0\n", "1 1 0 1 100.000000 1.0 0.0 0\n", "2 2 0 2 100.000000 1.0 0.0 0\n", "3 3 1 0 200.000000 2.0 0.0 1\n", "4 4 1 1 200.000000 2.0 0.0 1\n", "5 5 1 2 200.000000 2.0 0.0 1\n", "6 6 2 0 133.333333 3.0 0.0 0\n", "7 7 2 1 133.333333 3.0 0.0 0\n", "8 8 2 2 133.333333 3.0 0.0 0\n", "9 9 3 0 66.666667 4.0 0.0 1\n", "10 10 3 1 66.666667 4.0 0.0 1\n", "11 11 3 2 66.666667 4.0 0.0 1\n", "12 12 4 0 53.333333 5.0 0.0 0\n", "13 13 4 1 53.333333 5.0 0.0 0\n", "14 14 4 2 53.333333 5.0 0.0 0\n" ] } ], "source": [ "portfolio = vbt.Portfolio.from_order_func(\n", " price_wide, order_func_nb, np.inf,\n", " group_by=np.array([0, 0, 1]))\n", "print(portfolio.orders.records)\n", "\n", "portfolio = vbt.Portfolio.from_order_func(\n", " price_wide, order_func_nb, np.inf,\n", " group_by=np.array([0, 0, 1]), row_wise=True)\n", "print(portfolio.orders.records)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " id idx col size price fees side\n", "0 0 0 0 100.000000 1.0 0.0 0\n", "1 1 1 0 200.000000 2.0 0.0 1\n", "2 2 2 0 133.333333 3.0 0.0 0\n", "3 3 3 0 66.666667 4.0 0.0 1\n", "4 4 4 0 53.333333 5.0 0.0 0\n", "5 5 0 2 100.000000 1.0 0.0 0\n", "6 6 1 2 200.000000 2.0 0.0 1\n", "7 7 2 2 133.333333 3.0 0.0 0\n", "8 8 3 2 66.666667 4.0 0.0 1\n", "9 9 4 2 53.333333 5.0 0.0 0\n", " id idx col size price fees side\n", "0 0 0 0 100.000000 1.0 0.0 0\n", "1 1 0 2 100.000000 1.0 0.0 0\n", "2 2 1 0 200.000000 2.0 0.0 1\n", "3 3 1 2 200.000000 2.0 0.0 1\n", "4 4 2 0 133.333333 3.0 0.0 0\n", "5 5 2 2 133.333333 3.0 0.0 0\n", "6 6 3 0 66.666667 4.0 0.0 1\n", "7 7 3 2 66.666667 4.0 0.0 1\n", "8 8 4 0 53.333333 5.0 0.0 0\n", "9 9 4 2 53.333333 5.0 0.0 0\n" ] } ], "source": [ "portfolio = vbt.Portfolio.from_order_func(\n", " price_wide, order_func_nb, np.inf,\n", " group_by=np.array([0, 0, 1]), cash_sharing=True)\n", "print(portfolio.orders.records)\n", "\n", "portfolio = vbt.Portfolio.from_order_func(\n", " price_wide, order_func_nb, np.inf,\n", " group_by=np.array([0, 0, 1]), cash_sharing=True, row_wise=True)\n", "print(portfolio.orders.records)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1.] 25.0\n", "[2.] -33.33333333333333\n", "[3.] -12.5\n", "[4.] -6.666666666666668\n", " id idx col size price fees side\n", "0 0 0 0 50.000000 2.0 0.0 0\n", "1 1 1 0 25.000000 3.0 0.0 1\n", "2 2 2 0 8.333333 4.0 0.0 1\n", "3 3 3 0 4.166667 5.0 0.0 1\n", "[1.] 25.0\n", "[2.] -33.33333333333333\n", "[3.] -12.5\n", "[4.] -6.666666666666668\n", " id idx col size price fees side\n", "0 0 0 0 50.000000 2.0 0.0 0\n", "1 1 1 0 25.000000 3.0 0.0 1\n", "2 2 2 0 8.333333 4.0 0.0 1\n", "3 3 3 0 4.166667 5.0 0.0 1\n" ] } ], "source": [ "@njit\n", "def target_val_pre_segment_func_nb(c, val_price):\n", " c.last_val_price[c.from_col:c.to_col] = val_price[c.i]\n", " return ()\n", "\n", "@njit\n", "def target_val_order_func_nb(c):\n", " print(c.last_val_price[c.from_col:c.to_col], 50. / c.close[c.i, c.col] - c.position_now)\n", " return order_nb(size=50., size_type=SizeType.TargetValue, price=c.close[c.i, c.col])\n", "\n", "portfolio = vbt.Portfolio.from_order_func(\n", " price.iloc[1:], target_val_order_func_nb, \n", " pre_segment_func_nb=target_val_pre_segment_func_nb,\n", " pre_segment_args=(price.values[:-1],) # lagged valuation price\n", ")\n", "print(portfolio.orders.records)\n", "\n", "portfolio = vbt.Portfolio.from_order_func(\n", " price.iloc[1:], target_val_order_func_nb, \n", " pre_segment_func_nb=target_val_pre_segment_func_nb,\n", " pre_segment_args=(price.values[:-1],), row_wise=True\n", ")\n", "print(portfolio.orders.records)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[2.] 25.0\n", "[3.] -8.333333333333332\n", "[4.] -4.166666666666668\n", "[5.] -2.5\n", " id idx col size price fees side\n", "0 0 0 0 25.000000 2.0 0.0 0\n", "1 1 1 0 8.333333 3.0 0.0 1\n", "2 2 2 0 4.166667 4.0 0.0 1\n", "3 3 3 0 2.500000 5.0 0.0 1\n", "[2.] 25.0\n", "[3.] -8.333333333333332\n", "[4.] -4.166666666666668\n", "[5.] -2.5\n", " id idx col size price fees side\n", "0 0 0 0 25.000000 2.0 0.0 0\n", "1 1 1 0 8.333333 3.0 0.0 1\n", "2 2 2 0 4.166667 4.0 0.0 1\n", "3 3 3 0 2.500000 5.0 0.0 1\n" ] } ], "source": [ "portfolio = vbt.Portfolio.from_order_func(\n", " price.iloc[1:], target_val_order_func_nb, \n", " pre_segment_func_nb=target_val_pre_segment_func_nb,\n", " pre_segment_args=(price.values[1:],) # current order price\n", ")\n", "print(portfolio.orders.records)\n", "\n", "portfolio = vbt.Portfolio.from_order_func(\n", " price.iloc[1:], target_val_order_func_nb, \n", " pre_segment_func_nb=target_val_pre_segment_func_nb,\n", " pre_segment_args=(price.values[1:],), row_wise=True\n", ")\n", "print(portfolio.orders.records)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1.] 25.0\n", "[2.] -33.33333333333333\n", "[3.] -6.25\n", "[4.] -7.5\n", " id idx col size price fees side\n", "0 0 0 0 50.000 2.0 0.0 0\n", "1 1 1 0 25.000 3.0 0.0 1\n", "2 2 3 0 3.125 5.0 0.0 1\n", "[1.] 25.0\n", "[2.] -33.33333333333333\n", "[3.] -6.25\n", "[4.] -7.5\n", " id idx col size price fees side\n", "0 0 0 0 50.000 2.0 0.0 0\n", "1 1 1 0 25.000 3.0 0.0 1\n", "2 2 3 0 3.125 5.0 0.0 1\n" ] } ], "source": [ "@njit\n", "def target_pct_pre_segment_func_nb(c, val_price):\n", " c.last_val_price[c.from_col:c.to_col] = val_price[c.i]\n", " return ()\n", "\n", "@njit\n", "def target_pct_order_func_nb(c):\n", " print(c.last_val_price[c.from_col:c.to_col], 0.5 * c.value_now / c.close[c.i, c.col] - c.position_now)\n", " return order_nb(size=0.5, size_type=SizeType.TargetPercent, price=c.close[c.i, c.col])\n", "\n", "portfolio = vbt.Portfolio.from_order_func(\n", " price.iloc[1:], target_pct_order_func_nb, \n", " pre_segment_func_nb=target_pct_pre_segment_func_nb,\n", " pre_segment_args=(price.values[:-1],) # lagged valuation price\n", ")\n", "print(portfolio.orders.records)\n", "\n", "portfolio = vbt.Portfolio.from_order_func(\n", " price.iloc[1:], target_pct_order_func_nb, \n", " pre_segment_func_nb=target_pct_pre_segment_func_nb,\n", " pre_segment_args=(price.values[:-1],), row_wise=True\n", ")\n", "print(portfolio.orders.records)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[2.] 25.0\n", "[3.] -4.166666666666668\n", "[4.] -2.604166666666668\n", "[5.] -1.8229166666666643\n", " id idx col size price fees side\n", "0 0 0 0 25.000000 2.0 0.0 0\n", "1 1 1 0 4.166667 3.0 0.0 1\n", "2 2 2 0 2.604167 4.0 0.0 1\n", "3 3 3 0 1.822917 5.0 0.0 1\n", "[2.] 25.0\n", "[3.] -4.166666666666668\n", "[4.] -2.604166666666668\n", "[5.] -1.8229166666666643\n", " id idx col size price fees side\n", "0 0 0 0 25.000000 2.0 0.0 0\n", "1 1 1 0 4.166667 3.0 0.0 1\n", "2 2 2 0 2.604167 4.0 0.0 1\n", "3 3 3 0 1.822917 5.0 0.0 1\n" ] } ], "source": [ "portfolio = vbt.Portfolio.from_order_func(\n", " price.iloc[1:], target_pct_order_func_nb, \n", " pre_segment_func_nb=target_pct_pre_segment_func_nb,\n", " pre_segment_args=(price.values[1:],) # current order price\n", ")\n", "print(portfolio.orders.records)\n", "\n", "portfolio = vbt.Portfolio.from_order_func(\n", " price.iloc[1:], target_pct_order_func_nb, \n", " pre_segment_func_nb=target_pct_pre_segment_func_nb,\n", " pre_segment_args=(price.values[1:],), row_wise=True\n", ")\n", "print(portfolio.orders.records)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " id idx col size price fees side\n", "0 0 0 0 1.0 1.0 0.0 0\n", "1 1 2 0 1.0 3.0 0.0 0\n", "2 2 4 0 1.0 5.0 0.0 0\n", " id idx col size price fees side\n", "0 0 0 0 1.0 1.0 0.0 0\n", "1 1 2 0 1.0 3.0 0.0 0\n", "2 2 4 0 1.0 5.0 0.0 0\n" ] } ], "source": [ "portfolio = vbt.Portfolio.from_order_func(\n", " price, order_func_nb, 1.,\n", " segment_mask=pd.Series([True, False, True, False, True]))\n", "print(portfolio.orders.records)\n", "\n", "portfolio = vbt.Portfolio.from_order_func(\n", " price, order_func_nb, 1.,\n", " segment_mask=pd.Series([True, False, True, False, True]), row_wise=True)\n", "print(portfolio.orders.records)" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "preparing simulation\n", "\tpreparing group 0\n", "\t\tpreparing segment 0 (row)\n", "\t\t\tprocessing order 0 at column 0\n", "\t\t\tprocessing order 1 at column 1\n", "\t\tpreparing segment 1 (row)\n", "\t\t\tprocessing order 0 at column 0\n", "\t\t\tprocessing order 1 at column 1\n", "\t\tpreparing segment 2 (row)\n", "\t\t\tprocessing order 0 at column 0\n", "\t\t\tprocessing order 1 at column 1\n", "\t\tpreparing segment 3 (row)\n", "\t\t\tprocessing order 0 at column 0\n", "\t\t\tprocessing order 1 at column 1\n", "\t\tpreparing segment 4 (row)\n", "\t\t\tprocessing order 0 at column 0\n", "\t\t\tprocessing order 1 at column 1\n", "\tpreparing group 1\n", "\t\tpreparing segment 0 (row)\n", "\t\t\tprocessing order 0 at column 2\n", "\t\tpreparing segment 1 (row)\n", "\t\t\tprocessing order 0 at column 2\n", "\t\tpreparing segment 2 (row)\n", "\t\t\tprocessing order 0 at column 2\n", "\t\tpreparing segment 3 (row)\n", "\t\t\tprocessing order 0 at column 2\n", "\t\tpreparing segment 4 (row)\n", "\t\t\tprocessing order 0 at column 2\n", "[1] [2] [10] [15]\n" ] } ], "source": [ "@njit\n", "def pre_sim_func_nb(c, sim_i):\n", " print('preparing simulation')\n", " sim_i[0] += 1\n", " return sim_i,\n", "\n", "@njit\n", "def group_pre_sim_func_nb(c, sim_i, group_i):\n", " print('\\tpreparing group', c.group)\n", " group_i[0] += 1\n", " return sim_i, group_i\n", "\n", "@njit\n", "def pre_segment_func_nb(c, sim_i, group_i, segment_i):\n", " print('\\t\\tpreparing segment', c.i, '(row)')\n", " segment_i[0] += 1\n", " return sim_i, group_i, segment_i\n", "\n", "@njit\n", "def order_func_nb(c, sim_i, group_i, segment_i, order_i):\n", " print('\\t\\t\\tprocessing order', c.call_idx, 'at column', c.col)\n", " order_i[0] += 1\n", " return NoOrder\n", "\n", "sim_i = np.array([0])\n", "group_i = np.array([0])\n", "segment_i = np.array([0])\n", "order_i = np.array([0])\n", "portfolio = vbt.Portfolio.from_order_func(\n", " price_wide, order_func_nb, order_i, \n", " group_by=np.array([0, 0, 1]), \n", " pre_sim_func_nb=pre_sim_func_nb, pre_sim_args=(sim_i,),\n", " pre_group_func_nb=group_pre_sim_func_nb, pre_group_args=(group_i,),\n", " pre_segment_func_nb=pre_segment_func_nb, pre_segment_args=(segment_i,)\n", ")\n", "print(sim_i, group_i, segment_i, order_i)" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "preparing simulation\n", "\tpreparing row 0\n", "\t\tpreparing segment 0 (group)\n", "\t\t\tprocessing order 0 at column 0\n", "\t\t\tprocessing order 1 at column 1\n", "\t\tpreparing segment 1 (group)\n", "\t\t\tprocessing order 0 at column 2\n", "\tpreparing row 1\n", "\t\tpreparing segment 0 (group)\n", "\t\t\tprocessing order 0 at column 0\n", "\t\t\tprocessing order 1 at column 1\n", "\t\tpreparing segment 1 (group)\n", "\t\t\tprocessing order 0 at column 2\n", "\tpreparing row 2\n", "\t\tpreparing segment 0 (group)\n", "\t\t\tprocessing order 0 at column 0\n", "\t\t\tprocessing order 1 at column 1\n", "\t\tpreparing segment 1 (group)\n", "\t\t\tprocessing order 0 at column 2\n", "\tpreparing row 3\n", "\t\tpreparing segment 0 (group)\n", "\t\t\tprocessing order 0 at column 0\n", "\t\t\tprocessing order 1 at column 1\n", "\t\tpreparing segment 1 (group)\n", "\t\t\tprocessing order 0 at column 2\n", "\tpreparing row 4\n", "\t\tpreparing segment 0 (group)\n", "\t\t\tprocessing order 0 at column 0\n", "\t\t\tprocessing order 1 at column 1\n", "\t\tpreparing segment 1 (group)\n", "\t\t\tprocessing order 0 at column 2\n", "[1] [5] [10] [15]\n" ] } ], "source": [ "@njit\n", "def pre_sim_func_nb(c, sim_i):\n", " print('preparing simulation')\n", " sim_i[0] += 1\n", " return sim_i,\n", "\n", "@njit\n", "def row_pre_sim_func_nb(c, sim_i, row_i):\n", " print('\\tpreparing row', c.i)\n", " row_i[0] += 1\n", " return sim_i, row_i\n", "\n", "@njit\n", "def pre_segment_func_nb(c, sim_i, row_i, segment_i):\n", " print('\\t\\tpreparing segment', c.group, '(group)')\n", " segment_i[0] += 1\n", " return sim_i, row_i, segment_i\n", "\n", "@njit\n", "def order_func_nb(c, sim_i, row_i, segment_i, order_i):\n", " print('\\t\\t\\tprocessing order', c.call_idx, 'at column', c.col)\n", " order_i[0] += 1\n", " return NoOrder\n", "\n", "sim_i = np.array([0])\n", "row_i = np.array([0])\n", "segment_i = np.array([0])\n", "order_i = np.array([0])\n", "\n", "portfolio = vbt.Portfolio.from_order_func(\n", " price_wide, order_func_nb, order_i, \n", " group_by=np.array([0, 0, 1]), \n", " pre_sim_func_nb=pre_sim_func_nb, pre_sim_args=(sim_i,),\n", " pre_row_func_nb=row_pre_sim_func_nb, pre_row_args=(row_i,),\n", " pre_segment_func_nb=pre_segment_func_nb, pre_segment_args=(segment_i,),\n", " row_wise=True\n", ")\n", "print(sim_i, row_i, segment_i, order_i)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## methods and properties" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "price_na = pd.DataFrame({\n", " 'a': [np.nan, 2., 3., 4., 5.],\n", " 'b': [1., 2., np.nan, 4., 5.],\n", " 'c': [1., 2., 3., 4., np.nan]\n", "}, index=price.index)\n", "order_size = pd.Series([1., 0.1, -1., -0.1, 1.])\n", "directions = ['longonly', 'shortonly', 'both']\n", "group_by = pd.Index(['first', 'first', 'second'], name='group')" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " id col idx size price fees side\n", "0 0 0 1 0.1 2.02 0.10202 0\n", "1 1 0 2 0.1 2.97 0.10297 1\n", "2 2 0 4 1.0 5.05 0.15050 0\n", "3 3 1 0 1.0 0.99 0.10990 1\n", "4 4 1 1 0.1 1.98 0.10198 1\n", "5 5 1 3 0.1 4.04 0.10404 0\n", "6 6 1 4 1.0 4.95 0.14950 1\n", "7 7 2 0 1.0 1.01 0.11010 0\n", "8 8 2 1 0.1 2.02 0.10202 0\n", "9 9 2 2 1.0 2.97 0.12970 1\n", "10 10 2 3 0.1 3.96 0.10396 1\n", " id col idx size price fees side\n", "0 0 0 1 0.1 2.02 0.10202 0\n", "1 1 0 2 0.1 2.97 0.10297 1\n", "2 2 0 4 1.0 5.05 0.15050 0\n", "3 3 1 0 1.0 0.99 0.10990 1\n", "4 4 1 1 0.1 1.98 0.10198 1\n", "5 5 1 3 0.1 4.04 0.10404 0\n", "6 6 1 4 1.0 4.95 0.14950 1\n", "7 7 2 0 1.0 1.01 0.11010 0\n", "8 8 2 1 0.1 2.02 0.10202 0\n", "9 9 2 2 1.0 2.97 0.12970 1\n", "10 10 2 3 0.1 3.96 0.10396 1\n", " id col idx size price fees side\n", "0 0 1 0 1.0 0.99 0.10990 1\n", "1 1 1 1 0.1 1.98 0.10198 1\n", "2 2 0 1 0.1 2.02 0.10202 0\n", "3 3 0 2 0.1 2.97 0.10297 1\n", "4 4 1 3 0.1 4.04 0.10404 0\n", "5 5 1 4 1.0 4.95 0.14950 1\n", "6 6 0 4 1.0 5.05 0.15050 0\n", "7 7 2 0 1.0 1.01 0.11010 0\n", "8 8 2 1 0.1 2.02 0.10202 0\n", "9 9 2 2 1.0 2.97 0.12970 1\n", "10 10 2 3 0.1 3.96 0.10396 1\n" ] } ], "source": [ "portfolio = vbt.Portfolio.from_orders(\n", " price_na, order_size, size_type='amount', direction=directions,\n", " fees=0.01, fixed_fees=0.1, slippage=0.01, log=True,\n", " call_seq='reversed', group_by=None,\n", " init_cash=[100., 100., 100.], freq='1D'\n", ") # independent\n", "print(portfolio.orders.records)\n", "\n", "portfolio_grouped = vbt.Portfolio.from_orders(\n", " price_na, order_size, size_type='amount', direction=directions,\n", " fees=0.01, fixed_fees=0.1, slippage=0.01, log=True,\n", " call_seq='reversed', group_by=group_by, cash_sharing=False,\n", " init_cash=[100., 100., 100.], freq='1D'\n", ") # grouped\n", "print(portfolio_grouped.orders.records)\n", "\n", "portfolio_shared = vbt.Portfolio.from_orders(\n", " price_na, order_size, size_type='amount', direction=directions,\n", " fees=0.01, fixed_fees=0.1, slippage=0.01, log=True,\n", " call_seq='reversed', group_by=group_by, cash_sharing=True,\n", " init_cash=[200., 100.], freq='1D'\n", ") # shared\n", "print(portfolio_shared.orders.records)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(1000000,)\n", "(1000000,)\n", "(1000000,)\n" ] } ], "source": [ "big_group_by = np.repeat(np.arange(500), 2)\n", "big_portfolio = vbt.Portfolio.from_orders(\n", " big_price_wide, big_order_size)\n", "print(big_portfolio.orders.values.shape)\n", "\n", "big_portfolio_grouped = vbt.Portfolio.from_orders(\n", " big_price_wide, big_order_size, group_by=big_group_by)\n", "print(big_portfolio_grouped.orders.values.shape)\n", "\n", "big_portfolio_shared = vbt.Portfolio.from_orders(\n", " big_price_wide, big_order_size, group_by=big_group_by, cash_sharing=True)\n", "print(big_portfolio_shared.orders.values.shape)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "DatetimeIndex(['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-04',\n", " '2020-01-05'],\n", " dtype='datetime64[ns]', freq=None)\n", "Index(['a', 'b', 'c'], dtype='object')\n", "2\n", "None\n", "True\n", "True\n", "True\n", "DatetimeIndex(['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-04',\n", " '2020-01-05'],\n", " dtype='datetime64[ns]', freq=None)\n", "Index(['a', 'b', 'c'], dtype='object')\n", "2\n", "Index(['first', 'first', 'second'], dtype='object', name='group')\n", "True\n", "True\n", "True\n", "DatetimeIndex(['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-04',\n", " '2020-01-05'],\n", " dtype='datetime64[ns]', freq=None)\n", "Index(['a', 'b', 'c'], dtype='object')\n", "2\n", "Index(['first', 'first', 'second'], dtype='object', name='group')\n", "False\n", "True\n", "False\n" ] } ], "source": [ "print(portfolio.wrapper.index)\n", "print(portfolio.wrapper.columns)\n", "print(portfolio.wrapper.ndim)\n", "print(portfolio.wrapper.grouper.group_by)\n", "print(portfolio.wrapper.grouper.allow_enable)\n", "print(portfolio.wrapper.grouper.allow_disable)\n", "print(portfolio.wrapper.grouper.allow_modify)\n", "\n", "print(portfolio_grouped.wrapper.index)\n", "print(portfolio_grouped.wrapper.columns)\n", "print(portfolio_grouped.wrapper.ndim)\n", "print(portfolio_grouped.wrapper.grouper.group_by)\n", "print(portfolio_grouped.wrapper.grouper.allow_enable)\n", "print(portfolio_grouped.wrapper.grouper.allow_disable)\n", "print(portfolio_grouped.wrapper.grouper.allow_modify)\n", "\n", "print(portfolio_shared.wrapper.index)\n", "print(portfolio_shared.wrapper.columns)\n", "print(portfolio_shared.wrapper.ndim)\n", "print(portfolio_shared.wrapper.grouper.group_by)\n", "print(portfolio_shared.wrapper.grouper.allow_enable)\n", "print(portfolio_shared.wrapper.grouper.allow_disable)\n", "print(portfolio_shared.wrapper.grouper.allow_modify)" ] }, { "cell_type": "code", "execution_count": 106, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " id idx col size price fees side\n", "0 0 1 0 0.1 2.02 0.10202 0\n", "1 1 2 0 0.1 2.97 0.10297 1\n", "2 2 4 0 1.0 5.05 0.15050 0\n", "3 3 0 1 1.0 0.99 0.10990 1\n", "4 4 1 1 0.1 1.98 0.10198 1\n", "5 5 3 1 0.1 4.04 0.10404 0\n", "6 6 4 1 1.0 4.95 0.14950 1\n", "7 7 0 2 1.0 1.01 0.11010 0\n", "8 8 1 2 0.1 2.02 0.10202 0\n", "9 9 2 2 1.0 2.97 0.12970 1\n", "10 10 3 2 0.1 3.96 0.10396 1\n", "a 3\n", "b 4\n", "c 4\n", "Name: count, dtype: int64\n", "a 5\n", "b 5\n", "c 5\n", "Name: count, dtype: int64\n", " a b c\n", "2020-01-01 NaN 1.0 1.0\n", "2020-01-02 2.0 2.0 2.0\n", "2020-01-03 3.0 NaN 3.0\n", "2020-01-04 4.0 4.0 4.0\n", "2020-01-05 5.0 5.0 NaN\n", "a 100.0\n", "b 100.0\n", "c 100.0\n", "Name: init_cash, dtype: float64\n", " a b c\n", "2020-01-01 100.00000 99.88010 99.87990\n", "2020-01-02 99.89598 98.77612 100.77588\n", "2020-01-03 99.89001 98.77612 101.71618\n", "2020-01-04 99.89001 96.46808 101.70822\n", "2020-01-05 99.68951 95.26858 101.70822\n", "a 99.68951\n", "b 95.26858\n", "c 101.70822\n", "Name: final_value, dtype: float64\n" ] } ], "source": [ "print(portfolio.orders.records)\n", "print(portfolio.orders.count())\n", "print(portfolio.logs.count())\n", "print(portfolio.close)\n", "print(portfolio.init_cash)\n", "print(portfolio.value())\n", "print(portfolio.final_value())" ] }, { "cell_type": "code", "execution_count": 107, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " id idx col size price fees side\n", "0 0 1 0 0.1 2.02 0.10202 0\n", "1 1 2 0 0.1 2.97 0.10297 1\n", "2 2 4 0 1.0 5.05 0.15050 0\n", "3\n", "5\n", "2020-01-01 NaN\n", "2020-01-02 2.0\n", "2020-01-03 3.0\n", "2020-01-04 4.0\n", "2020-01-05 5.0\n", "Name: a, dtype: float64\n", "100.0\n", "2020-01-01 100.00000\n", "2020-01-02 99.89598\n", "2020-01-03 99.89001\n", "2020-01-04 99.89001\n", "2020-01-05 99.68951\n", "Name: a, dtype: float64\n", "99.68951\n" ] } ], "source": [ "print(portfolio['a'].orders.records)\n", "print(portfolio['a'].orders.count())\n", "print(portfolio['a'].logs.count())\n", "print(portfolio['a'].close)\n", "print(portfolio['a'].init_cash)\n", "print(portfolio['a'].value())\n", "print(portfolio['a'].final_value())" ] }, { "cell_type": "code", "execution_count": 108, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " id idx col size price fees side\n", "0 7 0 0 1.0 1.01 0.11010 0\n", "1 8 1 0 0.1 2.02 0.10202 0\n", "2 9 2 0 1.0 2.97 0.12970 1\n", "3 10 3 0 0.1 3.96 0.10396 1\n", "4\n", "5\n", "2020-01-01 1.0\n", "2020-01-02 2.0\n", "2020-01-03 3.0\n", "2020-01-04 4.0\n", "2020-01-05 NaN\n", "Name: c, dtype: float64\n", "100.0\n", "2020-01-01 99.87990\n", "2020-01-02 100.77588\n", "2020-01-03 101.71618\n", "2020-01-04 101.70822\n", "2020-01-05 101.70822\n", "Name: c, dtype: float64\n", "101.70822\n" ] } ], "source": [ "print(portfolio['c'].orders.records)\n", "print(portfolio['c'].orders.count())\n", "print(portfolio['c'].logs.count())\n", "print(portfolio['c'].close)\n", "print(portfolio['c'].init_cash)\n", "print(portfolio['c'].value())\n", "print(portfolio['c'].final_value())" ] }, { "cell_type": "code", "execution_count": 109, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " id idx col size price fees side\n", "0 7 0 0 1.0 1.01 0.11010 0\n", "1 8 1 0 0.1 2.02 0.10202 0\n", "2 9 2 0 1.0 2.97 0.12970 1\n", "3 10 3 0 0.1 3.96 0.10396 1\n", "c 4\n", "Name: count, dtype: int64\n", "c 5\n", "Name: count, dtype: int64\n", " c\n", "2020-01-01 1.0\n", "2020-01-02 2.0\n", "2020-01-03 3.0\n", "2020-01-04 4.0\n", "2020-01-05 NaN\n", "c 100.0\n", "Name: init_cash, dtype: float64\n", " c\n", "2020-01-01 99.87990\n", "2020-01-02 100.77588\n", "2020-01-03 101.71618\n", "2020-01-04 101.70822\n", "2020-01-05 101.70822\n", "c 101.70822\n", "Name: final_value, dtype: float64\n" ] } ], "source": [ "print(portfolio[['c']].orders.records)\n", "print(portfolio[['c']].orders.count())\n", "print(portfolio[['c']].logs.count())\n", "print(portfolio[['c']].close)\n", "print(portfolio[['c']].init_cash)\n", "print(portfolio[['c']].value())\n", "print(portfolio[['c']].final_value())" ] }, { "cell_type": "code", "execution_count": 110, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " id idx col size price fees side\n", "0 0 1 0 0.1 2.02 0.10202 0\n", "1 1 2 0 0.1 2.97 0.10297 1\n", "2 2 4 0 1.0 5.05 0.15050 0\n", "3 3 0 1 1.0 0.99 0.10990 1\n", "4 4 1 1 0.1 1.98 0.10198 1\n", "5 5 3 1 0.1 4.04 0.10404 0\n", "6 6 4 1 1.0 4.95 0.14950 1\n", "7 7 0 2 1.0 1.01 0.11010 0\n", "8 8 1 2 0.1 2.02 0.10202 0\n", "9 9 2 2 1.0 2.97 0.12970 1\n", "10 10 3 2 0.1 3.96 0.10396 1\n", "group\n", "first 7\n", "second 4\n", "Name: count, dtype: int64\n", "group\n", "first 10\n", "second 5\n", "Name: count, dtype: int64\n", " a b c\n", "2020-01-01 NaN 1.0 1.0\n", "2020-01-02 2.0 2.0 2.0\n", "2020-01-03 3.0 NaN 3.0\n", "2020-01-04 4.0 4.0 4.0\n", "2020-01-05 5.0 5.0 NaN\n", "group\n", "first 200.0\n", "second 100.0\n", "Name: init_cash, dtype: float64\n", "group first second\n", "2020-01-01 199.88010 99.87990\n", "2020-01-02 198.67210 100.77588\n", "2020-01-03 198.66613 101.71618\n", "2020-01-04 196.35809 101.70822\n", "2020-01-05 194.95809 101.70822\n", "group\n", "first 194.95809\n", "second 101.70822\n", "Name: final_value, dtype: float64\n" ] } ], "source": [ "print(portfolio_grouped.orders.records)\n", "print(portfolio_grouped.orders.count())\n", "print(portfolio_grouped.logs.count())\n", "print(portfolio_grouped.close)\n", "print(portfolio_grouped.init_cash)\n", "print(portfolio_grouped.value())\n", "print(portfolio_grouped.final_value())" ] }, { "cell_type": "code", "execution_count": 111, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " id idx col size price fees side\n", "0 0 1 0 0.1 2.02 0.10202 0\n", "1 1 2 0 0.1 2.97 0.10297 1\n", "2 2 4 0 1.0 5.05 0.15050 0\n", "3 3 0 1 1.0 0.99 0.10990 1\n", "4 4 1 1 0.1 1.98 0.10198 1\n", "5 5 3 1 0.1 4.04 0.10404 0\n", "6 6 4 1 1.0 4.95 0.14950 1\n", "7\n", "10\n", " a b\n", "2020-01-01 NaN 1.0\n", "2020-01-02 2.0 2.0\n", "2020-01-03 3.0 NaN\n", "2020-01-04 4.0 4.0\n", "2020-01-05 5.0 5.0\n", "200.0\n", "2020-01-01 199.88010\n", "2020-01-02 198.67210\n", "2020-01-03 196.46613\n", "2020-01-04 196.35809\n", "2020-01-05 194.95809\n", "Name: first, dtype: float64\n", "194.95809\n" ] } ], "source": [ "print(portfolio_grouped['first'].orders.records)\n", "print(portfolio_grouped['first'].orders.count())\n", "print(portfolio_grouped['first'].logs.count())\n", "print(portfolio_grouped['first'].close)\n", "print(portfolio_grouped['first'].init_cash)\n", "print(portfolio_grouped['first'].value())\n", "print(portfolio_grouped['first'].final_value())" ] }, { "cell_type": "code", "execution_count": 112, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " id idx col size price fees side\n", "0 7 0 0 1.0 1.01 0.11010 0\n", "1 8 1 0 0.1 2.02 0.10202 0\n", "2 9 2 0 1.0 2.97 0.12970 1\n", "3 10 3 0 0.1 3.96 0.10396 1\n", "4\n", "5\n", "2020-01-01 1.0\n", "2020-01-02 2.0\n", "2020-01-03 3.0\n", "2020-01-04 4.0\n", "2020-01-05 NaN\n", "Name: c, dtype: float64\n", "100.0\n", "2020-01-01 99.87990\n", "2020-01-02 100.77588\n", "2020-01-03 101.71618\n", "2020-01-04 101.70822\n", "2020-01-05 101.70822\n", "Name: second, dtype: float64\n", "101.70822\n" ] } ], "source": [ "print(portfolio_grouped['second'].orders.records)\n", "print(portfolio_grouped['second'].orders.count())\n", "print(portfolio_grouped['second'].logs.count())\n", "print(portfolio_grouped['second'].close)\n", "print(portfolio_grouped['second'].init_cash)\n", "print(portfolio_grouped['second'].value())\n", "print(portfolio_grouped['second'].final_value())" ] }, { "cell_type": "code", "execution_count": 113, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " id idx col size price fees side\n", "0 7 0 0 1.0 1.01 0.11010 0\n", "1 8 1 0 0.1 2.02 0.10202 0\n", "2 9 2 0 1.0 2.97 0.12970 1\n", "3 10 3 0 0.1 3.96 0.10396 1\n", "group\n", "second 4\n", "Name: count, dtype: int64\n", "group\n", "second 5\n", "Name: count, dtype: int64\n", " c\n", "2020-01-01 1.0\n", "2020-01-02 2.0\n", "2020-01-03 3.0\n", "2020-01-04 4.0\n", "2020-01-05 NaN\n", "group\n", "second 100.0\n", "Name: init_cash, dtype: float64\n", "group second\n", "2020-01-01 99.87990\n", "2020-01-02 100.77588\n", "2020-01-03 101.71618\n", "2020-01-04 101.70822\n", "2020-01-05 101.70822\n", "group\n", "second 101.70822\n", "Name: final_value, dtype: float64\n" ] } ], "source": [ "print(portfolio_grouped[['second']].orders.records)\n", "print(portfolio_grouped[['second']].orders.count())\n", "print(portfolio_grouped[['second']].logs.count())\n", "print(portfolio_grouped[['second']].close)\n", "print(portfolio_grouped[['second']].init_cash)\n", "print(portfolio_grouped[['second']].value())\n", "print(portfolio_grouped[['second']].final_value())" ] }, { "cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3.42 ms ± 283 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n", "The slowest run took 17.43 times longer than the fastest. This could mean that an intermediate result is being cached.\n", "111 ms ± 89.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n", "3.37 ms ± 46.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "14.3 ms ± 1.99 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "6.41 ms ± 139 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "18.1 ms ± 366 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" ] } ], "source": [ "%timeit big_portfolio.iloc[0]\n", "%timeit big_portfolio.iloc[:]\n", "%timeit big_portfolio_grouped.iloc[0]\n", "%timeit big_portfolio_grouped.iloc[:]\n", "%timeit big_portfolio_shared.iloc[0]\n", "%timeit big_portfolio_shared.iloc[:]" ] }, { "cell_type": "code", "execution_count": 114, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\n", "False\n", "True\n" ] } ], "source": [ "print(portfolio.cash_sharing)\n", "print(portfolio_grouped.cash_sharing)\n", "print(portfolio_shared.cash_sharing)" ] }, { "cell_type": "code", "execution_count": 115, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " a b c\n", "2020-01-01 0 0 0\n", "2020-01-02 0 0 0\n", "2020-01-03 0 0 0\n", "2020-01-04 0 0 0\n", "2020-01-05 0 0 0\n", " a b c\n", "2020-01-01 1 0 0\n", "2020-01-02 1 0 0\n", "2020-01-03 1 0 0\n", "2020-01-04 1 0 0\n", "2020-01-05 1 0 0\n", " a b c\n", "2020-01-01 1 0 0\n", "2020-01-02 1 0 0\n", "2020-01-03 1 0 0\n", "2020-01-04 1 0 0\n", "2020-01-05 1 0 0\n" ] } ], "source": [ "print(portfolio.call_seq)\n", "print(portfolio_grouped.call_seq)\n", "print(portfolio_shared.call_seq)" ] }, { "cell_type": "code", "execution_count": 116, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a 3\n", "b 4\n", "c 4\n", "Name: count, dtype: int64\n", "a 3\n", "b 4\n", "c 4\n", "Name: count, dtype: int64\n", "a 3\n", "b 4\n", "c 4\n", "Name: count, dtype: int64\n", "group\n", "first 7\n", "second 4\n", "Name: count, dtype: int64\n", "group\n", "first 7\n", "second 4\n", "Name: count, dtype: int64\n", "group\n", "first 7\n", "second 4\n", "Name: count, dtype: int64\n" ] } ], "source": [ "print(portfolio.orders.count())\n", "print(portfolio_grouped.get_orders(group_by=False).count())\n", "print(portfolio_shared.get_orders(group_by=False).count())\n", "\n", "print(portfolio.get_orders(group_by=group_by).count())\n", "print(portfolio_grouped.orders.count())\n", "print(portfolio_shared.orders.count())" ] }, { "cell_type": "code", "execution_count": 117, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a 5\n", "b 5\n", "c 5\n", "Name: count, dtype: int64\n", "a 5\n", "b 5\n", "c 5\n", "Name: count, dtype: int64\n", "a 5\n", "b 5\n", "c 5\n", "Name: count, dtype: int64\n", "group\n", "first 10\n", "second 5\n", "Name: count, dtype: int64\n", "group\n", "first 10\n", "second 5\n", "Name: count, dtype: int64\n", "group\n", "first 10\n", "second 5\n", "Name: count, dtype: int64\n" ] } ], "source": [ "print(portfolio.logs.count())\n", "print(portfolio_grouped.get_logs(group_by=False).count())\n", "print(portfolio_shared.get_logs(group_by=False).count())\n", "\n", "print(portfolio.get_logs(group_by=group_by).count())\n", "print(portfolio_grouped.logs.count())\n", "print(portfolio_shared.logs.count())" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a 2\n", "b 3\n", "c 2\n", "Name: count, dtype: int64\n", "a 2\n", "b 3\n", "c 2\n", "Name: count, dtype: int64\n", "a 2\n", "b 3\n", "c 2\n", "Name: count, dtype: int64\n", "group\n", "first 5\n", "second 2\n", "Name: count, dtype: int64\n", "group\n", "first 5\n", "second 2\n", "Name: count, dtype: int64\n", "group\n", "first 5\n", "second 2\n", "Name: count, dtype: int64\n" ] } ], "source": [ "print(portfolio.entry_trades.count())\n", "print(portfolio_grouped.get_entry_trades(group_by=False).count())\n", "print(portfolio_shared.get_entry_trades(group_by=False).count())\n", "\n", "print(portfolio.get_entry_trades(group_by=group_by).count())\n", "print(portfolio_grouped.entry_trades.count())\n", "print(portfolio_shared.entry_trades.count())" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "397 ms ± 3.87 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" ] } ], "source": [ "%timeit big_portfolio.entry_trades" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a 2\n", "b 2\n", "c 2\n", "Name: count, dtype: int64\n", "a 2\n", "b 2\n", "c 2\n", "Name: count, dtype: int64\n", "a 2\n", "b 2\n", "c 2\n", "Name: count, dtype: int64\n", "group\n", "first 4\n", "second 2\n", "Name: count, dtype: int64\n", "group\n", "first 4\n", "second 2\n", "Name: count, dtype: int64\n", "group\n", "first 4\n", "second 2\n", "Name: count, dtype: int64\n" ] } ], "source": [ "print(portfolio.exit_trades.count())\n", "print(portfolio_grouped.get_exit_trades(group_by=False).count())\n", "print(portfolio_shared.get_exit_trades(group_by=False).count())\n", "\n", "print(portfolio.get_exit_trades(group_by=group_by).count())\n", "print(portfolio_grouped.exit_trades.count())\n", "print(portfolio_shared.exit_trades.count())" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "13.8 ms ± 607 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" ] } ], "source": [ "%timeit big_portfolio.exit_trades" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a 2\n", "b 1\n", "c 1\n", "Name: count, dtype: int64\n", "a 2\n", "b 1\n", "c 1\n", "Name: count, dtype: int64\n", "a 2\n", "b 1\n", "c 1\n", "Name: count, dtype: int64\n", "group\n", "first 3\n", "second 1\n", "Name: count, dtype: int64\n", "group\n", "first 3\n", "second 1\n", "Name: count, dtype: int64\n", "group\n", "first 3\n", "second 1\n", "Name: count, dtype: int64\n" ] } ], "source": [ "print(portfolio.positions.count())\n", "print(portfolio_grouped.get_positions(group_by=False).count())\n", "print(portfolio_shared.get_positions(group_by=False).count())\n", "\n", "print(portfolio.get_positions(group_by=group_by).count())\n", "print(portfolio_grouped.positions.count())\n", "print(portfolio_shared.positions.count())" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "28.4 ms ± 3 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" ] } ], "source": [ "%timeit big_portfolio.positions" ] }, { "cell_type": "code", "execution_count": 120, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a 1\n", "b 1\n", "c 1\n", "Name: count, dtype: int64\n", "a 1\n", "b 1\n", "c 1\n", "Name: count, dtype: int64\n", "a 1\n", "b 1\n", "c 1\n", "Name: count, dtype: int64\n", "group\n", "first 1\n", "second 1\n", "Name: count, dtype: int64\n", "group\n", "first 1\n", "second 1\n", "Name: count, dtype: int64\n", "group\n", "first 1\n", "second 1\n", "Name: count, dtype: int64\n" ] } ], "source": [ "print(portfolio.drawdowns.count())\n", "print(portfolio_grouped.get_drawdowns(group_by=False).count())\n", "print(portfolio_shared.get_drawdowns(group_by=False).count())\n", "\n", "print(portfolio.get_drawdowns(group_by=group_by).count())\n", "print(portfolio_grouped.drawdowns.count())\n", "print(portfolio_shared.drawdowns.count())" ] }, { "cell_type": "code", "execution_count": 72, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "39.9 ms ± 907 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" ] } ], "source": [ "%timeit big_portfolio.drawdowns" ] }, { "cell_type": "code", "execution_count": 121, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " a b c\n", "2020-01-01 NaN 1.0 1.0\n", "2020-01-02 2.0 2.0 2.0\n", "2020-01-03 3.0 NaN 3.0\n", "2020-01-04 4.0 4.0 4.0\n", "2020-01-05 5.0 5.0 NaN\n", " a b c\n", "2020-01-01 NaN 1.0 1.0\n", "2020-01-02 2.0 2.0 2.0\n", "2020-01-03 3.0 NaN 3.0\n", "2020-01-04 4.0 4.0 4.0\n", "2020-01-05 5.0 5.0 NaN\n", " a b c\n", "2020-01-01 NaN 1.0 1.0\n", "2020-01-02 2.0 2.0 2.0\n", "2020-01-03 3.0 NaN 3.0\n", "2020-01-04 4.0 4.0 4.0\n", "2020-01-05 5.0 5.0 NaN\n" ] } ], "source": [ "print(portfolio.close)\n", "print(portfolio_grouped.close)\n", "print(portfolio_shared.close)" ] }, { "cell_type": "code", "execution_count": 122, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " a b c\n", "2020-01-01 NaN 1.0 1.0\n", "2020-01-02 2.0 2.0 2.0\n", "2020-01-03 3.0 NaN 3.0\n", "2020-01-04 4.0 4.0 4.0\n", "2020-01-05 5.0 5.0 NaN\n", " a b c\n", "2020-01-01 NaN 1.0 1.0\n", "2020-01-02 2.0 2.0 2.0\n", "2020-01-03 3.0 2.0 3.0\n", "2020-01-04 4.0 4.0 4.0\n", "2020-01-05 5.0 5.0 4.0\n", " a b c\n", "2020-01-01 2.0 1.0 1.0\n", "2020-01-02 2.0 2.0 2.0\n", "2020-01-03 3.0 4.0 3.0\n", "2020-01-04 4.0 4.0 4.0\n", "2020-01-05 5.0 5.0 NaN\n", " a b c\n", "2020-01-01 2.0 1.0 1.0\n", "2020-01-02 2.0 2.0 2.0\n", "2020-01-03 3.0 2.0 3.0\n", "2020-01-04 4.0 4.0 4.0\n", "2020-01-05 5.0 5.0 4.0\n" ] } ], "source": [ "print(portfolio.fill_close(ffill=False, bfill=False))\n", "print(portfolio.fill_close(ffill=True, bfill=False))\n", "print(portfolio.fill_close(ffill=False, bfill=True))\n", "print(portfolio.fill_close(ffill=True, bfill=True))" ] }, { "cell_type": "code", "execution_count": 75, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "67.6 µs ± 1.39 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)\n" ] } ], "source": [ "%timeit big_portfolio.fill_close()" ] }, { "cell_type": "code", "execution_count": 123, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " a b c\n", "2020-01-01 0.0 0.0 1.0\n", "2020-01-02 0.1 0.0 0.1\n", "2020-01-03 -0.1 0.0 -1.0\n", "2020-01-04 0.0 0.0 -0.1\n", "2020-01-05 1.0 0.0 0.0\n", " a b c\n", "2020-01-01 0.0 1.0 0.0\n", "2020-01-02 0.0 0.1 0.0\n", "2020-01-03 0.0 0.0 0.0\n", "2020-01-04 0.0 -0.1 0.0\n", "2020-01-05 0.0 1.0 0.0\n", " a b c\n", "2020-01-01 0.0 -1.0 1.0\n", "2020-01-02 0.1 -0.1 0.1\n", "2020-01-03 -0.1 0.0 -1.0\n", "2020-01-04 0.0 0.1 -0.1\n", "2020-01-05 1.0 -1.0 0.0\n", " a b c\n", "2020-01-01 0.0 -1.0 1.0\n", "2020-01-02 0.1 -0.1 0.1\n", "2020-01-03 -0.1 0.0 -1.0\n", "2020-01-04 0.0 0.1 -0.1\n", "2020-01-05 1.0 -1.0 0.0\n", " a b c\n", "2020-01-01 0.0 -1.0 1.0\n", "2020-01-02 0.1 -0.1 0.1\n", "2020-01-03 -0.1 0.0 -1.0\n", "2020-01-04 0.0 0.1 -0.1\n", "2020-01-05 1.0 -1.0 0.0\n" ] } ], "source": [ "print(portfolio.asset_flow(direction='longonly'))\n", "print(portfolio.asset_flow(direction='shortonly'))\n", "\n", "print(portfolio.asset_flow())\n", "print(portfolio_grouped.asset_flow())\n", "print(portfolio_shared.asset_flow())" ] }, { "cell_type": "code", "execution_count": 77, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "11 ms ± 539 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "10.6 ms ± 276 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "10.5 ms ± 148 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n" ] } ], "source": [ "%timeit big_portfolio.asset_flow()\n", "%timeit big_portfolio_grouped.asset_flow()\n", "%timeit big_portfolio_shared.asset_flow()" ] }, { "cell_type": "code", "execution_count": 124, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " a b c\n", "2020-01-01 0.0 0.0 1.0\n", "2020-01-02 0.1 0.0 1.1\n", "2020-01-03 0.0 0.0 0.1\n", "2020-01-04 0.0 0.0 0.0\n", "2020-01-05 1.0 0.0 0.0\n", " a b c\n", "2020-01-01 0.0 1.0 0.0\n", "2020-01-02 0.0 1.1 0.0\n", "2020-01-03 0.0 1.1 0.0\n", "2020-01-04 0.0 1.0 0.0\n", "2020-01-05 0.0 2.0 0.0\n", " a b c\n", "2020-01-01 0.0 -1.0 1.0\n", "2020-01-02 0.1 -1.1 1.1\n", "2020-01-03 0.0 -1.1 0.1\n", "2020-01-04 0.0 -1.0 0.0\n", "2020-01-05 1.0 -2.0 0.0\n", " a b c\n", "2020-01-01 0.0 -1.0 1.0\n", "2020-01-02 0.1 -1.1 1.1\n", "2020-01-03 0.0 -1.1 0.1\n", "2020-01-04 0.0 -1.0 0.0\n", "2020-01-05 1.0 -2.0 0.0\n", " a b c\n", "2020-01-01 0.0 -1.0 1.0\n", "2020-01-02 0.1 -1.1 1.1\n", "2020-01-03 0.0 -1.1 0.1\n", "2020-01-04 0.0 -1.0 0.0\n", "2020-01-05 1.0 -2.0 0.0\n" ] } ], "source": [ "print(portfolio.assets(direction='longonly'))\n", "print(portfolio.assets(direction='shortonly'))\n", "\n", "print(portfolio.assets())\n", "print(portfolio_grouped.assets())\n", "print(portfolio_shared.assets())" ] }, { "cell_type": "code", "execution_count": 79, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "14.4 ms ± 539 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "14.6 ms ± 265 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "14 ms ± 50.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n" ] } ], "source": [ "%timeit big_portfolio.assets()\n", "%timeit big_portfolio_grouped.assets()\n", "%timeit big_portfolio_shared.assets()" ] }, { "cell_type": "code", "execution_count": 127, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " a b c\n", "2020-01-01 False False True\n", "2020-01-02 True False True\n", "2020-01-03 False False True\n", "2020-01-04 False False False\n", "2020-01-05 True False False\n", " a b c\n", "2020-01-01 False True False\n", "2020-01-02 False True False\n", "2020-01-03 False True False\n", "2020-01-04 False True False\n", "2020-01-05 False True False\n", " a b c\n", "2020-01-01 False True True\n", "2020-01-02 True True True\n", "2020-01-03 False True True\n", "2020-01-04 False True False\n", "2020-01-05 True True False\n", " a b c\n", "2020-01-01 False True True\n", "2020-01-02 True True True\n", "2020-01-03 False True True\n", "2020-01-04 False True False\n", "2020-01-05 True True False\n", " a b c\n", "2020-01-01 False True True\n", "2020-01-02 True True True\n", "2020-01-03 False True True\n", "2020-01-04 False True False\n", "2020-01-05 True True False\n", "group first second\n", "2020-01-01 True True\n", "2020-01-02 True True\n", "2020-01-03 True True\n", "2020-01-04 True False\n", "2020-01-05 True False\n", "group first second\n", "2020-01-01 True True\n", "2020-01-02 True True\n", "2020-01-03 True True\n", "2020-01-04 True False\n", "2020-01-05 True False\n", "group first second\n", "2020-01-01 True True\n", "2020-01-02 True True\n", "2020-01-03 True True\n", "2020-01-04 True False\n", "2020-01-05 True False\n" ] } ], "source": [ "print(portfolio.position_mask(direction='longonly'))\n", "print(portfolio.position_mask(direction='shortonly'))\n", "\n", "print(portfolio.position_mask())\n", "print(portfolio_grouped.position_mask(group_by=False))\n", "print(portfolio_shared.position_mask(group_by=False))\n", "\n", "print(portfolio.position_mask(group_by=group_by))\n", "print(portfolio_grouped.position_mask())\n", "print(portfolio_shared.position_mask())" ] }, { "cell_type": "code", "execution_count": 81, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "14.8 ms ± 113 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "15.1 ms ± 462 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "15.6 ms ± 299 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "31.4 ms ± 275 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "31 ms ± 198 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "32 ms ± 208 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" ] } ], "source": [ "%timeit big_portfolio.position_mask()\n", "%timeit big_portfolio_grouped.position_mask(group_by=False)\n", "%timeit big_portfolio_shared.position_mask(group_by=False)\n", "\n", "%timeit big_portfolio.position_mask(group_by=big_group_by)\n", "%timeit big_portfolio_grouped.position_mask()\n", "%timeit big_portfolio_shared.position_mask()" ] }, { "cell_type": "code", "execution_count": 128, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a 0.4\n", "b 0.0\n", "c 0.6\n", "Name: position_coverage, dtype: float64\n", "a 0.0\n", "b 1.0\n", "c 0.0\n", "Name: position_coverage, dtype: float64\n", "a 0.4\n", "b 1.0\n", "c 0.6\n", "Name: position_coverage, dtype: float64\n", "a 0.4\n", "b 1.0\n", "c 0.6\n", "Name: position_coverage, dtype: float64\n", "a 0.4\n", "b 1.0\n", "c 0.6\n", "Name: position_coverage, dtype: float64\n", "group\n", "first 0.7\n", "second 0.6\n", "Name: position_coverage, dtype: float64\n", "group\n", "first 0.7\n", "second 0.6\n", "Name: position_coverage, dtype: float64\n", "group\n", "first 0.7\n", "second 0.6\n", "Name: position_coverage, dtype: float64\n" ] } ], "source": [ "print(portfolio.position_coverage(direction='longonly'))\n", "print(portfolio.position_coverage(direction='shortonly'))\n", "\n", "print(portfolio.position_coverage())\n", "print(portfolio_grouped.position_coverage(group_by=False))\n", "print(portfolio_shared.position_coverage(group_by=False))\n", "\n", "print(portfolio.position_coverage(group_by=group_by))\n", "print(portfolio_grouped.position_coverage())\n", "print(portfolio_shared.position_coverage())" ] }, { "cell_type": "code", "execution_count": 83, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "16.6 ms ± 1.51 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "14.8 ms ± 104 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "15 ms ± 116 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "34.1 ms ± 1.49 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "32.2 ms ± 1.15 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "33.4 ms ± 1.19 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" ] } ], "source": [ "%timeit big_portfolio.position_coverage()\n", "%timeit big_portfolio_grouped.position_coverage(group_by=False)\n", "%timeit big_portfolio_shared.position_coverage(group_by=False)\n", "\n", "%timeit big_portfolio.position_coverage(group_by=big_group_by)\n", "%timeit big_portfolio_grouped.position_coverage()\n", "%timeit big_portfolio_shared.position_coverage()" ] }, { "cell_type": "code", "execution_count": 129, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " a b c\n", "2020-01-01 0.00000 -1.09990 -1.12010\n", "2020-01-02 -0.30402 -0.29998 -0.30402\n", "2020-01-03 0.19403 0.00000 2.84030\n", "2020-01-04 0.00000 -0.29204 0.29204\n", "2020-01-05 -5.20050 -5.09950 0.00000\n", " a b c\n", "2020-01-01 0.00000 0.88010 -1.12010\n", "2020-01-02 -0.30402 0.09602 -0.30402\n", "2020-01-03 0.19403 0.00000 2.84030\n", "2020-01-04 0.00000 -0.50804 0.29204\n", "2020-01-05 -5.20050 4.80050 0.00000\n", " a b c\n", "2020-01-01 0.00000 0.88010 -1.12010\n", "2020-01-02 -0.30402 0.09602 -0.30402\n", "2020-01-03 0.19403 0.00000 2.84030\n", "2020-01-04 0.00000 -0.50804 0.29204\n", "2020-01-05 -5.20050 4.80050 0.00000\n", " a b c\n", "2020-01-01 0.00000 0.88010 -1.12010\n", "2020-01-02 -0.30402 0.09602 -0.30402\n", "2020-01-03 0.19403 0.00000 2.84030\n", "2020-01-04 0.00000 -0.50804 0.29204\n", "2020-01-05 -5.20050 4.80050 0.00000\n", "group first second\n", "2020-01-01 0.88010 -1.12010\n", "2020-01-02 -0.20800 -0.30402\n", "2020-01-03 0.19403 2.84030\n", "2020-01-04 -0.50804 0.29204\n", "2020-01-05 -0.40000 0.00000\n", "group first second\n", "2020-01-01 0.88010 -1.12010\n", "2020-01-02 -0.20800 -0.30402\n", "2020-01-03 0.19403 2.84030\n", "2020-01-04 -0.50804 0.29204\n", "2020-01-05 -0.40000 0.00000\n", "group first second\n", "2020-01-01 0.88010 -1.12010\n", "2020-01-02 -0.20800 -0.30402\n", "2020-01-03 0.19403 2.84030\n", "2020-01-04 -0.50804 0.29204\n", "2020-01-05 -0.40000 0.00000\n" ] } ], "source": [ "print(portfolio.cash_flow(free=True))\n", "print(portfolio.cash_flow())\n", "print(portfolio_grouped.cash_flow(group_by=False))\n", "print(portfolio_shared.cash_flow(group_by=False))\n", "\n", "print(portfolio.cash_flow(group_by=group_by))\n", "print(portfolio_grouped.cash_flow())\n", "print(portfolio_shared.cash_flow())" ] }, { "cell_type": "code", "execution_count": 122, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "14.4 ms ± 912 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "20.4 ms ± 144 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "14.6 ms ± 88.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "16.3 ms ± 81.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "17.9 ms ± 126 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "16.7 ms ± 118 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "20.1 ms ± 155 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n" ] } ], "source": [ "%timeit big_portfolio.cash_flow()\n", "%timeit big_portfolio.cash_flow(free=True)\n", "%timeit big_portfolio_grouped.cash_flow(group_by=False)\n", "%timeit big_portfolio_shared.cash_flow(group_by=False)\n", "\n", "%timeit big_portfolio.cash_flow(group_by=big_group_by)\n", "%timeit big_portfolio_grouped.cash_flow()\n", "%timeit big_portfolio_shared.cash_flow()" ] }, { "cell_type": "code", "execution_count": 130, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a 100.0\n", "b 100.0\n", "c 100.0\n", "Name: init_cash, dtype: float64\n", "a 100.0\n", "b 100.0\n", "c 100.0\n", "Name: init_cash, dtype: float64\n", "a 200.0\n", "b 200.0\n", "c 100.0\n", "Name: init_cash, dtype: float64\n", "group\n", "first 200.0\n", "second 100.0\n", "Name: init_cash, dtype: float64\n", "group\n", "first 200.0\n", "second 100.0\n", "Name: init_cash, dtype: float64\n", "group\n", "first 200.0\n", "second 100.0\n", "Name: init_cash, dtype: float64\n" ] } ], "source": [ "print(portfolio.get_init_cash())\n", "print(portfolio_grouped.get_init_cash(group_by=False))\n", "print(portfolio_shared.get_init_cash(group_by=False))\n", "\n", "print(portfolio.get_init_cash(group_by=group_by))\n", "print(portfolio_grouped.get_init_cash())\n", "print(portfolio_shared.get_init_cash())" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "53.9 µs ± 387 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)\n", "53.6 µs ± 187 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)\n", "870 µs ± 2.61 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n", "912 µs ± 2.62 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n", "57.9 µs ± 1.76 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)\n", "1.26 ms ± 20.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n" ] } ], "source": [ "%timeit big_portfolio.get_init_cash()\n", "%timeit big_portfolio_grouped.get_init_cash(group_by=False)\n", "%timeit big_portfolio_shared.get_init_cash(group_by=False)\n", "\n", "%timeit big_portfolio.get_init_cash(group_by=big_group_by)\n", "%timeit big_portfolio_grouped.get_init_cash()\n", "%timeit big_portfolio_shared.get_init_cash()" ] }, { "cell_type": "code", "execution_count": 87, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "43.2 µs ± 125 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)\n", "42.9 µs ± 611 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)\n", "533 µs ± 13.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n", "737 µs ± 44.3 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n", "46.6 µs ± 617 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)\n", "850 µs ± 37.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n" ] } ], "source": [ "%timeit big_portfolio.get_init_cash()\n", "%timeit big_portfolio_grouped.get_init_cash(group_by=False)\n", "%timeit big_portfolio_shared.get_init_cash(group_by=False)\n", "\n", "%timeit big_portfolio.get_init_cash(group_by=big_group_by)\n", "%timeit big_portfolio_grouped.get_init_cash()\n", "%timeit big_portfolio_shared.get_init_cash()" ] }, { "cell_type": "code", "execution_count": 131, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a 14000.0\n", "b 12000.0\n", "c 10000.0\n", "Name: init_cash, dtype: float64\n", "group\n", "first 26000.0\n", "second 10000.0\n", "Name: init_cash, dtype: float64\n", "group\n", "first 26000.0\n", "second 10000.0\n", "Name: init_cash, dtype: float64\n", "a 14000.0\n", "b 14000.0\n", "c 14000.0\n", "Name: init_cash, dtype: float64\n", "group\n", "first 26000.0\n", "second 26000.0\n", "Name: init_cash, dtype: float64\n", "group\n", "first 26000.0\n", "second 26000.0\n", "Name: init_cash, dtype: float64\n" ] } ], "source": [ "print(vbt.Portfolio.from_orders(\n", " price_na, 1000., init_cash=InitCashMode.Auto, group_by=None).init_cash)\n", "\n", "print(vbt.Portfolio.from_orders(\n", " price_na, 1000., init_cash=InitCashMode.Auto, group_by=group_by).init_cash)\n", "\n", "print(vbt.Portfolio.from_orders(\n", " price_na, 1000., init_cash=InitCashMode.Auto, group_by=group_by, cash_sharing=True).init_cash)\n", "\n", "print(vbt.Portfolio.from_orders(\n", " price_na, 1000., init_cash=InitCashMode.AutoAlign, group_by=None).init_cash)\n", "\n", "print(vbt.Portfolio.from_orders(\n", " price_na, 1000., init_cash=InitCashMode.AutoAlign, group_by=group_by).init_cash)\n", "\n", "print(vbt.Portfolio.from_orders(\n", " price_na, 1000., init_cash=InitCashMode.AutoAlign, group_by=group_by, cash_sharing=True).init_cash)" ] }, { "cell_type": "code", "execution_count": 132, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " a b c\n", "2020-01-01 100.00000 98.90010 98.87990\n", "2020-01-02 99.69598 98.60012 98.57588\n", "2020-01-03 99.89001 98.60012 101.41618\n", "2020-01-04 99.89001 98.30808 101.70822\n", "2020-01-05 94.68951 93.20858 101.70822\n", " a b c\n", "2020-01-01 100.00000 100.88010 98.87990\n", "2020-01-02 99.69598 100.97612 98.57588\n", "2020-01-03 99.89001 100.97612 101.41618\n", "2020-01-04 99.89001 100.46808 101.70822\n", "2020-01-05 94.68951 105.26858 101.70822\n", " a b c\n", "2020-01-01 100.00000 100.88010 98.87990\n", "2020-01-02 99.69598 100.97612 98.57588\n", "2020-01-03 99.89001 100.97612 101.41618\n", "2020-01-04 99.89001 100.46808 101.70822\n", "2020-01-05 94.68951 105.26858 101.70822\n", " a b c\n", "2020-01-01 200.00000 200.88010 98.87990\n", "2020-01-02 199.69598 200.97612 98.57588\n", "2020-01-03 199.89001 200.97612 101.41618\n", "2020-01-04 199.89001 200.46808 101.70822\n", "2020-01-05 194.68951 205.26858 101.70822\n", " a b c\n", "2020-01-01 200.88010 200.88010 98.87990\n", "2020-01-02 200.67210 200.97612 98.57588\n", "2020-01-03 200.86613 200.67210 101.41618\n", "2020-01-04 200.35809 200.35809 101.70822\n", "2020-01-05 199.95809 205.15859 101.70822\n", "group first second\n", "2020-01-01 200.88010 98.87990\n", "2020-01-02 200.67210 98.57588\n", "2020-01-03 200.86613 101.41618\n", "2020-01-04 200.35809 101.70822\n", "2020-01-05 199.95809 101.70822\n", "group first second\n", "2020-01-01 200.88010 98.87990\n", "2020-01-02 200.67210 98.57588\n", "2020-01-03 200.86613 101.41618\n", "2020-01-04 200.35809 101.70822\n", "2020-01-05 199.95809 101.70822\n", "group first second\n", "2020-01-01 200.88010 98.87990\n", "2020-01-02 200.67210 98.57588\n", "2020-01-03 200.86613 101.41618\n", "2020-01-04 200.35809 101.70822\n", "2020-01-05 199.95809 101.70822\n" ] } ], "source": [ "print(portfolio.cash(free=True))\n", "print(portfolio.cash())\n", "print(portfolio_grouped.cash(group_by=False))\n", "print(portfolio_shared.cash(group_by=False))\n", "print(portfolio_shared.cash(group_by=False, in_sim_order=True))\n", "\n", "print(portfolio.cash(group_by=group_by))\n", "print(portfolio_grouped.cash())\n", "print(portfolio_shared.cash())" ] }, { "cell_type": "code", "execution_count": 90, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "19.4 ms ± 920 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "18.3 ms ± 470 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "18.4 ms ± 2.12 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "17.6 ms ± 201 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "18.7 ms ± 303 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n", "18.3 ms ± 292 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "19.6 ms ± 1.75 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "21.7 ms ± 1.76 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" ] } ], "source": [ "%timeit big_portfolio.cash()\n", "%timeit big_portfolio.cash(free=True)\n", "%timeit big_portfolio_grouped.cash(group_by=False)\n", "%timeit big_portfolio_shared.cash(group_by=False)\n", "%timeit big_portfolio_shared.cash(group_by=False, in_sim_order=True)\n", "\n", "%timeit big_portfolio.cash(group_by=big_group_by)\n", "%timeit big_portfolio_grouped.cash()\n", "%timeit big_portfolio_shared.cash()" ] }, { "cell_type": "code", "execution_count": 133, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " a b c\n", "2020-01-01 0.0 0.0 1.0\n", "2020-01-02 0.2 0.0 2.2\n", "2020-01-03 0.0 0.0 0.3\n", "2020-01-04 0.0 0.0 0.0\n", "2020-01-05 5.0 0.0 0.0\n", " a b c\n", "2020-01-01 0.0 1.0 0.0\n", "2020-01-02 0.0 2.2 0.0\n", "2020-01-03 0.0 2.2 0.0\n", "2020-01-04 0.0 4.0 0.0\n", "2020-01-05 0.0 10.0 0.0\n", " a b c\n", "2020-01-01 0.0 -1.0 1.0\n", "2020-01-02 0.2 -2.2 2.2\n", "2020-01-03 0.0 -2.2 0.3\n", "2020-01-04 0.0 -4.0 0.0\n", "2020-01-05 5.0 -10.0 0.0\n", " a b c\n", "2020-01-01 0.0 -1.0 1.0\n", "2020-01-02 0.2 -2.2 2.2\n", "2020-01-03 0.0 -2.2 0.3\n", "2020-01-04 0.0 -4.0 0.0\n", "2020-01-05 5.0 -10.0 0.0\n", " a b c\n", "2020-01-01 0.0 -1.0 1.0\n", "2020-01-02 0.2 -2.2 2.2\n", "2020-01-03 0.0 -2.2 0.3\n", "2020-01-04 0.0 -4.0 0.0\n", "2020-01-05 5.0 -10.0 0.0\n", "group first second\n", "2020-01-01 -1.0 1.0\n", "2020-01-02 -2.0 2.2\n", "2020-01-03 -2.2 0.3\n", "2020-01-04 -4.0 0.0\n", "2020-01-05 -5.0 0.0\n", "group first second\n", "2020-01-01 -1.0 1.0\n", "2020-01-02 -2.0 2.2\n", "2020-01-03 -2.2 0.3\n", "2020-01-04 -4.0 0.0\n", "2020-01-05 -5.0 0.0\n", "group first second\n", "2020-01-01 -1.0 1.0\n", "2020-01-02 -2.0 2.2\n", "2020-01-03 -2.2 0.3\n", "2020-01-04 -4.0 0.0\n", "2020-01-05 -5.0 0.0\n" ] } ], "source": [ "print(portfolio.asset_value(direction='longonly'))\n", "print(portfolio.asset_value(direction='shortonly'))\n", "\n", "print(portfolio.asset_value())\n", "print(portfolio_grouped.asset_value(group_by=False))\n", "print(portfolio_shared.asset_value(group_by=False))\n", "\n", "print(portfolio.asset_value(group_by=group_by))\n", "print(portfolio_grouped.asset_value())\n", "print(portfolio_shared.asset_value())" ] }, { "cell_type": "code", "execution_count": 92, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "16.7 ms ± 331 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "19.4 ms ± 2.51 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "18.4 ms ± 1.48 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "34.4 ms ± 308 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "33.6 ms ± 428 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "34.7 ms ± 213 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" ] } ], "source": [ "%timeit big_portfolio.asset_value()\n", "%timeit big_portfolio_grouped.asset_value(group_by=False)\n", "%timeit big_portfolio_shared.asset_value(group_by=False)\n", "\n", "%timeit big_portfolio.asset_value(group_by=big_group_by)\n", "%timeit big_portfolio_grouped.asset_value()\n", "%timeit big_portfolio_shared.asset_value()" ] }, { "cell_type": "code", "execution_count": 134, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " a b c\n", "2020-01-01 0.000000 0.0 0.010012\n", "2020-01-02 0.002002 0.0 0.021831\n", "2020-01-03 0.000000 0.0 0.002949\n", "2020-01-04 0.000000 0.0 0.000000\n", "2020-01-05 0.050156 0.0 0.000000\n", " a b c\n", "2020-01-01 0.0 0.010010 0.0\n", "2020-01-02 0.0 0.021825 0.0\n", "2020-01-03 0.0 0.021825 0.0\n", "2020-01-04 0.0 0.039098 0.0\n", "2020-01-05 0.0 0.096891 0.0\n", " a b c\n", "2020-01-01 0.000000 -0.010214 0.010012\n", "2020-01-02 0.002002 -0.022822 0.021831\n", "2020-01-03 0.000000 -0.022822 0.002949\n", "2020-01-04 0.000000 -0.042414 0.000000\n", "2020-01-05 0.050156 -0.120180 0.000000\n", " a b c\n", "2020-01-01 0.000000 -0.010214 0.010012\n", "2020-01-02 0.002002 -0.022822 0.021831\n", "2020-01-03 0.000000 -0.022822 0.002949\n", "2020-01-04 0.000000 -0.042414 0.000000\n", "2020-01-05 0.050156 -0.120180 0.000000\n", " a b c\n", "2020-01-01 0.000000 -0.005053 0.010012\n", "2020-01-02 0.001001 -0.011202 0.021831\n", "2020-01-03 0.000000 -0.011202 0.002949\n", "2020-01-04 0.000000 -0.020586 0.000000\n", "2020-01-05 0.025039 -0.054583 0.000000\n", "group first second\n", "2020-01-01 -0.005053 0.010012\n", "2020-01-02 -0.010189 0.021831\n", "2020-01-03 -0.011208 0.002949\n", "2020-01-04 -0.020598 0.000000\n", "2020-01-05 -0.027338 0.000000\n", "group first second\n", "2020-01-01 -0.005053 0.010012\n", "2020-01-02 -0.010189 0.021831\n", "2020-01-03 -0.011208 0.002949\n", "2020-01-04 -0.020598 0.000000\n", "2020-01-05 -0.027338 0.000000\n", "group first second\n", "2020-01-01 -0.005053 0.010012\n", "2020-01-02 -0.010189 0.021831\n", "2020-01-03 -0.011208 0.002949\n", "2020-01-04 -0.020598 0.000000\n", "2020-01-05 -0.027338 0.000000\n" ] } ], "source": [ "print(portfolio.gross_exposure(direction='longonly'))\n", "print(portfolio.gross_exposure(direction='shortonly'))\n", "\n", "print(portfolio.gross_exposure())\n", "print(portfolio_grouped.gross_exposure(group_by=False))\n", "print(portfolio_shared.gross_exposure(group_by=False))\n", "\n", "print(portfolio.gross_exposure(group_by=group_by))\n", "print(portfolio_grouped.gross_exposure())\n", "print(portfolio_shared.gross_exposure())" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "54.6 ms ± 5.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n", "44.3 ms ± 1.64 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "44.2 ms ± 1.07 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "58.8 ms ± 2.64 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "55 ms ± 1.09 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "60.9 ms ± 1.87 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" ] } ], "source": [ "%timeit big_portfolio.gross_exposure()\n", "%timeit big_portfolio_grouped.gross_exposure(group_by=False)\n", "%timeit big_portfolio_shared.gross_exposure(group_by=False)\n", "\n", "%timeit big_portfolio.gross_exposure(group_by=big_group_by)\n", "%timeit big_portfolio_grouped.gross_exposure()\n", "%timeit big_portfolio_shared.gross_exposure()" ] }, { "cell_type": "code", "execution_count": 135, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " a b c\n", "2020-01-01 0.000000 -0.010010 0.010012\n", "2020-01-02 0.002002 -0.021825 0.021831\n", "2020-01-03 0.000000 -0.021825 0.002949\n", "2020-01-04 0.000000 -0.039098 0.000000\n", "2020-01-05 0.050156 -0.096891 0.000000\n", " a b c\n", "2020-01-01 0.000000 -0.010010 0.010012\n", "2020-01-02 0.002002 -0.021825 0.021831\n", "2020-01-03 0.000000 -0.021825 0.002949\n", "2020-01-04 0.000000 -0.039098 0.000000\n", "2020-01-05 0.050156 -0.096891 0.000000\n", " a b c\n", "2020-01-01 0.000000 -0.005002 0.010012\n", "2020-01-02 0.001001 -0.010956 0.021831\n", "2020-01-03 0.000000 -0.010956 0.002949\n", "2020-01-04 0.000000 -0.019772 0.000000\n", "2020-01-05 0.025039 -0.049211 0.000000\n", "group first second\n", "2020-01-01 -0.005002 0.010012\n", "2020-01-02 -0.009965 0.021831\n", "2020-01-03 -0.010962 0.002949\n", "2020-01-04 -0.019783 0.000000\n", "2020-01-05 -0.024611 0.000000\n", "group first second\n", "2020-01-01 -0.005002 0.010012\n", "2020-01-02 -0.009965 0.021831\n", "2020-01-03 -0.010962 0.002949\n", "2020-01-04 -0.019783 0.000000\n", "2020-01-05 -0.024611 0.000000\n", "group first second\n", "2020-01-01 -0.005002 0.010012\n", "2020-01-02 -0.009965 0.021831\n", "2020-01-03 -0.010962 0.002949\n", "2020-01-04 -0.019783 0.000000\n", "2020-01-05 -0.024611 0.000000\n" ] } ], "source": [ "print(portfolio.net_exposure())\n", "print(portfolio_grouped.net_exposure(group_by=False))\n", "print(portfolio_shared.net_exposure(group_by=False))\n", "\n", "print(portfolio.net_exposure(group_by=group_by))\n", "print(portfolio_grouped.net_exposure())\n", "print(portfolio_shared.net_exposure())" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "91.5 ms ± 1.76 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "90.4 ms ± 1.52 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "95.4 ms ± 4.26 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "129 ms ± 3.21 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "119 ms ± 1.51 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "127 ms ± 1.85 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" ] } ], "source": [ "%timeit big_portfolio.net_exposure()\n", "%timeit big_portfolio_grouped.net_exposure(group_by=False)\n", "%timeit big_portfolio_shared.net_exposure(group_by=False)\n", "\n", "%timeit big_portfolio.net_exposure(group_by=big_group_by)\n", "%timeit big_portfolio_grouped.net_exposure()\n", "%timeit big_portfolio_shared.net_exposure()" ] }, { "cell_type": "code", "execution_count": 136, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " a b c\n", "2020-01-01 100.00000 99.88010 99.87990\n", "2020-01-02 99.89598 98.77612 100.77588\n", "2020-01-03 99.89001 98.77612 101.71618\n", "2020-01-04 99.89001 96.46808 101.70822\n", "2020-01-05 99.68951 95.26858 101.70822\n", " a b c\n", "2020-01-01 100.00000 99.88010 99.87990\n", "2020-01-02 99.89598 98.77612 100.77588\n", "2020-01-03 99.89001 98.77612 101.71618\n", "2020-01-04 99.89001 96.46808 101.70822\n", "2020-01-05 99.68951 95.26858 101.70822\n", " a b c\n", "2020-01-01 200.00000 199.88010 99.87990\n", "2020-01-02 199.89598 198.77612 100.77588\n", "2020-01-03 199.89001 198.77612 101.71618\n", "2020-01-04 199.89001 196.46808 101.70822\n", "2020-01-05 199.68951 195.26858 101.70822\n", " a b c\n", "2020-01-01 199.88010 199.88010 99.87990\n", "2020-01-02 198.67210 198.77612 100.77588\n", "2020-01-03 198.66613 198.67210 101.71618\n", "2020-01-04 196.35809 196.35809 101.70822\n", "2020-01-05 194.95809 195.15859 101.70822\n", "group first second\n", "2020-01-01 199.88010 99.87990\n", "2020-01-02 198.67210 100.77588\n", "2020-01-03 198.66613 101.71618\n", "2020-01-04 196.35809 101.70822\n", "2020-01-05 194.95809 101.70822\n", "group first second\n", "2020-01-01 199.88010 99.87990\n", "2020-01-02 198.67210 100.77588\n", "2020-01-03 198.66613 101.71618\n", "2020-01-04 196.35809 101.70822\n", "2020-01-05 194.95809 101.70822\n", "group first second\n", "2020-01-01 199.88010 99.87990\n", "2020-01-02 198.67210 100.77588\n", "2020-01-03 198.66613 101.71618\n", "2020-01-04 196.35809 101.70822\n", "2020-01-05 194.95809 101.70822\n" ] } ], "source": [ "print(portfolio.value())\n", "print(portfolio_grouped.value(group_by=False))\n", "print(portfolio_shared.value(group_by=False))\n", "print(portfolio_shared.value(group_by=False, in_sim_order=True))\n", "\n", "print(portfolio.value(group_by=group_by))\n", "print(portfolio_grouped.value())\n", "print(portfolio_shared.value())" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "36.9 ms ± 1.21 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "35 ms ± 210 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "35.8 ms ± 81.1 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "46 ms ± 152 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "53.9 ms ± 626 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "50.4 ms ± 722 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "55.3 ms ± 941 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" ] } ], "source": [ "%timeit big_portfolio.value()\n", "%timeit big_portfolio_grouped.value(group_by=False)\n", "%timeit big_portfolio_shared.value(group_by=False)\n", "%timeit big_portfolio_shared.value(group_by=False, in_sim_order=True)\n", "\n", "%timeit big_portfolio.value(group_by=big_group_by)\n", "%timeit big_portfolio_grouped.value()\n", "%timeit big_portfolio_shared.value()" ] }, { "cell_type": "code", "execution_count": 137, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a -0.31049\n", "b -4.73142\n", "c 1.70822\n", "Name: total_profit, dtype: float64\n", "a -0.31049\n", "b -4.73142\n", "c 1.70822\n", "Name: total_profit, dtype: float64\n", "a -0.31049\n", "b -4.73142\n", "c 1.70822\n", "Name: total_profit, dtype: float64\n", "group\n", "first -5.04191\n", "second 1.70822\n", "Name: total_profit, dtype: float64\n", "group\n", "first -5.04191\n", "second 1.70822\n", "Name: total_profit, dtype: float64\n", "group\n", "first -5.04191\n", "second 1.70822\n", "Name: total_profit, dtype: float64\n" ] } ], "source": [ "print(portfolio.total_profit())\n", "print(portfolio_grouped.total_profit(group_by=False))\n", "print(portfolio_shared.total_profit(group_by=False))\n", "\n", "print(portfolio.total_profit(group_by=group_by))\n", "print(portfolio_grouped.total_profit())\n", "print(portfolio_shared.total_profit())" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "12.3 ms ± 79.7 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n", "12.5 ms ± 190 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "12.5 ms ± 225 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "13.2 ms ± 224 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "12.6 ms ± 176 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "13.4 ms ± 217 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n" ] } ], "source": [ "%timeit big_portfolio.total_profit()\n", "%timeit big_portfolio_grouped.total_profit(group_by=False)\n", "%timeit big_portfolio_shared.total_profit(group_by=False)\n", "\n", "%timeit big_portfolio.total_profit(group_by=big_group_by)\n", "%timeit big_portfolio_grouped.total_profit()\n", "%timeit big_portfolio_shared.total_profit()" ] }, { "cell_type": "code", "execution_count": 138, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a 99.68951\n", "b 95.26858\n", "c 101.70822\n", "Name: final_value, dtype: float64\n", "a 99.68951\n", "b 95.26858\n", "c 101.70822\n", "Name: final_value, dtype: float64\n", "a 199.68951\n", "b 195.26858\n", "c 101.70822\n", "Name: final_value, dtype: float64\n", "group\n", "first 194.95809\n", "second 101.70822\n", "Name: final_value, dtype: float64\n", "group\n", "first 194.95809\n", "second 101.70822\n", "Name: final_value, dtype: float64\n", "group\n", "first 194.95809\n", "second 101.70822\n", "Name: final_value, dtype: float64\n" ] } ], "source": [ "print(portfolio.final_value())\n", "print(portfolio_grouped.final_value(group_by=False))\n", "print(portfolio_shared.final_value(group_by=False))\n", "\n", "print(portfolio.final_value(group_by=group_by))\n", "print(portfolio_grouped.final_value())\n", "print(portfolio_shared.final_value())" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "12.3 ms ± 159 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "12.2 ms ± 122 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "12.9 ms ± 128 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "14.1 ms ± 280 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "12 ms ± 145 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "14.1 ms ± 231 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n" ] } ], "source": [ "%timeit big_portfolio.final_value()\n", "%timeit big_portfolio_grouped.final_value(group_by=False)\n", "%timeit big_portfolio_shared.final_value(group_by=False)\n", "\n", "%timeit big_portfolio.final_value(group_by=big_group_by)\n", "%timeit big_portfolio_grouped.final_value()\n", "%timeit big_portfolio_shared.final_value()" ] }, { "cell_type": "code", "execution_count": 139, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a -0.003105\n", "b -0.047314\n", "c 0.017082\n", "Name: total_return, dtype: float64\n", "a -0.003105\n", "b -0.047314\n", "c 0.017082\n", "Name: total_return, dtype: float64\n", "a -0.001552\n", "b -0.023657\n", "c 0.017082\n", "Name: total_return, dtype: float64\n", "group\n", "first -0.025210\n", "second 0.017082\n", "Name: total_return, dtype: float64\n", "group\n", "first -0.025210\n", "second 0.017082\n", "Name: total_return, dtype: float64\n", "group\n", "first -0.025210\n", "second 0.017082\n", "Name: total_return, dtype: float64\n" ] } ], "source": [ "print(portfolio.total_return())\n", "print(portfolio_grouped.total_return(group_by=False))\n", "print(portfolio_shared.total_return(group_by=False))\n", "\n", "print(portfolio.total_return(group_by=group_by))\n", "print(portfolio_grouped.total_return())\n", "print(portfolio_shared.total_return())" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "12.5 ms ± 200 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "12.4 ms ± 207 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "12.8 ms ± 151 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "14 ms ± 178 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "12.6 ms ± 199 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "14.2 ms ± 122 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n" ] } ], "source": [ "%timeit big_portfolio.total_return()\n", "%timeit big_portfolio_grouped.total_return(group_by=False)\n", "%timeit big_portfolio_shared.total_return(group_by=False)\n", "\n", "%timeit big_portfolio.total_return(group_by=big_group_by)\n", "%timeit big_portfolio_grouped.total_return()\n", "%timeit big_portfolio_shared.total_return()" ] }, { "cell_type": "code", "execution_count": 140, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " a b c\n", "2020-01-01 0.000000 -0.001199 -0.001201\n", "2020-01-02 -0.001040 -0.011053 0.008971\n", "2020-01-03 -0.000060 0.000000 0.009331\n", "2020-01-04 0.000000 -0.023366 -0.000078\n", "2020-01-05 -0.002007 -0.012434 0.000000\n", " a b c\n", "2020-01-01 0.000000 -0.001199 -0.001201\n", "2020-01-02 -0.001040 -0.011053 0.008971\n", "2020-01-03 -0.000060 0.000000 0.009331\n", "2020-01-04 0.000000 -0.023366 -0.000078\n", "2020-01-05 -0.002007 -0.012434 0.000000\n", " a b c\n", "2020-01-01 0.000000 -0.000600 -0.001201\n", "2020-01-02 -0.000520 -0.005523 0.008971\n", "2020-01-03 -0.000030 0.000000 0.009331\n", "2020-01-04 0.000000 -0.011611 -0.000078\n", "2020-01-05 -0.001003 -0.006105 0.000000\n", " a b c\n", "2020-01-01 0.000000 -0.000600 -0.001201\n", "2020-01-02 -0.000523 -0.005523 0.008971\n", "2020-01-03 -0.000030 0.000000 0.009331\n", "2020-01-04 0.000000 -0.011618 -0.000078\n", "2020-01-05 -0.001027 -0.006109 0.000000\n", "group first second\n", "2020-01-01 -0.000600 -0.001201\n", "2020-01-02 -0.006044 0.008971\n", "2020-01-03 -0.000030 0.009331\n", "2020-01-04 -0.011618 -0.000078\n", "2020-01-05 -0.007130 0.000000\n", "group first second\n", "2020-01-01 -0.000600 -0.001201\n", "2020-01-02 -0.006044 0.008971\n", "2020-01-03 -0.000030 0.009331\n", "2020-01-04 -0.011618 -0.000078\n", "2020-01-05 -0.007130 0.000000\n", "group first second\n", "2020-01-01 -0.000600 -0.001201\n", "2020-01-02 -0.006044 0.008971\n", "2020-01-03 -0.000030 0.009331\n", "2020-01-04 -0.011618 -0.000078\n", "2020-01-05 -0.007130 0.000000\n" ] } ], "source": [ "print(portfolio.returns())\n", "print(portfolio_grouped.returns(group_by=False))\n", "print(portfolio_shared.returns(group_by=False))\n", "print(portfolio_shared.returns(group_by=False, in_sim_order=True))\n", "\n", "print(portfolio.returns(group_by=group_by))\n", "print(portfolio_grouped.returns())\n", "print(portfolio_shared.returns())" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "39.5 ms ± 2.59 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "37.4 ms ± 313 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "39.4 ms ± 226 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "52.3 ms ± 149 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "55.6 ms ± 310 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "50.9 ms ± 276 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "63.5 ms ± 4.23 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" ] } ], "source": [ "%timeit big_portfolio.returns()\n", "%timeit big_portfolio_grouped.returns(group_by=False)\n", "%timeit big_portfolio_shared.returns(group_by=False)\n", "%timeit big_portfolio_shared.returns(group_by=False, in_sim_order=True)\n", "\n", "%timeit big_portfolio.returns(group_by=big_group_by)\n", "%timeit big_portfolio_grouped.returns()\n", "%timeit big_portfolio_shared.returns()" ] }, { "cell_type": "code", "execution_count": 141, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " a b c\n", "2020-01-01 0.00000 -inf -inf\n", "2020-01-02 -inf -1.103980 0.895980\n", "2020-01-03 -0.02985 0.000000 0.427409\n", "2020-01-04 0.00000 -1.049109 -0.026533\n", "2020-01-05 -inf -0.299875 0.000000\n", " a b c\n", "2020-01-01 0.00000 -inf -inf\n", "2020-01-02 -inf -1.103980 0.895980\n", "2020-01-03 -0.02985 0.000000 0.427409\n", "2020-01-04 0.00000 -1.049109 -0.026533\n", "2020-01-05 -inf -0.299875 0.000000\n", " a b c\n", "2020-01-01 0.00000 -inf -inf\n", "2020-01-02 -inf -1.103980 0.895980\n", "2020-01-03 -0.02985 0.000000 0.427409\n", "2020-01-04 0.00000 -1.049109 -0.026533\n", "2020-01-05 -inf -0.299875 0.000000\n", "group first second\n", "2020-01-01 -inf -inf\n", "2020-01-02 -1.208000 0.895980\n", "2020-01-03 -0.002985 0.427409\n", "2020-01-04 -1.049109 -0.026533\n", "2020-01-05 -0.350000 0.000000\n", "group first second\n", "2020-01-01 -inf -inf\n", "2020-01-02 -1.208000 0.895980\n", "2020-01-03 -0.002985 0.427409\n", "2020-01-04 -1.049109 -0.026533\n", "2020-01-05 -0.350000 0.000000\n", "group first second\n", "2020-01-01 -inf -inf\n", "2020-01-02 -1.208000 0.895980\n", "2020-01-03 -0.002985 0.427409\n", "2020-01-04 -1.049109 -0.026533\n", "2020-01-05 -0.350000 0.000000\n" ] } ], "source": [ "print(portfolio.active_returns())\n", "print(portfolio_grouped.active_returns(group_by=False))\n", "print(portfolio_shared.active_returns(group_by=False))\n", "\n", "print(portfolio.active_returns(group_by=group_by))\n", "print(portfolio_grouped.active_returns())\n", "print(portfolio_shared.active_returns())" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "40.2 ms ± 5.18 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "36.9 ms ± 235 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "37.4 ms ± 193 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "51.7 ms ± 195 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "49.8 ms ± 220 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "52.4 ms ± 264 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" ] } ], "source": [ "%timeit big_portfolio.active_returns()\n", "%timeit big_portfolio_grouped.active_returns(group_by=False)\n", "%timeit big_portfolio_shared.active_returns(group_by=False)\n", "\n", "%timeit big_portfolio.active_returns(group_by=big_group_by)\n", "%timeit big_portfolio_grouped.active_returns()\n", "%timeit big_portfolio_shared.active_returns()" ] }, { "cell_type": "code", "execution_count": 142, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " a b c\n", "2020-01-01 100.0 100.0 100.0\n", "2020-01-02 100.0 200.0 200.0\n", "2020-01-03 150.0 200.0 300.0\n", "2020-01-04 200.0 400.0 400.0\n", "2020-01-05 250.0 500.0 400.0\n", " a b c\n", "2020-01-01 100.0 100.0 100.0\n", "2020-01-02 100.0 200.0 200.0\n", "2020-01-03 150.0 200.0 300.0\n", "2020-01-04 200.0 400.0 400.0\n", "2020-01-05 250.0 500.0 400.0\n", " a b c\n", "2020-01-01 200.0 200.0 100.0\n", "2020-01-02 200.0 400.0 200.0\n", "2020-01-03 300.0 400.0 300.0\n", "2020-01-04 400.0 800.0 400.0\n", "2020-01-05 500.0 1000.0 400.0\n", "group first second\n", "2020-01-01 200.0 100.0\n", "2020-01-02 300.0 200.0\n", "2020-01-03 350.0 300.0\n", "2020-01-04 600.0 400.0\n", "2020-01-05 750.0 400.0\n", "group first second\n", "2020-01-01 200.0 100.0\n", "2020-01-02 300.0 200.0\n", "2020-01-03 350.0 300.0\n", "2020-01-04 600.0 400.0\n", "2020-01-05 750.0 400.0\n", "group first second\n", "2020-01-01 200.0 100.0\n", "2020-01-02 300.0 200.0\n", "2020-01-03 350.0 300.0\n", "2020-01-04 600.0 400.0\n", "2020-01-05 750.0 400.0\n" ] } ], "source": [ "print(portfolio.market_value())\n", "print(portfolio_grouped.market_value(group_by=False))\n", "print(portfolio_shared.market_value(group_by=False))\n", "\n", "print(portfolio.market_value(group_by=group_by))\n", "print(portfolio_grouped.market_value())\n", "print(portfolio_shared.market_value())" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "909 µs ± 51.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n", "967 µs ± 34.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n", "1.81 ms ± 111 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "4.86 ms ± 415 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n", "2.82 ms ± 35.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "5.2 ms ± 387 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" ] } ], "source": [ "%timeit big_portfolio.market_value()\n", "%timeit big_portfolio_grouped.market_value(group_by=False)\n", "%timeit big_portfolio_shared.market_value(group_by=False)\n", "\n", "%timeit big_portfolio.market_value(group_by=big_group_by)\n", "%timeit big_portfolio_grouped.market_value()\n", "%timeit big_portfolio_shared.market_value()" ] }, { "cell_type": "code", "execution_count": 143, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " a b c\n", "2020-01-01 0.000000 0.00 0.000000\n", "2020-01-02 0.000000 1.00 1.000000\n", "2020-01-03 0.500000 0.00 0.500000\n", "2020-01-04 0.333333 1.00 0.333333\n", "2020-01-05 0.250000 0.25 0.000000\n", " a b c\n", "2020-01-01 0.000000 0.00 0.000000\n", "2020-01-02 0.000000 1.00 1.000000\n", "2020-01-03 0.500000 0.00 0.500000\n", "2020-01-04 0.333333 1.00 0.333333\n", "2020-01-05 0.250000 0.25 0.000000\n", " a b c\n", "2020-01-01 0.000000 0.00 0.000000\n", "2020-01-02 0.000000 1.00 1.000000\n", "2020-01-03 0.500000 0.00 0.500000\n", "2020-01-04 0.333333 1.00 0.333333\n", "2020-01-05 0.250000 0.25 0.000000\n", "group first second\n", "2020-01-01 0.000000 0.000000\n", "2020-01-02 0.500000 1.000000\n", "2020-01-03 0.166667 0.500000\n", "2020-01-04 0.714286 0.333333\n", "2020-01-05 0.250000 0.000000\n", "group first second\n", "2020-01-01 0.000000 0.000000\n", "2020-01-02 0.500000 1.000000\n", "2020-01-03 0.166667 0.500000\n", "2020-01-04 0.714286 0.333333\n", "2020-01-05 0.250000 0.000000\n", "group first second\n", "2020-01-01 0.000000 0.000000\n", "2020-01-02 0.500000 1.000000\n", "2020-01-03 0.166667 0.500000\n", "2020-01-04 0.714286 0.333333\n", "2020-01-05 0.250000 0.000000\n" ] } ], "source": [ "print(portfolio.market_returns())\n", "print(portfolio_grouped.market_returns(group_by=False))\n", "print(portfolio_shared.market_returns(group_by=False))\n", "\n", "print(portfolio.market_returns(group_by=group_by))\n", "print(portfolio_grouped.market_returns())\n", "print(portfolio_shared.market_returns())" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3.7 ms ± 67.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "3.72 ms ± 66.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "5.11 ms ± 5.82 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "7.2 ms ± 618 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "4.1 ms ± 52.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "7.28 ms ± 40.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n" ] } ], "source": [ "%timeit big_portfolio.market_returns()\n", "%timeit big_portfolio_grouped.market_returns(group_by=False)\n", "%timeit big_portfolio_shared.market_returns(group_by=False)\n", "\n", "%timeit big_portfolio.market_returns(group_by=big_group_by)\n", "%timeit big_portfolio_grouped.market_returns()\n", "%timeit big_portfolio_shared.market_returns()" ] }, { "cell_type": "code", "execution_count": 144, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a 1.5\n", "b 4.0\n", "c 3.0\n", "Name: total_market_return, dtype: float64\n", "a 1.5\n", "b 4.0\n", "c 3.0\n", "Name: total_market_return, dtype: float64\n", "a 1.5\n", "b 4.0\n", "c 3.0\n", "Name: total_market_return, dtype: float64\n", "group\n", "first 2.75\n", "second 3.00\n", "Name: total_market_return, dtype: float64\n", "group\n", "first 2.75\n", "second 3.00\n", "Name: total_market_return, dtype: float64\n", "group\n", "first 2.75\n", "second 3.00\n", "Name: total_market_return, dtype: float64\n" ] } ], "source": [ "print(portfolio.total_market_return())\n", "print(portfolio_grouped.total_market_return(group_by=False))\n", "print(portfolio_shared.total_market_return(group_by=False))\n", "\n", "print(portfolio.total_market_return(group_by=group_by))\n", "print(portfolio_grouped.total_market_return())\n", "print(portfolio_shared.total_market_return())" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "975 µs ± 61.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n", "937 µs ± 10.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n", "1.83 ms ± 7.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n", "4.77 ms ± 30 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "2.85 ms ± 11.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "5.21 ms ± 79.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n" ] } ], "source": [ "%timeit big_portfolio.total_market_return()\n", "%timeit big_portfolio_grouped.total_market_return(group_by=False)\n", "%timeit big_portfolio_shared.total_market_return(group_by=False)\n", "\n", "%timeit big_portfolio.total_market_return(group_by=big_group_by)\n", "%timeit big_portfolio_grouped.total_market_return()\n", "%timeit big_portfolio_shared.total_market_return()" ] }, { "cell_type": "code", "execution_count": 145, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "group first second\n", "2020-01-01 -0.000599 -0.001201\n", "2020-01-02 -0.006639 0.007759\n", "2020-01-03 -0.006669 0.017162\n", "2020-01-04 -0.018210 0.017082\n", "2020-01-05 -0.025210 0.017082\n", " a b c\n", "2020-01-01 0.000000 -0.000599 -0.001201\n", "2020-01-02 -0.000520 -0.006119 0.007759\n", "2020-01-03 -0.000550 -0.006119 0.017162\n", "2020-01-04 -0.000550 -0.017660 0.017082\n", "2020-01-05 -0.001552 -0.023657 0.017082\n" ] } ], "source": [ "print(portfolio_shared.cumulative_returns())\n", "print(portfolio_shared.cumulative_returns(group_by=False))" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "group\n", "first -20.095907\n", "second 12.345065\n", "Name: sharpe_ratio, dtype: float64\n", "group\n", "first -59.622588\n", "second -23.917188\n", "Name: sharpe_ratio, dtype: float64\n", "group\n", "first -16.697884\n", "second 10.257635\n", "Name: sharpe_ratio, dtype: float64\n", "a -13.309506\n", "b -19.278625\n", "c 12.345065\n", "Name: sharpe_ratio, dtype: float64\n" ] } ], "source": [ "print(portfolio_shared.sharpe_ratio())\n", "print(portfolio_shared.sharpe_ratio(risk_free=0.01))\n", "print(portfolio_shared.sharpe_ratio(year_freq='252D'))\n", "print(portfolio_shared.sharpe_ratio(group_by=False))" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Start 2020-01-01 00:00:00\n", "End 2020-01-05 00:00:00\n", "Period 5 days 00:00:00\n", "Start Value 100.0\n", "End Value 98.88877\n", "Total Return [%] -1.11123\n", "Benchmark Return [%] 283.333333\n", "Max Gross Exposure [%] 2.059062\n", "Total Fees Paid 0.42223\n", "Max Drawdown [%] 1.645124\n", "Max Drawdown Duration 3 days 08:00:00\n", "Total Trades 2.0\n", "Total Closed Trades 1.333333\n", "Total Open Trades 0.666667\n", "Open Trade PnL -1.504206\n", "Win Rate [%] 33.333333\n", "Best Trade [%] -98.380588\n", "Worst Trade [%] -100.803855\n", "Avg Winning Trade [%] 143.916254\n", "Avg Losing Trade [%] -221.34646\n", "Avg Winning Trade Duration 2 days 12:00:00\n", "Avg Losing Trade Duration 2 days 00:00:00\n", "Profit Factor inf\n", "Expectancy 0.108273\n", "Sharpe Ratio -6.751008\n", "Calmar Ratio 10378.930331\n", "Omega Ratio 4.7687\n", "Sortino Ratio 31.599761\n", "Name: agg_func_mean, dtype: object\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "/Users/olegpolakow/miniconda3/lib/python3.7/site-packages/ipykernel_launcher.py:1: UserWarning: Object has multiple columns. Aggregating using . Pass column to select a single column/group.\n", " \"\"\"Entry point for launching an IPython kernel.\n" ] } ], "source": [ "print(portfolio.stats()) # mean statistics" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Start 2020-01-01 00:00:00\n", "End 2020-01-05 00:00:00\n", "Period 5 days 00:00:00\n", "Start Value 100.0\n", "End Value 99.68951\n", "Total Return [%] -0.31049\n", "Benchmark Return [%] 150.0\n", "Max Gross Exposure [%] 5.015573\n", "Total Fees Paid 0.35549\n", "Max Drawdown [%] 0.31049\n", "Max Drawdown Duration 4 days 00:00:00\n", "Total Trades 2\n", "Total Closed Trades 1\n", "Total Open Trades 1\n", "Open Trade PnL -0.2005\n", "Win Rate [%] 0.0\n", "Best Trade [%] -54.450495\n", "Worst Trade [%] -54.450495\n", "Avg Winning Trade [%] NaN\n", "Avg Losing Trade [%] -54.450495\n", "Avg Winning Trade Duration NaT\n", "Avg Losing Trade Duration 1 days 00:00:00\n", "Profit Factor 0.0\n", "Expectancy -0.10999\n", "Sharpe Ratio -13.308045\n", "Calmar Ratio -65.408686\n", "Omega Ratio 0.0\n", "Sortino Ratio -11.738865\n", "Name: a, dtype: object\n" ] } ], "source": [ "print(portfolio['a'].stats())" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Start 2020-01-01 00:00:00\n", "End 2020-01-05 00:00:00\n", "Period 5 days 00:00:00\n", "Start Value 100.0\n", "End Value 99.68951\n", "Total Return [%] -0.31049\n", "Benchmark Return [%] 150.0\n", "Max Gross Exposure [%] 5.015573\n", "Total Fees Paid 0.35549\n", "Max Drawdown [%] 0.31049\n", "Max Drawdown Duration 4 days 00:00:00\n", "Total Trades 2\n", "Total Closed Trades 1\n", "Total Open Trades 1\n", "Open Trade PnL -0.2005\n", "Win Rate [%] 0.0\n", "Best Trade [%] -54.450495\n", "Worst Trade [%] -54.450495\n", "Avg Winning Trade [%] NaN\n", "Avg Losing Trade [%] -54.450495\n", "Avg Winning Trade Duration NaT\n", "Avg Losing Trade Duration 1 days 00:00:00\n", "Profit Factor 0.0\n", "Expectancy -0.10999\n", "Sharpe Ratio -227.458628\n", "Calmar Ratio -65.408686\n", "Omega Ratio 0.0\n", "Sortino Ratio -19.104372\n", "Name: a, dtype: object\n" ] } ], "source": [ "print(portfolio['a'].stats(settings=dict(required_return=0.1, risk_free=0.01))) # test kwargs" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Start 2020-01-01 00:00:00\n", "End 2020-01-05 00:00:00\n", "Period 5 days 00:00:00\n", "Start Value 100.0\n", "End Value 99.68951\n", "Total Return [%] -0.31049\n", "Benchmark Return [%] 150.0\n", "Max Gross Exposure [%] 5.015573\n", "Total Fees Paid 0.35549\n", "Max Drawdown [%] 0.31049\n", "Max Drawdown Duration 4 days 00:00:00\n", "Total Trades 2\n", "Total Closed Trades 1\n", "Total Open Trades 1\n", "Open Trade PnL -0.2005\n", "Win Rate [%] 0.0\n", "Best Trade [%] -3.970297\n", "Worst Trade [%] -54.450495\n", "Avg Winning Trade [%] NaN\n", "Avg Losing Trade [%] -29.210396\n", "Avg Winning Trade Duration NaT\n", "Avg Losing Trade Duration 1 days 00:00:00\n", "Profit Factor 0.0\n", "Expectancy -0.155245\n", "Sharpe Ratio -13.308045\n", "Calmar Ratio -65.408686\n", "Omega Ratio 0.0\n", "Sortino Ratio -11.738865\n", "Name: a, dtype: object\n" ] } ], "source": [ "print(portfolio['a'].stats(settings=dict(incl_open=True))) # test incl_open" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Start 2020-01-01 00:00:00\n", "End 2020-01-05 00:00:00\n", "Period 5 days 00:00:00\n", "Start Value 200.0\n", "End Value 194.95809\n", "Total Return [%] -2.520955\n", "Benchmark Return [%] 275.0\n", "Max Gross Exposure [%] -0.505305\n", "Total Fees Paid 0.82091\n", "Max Drawdown [%] 2.462481\n", "Max Drawdown Duration 4 days 00:00:00\n", "Total Trades 4\n", "Total Closed Trades 2\n", "Total Open Trades 2\n", "Open Trade PnL -4.512618\n", "Win Rate [%] 0.0\n", "Best Trade [%] -54.450495\n", "Worst Trade [%] -388.242424\n", "Avg Winning Trade [%] NaN\n", "Avg Losing Trade [%] -221.34646\n", "Avg Winning Trade Duration NaT\n", "Avg Losing Trade Duration 2 days 00:00:00\n", "Profit Factor 0.0\n", "Expectancy -0.264646\n", "Sharpe Ratio -20.095907\n", "Calmar Ratio -34.312217\n", "Omega Ratio 0.0\n", "Sortino Ratio -14.554512\n", "Name: first, dtype: object" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "portfolio_grouped['first'].stats()" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "tags": [] }, "outputs": [], "source": [ "pd.testing.assert_series_equal(portfolio['c'].stats(), portfolio.stats(column='c'))\n", "pd.testing.assert_series_equal(portfolio['c'].stats(), portfolio_grouped.stats(column='c', group_by=False))\n", "pd.testing.assert_series_equal(portfolio_grouped['second'].stats(), portfolio_grouped.stats(column='second'))" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "64.9 ms ± 525 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n", "76 ms ± 478 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "145 ms ± 588 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "101 ms ± 87.9 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "72.4 ms ± 151 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "158 ms ± 1.02 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" ] } ], "source": [ "# Calculates stats for one column\n", "%timeit big_portfolio.iloc[0].stats()\n", "%timeit big_portfolio_grouped.iloc[0].stats(group_by=False, column=0)\n", "%timeit big_portfolio_shared.iloc[0].stats(group_by=False, column=0)\n", "\n", "%timeit big_portfolio.iloc[0].stats(group_by=np.array([0]))\n", "%timeit big_portfolio_grouped.iloc[0].stats()\n", "%timeit big_portfolio_shared.iloc[0].stats()" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "big_portfolio_one = big_portfolio.iloc[0]" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "start\n", "1.72 ms ± 643 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "end\n", "1.17 ms ± 25.3 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "period\n", "1.18 ms ± 33.2 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "start_value\n", "1.23 ms ± 51.1 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "end_value\n", "2.43 ms ± 126 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "total_return\n", "2.38 ms ± 7.53 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "benchmark_return\n", "1.56 ms ± 12.2 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "max_gross_exposure\n", "5.51 ms ± 22.4 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "total_fees_paid\n", "2.11 ms ± 132 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "max_dd\n", "5.3 ms ± 22.5 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "max_dd_duration\n", "5.39 ms ± 49.2 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "total_trades\n", "2.68 ms ± 320 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "total_closed_trades\n", "4.07 ms ± 111 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "total_open_trades\n", "3.24 ms ± 28.8 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "open_trade_pnl\n", "3.72 ms ± 136 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "win_rate\n", "4.19 ms ± 128 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "best_trade\n", "3.62 ms ± 44.6 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "worst_trade\n", "3.71 ms ± 178 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "avg_winning_trade\n", "4.54 ms ± 161 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "avg_losing_trade\n", "4.46 ms ± 122 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "avg_winning_trade_duration\n", "4.5 ms ± 140 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "avg_losing_trade_duration\n", "4.99 ms ± 224 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "profit_factor\n", "5.82 ms ± 86.1 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "expectancy\n", "7.09 ms ± 288 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "sharpe_ratio\n", "8.79 ms ± 613 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "calmar_ratio\n", "8.56 ms ± 527 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "omega_ratio\n", "8.38 ms ± 215 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "sortino_ratio\n", "8.15 ms ± 101 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" ] } ], "source": [ "for metric in big_portfolio_one.metrics:\n", " print(metric)\n", " %timeit -n 10 big_portfolio_one.stats(metrics=metric)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "start\n", "1.51 ms ± 362 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "end\n", "1.54 ms ± 74 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "period\n", "1.92 ms ± 19.8 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "start_value\n", "2.46 ms ± 117 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "end_value\n", "4.1 ms ± 117 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "total_return\n", "5.67 ms ± 12.9 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "benchmark_return\n", "6.59 ms ± 46.7 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "max_gross_exposure\n", "11.4 ms ± 33.9 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "total_fees_paid\n", "12.8 ms ± 232 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "max_dd\n", "17.6 ms ± 281 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "max_dd_duration\n", "19.1 ms ± 833 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "total_trades\n", "20.6 ms ± 434 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "total_closed_trades\n", "22.5 ms ± 234 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "total_open_trades\n", "23.9 ms ± 228 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "open_trade_pnl\n", "25.7 ms ± 140 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "win_rate\n", "28 ms ± 246 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "best_trade\n", "30.3 ms ± 710 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "worst_trade\n", "31.9 ms ± 606 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "avg_winning_trade\n", "35.8 ms ± 1.27 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "avg_losing_trade\n", "36.8 ms ± 183 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "avg_winning_trade_duration\n", "39.5 ms ± 140 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "avg_losing_trade_duration\n", "41.7 ms ± 235 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "profit_factor\n", "45.8 ms ± 240 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "expectancy\n", "50.6 ms ± 425 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "sharpe_ratio\n", "58 ms ± 176 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "calmar_ratio\n", "58.5 ms ± 182 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "omega_ratio\n", "59.1 ms ± 227 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "sortino_ratio\n", "60 ms ± 144 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" ] } ], "source": [ "metrics = []\n", "for metric in big_portfolio_one.metrics:\n", " print(metric)\n", " metrics.append(metric)\n", " %timeit -n 10 big_portfolio_one.stats(metrics=metrics)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "38 ms ± 179 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "47.3 ms ± 852 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n", "94.6 ms ± 237 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "68.4 ms ± 511 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "40.1 ms ± 161 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n", "90.3 ms ± 1.48 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" ] } ], "source": [ "# Calculates stats for one column with caching enabled\n", "vbt.settings.caching.enabled = True\n", "%timeit big_portfolio.iloc[0].stats()\n", "%timeit big_portfolio_grouped.iloc[0].stats(group_by=False, column=0)\n", "%timeit big_portfolio_shared.iloc[0].stats(group_by=False, column=0)\n", "\n", "%timeit big_portfolio.iloc[0].stats(group_by=np.array([0]))\n", "%timeit big_portfolio_grouped.iloc[0].stats()\n", "%timeit big_portfolio_shared.iloc[0].stats()\n", "vbt.settings.caching.enabled = False" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "560 ms ± 29.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n", "554 ms ± 13.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n", "609 ms ± 4.04 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n", "676 ms ± 10.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n", "635 ms ± 12.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n", "741 ms ± 14.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" ] } ], "source": [ "# Calculates stats for all columns and selects one, takes advantage of caching (which is disabled here)\n", "# Thus some series are re-calculated multiple times, such as records and returns\n", "%timeit big_portfolio.stats(column=0)\n", "%timeit big_portfolio_grouped.stats(group_by=False, column=0)\n", "%timeit big_portfolio_shared.stats(group_by=False, column=0)\n", "\n", "%timeit big_portfolio.stats(group_by=big_group_by, column=0)\n", "%timeit big_portfolio_grouped.stats(column=0)\n", "%timeit big_portfolio_shared.stats(column=0)" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Start 2020-01-01 00:00:00\n", "End 2020-01-05 00:00:00\n", "Period 5 days 00:00:00\n", "Total Return [%] -1.11123\n", "Benchmark Return [%] 283.333333\n", "Annualized Return [%] 42.313666\n", "Annualized Volatility [%] 9.984895\n", "Max Drawdown [%] 1.645124\n", "Max Drawdown Duration 3 days 08:00:00\n", "Sharpe Ratio -6.751008\n", "Calmar Ratio 10378.930331\n", "Omega Ratio 4.7687\n", "Sortino Ratio 31.599761\n", "Skew -0.399797\n", "Kurtosis -1.202541\n", "Tail Ratio 3.164402\n", "Common Sense Ratio 10.883528\n", "Value at Risk -0.00799\n", "Alpha -0.35365\n", "Beta -0.001234\n", "Name: agg_func_mean, dtype: object\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "/Users/olegpolakow/Documents/SourceTree/vectorbt/vectorbt/portfolio/base.py:4618: UserWarning: Object has multiple columns. Aggregating using . Pass column to select a single column/group.\n", " return getattr(returns_acc, 'stats')(settings=settings, **kwargs)\n" ] } ], "source": [ "print(portfolio.returns_stats()) # mean statistics" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Start 2020-01-01 00:00:00\n", "End 2020-01-05 00:00:00\n", "Period 5 days 00:00:00\n", "Total Return [%] -0.31049\n", "Benchmark Return [%] 150.0\n", "Annualized Return [%] -20.308743\n", "Annualized Volatility [%] 1.704408\n", "Max Drawdown [%] 0.31049\n", "Max Drawdown Duration 4 days 00:00:00\n", "Sharpe Ratio -13.308045\n", "Calmar Ratio -65.408686\n", "Omega Ratio 0.0\n", "Sortino Ratio -11.738865\n", "Skew -1.219107\n", "Kurtosis 0.122976\n", "Tail Ratio 0.0\n", "Common Sense Ratio 0.0\n", "Value at Risk -0.001814\n", "Alpha -0.248883\n", "Beta 0.000749\n", "Name: a, dtype: object\n" ] } ], "source": [ "print(portfolio['a'].returns_stats())" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Start 2020-01-01 00:00:00\n", "End 2020-01-05 00:00:00\n", "Period 5 days 00:00:00\n", "Total Return [%] -2.520955\n", "Benchmark Return [%] 275.0\n", "Annualized Return [%] -84.493192\n", "Annualized Volatility [%] 9.234269\n", "Max Drawdown [%] 2.462481\n", "Max Drawdown Duration 4 days 00:00:00\n", "Sharpe Ratio -20.095907\n", "Calmar Ratio -34.312217\n", "Omega Ratio 0.0\n", "Sortino Ratio -14.554512\n", "Skew -0.254782\n", "Kurtosis -1.363876\n", "Tail Ratio 0.013427\n", "Common Sense Ratio 0.002082\n", "Value at Risk -0.01072\n", "Alpha -0.053947\n", "Beta -0.015121\n", "Name: first, dtype: object\n" ] } ], "source": [ "print(portfolio_grouped['first'].returns_stats())" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [], "source": [ "pd.testing.assert_series_equal(\n", " portfolio['c'].returns_stats(), \n", " portfolio.returns_stats(column='c'))\n", "pd.testing.assert_series_equal(\n", " portfolio['c'].returns_stats(), \n", " portfolio_grouped.returns_stats(column='c', group_by=False))\n", "pd.testing.assert_series_equal(\n", " portfolio_grouped['second'].returns_stats(), \n", " portfolio_grouped.returns_stats(column='second'))" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "22.533.544.55−50.00%−40.00%−30.00%−20.00%−10.00%0.00%Jan 12020Jan 2Jan 3Jan 4Jan 511.522.5CloseBuySellClosed - LossOpenBenchmarkValueIndexPriceTrade PnLCumulative returnsOrdersTrade PnLCumulative Returns" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "portfolio['a'].plot().show_svg()" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/Users/olegpolakow/Documents/SourceTree/vectorbt/vectorbt/generic/plots_builder.py:340: UserWarning:\n", "\n", "Subplot 'orders' does not support grouped data\n", "\n", "/Users/olegpolakow/Documents/SourceTree/vectorbt/vectorbt/generic/plots_builder.py:340: UserWarning:\n", "\n", "Subplot 'trade_pnl' does not support grouped data\n", "\n" ] }, { "data": { "image/svg+xml": [ "00:00Jan 1, 202012:0000:00Jan 2, 202012:0000:00Jan 3, 202012:0000:00Jan 4, 202012:0000:00Jan 5, 202011.522.533.5BenchmarkValueIndexCumulative returnsCumulative Returns" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "portfolio_shared['first'].plot().show_svg()" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "22.533.544.5522.533.544.55−50.00%−40.00%−30.00%−20.00%−10.00%0.00%00.20.40.60.81−5−4−3−2−1000.20.40.60.81959697989910001234599.799.7599.899.8599.999.9510011.522.599.799.899.9100−0%−0%−0%−0%−0%−0%0%00.20.40.60.81Jan 12020Jan 2Jan 3Jan 4Jan 500.010.020.030.040.05CloseBuySellEntryExit - LossActiveClosed - LossOpenAssetsCashAsset ValueValueBenchmarkPeakActiveDrawdownExposureIndexPricePriceTrade PnLAsset flowCash flowAssetsCashAsset valueValueCumulative returnsValueDrawdownGross exposureNet exposureOrdersTradesTrade PnLAsset FlowCash FlowAssetsCashAsset ValueValueCumulative ReturnsDrawdownsUnderwaterGross ExposureNet Exposure" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "portfolio['a'].plot(subplots='all').show_svg()" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/Users/olegpolakow/Documents/SourceTree/vectorbt/vectorbt/generic/plots_builder.py:340: UserWarning:\n", "\n", "Subplot 'orders' does not support grouped data\n", "\n", "/Users/olegpolakow/Documents/SourceTree/vectorbt/vectorbt/generic/plots_builder.py:340: UserWarning:\n", "\n", "Subplot 'trades' does not support grouped data\n", "\n", "/Users/olegpolakow/Documents/SourceTree/vectorbt/vectorbt/generic/plots_builder.py:340: UserWarning:\n", "\n", "Subplot 'trade_pnl' does not support grouped data\n", "\n", "/Users/olegpolakow/Documents/SourceTree/vectorbt/vectorbt/generic/plots_builder.py:340: UserWarning:\n", "\n", "Subplot 'asset_flow' does not support grouped data\n", "\n", "/Users/olegpolakow/Documents/SourceTree/vectorbt/vectorbt/generic/plots_builder.py:340: UserWarning:\n", "\n", "Subplot 'assets' does not support grouped data\n", "\n" ] }, { "data": { "image/svg+xml": [ "−0.500.5200200.2200.4200.6200.8−5−4−3−2−1019519619719819920011.522.533.5195196197198199200−3%−2%−2%−1%−1%0%00.20.40.60.81Jan 12020Jan 2Jan 3Jan 4Jan 5−0.025−0.02−0.015−0.01−0.0050CashAsset ValueValueBenchmarkPeakActiveDrawdownExposureIndexCash flowCashAsset valueValueCumulative returnsValueDrawdownGross exposureNet exposureCash FlowCashAsset ValueValueCumulative ReturnsDrawdownsUnderwaterGross ExposureNet Exposure" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "portfolio_shared['first'].plot(subplots='all').show_svg()" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/Users/olegpolakow/Documents/SourceTree/vectorbt/vectorbt/generic/plots_builder.py:340: UserWarning:\n", "\n", "Subplot 'orders' does not support grouped data\n", "\n", "/Users/olegpolakow/Documents/SourceTree/vectorbt/vectorbt/generic/plots_builder.py:340: UserWarning:\n", "\n", "Subplot 'trades' does not support grouped data\n", "\n", "/Users/olegpolakow/Documents/SourceTree/vectorbt/vectorbt/generic/plots_builder.py:340: UserWarning:\n", "\n", "Subplot 'trade_pnl' does not support grouped data\n", "\n", "/Users/olegpolakow/Documents/SourceTree/vectorbt/vectorbt/generic/plots_builder.py:340: UserWarning:\n", "\n", "Subplot 'asset_flow' does not support grouped data\n", "\n", "/Users/olegpolakow/Documents/SourceTree/vectorbt/vectorbt/generic/plots_builder.py:340: UserWarning:\n", "\n", "Subplot 'assets' does not support grouped data\n", "\n" ] }, { "data": { "image/svg+xml": [ "−0.500.5200200.2200.4200.6200.8−5−4−3−2−1019519619719819920011.522.533.5195196197198199200−3%−2%−2%−1%−1%0%00.20.40.60.81Jan 12020Jan 2Jan 3Jan 4Jan 5−0.025−0.02−0.015−0.01−0.0050CashAsset ValueValueBenchmarkPeakActiveDrawdownExposureIndexCash flowCashAsset valueValueCumulative returnsValueDrawdownGross exposureNet exposureCash FlowCashAsset ValueValueCumulative ReturnsDrawdownsUnderwaterGross ExposureNet Exposure" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "portfolio_shared.plot(subplots='all', column='first').show_svg()" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "22.533.544.5522.533.544.55−50.00%−40.00%−30.00%−20.00%−10.00%0.00%00.20.40.60.81−5−4−3−2−1000.20.40.60.81195196197198199200012345199.7199.75199.8199.85199.9199.9520011.522.5199.7199.8199.9200−0%−0%−0%0%00.20.40.60.81Jan 12020Jan 2Jan 3Jan 4Jan 500.0050.010.0150.020.025CloseBuySellEntryExit - LossActiveClosed - LossOpenAssetsCashAsset ValueValueBenchmarkPeakActiveDrawdownExposureIndexPricePriceTrade PnLAsset flowCash flowAssetsCashAsset valueValueCumulative returnsValueDrawdownGross exposureNet exposureOrdersTradesTrade PnLAsset FlowCash FlowAssetsCashAsset ValueValueCumulative ReturnsDrawdownsUnderwaterGross ExposureNet Exposure" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "portfolio_shared.plot(subplots='all', column='a', group_by=False).show_svg()" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "99.799.7599.899.8599.999.9510000:00Jan 1, 202012:0000:00Jan 2, 202012:0000:00Jan 3, 202012:0000:00Jan 4, 202012:0000:00Jan 5, 2020−0%−0%−0%−0%−0%−0%0%ValuePeakActiveDrawdownIndexValueDrawdownDrawdownsUnderwater" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from vectorbt.utils.colors import adjust_opacity\n", "\n", "portfolio['a'].plot(\n", " subplots=['drawdowns', 'underwater'],\n", " subplot_settings=dict(\n", " drawdowns=dict(top_n=3),\n", " underwater=dict(\n", " trace_kwargs=dict(\n", " line_color='#FF6F00',\n", " fillcolor=adjust_opacity('#FF6F00', 0.3)\n", " )\n", " )\n", " )\n", ").show_svg()" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "22.533.544.5500.511.522.533.54−1−0.500.51CloseBuySellOrder SizeIndexPriceOrdersOrder Size" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from vectorbt import settings\n", "color_schema = settings['plotting']['color_schema']\n", "\n", "fig = portfolio['a'].plot(subplots=[\n", " 'orders',\n", " ('order_size', dict(title='Order Size', check_is_not_grouped=True)) # placeholder\n", "])\n", "\n", "order_size.vbt.plot(trace_kwargs=dict(name='Order Size'), add_trace_kwargs=dict(row=2, col=1), fig=fig).show_svg()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.3" }, "widgets": { "application/vnd.jupyter.widget-state+json": { "state": {}, "version_major": 2, "version_minor": 0 } } }, "nbformat": 4, "nbformat_minor": 4 }