Skip to content

Instantly share code, notes, and snippets.

@brandonros
Created December 26, 2021 02:49
Show Gist options
  • Save brandonros/f95e8a3ebfcf0ed9374ce6267e63d985 to your computer and use it in GitHub Desktop.
Save brandonros/f95e8a3ebfcf0ed9374ce6267e63d985 to your computer and use it in GitHub Desktop.
// 1. starting balance: $10000, add $1000 every 7 days
// 2. first trade: buy $1000 worth of SPY on 2021-01-04 at the open price
// 3. all subsequent trades: buy $1000 worth of SPY every 7 days
// 4. include dividend revinesting
// 5. what is account value as of 2021-12-23 using closing price
const assert = require('assert')
const rows = [
{
"Date": "2021-01-04",
"Open": 375.309998,
"High": 375.450012,
"Low": 364.820007,
"Close": 368.790009,
"Adj Close": 363.936432,
"Volume": 110210800
},
{
"Date": "2021-01-05",
"Open": 368.100006,
"High": 372.5,
"Low": 368.049988,
"Close": 371.329987,
"Adj Close": 366.442993,
"Volume": 66426200
},
{
"Date": "2021-01-06",
"Open": 369.709991,
"High": 376.980011,
"Low": 369.119995,
"Close": 373.549988,
"Adj Close": 368.633789,
"Volume": 107997700
},
{
"Date": "2021-01-07",
"Open": 376.100006,
"High": 379.899994,
"Low": 375.910004,
"Close": 379.100006,
"Adj Close": 374.110748,
"Volume": 68766800
},
{
"Date": "2021-01-08",
"Open": 380.589996,
"High": 381.48999,
"Low": 377.100006,
"Close": 381.26001,
"Adj Close": 376.24234,
"Volume": 71677200
},
{
"Date": "2021-01-11",
"Open": 377.850006,
"High": 380.579987,
"Low": 377.720001,
"Close": 378.690002,
"Adj Close": 373.706177,
"Volume": 51034700
},
{
"Date": "2021-01-12",
"Open": 378.890015,
"High": 379.859985,
"Low": 376.359985,
"Close": 378.769989,
"Adj Close": 373.785095,
"Volume": 52547700
},
{
"Date": "2021-01-13",
"Open": 378.690002,
"High": 380.859985,
"Low": 377.850006,
"Close": 379.790009,
"Adj Close": 374.791687,
"Volume": 45303600
},
{
"Date": "2021-01-14",
"Open": 380.589996,
"High": 381.130005,
"Low": 378.100006,
"Close": 378.459991,
"Adj Close": 373.479156,
"Volume": 49989100
},
{
"Date": "2021-01-15",
"Open": 376.720001,
"High": 377.579987,
"Low": 373.700012,
"Close": 375.700012,
"Adj Close": 370.755524,
"Volume": 107160000
},
{
"Date": "2021-01-19",
"Open": 378.339996,
"High": 379.230011,
"Low": 376.75,
"Close": 378.649994,
"Adj Close": 373.666687,
"Volume": 51233300
},
{
"Date": "2021-01-20",
"Open": 381.109985,
"High": 384.790009,
"Low": 380.690002,
"Close": 383.890015,
"Adj Close": 378.837708,
"Volume": 61836100
},
{
"Date": "2021-01-21",
"Open": 384.48999,
"High": 384.950012,
"Low": 383.25,
"Close": 384.23999,
"Adj Close": 379.183075,
"Volume": 47840100
},
{
"Date": "2021-01-22",
"Open": 382.25,
"High": 384.130005,
"Low": 381.839996,
"Close": 382.880005,
"Adj Close": 377.840973,
"Volume": 52860500
},
{
"Date": "2021-01-25",
"Open": 383.670013,
"High": 384.769989,
"Low": 378.459991,
"Close": 384.390015,
"Adj Close": 379.331146,
"Volume": 70402000
},
{
"Date": "2021-01-26",
"Open": 385.410004,
"High": 385.850006,
"Low": 383.540009,
"Close": 383.790009,
"Adj Close": 378.739044,
"Volume": 42665300
},
{
"Date": "2021-01-27",
"Open": 380.220001,
"High": 380.320007,
"Low": 372.01001,
"Close": 374.410004,
"Adj Close": 369.482452,
"Volume": 123351100
},
{
"Date": "2021-01-28",
"Open": 376.359985,
"High": 381.929993,
"Low": 375.890015,
"Close": 377.630005,
"Adj Close": 372.660095,
"Volume": 94198100
},
{
"Date": "2021-01-29",
"Open": 375.630005,
"High": 376.670013,
"Low": 368.269989,
"Close": 370.070007,
"Adj Close": 365.199585,
"Volume": 126765100
},
{
"Date": "2021-02-01",
"Open": 373.720001,
"High": 377.339996,
"Low": 370.380005,
"Close": 376.230011,
"Adj Close": 371.278534,
"Volume": 75817600
},
{
"Date": "2021-02-02",
"Open": 379.649994,
"High": 383.220001,
"Low": 376.320007,
"Close": 381.549988,
"Adj Close": 376.528503,
"Volume": 64450700
},
{
"Date": "2021-02-03",
"Open": 382.440002,
"High": 383.700012,
"Low": 380.480011,
"Close": 381.850006,
"Adj Close": 376.824554,
"Volume": 52427100
},
{
"Date": "2021-02-04",
"Open": 382.959991,
"High": 386.23999,
"Low": 381.970001,
"Close": 386.190002,
"Adj Close": 381.107452,
"Volume": 47142600
},
{
"Date": "2021-02-05",
"Open": 388.200012,
"High": 388.470001,
"Low": 386.140015,
"Close": 387.709991,
"Adj Close": 382.607422,
"Volume": 48669800
},
{
"Date": "2021-02-08",
"Open": 389.269989,
"High": 390.559998,
"Low": 388.350006,
"Close": 390.51001,
"Adj Close": 385.370605,
"Volume": 38365200
},
{
"Date": "2021-02-09",
"Open": 389.609985,
"High": 390.890015,
"Low": 389.170013,
"Close": 390.25,
"Adj Close": 385.114014,
"Volume": 35551100
},
{
"Date": "2021-02-10",
"Open": 392.119995,
"High": 392.279999,
"Low": 387.5,
"Close": 390.079987,
"Adj Close": 384.946228,
"Volume": 59154400
},
{
"Date": "2021-02-11",
"Open": 391.23999,
"High": 391.690002,
"Low": 388.100006,
"Close": 390.709991,
"Adj Close": 385.567932,
"Volume": 42913300
},
{
"Date": "2021-02-12",
"Open": 389.850006,
"High": 392.899994,
"Low": 389.769989,
"Close": 392.640015,
"Adj Close": 387.472565,
"Volume": 50593300
},
{
"Date": "2021-02-16",
"Open": 393.959991,
"High": 394.170013,
"Low": 391.529999,
"Close": 392.299988,
"Adj Close": 387.137024,
"Volume": 50972400
},
{
"Date": "2021-02-17",
"Open": 390.420013,
"High": 392.660004,
"Low": 389.329987,
"Close": 392.390015,
"Adj Close": 387.225861,
"Volume": 52290600
},
{
"Date": "2021-02-18",
"Open": 389.589996,
"High": 391.519989,
"Low": 387.73999,
"Close": 390.720001,
"Adj Close": 385.57782,
"Volume": 59712800
},
{
"Date": "2021-02-19",
"Open": 392.070007,
"High": 392.380005,
"Low": 389.549988,
"Close": 390.029999,
"Adj Close": 384.896912,
"Volume": 83241000
},
{
"Date": "2021-02-22",
"Open": 387.059998,
"High": 389.619995,
"Low": 386.73999,
"Close": 387.029999,
"Adj Close": 381.936371,
"Volume": 67414200
},
{
"Date": "2021-02-23",
"Open": 384.660004,
"High": 388.950012,
"Low": 380.200012,
"Close": 387.5,
"Adj Close": 382.400208,
"Volume": 107284100
},
{
"Date": "2021-02-24",
"Open": 386.329987,
"High": 392.230011,
"Low": 385.269989,
"Close": 391.769989,
"Adj Close": 386.614014,
"Volume": 72433900
},
{
"Date": "2021-02-25",
"Open": 390.410004,
"High": 391.880005,
"Low": 380.779999,
"Close": 382.329987,
"Adj Close": 377.298218,
"Volume": 146670500
},
{
"Date": "2021-02-26",
"Open": 384.350006,
"High": 385.579987,
"Low": 378.230011,
"Close": 380.359985,
"Adj Close": 375.354156,
"Volume": 152701600
},
{
"Date": "2021-03-01",
"Open": 385.589996,
"High": 390.920013,
"Low": 380.570007,
"Close": 389.579987,
"Adj Close": 384.452759,
"Volume": 105348800
},
{
"Date": "2021-03-02",
"Open": 389.820007,
"High": 390.070007,
"Low": 386,
"Close": 386.540009,
"Adj Close": 381.45282,
"Volume": 79595300
},
{
"Date": "2021-03-03",
"Open": 385.790009,
"High": 386.829987,
"Low": 381.309998,
"Close": 381.420013,
"Adj Close": 376.400208,
"Volume": 119940200
},
{
"Date": "2021-03-04",
"Open": 381.220001,
"High": 384,
"Low": 371.880005,
"Close": 376.700012,
"Adj Close": 371.74234,
"Volume": 183433000
},
{
"Date": "2021-03-05",
"Open": 380.459991,
"High": 384.76001,
"Low": 372.640015,
"Close": 383.630005,
"Adj Close": 378.581146,
"Volume": 152039600
},
{
"Date": "2021-03-08",
"Open": 384.660004,
"High": 387.679993,
"Low": 381.420013,
"Close": 381.720001,
"Adj Close": 376.696289,
"Volume": 123149200
},
{
"Date": "2021-03-09",
"Open": 385.850006,
"High": 389.910004,
"Low": 385.309998,
"Close": 387.170013,
"Adj Close": 382.074554,
"Volume": 113633600
},
{
"Date": "2021-03-10",
"Open": 389.690002,
"High": 391.399994,
"Low": 388.170013,
"Close": 389.579987,
"Adj Close": 384.452759,
"Volume": 109899400
},
{
"Date": "2021-03-11",
"Open": 392.230011,
"High": 395.649994,
"Low": 391.73999,
"Close": 393.529999,
"Adj Close": 388.350861,
"Volume": 86245000
},
{
"Date": "2021-03-12",
"Open": 392.070007,
"High": 394.209991,
"Low": 391.200012,
"Close": 394.059998,
"Adj Close": 388.873871,
"Volume": 64653600
},
{
"Date": "2021-03-15",
"Open": 394.329987,
"High": 396.690002,
"Low": 392.029999,
"Close": 396.410004,
"Adj Close": 391.192963,
"Volume": 73427200
},
{
"Date": "2021-03-16",
"Open": 397.070007,
"High": 397.829987,
"Low": 395.079987,
"Close": 395.910004,
"Adj Close": 390.699524,
"Volume": 73722500
},
{
"Date": "2021-03-17",
"Open": 394.529999,
"High": 398.119995,
"Low": 393.299988,
"Close": 397.26001,
"Adj Close": 392.031769,
"Volume": 97959300
},
{
"Date": "2021-03-18",
"Open": 394.480011,
"High": 396.720001,
"Low": 390.75,
"Close": 391.480011,
"Adj Close": 386.32782,
"Volume": 115349100
},
{
"Date": "2021-03-19",
"Open": 389.880005,
"High": 391.570007,
"Low": 387.149994,
"Close": 389.480011,
"Adj Close": 385.613007,
"Volume": 113624500
},
{
"Date": "2021-03-22",
"Open": 390.029999,
"High": 394.070007,
"Low": 389.970001,
"Close": 392.589996,
"Adj Close": 388.692108,
"Volume": 73778600
},
{
"Date": "2021-03-23",
"Open": 391.910004,
"High": 393.459991,
"Low": 388.660004,
"Close": 389.5,
"Adj Close": 385.632813,
"Volume": 90686600
},
{
"Date": "2021-03-24",
"Open": 391,
"High": 392.75,
"Low": 387.470001,
"Close": 387.519989,
"Adj Close": 383.672424,
"Volume": 97588600
},
{
"Date": "2021-03-25",
"Open": 385.980011,
"High": 390.549988,
"Low": 383.899994,
"Close": 389.700012,
"Adj Close": 385.830841,
"Volume": 116128600
},
{
"Date": "2021-03-26",
"Open": 390.929993,
"High": 396.410004,
"Low": 390.290009,
"Close": 395.980011,
"Adj Close": 392.048462,
"Volume": 114409100
},
{
"Date": "2021-03-29",
"Open": 394.399994,
"High": 396.75,
"Low": 392.809998,
"Close": 395.779999,
"Adj Close": 391.850433,
"Volume": 108107600
},
{
"Date": "2021-03-30",
"Open": 394.420013,
"High": 395.450012,
"Low": 393.019989,
"Close": 394.730011,
"Adj Close": 390.810852,
"Volume": 76262200
},
{
"Date": "2021-03-31",
"Open": 395.339996,
"High": 398,
"Low": 395.309998,
"Close": 396.329987,
"Adj Close": 392.394958,
"Volume": 112734200
},
{
"Date": "2021-04-01",
"Open": 398.399994,
"High": 400.670013,
"Low": 398.179993,
"Close": 400.609985,
"Adj Close": 396.632477,
"Volume": 99682900
},
{
"Date": "2021-04-05",
"Open": 403.459991,
"High": 406.940002,
"Low": 403.380005,
"Close": 406.359985,
"Adj Close": 402.325348,
"Volume": 91684800
},
{
"Date": "2021-04-06",
"Open": 405.76001,
"High": 407.23999,
"Low": 405.399994,
"Close": 406.119995,
"Adj Close": 402.087799,
"Volume": 62021000
},
{
"Date": "2021-04-07",
"Open": 405.940002,
"High": 406.959991,
"Low": 405.450012,
"Close": 406.589996,
"Adj Close": 402.553101,
"Volume": 55836300
},
{
"Date": "2021-04-08",
"Open": 407.929993,
"High": 408.579987,
"Low": 406.929993,
"Close": 408.519989,
"Adj Close": 404.463928,
"Volume": 57863100
},
{
"Date": "2021-04-09",
"Open": 408.390015,
"High": 411.670013,
"Low": 408.26001,
"Close": 411.48999,
"Adj Close": 407.404449,
"Volume": 61104600
},
{
"Date": "2021-04-12",
"Open": 410.850006,
"High": 411.929993,
"Low": 410.200012,
"Close": 411.640015,
"Adj Close": 407.552979,
"Volume": 56704900
},
{
"Date": "2021-04-13",
"Open": 411.529999,
"High": 413.529999,
"Low": 411.119995,
"Close": 412.859985,
"Adj Close": 408.760834,
"Volume": 56551000
},
{
"Date": "2021-04-14",
"Open": 412.829987,
"High": 413.959991,
"Low": 410.869995,
"Close": 411.450012,
"Adj Close": 407.364868,
"Volume": 61659900
},
{
"Date": "2021-04-15",
"Open": 413.73999,
"High": 416.160004,
"Low": 413.690002,
"Close": 415.869995,
"Adj Close": 411.740967,
"Volume": 60229800
},
{
"Date": "2021-04-16",
"Open": 417.25,
"High": 417.910004,
"Low": 415.730011,
"Close": 417.26001,
"Adj Close": 413.117188,
"Volume": 82037300
},
{
"Date": "2021-04-19",
"Open": 416.26001,
"High": 416.73999,
"Low": 413.790009,
"Close": 415.209991,
"Adj Close": 411.087494,
"Volume": 78498500
},
{
"Date": "2021-04-20",
"Open": 413.910004,
"High": 415.089996,
"Low": 410.589996,
"Close": 412.170013,
"Adj Close": 408.077728,
"Volume": 81851800
},
{
"Date": "2021-04-21",
"Open": 411.51001,
"High": 416.290009,
"Low": 411.359985,
"Close": 416.070007,
"Adj Close": 411.938995,
"Volume": 66793000
},
{
"Date": "2021-04-22",
"Open": 415.890015,
"High": 416.779999,
"Low": 411.130005,
"Close": 412.269989,
"Adj Close": 408.176697,
"Volume": 97582800
},
{
"Date": "2021-04-23",
"Open": 412.869995,
"High": 418.25,
"Low": 412.790009,
"Close": 416.73999,
"Adj Close": 412.602325,
"Volume": 73209200
},
{
"Date": "2021-04-26",
"Open": 417.440002,
"High": 418.220001,
"Low": 416.809998,
"Close": 417.609985,
"Adj Close": 413.463654,
"Volume": 52182400
},
{
"Date": "2021-04-27",
"Open": 417.929993,
"High": 418.140015,
"Low": 416.299988,
"Close": 417.519989,
"Adj Close": 413.374603,
"Volume": 51303100
},
{
"Date": "2021-04-28",
"Open": 417.809998,
"High": 419.01001,
"Low": 416.899994,
"Close": 417.399994,
"Adj Close": 413.255768,
"Volume": 51238900
},
{
"Date": "2021-04-29",
"Open": 420.320007,
"High": 420.720001,
"Low": 416.440002,
"Close": 420.059998,
"Adj Close": 415.889374,
"Volume": 78544300
},
{
"Date": "2021-04-30",
"Open": 417.630005,
"High": 418.540009,
"Low": 416.339996,
"Close": 417.299988,
"Adj Close": 413.156769,
"Volume": 85527000
},
{
"Date": "2021-05-03",
"Open": 419.429993,
"High": 419.839996,
"Low": 417.670013,
"Close": 418.200012,
"Adj Close": 414.047852,
"Volume": 68128300
},
{
"Date": "2021-05-04",
"Open": 416.070007,
"High": 416.600006,
"Low": 411.670013,
"Close": 415.619995,
"Adj Close": 411.493439,
"Volume": 101591200
},
{
"Date": "2021-05-05",
"Open": 417.380005,
"High": 417.630005,
"Low": 415.149994,
"Close": 415.75,
"Adj Close": 411.622162,
"Volume": 60162200
},
{
"Date": "2021-05-06",
"Open": 415.829987,
"High": 419.209991,
"Low": 413.679993,
"Close": 419.070007,
"Adj Close": 414.90918,
"Volume": 74321400
},
{
"Date": "2021-05-07",
"Open": 419.890015,
"High": 422.820007,
"Low": 419.160004,
"Close": 422.119995,
"Adj Close": 417.928925,
"Volume": 67733800
},
{
"Date": "2021-05-10",
"Open": 422.5,
"High": 422.73999,
"Low": 417.809998,
"Close": 417.940002,
"Adj Close": 413.790405,
"Volume": 81852400
},
{
"Date": "2021-05-11",
"Open": 413.100006,
"High": 415.269989,
"Low": 410.059998,
"Close": 414.209991,
"Adj Close": 410.097443,
"Volume": 116888000
},
{
"Date": "2021-05-12",
"Open": 411.230011,
"High": 412.589996,
"Low": 404,
"Close": 405.410004,
"Adj Close": 401.384827,
"Volume": 134811000
},
{
"Date": "2021-05-13",
"Open": 407.070007,
"High": 412.350006,
"Low": 407.019989,
"Close": 410.279999,
"Adj Close": 406.206451,
"Volume": 106394000
},
{
"Date": "2021-05-14",
"Open": 413.209991,
"High": 417.48999,
"Low": 413.179993,
"Close": 416.579987,
"Adj Close": 412.443909,
"Volume": 82201600
},
{
"Date": "2021-05-17",
"Open": 415.390015,
"High": 416.390015,
"Low": 413.359985,
"Close": 415.519989,
"Adj Close": 411.39444,
"Volume": 65129200
},
{
"Date": "2021-05-18",
"Open": 415.799988,
"High": 416.059998,
"Low": 411.769989,
"Close": 411.940002,
"Adj Close": 407.850006,
"Volume": 59810200
},
{
"Date": "2021-05-19",
"Open": 406.920013,
"High": 411.049988,
"Low": 405.329987,
"Close": 410.859985,
"Adj Close": 406.780731,
"Volume": 106467100
},
{
"Date": "2021-05-20",
"Open": 411.799988,
"High": 416.630005,
"Low": 411.670013,
"Close": 415.279999,
"Adj Close": 411.15683,
"Volume": 78022200
},
{
"Date": "2021-05-21",
"Open": 416.869995,
"High": 418.200012,
"Low": 414.450012,
"Close": 414.940002,
"Adj Close": 410.820221,
"Volume": 76578700
},
{
"Date": "2021-05-24",
"Open": 417.339996,
"High": 420.320007,
"Low": 417.079987,
"Close": 419.170013,
"Adj Close": 415.00824,
"Volume": 51376700
},
{
"Date": "2021-05-25",
"Open": 420.329987,
"High": 420.709991,
"Low": 417.619995,
"Close": 418.23999,
"Adj Close": 414.087433,
"Volume": 57451400
},
{
"Date": "2021-05-26",
"Open": 418.869995,
"High": 419.609985,
"Low": 417.76001,
"Close": 419.070007,
"Adj Close": 414.90918,
"Volume": 43088600
},
{
"Date": "2021-05-27",
"Open": 420.170013,
"High": 420.720001,
"Low": 418.98999,
"Close": 419.290009,
"Adj Close": 415.127014,
"Volume": 56707700
},
{
"Date": "2021-05-28",
"Open": 420.970001,
"High": 421.25,
"Low": 419.790009,
"Close": 420.040009,
"Adj Close": 415.869568,
"Volume": 58520200
},
{
"Date": "2021-06-01",
"Open": 422.570007,
"High": 422.720001,
"Low": 419.200012,
"Close": 419.670013,
"Adj Close": 415.503265,
"Volume": 54216600
},
{
"Date": "2021-06-02",
"Open": 420.369995,
"High": 421.230011,
"Low": 419.290009,
"Close": 420.329987,
"Adj Close": 416.156708,
"Volume": 49097100
},
{
"Date": "2021-06-03",
"Open": 417.850006,
"High": 419.98999,
"Low": 416.279999,
"Close": 418.769989,
"Adj Close": 414.612152,
"Volume": 58138800
},
{
"Date": "2021-06-04",
"Open": 420.75,
"High": 422.920013,
"Low": 418.839996,
"Close": 422.600006,
"Adj Close": 418.404175,
"Volume": 55938800
},
{
"Date": "2021-06-07",
"Open": 422.589996,
"High": 422.779999,
"Low": 421.190002,
"Close": 422.190002,
"Adj Close": 417.99823,
"Volume": 51555000
},
{
"Date": "2021-06-08",
"Open": 423.109985,
"High": 423.209991,
"Low": 420.320007,
"Close": 422.279999,
"Adj Close": 418.087341,
"Volume": 47134300
},
{
"Date": "2021-06-09",
"Open": 423.179993,
"High": 423.26001,
"Low": 421.410004,
"Close": 421.649994,
"Adj Close": 417.463562,
"Volume": 48436300
},
{
"Date": "2021-06-10",
"Open": 422.959991,
"High": 424.630005,
"Low": 421.549988,
"Close": 423.609985,
"Adj Close": 419.404114,
"Volume": 51020100
},
{
"Date": "2021-06-11",
"Open": 424.200012,
"High": 424.429993,
"Low": 422.820007,
"Close": 424.309998,
"Adj Close": 420.097168,
"Volume": 45570800
},
{
"Date": "2021-06-14",
"Open": 424.429993,
"High": 425.369995,
"Low": 423.100006,
"Close": 425.26001,
"Adj Close": 421.03775,
"Volume": 42358500
},
{
"Date": "2021-06-15",
"Open": 425.420013,
"High": 425.459991,
"Low": 423.540009,
"Close": 424.480011,
"Adj Close": 420.265472,
"Volume": 51508500
},
{
"Date": "2021-06-16",
"Open": 424.630005,
"High": 424.869995,
"Low": 419.920013,
"Close": 422.109985,
"Adj Close": 417.919006,
"Volume": 80386100
},
{
"Date": "2021-06-17",
"Open": 421.670013,
"High": 423.019989,
"Low": 419.320007,
"Close": 421.970001,
"Adj Close": 417.780426,
"Volume": 90949700
},
{
"Date": "2021-06-18",
"Open": 417.089996,
"High": 417.829987,
"Low": 414.700012,
"Close": 414.920013,
"Adj Close": 412.144379,
"Volume": 118676300
},
{
"Date": "2021-06-21",
"Open": 416.799988,
"High": 421.059998,
"Low": 415.929993,
"Close": 420.859985,
"Adj Close": 418.044617,
"Volume": 72822000
},
{
"Date": "2021-06-22",
"Open": 420.850006,
"High": 424,
"Low": 420.079987,
"Close": 423.109985,
"Adj Close": 420.279572,
"Volume": 57700300
},
{
"Date": "2021-06-23",
"Open": 423.190002,
"High": 424.049988,
"Low": 422.51001,
"Close": 422.600006,
"Adj Close": 419.77301,
"Volume": 49445400
},
{
"Date": "2021-06-24",
"Open": 424.890015,
"High": 425.549988,
"Low": 424.619995,
"Close": 425.100006,
"Adj Close": 422.256256,
"Volume": 45110300
},
{
"Date": "2021-06-25",
"Open": 425.899994,
"High": 427.089996,
"Low": 425.549988,
"Close": 426.609985,
"Adj Close": 423.756134,
"Volume": 58129500
},
{
"Date": "2021-06-28",
"Open": 427.170013,
"High": 427.649994,
"Low": 425.890015,
"Close": 427.470001,
"Adj Close": 424.610413,
"Volume": 53159600
},
{
"Date": "2021-06-29",
"Open": 427.880005,
"High": 428.559998,
"Low": 427.130005,
"Close": 427.700012,
"Adj Close": 424.838867,
"Volume": 35970500
},
{
"Date": "2021-06-30",
"Open": 427.209991,
"High": 428.779999,
"Low": 427.179993,
"Close": 428.059998,
"Adj Close": 425.196472,
"Volume": 64827900
},
{
"Date": "2021-07-01",
"Open": 428.869995,
"High": 430.600006,
"Low": 428.799988,
"Close": 430.429993,
"Adj Close": 427.550629,
"Volume": 53441000
},
{
"Date": "2021-07-02",
"Open": 431.670013,
"High": 434.100006,
"Low": 430.519989,
"Close": 433.720001,
"Adj Close": 430.818604,
"Volume": 57697700
},
{
"Date": "2021-07-06",
"Open": 433.779999,
"High": 434.01001,
"Low": 430.01001,
"Close": 432.929993,
"Adj Close": 430.033875,
"Volume": 68710400
},
{
"Date": "2021-07-07",
"Open": 433.660004,
"High": 434.76001,
"Low": 431.51001,
"Close": 434.459991,
"Adj Close": 431.55365,
"Volume": 63549500
},
{
"Date": "2021-07-08",
"Open": 428.779999,
"High": 431.730011,
"Low": 427.519989,
"Close": 430.920013,
"Adj Close": 428.037323,
"Volume": 97595200
},
{
"Date": "2021-07-09",
"Open": 432.529999,
"High": 435.839996,
"Low": 430.709991,
"Close": 435.519989,
"Adj Close": 432.606567,
"Volume": 76238600
},
{
"Date": "2021-07-12",
"Open": 435.429993,
"High": 437.350006,
"Low": 434.970001,
"Close": 437.079987,
"Adj Close": 434.156128,
"Volume": 52889600
},
{
"Date": "2021-07-13",
"Open": 436.23999,
"High": 437.839996,
"Low": 435.309998,
"Close": 435.589996,
"Adj Close": 432.676086,
"Volume": 52911300
},
{
"Date": "2021-07-14",
"Open": 437.399994,
"High": 437.920013,
"Low": 434.910004,
"Close": 436.23999,
"Adj Close": 433.321747,
"Volume": 64130400
},
{
"Date": "2021-07-15",
"Open": 434.809998,
"High": 435.529999,
"Low": 432.720001,
"Close": 434.75,
"Adj Close": 431.841736,
"Volume": 55126400
},
{
"Date": "2021-07-16",
"Open": 436.01001,
"High": 436.059998,
"Low": 430.920013,
"Close": 431.339996,
"Adj Close": 428.454498,
"Volume": 75874700
},
{
"Date": "2021-07-19",
"Open": 426.190002,
"High": 431.410004,
"Low": 421.970001,
"Close": 424.970001,
"Adj Close": 422.127136,
"Volume": 147987000
},
{
"Date": "2021-07-20",
"Open": 425.679993,
"High": 432.420013,
"Low": 424.829987,
"Close": 431.059998,
"Adj Close": 428.176392,
"Volume": 99608200
},
{
"Date": "2021-07-21",
"Open": 432.339996,
"High": 434.700012,
"Low": 431.01001,
"Close": 434.549988,
"Adj Close": 431.643066,
"Volume": 64724400
},
{
"Date": "2021-07-22",
"Open": 434.73999,
"High": 435.720001,
"Low": 433.690002,
"Close": 435.459991,
"Adj Close": 432.546936,
"Volume": 47878500
},
{
"Date": "2021-07-23",
"Open": 437.519989,
"High": 440.299988,
"Low": 436.790009,
"Close": 439.940002,
"Adj Close": 436.997009,
"Volume": 63766600
},
{
"Date": "2021-07-26",
"Open": 439.309998,
"High": 441.029999,
"Low": 439.26001,
"Close": 441.019989,
"Adj Close": 438.069763,
"Volume": 43719200
},
{
"Date": "2021-07-27",
"Open": 439.910004,
"High": 439.940002,
"Low": 435.98999,
"Close": 439.01001,
"Adj Close": 436.073242,
"Volume": 67397100
},
{
"Date": "2021-07-28",
"Open": 439.679993,
"High": 440.299988,
"Low": 437.309998,
"Close": 438.829987,
"Adj Close": 435.894409,
"Volume": 52472400
},
{
"Date": "2021-07-29",
"Open": 439.820007,
"High": 441.799988,
"Low": 439.809998,
"Close": 440.649994,
"Adj Close": 437.70224,
"Volume": 47435300
},
{
"Date": "2021-07-30",
"Open": 437.910004,
"High": 440.059998,
"Low": 437.769989,
"Close": 438.51001,
"Adj Close": 435.576569,
"Volume": 68890600
},
{
"Date": "2021-08-02",
"Open": 440.339996,
"High": 440.929993,
"Low": 437.209991,
"Close": 437.589996,
"Adj Close": 434.662689,
"Volume": 58783300
},
{
"Date": "2021-08-03",
"Open": 438.440002,
"High": 441.279999,
"Low": 436.100006,
"Close": 441.149994,
"Adj Close": 438.198914,
"Volume": 58053900
},
{
"Date": "2021-08-04",
"Open": 439.779999,
"High": 441.119995,
"Low": 438.730011,
"Close": 438.980011,
"Adj Close": 436.043427,
"Volume": 46732200
},
{
"Date": "2021-08-05",
"Open": 440.220001,
"High": 441.850006,
"Low": 439.880005,
"Close": 441.76001,
"Adj Close": 438.80484,
"Volume": 38969700
},
{
"Date": "2021-08-06",
"Open": 442.100006,
"High": 442.940002,
"Low": 441.799988,
"Close": 442.48999,
"Adj Close": 439.529938,
"Volume": 46864100
},
{
"Date": "2021-08-09",
"Open": 442.459991,
"High": 442.799988,
"Low": 441.309998,
"Close": 442.130005,
"Adj Close": 439.172333,
"Volume": 41222600
},
{
"Date": "2021-08-10",
"Open": 442.609985,
"High": 443.440002,
"Low": 441.880005,
"Close": 442.679993,
"Adj Close": 439.718658,
"Volume": 43339300
},
{
"Date": "2021-08-11",
"Open": 443.820007,
"High": 443.880005,
"Low": 442.619995,
"Close": 443.779999,
"Adj Close": 440.81131,
"Volume": 44034300
},
{
"Date": "2021-08-12",
"Open": 443.619995,
"High": 445.26001,
"Low": 442.660004,
"Close": 445.109985,
"Adj Close": 442.132416,
"Volume": 38909400
},
{
"Date": "2021-08-13",
"Open": 445.589996,
"High": 445.940002,
"Low": 445.070007,
"Close": 445.920013,
"Adj Close": 442.937012,
"Volume": 39388300
},
{
"Date": "2021-08-16",
"Open": 444.529999,
"High": 447.109985,
"Low": 442.869995,
"Close": 446.970001,
"Adj Close": 443.97998,
"Volume": 73740000
},
{
"Date": "2021-08-17",
"Open": 444.23999,
"High": 444.959991,
"Low": 440.850006,
"Close": 444.040009,
"Adj Close": 441.06958,
"Volume": 92673900
},
{
"Date": "2021-08-18",
"Open": 442.959991,
"High": 444.630005,
"Low": 438.920013,
"Close": 439.179993,
"Adj Close": 436.242065,
"Volume": 89351900
},
{
"Date": "2021-08-19",
"Open": 436.269989,
"High": 441.140015,
"Low": 436.119995,
"Close": 439.859985,
"Adj Close": 436.917511,
"Volume": 92812200
},
{
"Date": "2021-08-20",
"Open": 440.230011,
"High": 443.709991,
"Low": 439.709991,
"Close": 443.359985,
"Adj Close": 440.394104,
"Volume": 71975900
},
{
"Date": "2021-08-23",
"Open": 445.160004,
"High": 448.230011,
"Low": 443.440002,
"Close": 447.26001,
"Adj Close": 444.268066,
"Volume": 54973000
},
{
"Date": "2021-08-24",
"Open": 447.970001,
"High": 448.540009,
"Low": 447.420013,
"Close": 447.970001,
"Adj Close": 444.973267,
"Volume": 38744700
},
{
"Date": "2021-08-25",
"Open": 448.170013,
"High": 449.459991,
"Low": 447.769989,
"Close": 448.910004,
"Adj Close": 445.907013,
"Volume": 40529700
},
{
"Date": "2021-08-26",
"Open": 448.609985,
"High": 448.859985,
"Low": 446.160004,
"Close": 446.26001,
"Adj Close": 443.274719,
"Volume": 57829600
},
{
"Date": "2021-08-27",
"Open": 447.119995,
"High": 450.649994,
"Low": 447.059998,
"Close": 450.25,
"Adj Close": 447.238037,
"Volume": 77201900
},
{
"Date": "2021-08-30",
"Open": 450.970001,
"High": 453.070007,
"Low": 450.709991,
"Close": 452.230011,
"Adj Close": 449.204773,
"Volume": 48357400
},
{
"Date": "2021-08-31",
"Open": 452.130005,
"High": 452.48999,
"Low": 450.920013,
"Close": 451.559998,
"Adj Close": 448.539276,
"Volume": 59300200
},
{
"Date": "2021-09-01",
"Open": 452.559998,
"High": 453.109985,
"Low": 451.549988,
"Close": 451.799988,
"Adj Close": 448.777618,
"Volume": 48721400
},
{
"Date": "2021-09-02",
"Open": 453.320007,
"High": 454.049988,
"Low": 451.910004,
"Close": 453.190002,
"Adj Close": 450.158356,
"Volume": 42501000
},
{
"Date": "2021-09-03",
"Open": 451.980011,
"High": 453.630005,
"Low": 451.549988,
"Close": 453.079987,
"Adj Close": 450.049103,
"Volume": 47170500
},
{
"Date": "2021-09-07",
"Open": 452.709991,
"High": 452.809998,
"Low": 450.73999,
"Close": 451.459991,
"Adj Close": 448.439911,
"Volume": 51671500
},
{
"Date": "2021-09-08",
"Open": 450.890015,
"High": 451.670013,
"Low": 448.859985,
"Close": 450.910004,
"Adj Close": 447.893616,
"Volume": 56181900
},
{
"Date": "2021-09-09",
"Open": 450.700012,
"High": 452.570007,
"Low": 448.720001,
"Close": 448.980011,
"Adj Close": 445.976563,
"Volume": 57970400
},
{
"Date": "2021-09-10",
"Open": 451.040009,
"High": 451.48999,
"Low": 445.309998,
"Close": 445.440002,
"Adj Close": 442.460205,
"Volume": 89848000
},
{
"Date": "2021-09-13",
"Open": 448.640015,
"High": 448.920013,
"Low": 444.109985,
"Close": 446.579987,
"Adj Close": 443.59256,
"Volume": 83738600
},
{
"Date": "2021-09-14",
"Open": 448.119995,
"High": 448.339996,
"Low": 443.220001,
"Close": 444.170013,
"Adj Close": 441.19873,
"Volume": 78197100
},
{
"Date": "2021-09-15",
"Open": 444.619995,
"High": 448.410004,
"Low": 443.440002,
"Close": 447.880005,
"Adj Close": 444.883911,
"Volume": 78792200
},
{
"Date": "2021-09-16",
"Open": 447.320007,
"High": 448.359985,
"Low": 444.019989,
"Close": 447.170013,
"Adj Close": 444.17865,
"Volume": 77786700
},
{
"Date": "2021-09-17",
"Open": 444.920013,
"High": 445.369995,
"Low": 441.019989,
"Close": 441.399994,
"Adj Close": 439.851868,
"Volume": 118425000
},
{
"Date": "2021-09-20",
"Open": 434.880005,
"High": 436.559998,
"Low": 428.859985,
"Close": 434.040009,
"Adj Close": 432.5177,
"Volume": 166445500
},
{
"Date": "2021-09-21",
"Open": 436.529999,
"High": 437.910004,
"Low": 433.070007,
"Close": 433.630005,
"Adj Close": 432.109131,
"Volume": 92526100
},
{
"Date": "2021-09-22",
"Open": 436.049988,
"High": 440.029999,
"Low": 433.75,
"Close": 437.859985,
"Adj Close": 436.32428,
"Volume": 102350100
},
{
"Date": "2021-09-23",
"Open": 439.850006,
"High": 444.890015,
"Low": 439.600006,
"Close": 443.179993,
"Adj Close": 441.62561,
"Volume": 76396000
},
{
"Date": "2021-09-24",
"Open": 441.440002,
"High": 444.670013,
"Low": 441.209991,
"Close": 443.910004,
"Adj Close": 442.353058,
"Volume": 62094800
},
{
"Date": "2021-09-27",
"Open": 442.809998,
"High": 444.049988,
"Low": 441.899994,
"Close": 442.640015,
"Adj Close": 441.087524,
"Volume": 61371100
},
{
"Date": "2021-09-28",
"Open": 439.690002,
"High": 440.040009,
"Low": 432.940002,
"Close": 433.720001,
"Adj Close": 432.198822,
"Volume": 130436300
},
{
"Date": "2021-09-29",
"Open": 435.190002,
"High": 437.040009,
"Low": 433.850006,
"Close": 434.450012,
"Adj Close": 432.92627,
"Volume": 82329200
},
{
"Date": "2021-09-30",
"Open": 436.019989,
"High": 436.769989,
"Low": 428.779999,
"Close": 429.140015,
"Adj Close": 427.634888,
"Volume": 140181200
},
{
"Date": "2021-10-01",
"Open": 430.980011,
"High": 436.029999,
"Low": 427.230011,
"Close": 434.23999,
"Adj Close": 432.71698,
"Volume": 129240100
},
{
"Date": "2021-10-04",
"Open": 433,
"High": 433.959991,
"Low": 426.359985,
"Close": 428.640015,
"Adj Close": 427.136627,
"Volume": 128570000
},
{
"Date": "2021-10-05",
"Open": 430.23999,
"High": 435.48999,
"Low": 429.390015,
"Close": 433.100006,
"Adj Close": 431.580994,
"Volume": 90682500
},
{
"Date": "2021-10-06",
"Open": 429.269989,
"High": 435.119995,
"Low": 427.540009,
"Close": 434.899994,
"Adj Close": 433.374664,
"Volume": 113032200
},
{
"Date": "2021-10-07",
"Open": 438.390015,
"High": 441.679993,
"Low": 438.200012,
"Close": 438.660004,
"Adj Close": 437.12149,
"Volume": 72437500
},
{
"Date": "2021-10-08",
"Open": 439.480011,
"High": 439.890015,
"Low": 437.190002,
"Close": 437.859985,
"Adj Close": 436.32428,
"Volume": 74492900
},
{
"Date": "2021-10-11",
"Open": 437.160004,
"High": 440.26001,
"Low": 434.619995,
"Close": 434.690002,
"Adj Close": 433.165405,
"Volume": 65233300
},
{
"Date": "2021-10-12",
"Open": 435.670013,
"High": 436.100006,
"Low": 432.779999,
"Close": 433.619995,
"Adj Close": 432.099152,
"Volume": 71181200
},
{
"Date": "2021-10-13",
"Open": 434.709991,
"High": 436.049988,
"Low": 431.540009,
"Close": 435.179993,
"Adj Close": 433.653687,
"Volume": 72974000
},
{
"Date": "2021-10-14",
"Open": 439.079987,
"High": 442.660004,
"Low": 438.579987,
"Close": 442.5,
"Adj Close": 440.947998,
"Volume": 70236800
},
{
"Date": "2021-10-15",
"Open": 444.75,
"High": 446.26001,
"Low": 444.089996,
"Close": 445.869995,
"Adj Close": 444.306183,
"Volume": 66226800
},
{
"Date": "2021-10-18",
"Open": 443.970001,
"High": 447.549988,
"Low": 443.269989,
"Close": 447.190002,
"Adj Close": 445.621552,
"Volume": 62213200
},
{
"Date": "2021-10-19",
"Open": 448.920013,
"High": 450.709991,
"Low": 448.269989,
"Close": 450.640015,
"Adj Close": 449.059479,
"Volume": 46996800
},
{
"Date": "2021-10-20",
"Open": 451.130005,
"High": 452.730011,
"Low": 451.01001,
"Close": 452.410004,
"Adj Close": 450.823273,
"Volume": 49571600
},
{
"Date": "2021-10-21",
"Open": 451.769989,
"High": 453.829987,
"Low": 451.309998,
"Close": 453.589996,
"Adj Close": 451.999115,
"Volume": 41305400
},
{
"Date": "2021-10-22",
"Open": 453.130005,
"High": 454.670013,
"Low": 451.049988,
"Close": 453.119995,
"Adj Close": 451.530762,
"Volume": 58845100
},
{
"Date": "2021-10-25",
"Open": 454.279999,
"High": 455.899994,
"Low": 452.390015,
"Close": 455.549988,
"Adj Close": 453.95224,
"Volume": 45214500
},
{
"Date": "2021-10-26",
"Open": 457.200012,
"High": 458.48999,
"Low": 455.559998,
"Close": 455.959991,
"Adj Close": 454.360809,
"Volume": 56075100
},
{
"Date": "2021-10-27",
"Open": 456.450012,
"High": 457.160004,
"Low": 453.859985,
"Close": 453.940002,
"Adj Close": 452.3479,
"Volume": 72438000
},
{
"Date": "2021-10-28",
"Open": 455.459991,
"High": 458.399994,
"Low": 455.450012,
"Close": 458.320007,
"Adj Close": 456.712524,
"Volume": 51437900
},
{
"Date": "2021-10-29",
"Open": 455.869995,
"High": 459.559998,
"Low": 455.559998,
"Close": 459.25,
"Adj Close": 457.639252,
"Volume": 70108200
},
{
"Date": "2021-11-01",
"Open": 460.299988,
"High": 460.700012,
"Low": 458.200012,
"Close": 460.040009,
"Adj Close": 458.426514,
"Volume": 48433600
},
{
"Date": "2021-11-02",
"Open": 460.220001,
"High": 462.230011,
"Low": 460.079987,
"Close": 461.899994,
"Adj Close": 460.279968,
"Volume": 48908400
},
{
"Date": "2021-11-03",
"Open": 461.299988,
"High": 465.149994,
"Low": 460.829987,
"Close": 464.720001,
"Adj Close": 463.090088,
"Volume": 52509800
},
{
"Date": "2021-11-04",
"Open": 465.359985,
"High": 467,
"Low": 464.98999,
"Close": 466.910004,
"Adj Close": 465.2724,
"Volume": 52847100
},
{
"Date": "2021-11-05",
"Open": 469.279999,
"High": 470.649994,
"Low": 466.920013,
"Close": 468.529999,
"Adj Close": 466.886719,
"Volume": 66332200
},
{
"Date": "2021-11-08",
"Open": 469.700012,
"High": 470.230011,
"Low": 468.200012,
"Close": 468.929993,
"Adj Close": 467.285309,
"Volume": 50405200
},
{
"Date": "2021-11-09",
"Open": 469.320007,
"High": 469.570007,
"Low": 465.880005,
"Close": 467.380005,
"Adj Close": 465.740753,
"Volume": 51149100
},
{
"Date": "2021-11-10",
"Open": 465.579987,
"High": 467.380005,
"Low": 462.040009,
"Close": 463.619995,
"Adj Close": 461.993927,
"Volume": 69429700
},
{
"Date": "2021-11-11",
"Open": 465.209991,
"High": 465.290009,
"Low": 463.75,
"Close": 463.769989,
"Adj Close": 462.143402,
"Volume": 34848500
},
{
"Date": "2021-11-12",
"Open": 465.119995,
"High": 467.859985,
"Low": 464.109985,
"Close": 467.269989,
"Adj Close": 465.631134,
"Volume": 53423300
},
{
"Date": "2021-11-15",
"Open": 468.640015,
"High": 468.809998,
"Low": 466.230011,
"Close": 467.429993,
"Adj Close": 465.790558,
"Volume": 46980500
},
{
"Date": "2021-11-16",
"Open": 467.149994,
"High": 470.48999,
"Low": 467.070007,
"Close": 469.279999,
"Adj Close": 467.634094,
"Volume": 48857500
},
{
"Date": "2021-11-17",
"Open": 469,
"High": 469.190002,
"Low": 467.480011,
"Close": 468.140015,
"Adj Close": 466.498108,
"Volume": 47858300
},
{
"Date": "2021-11-18",
"Open": 469.23999,
"High": 470.01001,
"Low": 466.339996,
"Close": 469.730011,
"Adj Close": 468.08252,
"Volume": 50625600
},
{
"Date": "2021-11-19",
"Open": 469.609985,
"High": 470.940002,
"Low": 468.5,
"Close": 468.890015,
"Adj Close": 467.245483,
"Volume": 57315600
},
{
"Date": "2021-11-22",
"Open": 470.890015,
"High": 473.540009,
"Low": 467.350006,
"Close": 467.570007,
"Adj Close": 465.930084,
"Volume": 72762000
},
{
"Date": "2021-11-23",
"Open": 467.220001,
"High": 469.100006,
"Low": 464.450012,
"Close": 468.190002,
"Adj Close": 466.547913,
"Volume": 73206500
},
{
"Date": "2021-11-24",
"Open": 466.059998,
"High": 469.570007,
"Low": 465.190002,
"Close": 469.440002,
"Adj Close": 467.793518,
"Volume": 61858800
},
{
"Date": "2021-11-26",
"Open": 462.339996,
"High": 463.899994,
"Low": 457.769989,
"Close": 458.970001,
"Adj Close": 457.36026,
"Volume": 112669600
},
{
"Date": "2021-11-29",
"Open": 464.070007,
"High": 466.559998,
"Low": 461.730011,
"Close": 464.600006,
"Adj Close": 462.97052,
"Volume": 86268800
},
{
"Date": "2021-11-30",
"Open": 462,
"High": 464.029999,
"Low": 455.299988,
"Close": 455.559998,
"Adj Close": 453.962219,
"Volume": 148559600
},
{
"Date": "2021-12-01",
"Open": 461.640015,
"High": 464.670013,
"Low": 450.290009,
"Close": 450.5,
"Adj Close": 448.919952,
"Volume": 131939200
},
{
"Date": "2021-12-02",
"Open": 450.730011,
"High": 459.070007,
"Low": 450.309998,
"Close": 457.399994,
"Adj Close": 455.795746,
"Volume": 127637800
},
{
"Date": "2021-12-03",
"Open": 459.170013,
"High": 460.299988,
"Low": 448.920013,
"Close": 453.420013,
"Adj Close": 451.829712,
"Volume": 137167700
},
{
"Date": "2021-12-06",
"Open": 456.130005,
"High": 460.790009,
"Low": 453.559998,
"Close": 458.790009,
"Adj Close": 457.180878,
"Volume": 98977500
},
{
"Date": "2021-12-07",
"Open": 464.410004,
"High": 468.880005,
"Low": 458.649994,
"Close": 468.279999,
"Adj Close": 466.637604,
"Volume": 95484700
},
{
"Date": "2021-12-08",
"Open": 468.700012,
"High": 470,
"Low": 466.829987,
"Close": 469.519989,
"Adj Close": 467.87323,
"Volume": 72238800
},
{
"Date": "2021-12-09",
"Open": 468.149994,
"High": 469.630005,
"Low": 466.140015,
"Close": 466.350006,
"Adj Close": 464.714355,
"Volume": 61272600
},
{
"Date": "2021-12-10",
"Open": 469.230011,
"High": 470.899994,
"Low": 466.51001,
"Close": 470.73999,
"Adj Close": 469.088959,
"Volume": 76949400
},
{
"Date": "2021-12-13",
"Open": 470.190002,
"High": 470.559998,
"Low": 466.269989,
"Close": 466.570007,
"Adj Close": 464.933594,
"Volume": 87724700
},
{
"Date": "2021-12-14",
"Open": 463.089996,
"High": 465.73999,
"Low": 460.25,
"Close": 463.359985,
"Adj Close": 461.734833,
"Volume": 97264100
},
{
"Date": "2021-12-15",
"Open": 463.420013,
"High": 470.859985,
"Low": 460.73999,
"Close": 470.600006,
"Adj Close": 468.949463,
"Volume": 116899300
},
{
"Date": "2021-12-16",
"Open": 472.570007,
"High": 472.869995,
"Low": 464.799988,
"Close": 466.450012,
"Adj Close": 464.814026,
"Volume": 116568600
},
{
"Date": "2021-12-17",
"Open": 461.549988,
"High": 464.73999,
"Low": 458.059998,
"Close": 459.869995,
"Adj Close": 459.869995,
"Volume": 135511600
},
{
"Date": "2021-12-20",
"Open": 454.480011,
"High": 455.399994,
"Low": 451.140015,
"Close": 454.980011,
"Adj Close": 454.980011,
"Volume": 107134800
},
{
"Date": "2021-12-21",
"Open": 458.609985,
"High": 463.209991,
"Low": 456.309998,
"Close": 463.059998,
"Adj Close": 463.059998,
"Volume": 69806300
},
{
"Date": "2021-12-22",
"Open": 462.790009,
"High": 467.809998,
"Low": 462.579987,
"Close": 467.690002,
"Adj Close": 467.690002,
"Volume": 58890200
},
{
"Date": "2021-12-23",
"Open": 468.75,
"High": 472.190002,
"Low": 468.640015,
"Close": 470.600006,
"Adj Close": 470.600006,
"Volume": 56439700
}
]
const dividendRows = [
{
"Date": "2021-03-19",
"Dividends": 1.278
},
{
"Date": "2021-06-18",
"Dividends": 1.376
},
{
"Date": "2021-09-17",
"Dividends": 1.428
},
{
"Date": "2021-12-17",
"Dividends": 1.636
}
]
const getOpenPriceByDate = (rows, date) => {
const row = rows.find(row => row.Date === date)
assert(row !== undefined)
return row.Open
}
const getClosePriceByDate = (rows, date) => {
const row = rows.find(row => row.Date === date)
assert(row !== undefined)
return row.Close
}
const calculateNumberOfShares = (amount, price) => {
return amount / price
}
const calculatePortfolioValueOnDate = (holdings, rows, date) => {
const closePrice = getClosePriceByDate(rows, date)
let total = 0
for (let i = 0; i < holdings.length; ++i) {
const holding = holdings[i]
total += (holding.numberOfShares * closePrice)
}
return total
}
const performPurchase = (holdings, rows, date, amount) => {
const purchasePrice = getOpenPriceByDate(rows, date)
const numberOfShares = calculateNumberOfShares(amount, purchasePrice)
holdings.push({
date,
amount,
purchasePrice,
numberOfShares,
type: 'purchase'
})
}
const performDividendReinvestment = (holdings, rows, dividendDate, dividendAmount) => {
const numberOfSharesHeld = calculateNumberOfSharesHeld(holdings, dividendDate)
const purchasePrice = getOpenPriceByDate(rows, dividendDate)
const amount = dividendAmount * numberOfSharesHeld
const numberOfShares = calculateNumberOfShares(amount, purchasePrice)
holdings.push({
date: dividendDate,
amount,
purchasePrice,
numberOfShares,
numberOfSharesHeld,
dividendAmount,
type: 'dividend'
})
}
const calculatePurchaseDates = (startDate, interval, length) => {
startDate = new Date(startDate)
const purchaseDates = []
purchaseDates.push(startDate.toISOString().slice(0, 10))
let date = new Date(startDate)
for (;;) {
const oneDay = 1000 * 60 * 60 * 24 // in milliseconds
const currentLength = Math.ceil(Math.abs(date - startDate) / oneDay)
date.setDate(date.getDate() + interval)
if (currentLength > length) {
break
}
purchaseDates.push(date.toISOString().slice(0, 10))
}
return purchaseDates
}
const findClosestDate = (rows, purchaseDate) => {
purchaseDate = new Date(purchaseDate)
const dates = rows.map(row => row.Date)
dates.sort((a, b) => {
a = new Date(a)
b = new Date(b)
const aDifference = Math.abs(a - purchaseDate)
const bDifference = Math.abs(b - purchaseDate)
return aDifference - bDifference
})
const closestDate = dates[0]
return closestDate
}
const calculateNumberOfSharesHeld = (holdings, date) => {
date = new Date(date)
const filteredHoldings = holdings.filter(holding => {
const holdingDate = new Date(holding.date)
const dateDifference = holdingDate - date
return dateDifference <= 0
})
return filteredHoldings.reduce((prev, holding) => {
return prev + holding.numberOfShares
}, 0)
}
const holdings = []
const startDate = '2021-01-04' // first trading day of the year
const interval = 7 // weekly
const length = 365 // 1 year
const purchaseDates = calculatePurchaseDates(startDate, interval, length)
// adjust calculated dates for weekends/holidays
const tradingPurchaseDates = Array.from(new Set(purchaseDates.map(purchaseDate => {
// skip exact matches
const exactMatchRow = rows.find(row => row.Date === purchaseDate)
if (exactMatchRow) {
return purchaseDate
}
// find closest match
const closestDate = findClosestDate(rows, purchaseDate)
return closestDate
})))
// perform initial purchase
const initialAmount = 10000
performPurchase(holdings, rows, tradingPurchaseDates[0], initialAmount)
// perform additional contriubtions
const additionalContributionAmount = 1000
for (let i = 0; i < tradingPurchaseDates.length; ++i) {
const tradingPurchaseDate = tradingPurchaseDates[i]
// performPurchase(holdings, rows, tradingPurchaseDates[i], additionalContributionAmount)
}
// perform dividend reinvestments
for (let i = 0; i < dividendRows.length; ++i) {
const dividendRow = dividendRows[i]
const dividendDate = dividendRow.Date
const dividendAmount = dividendRow.Dividends
performDividendReinvestment(holdings, rows, dividendDate, dividendAmount)
}
// sort by date
holdings.sort((a, b) => {
if (a.date < b.date) {
return -1
} else if (a.date > b.date) {
return 1
}
return 0
})
// calculate portfolio value + contributions + dividends
const endDate = tradingPurchaseDates[tradingPurchaseDates.length - 1]
const currentValue = calculatePortfolioValueOnDate(holdings, rows, endDate)
const contributed = holdings.reduce((prev, holding) => {
if (holding.type === 'dividend') {
return prev
}
return prev + holding.amount
}, 0)
const dividends = holdings.reduce((prev, holding) => {
if (holding.type !== 'dividend') {
return prev
}
return prev + holding.amount
}, 0)
// log results
console.log({
holdings,
contributed,
dividends,
currentValue
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment