@shamdasani/

backtester

Python 2.7

No description

fork
loading
Files
  • main.py

This Plugin Crashed!

Error: Error: must not create an existing file {"type":"CREATE_FILE","wid":"0.9532857729820665","path":"main.py","file":{"path":"main.py","content":{"asEncoding":{"base64":"aW1wb3J0IG1hdHBsb3RsaWIucHlwbG90IGFzIHBsdAppbXBvcnQgcmVxdWVzdHMsIGpzb24KCgpkZWYgbW92aW5nX2F2ZXJhZ2VzKGhpc3RvcmljYWxfZGF0YSwgdGlja2VyLCBjYXNoKToKICAgICIiIgogICAgSWYgdGhlIDMgZGF5IGF2ZXJhZ2UgcHJpY2Ugb2YgRVRIIGlzIGFib3ZlIHRoZSA1IGRheSBhdmVyYWdlIHByaWNlLCBidXkuIElmIGJlbG93LCBzZWxsLgogICAgIiIiCiAgICBpbml0aWFsID0gaW50KGNhc2gpCiAgICBjYXNoID0gaW50KGNhc2gpCiAgICBjcnlwdG8gPSAwCiAgICB4X3ZhbHVlcyA9IFtdCiAgICB5X3ZhbHVlcyA9IFtdCiAgICBmb3IgcGxhY2UsIGRhdGFfc2V0IGluIGVudW1lcmF0ZShoaXN0b3JpY2FsX2RhdGFbNTotMV0pOgogICAgICAgIHRocmVlX2RheV9hdmVyYWdlID0gZ2V0X2F2ZXJhZ2UoW2hpc3RvcmljYWxfZGF0YVtwbGFjZS0xXSwgaGlzdG9yaWNhbF9kYXRhW3BsYWNlLTJdLCBoaXN0b3JpY2FsX2RhdGFbcGxhY2UtM11dKQogICAgICAgIGZpdmVfZGF5X2F2ZXJhZ2UgPSBnZXRfYXZlcmFnZShbaGlzdG9yaWNhbF9kYXRhW3BsYWNlLTFdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoaXN0b3JpY2FsX2RhdGFbcGxhY2UtMl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhpc3RvcmljYWxfZGF0YVtwbGFjZS0zXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGlzdG9yaWNhbF9kYXRhW3BsYWNlLTRdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoaXN0b3JpY2FsX2RhdGFbcGxhY2UtNV1dKQogICAgICAgIGlmIHRocmVlX2RheV9hdmVyYWdlID4gZml2ZV9kYXlfYXZlcmFnZToKICAgICAgICAgICAgY2FzaF91c2VkX3RvX2J1eSA9IGNhc2gvMgogICAgICAgICAgICBwcmljZSA9IGZsb2F0KGRhdGFfc2V0WyJjbG9zZSJdKQogICAgICAgICAgICBudW1iZXJfb2ZfY3J5cHRvX3dlX2p1c3RfYm91Z2h0ID0gY2FzaF91c2VkX3RvX2J1eS9wcmljZQogICAgICAgICAgICBjcnlwdG8gKz0gbnVtYmVyX29mX2NyeXB0b193ZV9qdXN0X2JvdWdodAogICAgICAgICAgICBjYXNoIC09IGNhc2hfdXNlZF90b19idXkKICAgICAgICAgICAgcHJpbnQgIkp1c3QgYm91Z2h0OiAiICsgc3RyKG51bWJlcl9vZl9jcnlwdG9fd2VfanVzdF9ib3VnaHQpICsgIiAiICsgdGlja2VyCiAgICAgICAgaWYgY3J5cHRvID4gMSBhbmQgdGhyZWVfZGF5X2F2ZXJhZ2UgPCBmaXZlX2RheV9hdmVyYWdlOgogICAgICAgICAgICBwcmljZSA9IGZsb2F0KGRhdGFfc2V0WyJjbG9zZSJdKQogICAgICAgICAgICBudW1iZXJfb2ZfY3J5cHRvX2JlaW5nX3NvbGQgPSBjcnlwdG8vMgogICAgICAgICAgICBuZXdfY2FzaCA9IG51bWJlcl9vZl9jcnlwdG9fYmVpbmdfc29sZCAqIHByaWNlCiAgICAgICAgICAgIGNhc2ggKz0gbmV3X2Nhc2gKICAgICAgICAgICAgY3J5cHRvIC09IG51bWJlcl9vZl9jcnlwdG9fYmVpbmdfc29sZAogICAgICAgICAgICBwcmludCAiSnVzdCBzb2xkOiAiICsgc3RyKG51bWJlcl9vZl9jcnlwdG9fYmVpbmdfc29sZCkgKyAiICIgKyB0aWNrZXIKICAgICAgICBwb3J0Zm9saW9fdmFsdWUgPSBjYXNoICsgKGNyeXB0byAqIGZsb2F0KGRhdGFfc2V0WyJjbG9zZSJdKSkKICAgICAgICB4X3ZhbHVlcy5hcHBlbmQocGxhY2UpCiAgICAgICAgeV92YWx1ZXMuYXBwZW5kKHBvcnRmb2xpb192YWx1ZSkKICAgIHByaW50ICJGaW5hbCBwb3J0Zm9saW8gdmFsdWU6ICIgKyBzdHIocG9ydGZvbGlvX3ZhbHVlKQogICAgbmV0ID0gcG9ydGZvbGlvX3ZhbHVlIC0gaW5pdGlhbAogICAgaWYgKG5ldCA+IDApOgogICAgICAgIHByaW50ICJZb3UgcHJvZml0ZWQ6ICIgKyBzdHIobmV0KQogICAgZWxzZToKICAgICAgICBwcmludCgiWW91IGxvc3Q6ICAiKSArIHN0cihuZXQpCiAgICBwbG90X2dyYXBoKHhfdmFsdWVzLCB5X3ZhbHVlcykKCgpkZWYgZ2V0X2F2ZXJhZ2UoYXZlcmFnZXNfbGlzdCk6CiAgICAiIiIKICAgIEdldHMgdGhlIGF2ZXJhZ2Ugb2Ygc29tZSBudW1iZXJzCiAgICAiIiIKICAgIHRvdGFsID0gMAogICAgZm9yIGRhdGFfc2V0IGluIGF2ZXJhZ2VzX2xpc3Q6CiAgICAgICAgdG90YWwgKz0gZmxvYXQoZGF0YV9zZXRbImNsb3NlIl0pCiAgICByZXR1cm4gdG90YWwvbGVuKGF2ZXJhZ2VzX2xpc3QpCgoKZGVmIHBsb3RfZ3JhcGgoeCwgeSk6CiAgICAiIiIKICAgIFBsb3RzIG91ciBHcmFwaAogICAgIiIiCiAgICBwbHQucGxvdCh4LCB5KQogICAgcGx0LnhsYWJlbCgiTWludXRlIikKICAgIHBsdC55bGFiZWwoIlBvcnRmb2xpbyBWYWx1ZSIpCiAgICBwbHQuc2hvdygpCgoKZGVmIHN0YXJ0KCk6CiAgICAiIiIKICAgIEhlcmUgd2UgYXNrIHRoZSB1c2VyIGZvciBzb21lIGJhc2ljIGlucHV0LCBmZXRjaCBvdXIgaGlzdG9yaWNhbCBkYXRhIGFuZCBkZXRlcm1pbmUgd2hhdCBzdHJhdGVneSB0byB1c2UuCiAgICAiIiIKICAgIHByaW50ICJTdGFydGluZyBDcnlwdG8gQm90IFYxIgogICAgdGlja2VyID0gcmF3X2lucHV0KCJFbnRlciB0aWNrZXI6ICIpLnVwcGVyKCkKICAgIGRhdGFfdXJsID0gJ2h0dHBzOi8vbWluLWFwaS5jcnlwdG9jb21wYXJlLmNvbS9kYXRhL2hpc3RvbWludXRlP2ZzeW09JyArIHRpY2tlciArICcmdHN5bT1VU0QmbGltaXQ9MjAwMCZhZ2dyZWdhdGU9MScKICAgIHJlc3BvbnNlID0gcmVxdWVzdHMuZ2V0KGRhdGFfdXJsKQogICAgdHJ5OgogICAgICAgIGRhdGEgPSByZXNwb25zZS5qc29uKClbJ0RhdGEnXQogICAgZXhjZXB0OgogICAgICAgIHByaW50ICJTb3JyeSwgdGhpcyBjcnlwdG8gaXNuJ3Qgc3VwcG9ydGVkISIKICAgICAgICBxdWl0KCkKICAgIGhpc3RvcmljYWxfZGF0YSA9IGRhdGEKICAgIHByaW50ICJGZXRjaGVkIGhpc3RvcmljYWwgZGF0YSBmb3IgY3J5cHRvOiAiICsgdGlja2VyCiAgICBjYXNoID0gcmF3X2lucHV0KCJFbnRlciBpbml0aWFsIGludmVzdG1lbnQ6ICIpCiAgICBzdHJhdGVneSA9IHJhd19pbnB1dCgiU2VsZWN0ICgxKSBmb3IgdGhlIG1vdmluZyBhdmVyYWdlcyBzdHJhdGVneTogIikKICAgIGlmIHN0cmF0ZWd5ID09ICIxIjoKICAgICAgICBtb3ZpbmdfYXZlcmFnZXMoaGlzdG9yaWNhbF9kYXRhLCB0aWNrZXIsIGNhc2gpCgpzdGFydCgp"},"asBuffer":null},"loaded":true}}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import matplotlib.pyplot as plt
import requests, json


