Market Data Analysis with Python #2

0 22
Avatar for cryptodontrading
Written by
3 weeks ago

Charting & The Simple Moving Average

In the previous article, we learnt how to get the data we wanted for Bitcoin Cash. In this lesson, we will learn how to display that data on a chart and we will also learn how to create a simple moving average. If you have not read the first lesson then I suggest reading that first before proceeding with this one.

Read Part 1

Tools Needed

In this lesson, we will be introducing two new packages for python to help us in working with our data.

Matplotlib & the Statistics Library

Simple Moving Average

Let's import those at the top of our code so we can make use of them.

import statistics as stats
import matplotlib.pyplot as plt

To create a simple moving average first we need to understand how that is calculated. The simple moving average is calculated by adding recent closing prices and then dividing that by the number of time periods in the calculation average.

sma = (A1 + A2 + ... + An) / n

An = the price of an asset at period n

n = the number of total periods

Let's translate this into python code. We need to create a variable that holds the number of time periods, an array to hold the price history and an array to hold the moving average values for that time period.

time_period = 21
price_history = []
sma_values = []

The moving average is calculated on the close price for the given time period, in this case, we are working with daily data. We need to create a variable to hold all out close prices.

close = bch_coin_data['close']

We are taking the close column in the data frame we created and assigning it to the close variable. If we run print(close) we get the following output.

0      1487.18
1      1267.99
2      1192.13
3      1273.08
4      1158.57
        ...   
726     362.42
727     378.37
728     379.97
729     393.55
730     384.17
Name: close, Length: 731, dtype: float64

This is exactly what we are looking for. Next, we want to create a for loop which will add the closing prices to the price_history array for the given time period.

for closing_price in close:
    price_history.append(closing_price)

This, however, will add the complete history to the price history array. We don't want that, we want the latest closing prices only for the given time_period.

