<reponame>smalbadger/TradeBot<gh_stars>0
"""
    Author: <NAME>
    
    This is the Bot class. The most important parts are:
        + self._client
            - Used to interact with the GDAX platform and user accounts. To do any trading, we need to use the 
              gdax.AuthenticatedClient() function. This gives access to functions that interact with a specific
              account, but requires that you provide an API key, secret, and passphrase.
              
        + self._socket
            - This will connect you to the websocket. The websocket allows you to get constant information. To 
              reduce thread usage, it's best to create a BotSocket object (my wrapper for the websocket) and pass
              it in to each of the Bot objects that you create.
              
        + self._trade_hands
            - This is what does the actual trading. It has a paper-trade mode for testing.
            
        + self._data_center
            - This is exactly what it sounds like. All of the data we store will go to the data center, get dispatched,
              and then get processed there. The data center also allows for easy access of all data.
              
    For simplicity, the Bot only supports trading one cryptocurrency. To trade multiple currencies, you should create 
    multiple bot objects with different currency attributes. Note that each bot will use its own thread for trading. 
    This is to prevent unnecessary delays in trading. SPAWNING TOO MANY BOTS WILL CRASH YOUR PROGRAM. Since the websocket
    also uses a thread, you should see how many threads you have on your computer (cores * threads) and spawn a maximum of 
    that number minus one bots. 
    
    I recommend not starting multiple bots that are trading the same cryptocurrency. Also, please note that the bot will
    default to trading bitocin if no other currency is given.
"""

import sys
import gdax
import time
from threading import Thread
import plotly
import plotly.plotly as py
import plotly.graph_objs as go

from bot_socket import BotSocket
from TradeHands import *
from DataCenter import *

################################################################################
#                                   Bot                                        #
################################################################################
class Bot():
    def __init__(self, name="Bot", currency="BTC-USD", webSocket=None):
        
        #obtain credentials, authenticate GDAX client and websocket, and then over-write credentials
        self._passphrase = ""
        self._secret = ""
        self._key = ""
        self.get_credentials(credentials_file="../../credentials.txt")      #fills in passphrase, secret, and key
        
        #main body parts
        self._data_center = DataCenter(self)
        self._client = gdax.AuthenticatedClient(self._key, self._secret, self._passphrase)
        self._socket = webSocket
        self._trade_hands = TradeHands(self)
        
        #other bot stuff
        self._name = name
        self._currency = currency
        self._running = False
        self._fake_crypto = 0          #set an initial value for fake crypto
        self._fake_cash = 1000         #set an initial fake cash value

        self._socket.set_data_center(self._data_center)
        self._socket.set_bot(self)
        
        self.scramble_credentials()

    #####################
    ##---- GETTERS ----##
    #####################
    def name(self):
        return self._name
        
    def currency(self):
        return self._currency
        
    def socket(self):
        return self._socket
        
    def client(self):
        return self._client
        
    def historical_prices(self, until_time=None):
        return self._socket._history[self.currency()]
        
    def fake_cash(self):
        return self._cash
        
    def fake_crypto(self):
        return self._crypto
        
    def running(self):
        self._running = self._running and not self.socket().stop
        return self._running
        
    #####################
    ##---- SETTERS ----##
    #####################
    def set_currency(self, product):
        print("New currency being traded: ", product)
        self._currency = product
        
    #Returns the amount of all holdings in your account including cash
    def get_balances(self, all_currencies=False):
        accounts = self.client().get_accounts()
        for account in accounts:
            currency = account["currency"]
            amount = float(account["balance"])
            if currency != "USD" and currency == "BTC":
                BTC = amount
            if currency != "USD" and currency == "BCH":
                BCH = amount
            if currency != "USD" and currency == "ETH":
                ETH = amount
            if currency != "USD" and currency == "LTC":
                LTC = amount
            if currency == "USD":
                USD = amount
            if currency in self.currency():
                crypto = amount
                
        if all_currencies == False:
            return USD, crypto
        else:
            return USD, BTC, BCH, ETH, LTC

    #Obtains GDAX credentials from a file and stores them as fields of the bot.
    #they will only be stored until everything has been verified, and then should 
    #be cleared by calling the self.scramble_credentials() method
    def get_credentials(self, credentials_file=None):
        if credentials_file is None:
            yay = 0
            while yay == 0:
                file_loc = input("Drag and drop credential file here, or type path: ")
                try:
                    cred_file = open(file_loc)
                    yay = 1
                except:
                    print("Sorry, That file doesn't seem to exist. Please try again.")
                    yay = 0
                
        else:
            cred_file = open(credentials_file)
            
        lines = cred_file.readlines()
        self._passphrase = lines[0].split()[1]
        self._key = lines[1].split()[1]
        self._secret = lines[2].split()[1]
        cred_file.close()

    #We really shouldn't keep the credentials information around, so this method
    #over-writes the memory with information that is not useful.
    def scramble_credentials(self):
        self._passphrase = "<PASSWORD>? What's that? I don't know what an API Passphrase is. Sorry, I think you got me confused with someone else"
        self._key = "Key? What's that? I don't know what an API Key is. Sorry, I think you got me confused with someone else"
        self._secret = "Secret? What's that? I don't know what an API Secret is. Sorry, I think you got me confused with someone else"

    #Starts the robot's listening and trading sequence
    def start(self, should_print=True):
        #self._data_center.create_portfolio()
        self._running = True
        self._socket.start()
        self._trade_hands.start()
        
        if should_print == True:
            print(self.name()+" has been started")

    #Stops the bot's trading sequence and ties up the trading thread
    def stop(self, should_print=True):
        if len(self._data_center._crypto_history[self.currency()]) > 0:
            self._trade_hands.sell()
            
        self._running = False           #shut down client
        #TODO: tie up trading thread
        self.socket().close()           #shut down web socket.
        
        if should_print == True:
            print(self.name()+" has been stopped")
            print("Cash:\t", self._fake_cash)
            print("Crypto:\t", self._fake_crypto)
            