def moving_averages(historical_data, ticker, cash):
    """
    If the 3 day average price of ETH is above the 5 day average price, buy. If below, sell.
    """
    initial = int(cash)
    cash = int(cash)
    crypto = 0
    x_values = []
    y_values = []
    for place, data_set in enumerate(historical_data[5:-1]):
        three_day_average = get_average([historical_data[place-1], historical_data[place-2], historical_data[place-3]])
        five_day_average = get_average([historical_data[place-1],
                                       historical_data[place-2],
                                       historical_data[place-3],
                                       historical_data[place-4],
                                       historical_data[place-5]])
        if three_day_average > five_day_average:
            cash_used_to_buy = cash/2
            price = float(data_set["close"])
            number_of_crypto_we_just_bought = cash_used_to_buy/price
            crypto += number_of_crypto_we_just_bought
            cash -= cash_used_to_buy
            print "Just bought: " + str(number_of_crypto_we_just_bought) + " " + ticker
        if crypto > 1 and three_day_average < five_day_average:
            price = float(data_set["close"])
            number_of_crypto_being_sold = crypto/2
            new_cash = number_of_crypto_being_sold * price
            cash += new_cash
            crypto -= number_of_crypto_being_sold
            print "Just sold: " + str(number_of_crypto_being_sold) + " " + ticker
        portfolio_value = cash + (crypto * float(data_set["close"]))
        x_values.append(place)
        y_values.append(portfolio_value)
    print "Final portfolio value: " + str(portfolio_value)
    net = portfolio_value - initial
    if (net > 0):
        print "You profited: " + str(net)
    else:
        print("You lost:  ") + str(net)
    plot_graph(x_values, y_values)


def get_average(averages_list):
    """
    Gets the average of some numbers
    """
    total = 0
    for data_set in averages_list:
        total += float(data_set["close"])
    return total/len(averages_list)


def plot_graph(x, y):
    """
    Plots our Graph
    """
    plt.plot(x, y)
    plt.xlabel("Minute")
    plt.ylabel("Portfolio Value")
    plt.show()


def start():
    """
    Here we ask the user for some basic input, fetch our historical data and determine what strategy to use.
    """
    print "Starting Crypto Bot V1"
    ticker = raw_input("Enter ticker: ").upper()
    data_url = 'https://min-api.cryptocompare.com/data/histominute?fsym=' + ticker + '&tsym=USD&limit=2000&aggregate=1'
    response = requests.get(data_url)
    try:
        data = response.json()['Data']
    except:
        print "Sorry, this crypto isn't supported!"
        quit()
    historical_data = data
    print "Fetched historical data for crypto: " + ticker
    cash = raw_input("Enter initial investment: ")
    strategy = raw_input("Select (1) for the moving averages strategy: ")
    if strategy == "1":
        moving_averages(historical_data, ticker, cash)

start()