[1487.18, 1267.99, 1192.13, 1273.08, 1158.57, 884.0, 966.79, 954.34, 1280.55, 1299.97, 1240.62, 1210.99, 1282.63, 1220.89, 1353.18, 1359.47, 1530.44, 1543.21, 1453.37, 1521.92, 1393.77, 1287.06, 1210.0, 1256.52, 1182.03, 1172.58, 1244.42, 1234.2, 1200.33, 1285.01, 1276.64, 1272.26, 1285.24, 1266.93, 1207.43, 1095.91, 1033.96, 1065.69, 1003.78, 1138.84, 1051.06, 1053.55, 950.28, 939.68, 972.37, 948.93, 936.27, 994.67, 1062.82, 1031.78, 1015.19, 1029.74, 975.94, 975.38, 913.74, 877.69, 861.18, 711.13, 696.93, 685.47, 644.25, 663.98, 710.13, 651.52, 644.1, 610.89, 642.65, 657.44, 638.73, 652.58, 670.06, 737.84, 743.27, 739.16, 782.05, 769.81, 759.77, 895.45, 966.63, 1124.67, 1154.45, 1195.64, 1440.95, 1407.55, 1289.86, 1421.87, 1331.97, 1390.64, 1440.09, 1348.27, 1354.28, 1457.08, 1507.36, 1513.29, 1758.59, 1756.57, 1651.39, 1599.52, 1626.63, 1519.84, 1367.01, 1458.55, 1478.75, 1412.97, 1337.53, 1280.11, 1192.88, 1203.32, 1177.02, 1291.59, 1229.05, 1135.15, 994.37, 1073.9, 1016.45, 1006.46, 996.48, 883.18, 988.06, 982.87, 996.48, 1001.86, 1084.22, 1168.41, 1097.9, 1150.06, 1129.12, 1144.55, 1115.05, 1085.65, 937.21, 954.26, 870.75, 842.82, 895.36, 842.61, 850.03, 847.28, 884.91, 907.69, 891.94, 871.58, 751.41, 762.42, 747.18, 754.23, 695.38, 713.38, 658.97, 715.5, 747.61, 736.91, 781.02, 755.83, 763.41, 743.02, 732.78, 772.76, 749.2, 729.59, 686.77, 707.1, 686.84, 694.23, 702.02, 724.17, 801.6, 852.79, 824.39, 824.27, 764.92, 787.28, 785.21, 781.91, 865.86, 831.23, 804.03, 820.01, 822.81, 830.31, 814.48, 776.27, 767.83, 731.03, 724.78, 695.86, 709.17, 690.96, 657.05, 588.63, 608.95, 570.32, 563.18, 571.36, 531.58, 510.26, 511.19, 516.12, 603.69, 554.89, 570.97, 513.43, 536.47, 518.42, 529.91, 533.45, 536.49, 523.98, 549.3, 565.28, 554.52, 538.73, 542.22, 617.79, 651.05, 628.3, 626.33, 526.8, 519.43, 497.43, 474.24, 479.21, 466.54, 439.9, 431.72, 463.72, 447.5, 448.9, 450.46, 417.55, 432.69, 429.8, 456.12, 501.93, 485.43, 489.53, 462.39, 446.34, 514.23, 566.03, 539.29, 538.21, 530.76, 532.4, 531.74, 516.3, 513.69, 520.37, 509.93, 519.66, 529.86, 518.92, 513.62, 431.47, 441.0, 449.93, 438.99, 463.11, 458.99, 450.87, 439.55, 441.99, 449.57, 451.07, 452.57, 444.87, 444.95, 442.73, 441.13, 438.48, 441.15, 416.51, 422.16, 425.36, 425.0, 463.8, 479.96, 569.53, 561.85, 631.45, 618.32, 576.75, 544.31, 556.78, 533.77, 516.24, 514.92, 444.16, 381.98, 355.2, 361.43, 338.1, 266.14, 247.55, 258.34, 250.22, 229.97, 196.11, 205.38, 195.69, 205.28, 219.44, 208.28, 192.66, 196.05, 198.23, 181.88, 174.49, 151.42, 119.77, 104.98, 100.29, 107.38, 102.17, 95.71, 97.03, 87.11, 79.72, 76.45, 79.06, 88.47, 104.48, 126.63, 192.61, 192.64, 197.72, 196.76, 181.77, 171.42, 175.68, 148.46, 174.34, 162.53, 163.22, 149.23, 165.02, 171.7, 160.99, 160.64, 159.38, 166.39, 160.89, 161.31, 160.44, 134.23, 130.49, 133.8, 125.37, 133.16, 126.98, 128.31, 130.28, 127.31, 129.77, 122.41, 122.18, 127.97, 132.11, 129.45, 127.09, 125.94, 121.4, 111.53, 109.61, 117.27, 113.59, 115.26, 121.1, 118.14, 118.17, 116.58, 114.18, 114.89, 128.94, 127.97, 126.49, 121.56, 121.95, 121.72, 120.67, 120.99, 121.4, 123.92, 143.35, 141.6, 147.14, 141.7, 143.75, 154.07, 127.29, 134.04, 132.82, 131.19, 130.17, 131.41, 130.77, 129.64, 123.69, 132.82, 131.77, 130.41, 128.03, 133.74, 131.75, 129.27, 127.86, 127.97, 132.44, 143.86, 156.58, 155.04, 161.71, 161.31, 159.97, 153.72, 157.1, 166.73, 164.18, 159.79, 159.3, 171.34, 168.66, 171.19, 167.7, 169.54, 167.89, 243.2, 301.25, 287.02, 294.59, 306.76, 321.07, 310.5, 296.41, 305.06, 271.56, 282.84, 279.36, 290.04, 312.93, 317.25, 310.62, 306.99, 307.25, 300.81, 291.33, 293.3, 289.2, 279.33, 265.27, 264.88, 262.66, 255.8, 238.92, 271.31, 272.69, 270.56, 292.79, 292.72, 294.86, 290.17, 283.86, 287.54, 284.11, 286.52, 353.18, 356.02, 383.25, 388.77, 403.81, 398.77, 368.02, 358.12, 418.08, 414.38, 416.79, 387.71, 405.65, 408.76, 406.03, 433.75, 440.37, 433.79, 456.69, 421.86, 442.98, 432.47, 441.57, 401.39, 382.94, 397.48, 397.09, 399.39, 393.63, 380.68, 394.5, 388.16, 397.11, 412.06, 421.34, 423.46, 427.54, 431.17, 413.43, 416.59, 412.85, 441.28, 480.49, 475.76, 478.2, 477.0, 481.92, 412.17, 434.11, 440.01, 399.3, 416.23, 407.46, 421.99, 400.03, 400.06, 406.54, 412.55, 417.88, 415.33, 388.88, 345.5, 352.93, 344.53, 281.76, 313.01, 282.28, 292.19, 314.47, 307.86, 324.8, 320.93, 310.64, 297.58, 302.63, 302.03, 317.73, 305.64, 309.82, 305.95, 318.01, 329.03, 329.18, 327.98, 335.48, 336.14, 347.54, 335.58, 338.43, 333.88, 314.83, 315.84, 338.63, 330.21, 347.12, 311.1, 314.39, 309.26, 306.77, 316.98, 325.02, 315.36, 303.64, 312.18, 315.86, 305.68, 305.75, 311.05, 308.36, 292.44, 279.86, 278.99, 279.58, 281.26, 293.61, 300.29, 294.14, 292.53, 286.57, 300.23, 306.74, 304.46, 304.13, 299.25, 300.16, 298.25, 304.67, 303.19, 307.77, 318.36, 323.73, 323.34, 315.86, 311.97, 307.65, 292.15, 222.9, 227.96, 214.26, 220.16, 227.24, 218.28, 227.45, 223.06, 225.04, 222.01, 221.55, 222.84, 220.66, 232.97, 231.7, 238.55, 229.56, 220.6, 224.31, 223.02, 228.02, 222.3, 217.15, 220.26, 211.97, 213.15, 224.76, 232.71, 227.0, 210.17, 212.39, 259.07, 253.02, 260.76, 264.27, 289.2, 288.72, 282.78, 278.53, 289.82, 291.31, 290.54, 292.73, 305.42, 291.9, 276.8, 282.64, 293.08, 286.64, 289.05, 285.35, 277.68, 263.31, 265.34, 266.1, 246.65, 241.95, 243.32, 226.12, 207.4, 215.26, 202.63, 207.59, 211.24, 219.52, 217.71, 224.22, 217.74, 214.45, 213.84, 211.72, 207.66, 211.66, 212.89, 211.21, 212.56, 208.49, 206.88, 207.09, 206.67, 211.53, 206.13, 206.98, 196.44, 176.55, 188.88, 186.2, 187.4, 186.25, 196.47, 190.11, 188.44, 185.29, 187.73, 203.1, 206.22, 212.68, 208.47, 204.65, 204.37, 195.54, 222.05, 224.6, 223.03, 244.13, 242.86, 240.07, 237.99, 271.68, 261.31, 269.94, 267.03, 349.25, 340.11, 327.27, 367.65, 338.44, 339.43, 343.29, 343.52, 348.83, 325.25, 318.68, 310.06, 347.77, 362.42, 378.37, 379.97, 393.55, 383.81]