"""
    Author: <NAME>
    
    This is the Bot class. The most important parts are:
        + self._client
            - Used to interact with the GDAX platform and user accounts. To do any trading, we need to use the 
              gdax.AuthenticatedClient() function. This gives access to functions that interact with a specific
              account, but requires that you provide an API key, secret, and passphrase.
              
        + self._socket
            - This will connect you to the websocket. The websocket allows you to get constant information. To 
              reduce thread usage, it's best to create a BotSocket object (my wrapper for the websocket) and pass
              it in to each of the Bot objects that you create.
              
        + self._trade_hands
            - This is what does the actual trading. It has a paper-trade mode for testing.
            
        + self._data_center
            - This is exactly what it sounds like. All of the data we store will go to the data center, get dispatched,
              and then get processed there. The data center also allows for easy access of all data.
              
    For simplicity, the Bot only supports trading one cryptocurrency. To trade multiple currencies, you should create 
    multiple bot objects with different currency attributes. Note that each bot will use its own thread for trading. 
    This is to prevent unnecessary delays in trading. SPAWNING TOO MANY BOTS WILL CRASH YOUR PROGRAM. Since the websocket
    also uses a thread, you should see how many threads you have on your computer (cores * threads) and spawn a maximum of 
    that number minus one bots. 
    
    I recommend not starting multiple bots that are trading the same cryptocurrency. Also, please note that the bot will
    default to trading bitocin if no other currency is given.
"""

import sys
import gdax
import time
from threading import Thread
import plotly
import plotly.plotly as py
import plotly.graph_objs as go

from bot_socket import BotSocket
from TradeHands import *
from DataCenter import *