We can achieve this by adding an if statement to the for loop that checks the length of price_history. If it is greater than the given time_period then it will delete the first entry in the array until the length is not greater than the time_period. This gives us the most recent closing prices that we require.

for closing_price in close:
    price_history.append(closing_price)
    if len(price_history) > time_period:
        del(price_history[0])

It does this for every iteration of the loop so we get a complete history for each daily closing price. We can now calculate the average in price_history each time and add it to our sma_values array.

We can use the statistics library to do this calculation quickly and with very little code.

sma_values.append(stats.mean(price_history))

Our complete for loop now looks like this.

for closing_price in close:
    price_history.append(closing_price)
    if len(price_history) > time_period:
        del(price_history[0])
    sma_values.append(stats.mean(price_history))

We now have the moving average values that we can add to our data frame which we can then use to plot against the price on a chart. let's add them to our data frame.

bch_coin_data = bch_coin_data.assign(sma=pd.Series(sma_values, index=bch_coin_data.index))

Now when we print(bch_coin_data) we have a new column on the end with the sma values populated.

          time    close     high  ...  volumefrom      volumeto          sma
0   2018-01-31  1487.18  1519.81  ...    48581.92  7.108496e+07  1487.180000
1   2018-02-01  1267.99  1497.56  ...    82606.34  1.098698e+08  1377.585000
2   2018-02-02  1192.13  1269.81  ...   125569.30  1.437148e+08  1315.766667
3   2018-02-03  1273.08  1318.52  ...    55292.57  6.630029e+07  1305.095000
4   2018-02-04  1158.57  1289.48  ...    56805.55  6.694511e+07  1275.790000
..         ...      ...      ...  ...         ...           ...          ...
726 2020-01-27   362.42   377.17  ...   164215.66  5.987151e+07   312.040476
727 2020-01-28   378.37   384.58  ...   325496.05  1.201279e+08   318.493333
728 2020-01-29   379.97   396.03  ...   351413.31  1.354978e+08   325.155238
729 2020-01-30   393.55   398.85  ...   319921.44  1.236012e+08   332.562857
730 2020-01-31   384.22   394.83  ...    96622.94  3.736882e+07   337.921905

We can now plot these on a chart to see the moving average plotted against the price.

First, we will create two variables to hold the information we want to plot. One for the closing_price and one for the sma.

closing_price = bch_coin_data['close']
sma = bch_coin_data['sma']

We can now use matplotlib to create a chart t plot both values.

fig = plt.figure()
ax1 = fig.add_subplot(111, ylabel="Price $")
closing_price.plot(ax=ax1, color='g', lw=2., legend=True)
sma.plot(ax=ax1, color='r', lw=2., legend=True)
plt.show()

Now when we run our code we should get a chart with the closing price for the past year and a 21 period simple moving average plotted on the chart also.

Full Code

Here is a copy of the full code to create this.

import cryptocompare as cc
import pandas as pd
import statistics as stats
import matplotlib.pyplot as plt

time_period = 21
price_history = []
sma_values = []

bch_history = cc.get_historical_price_day('BCH', curr='USD', limit=730)
bch_coin_data = pd.DataFrame(bch_history)
bch_coin_data['time'] = pd.to_datetime(bch_coin_data['time'], unit='s')

close = bch_coin_data['close']

for closing_price in close:
    price_history.append(closing_price)
    if len(price_history) > time_period:
        del(price_history[0])
    sma_values.append(stats.mean(price_history))

bch_coin_data = bch_coin_data.assign(sma=pd.Series(sma_values, index=bch_coin_data.index))

closing_price = bch_coin_data['close']
sma = bch_coin_data['sma']

fig = plt.figure()
ax1 = fig.add_subplot(111, ylabel="Price $")
closing_price.plot(ax=ax1, color='g', lw=2., legend=True)
sma.plot(ax=ax1, color='r', lw=2., legend=True)

plt.show()

Conclusion

Over the last two lessons, we have learnt how to use an API to get the data we want, organize that data and plot a chart of that data. We have also learnt how to do calculations on that data to plot a simple moving average against the price.

In Part 3 we will learn how to create an exponential moving average.

Useful Links & Further Reading

Simple Moving Averages

Matplotlib

Python Statistics


$ 0.10
$ 0.10 from @ZeusOnPills
Avatar for cryptodontrading
Written by
3 weeks ago
Enjoyed this article?  Earn Bitcoin Cash by sharing it! Explain
...and you will also help the author collect more tips.

Comments

About us Rules What is Bitcoin Cash? Roadmap Affiliate program Get sponsored Self-host
hello@read.cash (PGP key) Reddit