################################################################################
#                                   Bot                                        #
################################################################################
class Bot():
    def __init__(self, name="Bot", currency="BTC-USD", webSocket=None):
        
        #obtain credentials, authenticate GDAX client and websocket, and then over-write credentials
        self._passphrase = ""
        self._secret = ""
        self._key = ""
        self.get_credentials(credentials_file="../../credentials.txt")      #fills in passphrase, secret, and key
        
        #main body parts
        self._data_center = DataCenter(self)
        self._client = gdax.AuthenticatedClient(self._key, self._secret, self._passphrase)
        self._socket = webSocket
        self._trade_hands = TradeHands(self)
        
        #other bot stuff
        self._name = name
        self._currency = currency
        self._running = False
        self._fake_crypto = 0          #set an initial value for fake crypto
        self._fake_cash = 1000         #set an initial fake cash value

        self._socket.set_data_center(self._data_center)
        self._socket.set_bot(self)
        
        self.scramble_credentials()

    #####################
    ##---- GETTERS ----##
    #####################
    def name(self):
        return self._name
        
    def currency(self):
        return self._currency
        
    def socket(self):
        return self._socket
        
    def client(self):
        return self._client
        
    def historical_prices(self, until_time=None):
        return self._socket._history[self.currency()]
        
    def fake_cash(self):
        return self._cash
        
    def fake_crypto(self):
        return self._crypto
        
    def running(self):
        self._running = self._running and not self.socket().stop
        return self._running
        
    #####################
    ##---- SETTERS ----##
    #####################
    def set_currency(self, product):
        print("New currency being traded: ", product)
        self._currency = product
        
    #Returns the amount of all holdings in your account including cash
    def get_balances(self, all_currencies=False):
        accounts = self.client().get_accounts()
        for account in accounts:
            currency = account["currency"]
            amount = float(account["balance"])
            if currency != "USD" and currency == "BTC":
                BTC = amount
            if currency != "USD" and currency == "BCH":
                BCH = amount
            if currency != "USD" and currency == "ETH":
                ETH = amount
            if currency != "USD" and currency == "LTC":
                LTC = amount
            if currency == "USD":
                USD = amount
            if currency in self.currency():
                crypto = amount
                
        if all_currencies == False:
            return USD, crypto
        else:
            return USD, BTC, BCH, ETH, LTC

    #Obtains GDAX credentials from a file and stores them as fields of the bot.
    #they will only be stored until everything has been verified, and then should 
    #be cleared by calling the self.scramble_credentials() method
    def get_credentials(self, credentials_file=None):
        if credentials_file is None:
            yay = 0
            while yay == 0:
                file_loc = input("Drag and drop credential file here, or type path: ")
                try:
                    cred_file = open(file_loc)
                    yay = 1
                except:
                    print("Sorry, That file doesn't seem to exist. Please try again.")
                    yay = 0
                
        else:
            cred_file = open(credentials_file)
            
        lines = cred_file.readlines()
        self._passphrase = lines[0].split()[1]
        self._key = lines[1].split()[1]
        self._secret = lines[2].split()[1]
        cred_file.close()

    #We really shouldn't keep the credentials information around, so this method
    #over-writes the memory with information that is not useful.
    def scramble_credentials(self):
        self._passphrase = "<PASSWORD>? What's that? I don't know what an API Passphrase is. Sorry, I think you got me confused with someone else"
        self._key = "Key? What's that? I don't know what an API Key is. Sorry, I think you got me confused with someone else"
        self._secret = "Secret? What's that? I don't know what an API Secret is. Sorry, I think you got me confused with someone else"

    #Starts the robot's listening and trading sequence
    def start(self, should_print=True):
        #self._data_center.create_portfolio()
        self._running = True
        self._socket.start()
        self._trade_hands.start()
        
        if should_print == True:
            print(self.name()+" has been started")

    #Stops the bot's trading sequence and ties up the trading thread
    def stop(self, should_print=True):
        if len(self._data_center._crypto_history[self.currency()]) > 0:
            self._trade_hands.sell()
            
        self._running = False           #shut down client
        #TODO: tie up trading thread
        self.socket().close()           #shut down web socket.
        
        if should_print == True:
            print(self.name()+" has been stopped")
            print("Cash:\t", self._fake_cash)
            print("Crypto:\t", self._fake_crypto)
Author: <NAME>          This is the Bot class. The most important parts are:         + self._client             - Used to interact with the GDAX platform and user accounts. To do any trading, we need to use the                gdax.AuthenticatedClient() function. This gives access to functions that interact with a specific               account, but requires that you provide an API key, secret, and passphrase.                        + self._socket             - This will connect you to the websocket. The websocket allows you to get constant information. To                reduce thread usage, it's best to create a BotSocket object (my wrapper for the websocket) and pass               it in to each of the Bot objects that you create.                        + self._trade_hands             - This is what does the actual trading. It has a paper-trade mode for testing.                      + self._data_center             - This is exactly what it sounds like. All of the data we store will go to the data center, get dispatched,               and then get processed there. The data center also allows for easy access of all data.                    For simplicity, the Bot only supports trading one cryptocurrency. To trade multiple currencies, you should create      multiple bot objects with different currency attributes. Note that each bot will use its own thread for trading.      This is to prevent unnecessary delays in trading. SPAWNING TOO MANY BOTS WILL CRASH YOUR PROGRAM. Since the websocket     also uses a thread, you should see how many threads you have on your computer (cores * threads) and spawn a maximum of      that number minus one bots.           I recommend not starting multiple bots that are trading the same cryptocurrency. Also, please note that the bot will     default to trading bitocin if no other currency is given. ################################################################################ #                                   Bot                                        # ################################################################################ #obtain credentials, authenticate GDAX client and websocket, and then over-write credentials #fills in passphrase, secret, and key #main body parts #other bot stuff #set an initial value for fake crypto #set an initial fake cash value ##################### ##---- GETTERS ----## ##################### ##################### ##---- SETTERS ----## ##################### #Returns the amount of all holdings in your account including cash #Obtains GDAX credentials from a file and stores them as fields of the bot. #they will only be stored until everything has been verified, and then should #be cleared by calling the self.scramble_credentials() method #We really shouldn't keep the credentials information around, so this method #over-writes the memory with information that is not useful. #Starts the robot's listening and trading sequence #self._data_center.create_portfolio() #Stops the bot's trading sequence and ties up the trading thread #shut down client #TODO: tie up trading thread #shut down web socket.