<file_sep>from binance.client import Client
from binance.exceptions import BinanceAPIException, BinanceWithdrawException
from binance.enums import *
from secrets import KEY, SECRET

# initialize api
client = Client(KEY, SECRET)

# load constants
SYMBOL_TYPE_SPOT = 'SPOT'

ORDER_STATUS_NEW = 'NEW'
ORDER_STATUS_PARTIALLY_FILLED = 'PARTIALLY_FILLED'
ORDER_STATUS_FILLED = 'FILLED'
ORDER_STATUS_CANCELED = 'CANCELED'
ORDER_STATUS_PENDING_CANCEL = 'PENDING_CANCEL'
ORDER_STATUS_REJECTED = 'REJECTED'
ORDER_STATUS_EXPIRED = 'EXPIRED'

KLINE_INTERVAL_1MINUTE = '1m'
KLINE_INTERVAL_3MINUTE = '3m'
KLINE_INTERVAL_5MINUTE = '5m'
KLINE_INTERVAL_15MINUTE = '15m'
KLINE_INTERVAL_30MINUTE = '30m'
KLINE_INTERVAL_1HOUR = '1h'
KLINE_INTERVAL_2HOUR = '2h'
KLINE_INTERVAL_4HOUR = '4h'
KLINE_INTERVAL_6HOUR = '6h'
KLINE_INTERVAL_8HOUR = '8h'
KLINE_INTERVAL_12HOUR = '12h'
KLINE_INTERVAL_1DAY = '1d'
KLINE_INTERVAL_3DAY = '3d'
KLINE_INTERVAL_1WEEK = '1w'
KLINE_INTERVAL_1MONTH = '1M'

SIDE_BUY = 'BUY'
SIDE_SELL = 'SELL'

ORDER_TYPE_LIMIT = 'LIMIT'
ORDER_TYPE_MARKET = 'MARKET'
ORDER_TYPE_STOP_LOSS = 'STOP_LOSS'
ORDER_TYPE_STOP_LOSS_LIMIT = 'STOP_LOSS_LIMIT'
ORDER_TYPE_TAKE_PROFIT = 'TAKE_PROFIT'
ORDER_TYPE_TAKE_PROFIT_LIMIT = 'TAKE_PROFIT_LIMIT'
ORDER_TYPE_LIMIT_MAKER = 'LIMIT_MAKER'

TIME_IN_FORCE_GTC = 'GTC'
TIME_IN_FORCE_IOC = 'IOC'
TIME_IN_FORCE_FOK = 'FOK'

ORDER_RESP_TYPE_ACK = 'ACK'
ORDER_RESP_TYPE_RESULT = 'RESULT'
ORDER_RESP_TYPE_FULL = 'FULL'

# For accessing the data returned by Client.aggregate_trades().
AGG_ID = 'a'
AGG_PRICE = 'p'
AGG_QUANTITY = 'q'
AGG_FIRST_TRADE_ID = 'f'
AGG_LAST_TRADE_ID = 'l'
AGG_TIME = 'T'
AGG_BUYER_MAKES = 'm'
AGG_BEST_MATCH = 'M'


# create a class to load into the algorithm
class TradeSlice:
    def __init__(dict_info):
        self.price = price
        self.volume = volume
        self.time = time
        self.vwap = VWAP


# run class
symbol = 'BTCUSDT'

'''
NOTES
- inputs: price, time, VWAP
- ALWAYS check for 429 errors (warning for ban) --> rest for an hour
- bitcoin ticker: BTCUSDT

EXAMPLE KLINE RESPONSE
[1581029400000,  # timestamp (miliseconds)
'9715.01000000', # open
'9719.31000000', # high
'9715.01000000', # low
'9715.36000000', # close
'40.35176000', # volume
1581029459999, # close time
'392062.02410586', # quote asset volume
408, # number of trades
'14.41288300', ' # taker buy base asset volume --> amount being bought
140056.44775208', # taker by quote asset volume --> amount being sold
'0']

background-image: url("https://i1.sndcdn.com/artworks-000369285036-qrl6uu-t500x500.jpg"); width: 100%; height: 100%; opacity: 1;

SOURCES
- https://towardsdatascience.com/creating-bitcoin-trading-bots-that-dont-lose-money-2e7165fb0b29

'''
<file_sep># CryptAlgo
Crypto currency AI training. This is really just for fun.
<file_sep>from binance.client import Client
from secrets import KEY, SECRET
import pandas as pd
import ta  # keep this here --> it is how you will get technical indicators for the dataset
import time

# load constants
PERIOD = 5
LOW_PERIOD = PERIOD / 2
MEDIUM_PERIOD = PERIOD
HIGH_PERIOD = PERIOD * 2


class Record:
    # the related records are strictly for calculating intraday trading indicators
    def __init__(self, info_list):
        self.timestamp = info_list[0]
        self.open = float(info_list[1])
        self.high = float(info_list[2])
        self.low = float(info_list[3])
        self.close = float(info_list[4])
        self.volume = float(info_list[5])
        self.quote_asset_volume = float(info_list[7])
        self.number_of_trades = info_list[8]
        self.taker_buy_base_asset_volume = float(info_list[9])
        self.taker_quote_asset_volume = float(info_list[10])

    def __repr__(self):
        return f"{self.close} at {self.timestamp}"


# create a general mining class
class Miner:
    def __init__(self, raw_csv):
        self.headers = ["Timestamp", "Open", "High", "Low", "Close", "Volume",
                        "Quote Asset Volume", "Number of Trades", "Taker Buy Asset Volume", "Taker Quote Asset Volume"]
        self.raw_csv = raw_csv
        self.client = Client(KEY, SECRET)

    # this function automatically adds everything
    def add(self, records):
        # get the new records into a new dataframe
        formatted_records = [list(record.__dict__.values()) for record in records]

        new_df = pd.DataFrame(formatted_records, columns=self.headers)

        # add the new df to the old one and sort it by timestamp
        try:
            raw_df = pd.read_csv(self.raw_csv, header=0)
            raw_df = raw_df.append(new_df, ignore_index=True).drop_duplicates(keep='first', subset=['Timestamp'])
            raw_df = raw_df.sort_values(by=['Timestamp'])
        except FileNotFoundError:
            raw_df = new_df
            print(f"{self.raw_csv} was not found. A new file has been created")

        raw_df.to_csv(self.raw_csv, columns=self.headers, index=False)

    def get_technicals(self, raw_df, build_csv):
        build_df = ta.utils.dropna(raw_df)

        # trend indicators
        build_df['SMA'] = ta.trend.SMAIndicator(close=build_df['Close'], n=PERIOD).sma_indicator()
        build_df['EMA'] = ta.trend.EMAIndicator(close=build_df['Close'], n=PERIOD).ema_indicator()
        build_df['MACD'] = ta.trend.MACD(close=build_df['Close'], n_fast=LOW_PERIOD, n_slow=HIGH_PERIOD,).macd()

        ichimoku = ta.trend.IchimokuIndicator(low=build_df['Low'], high=build_df['High'],
                                              n1=LOW_PERIOD, n2=MEDIUM_PERIOD, n3=HIGH_PERIOD)
        build_df['ICHIMOKU_A'] = ichimoku.ichimoku_a()
        build_df['ICHIMOKU_B'] = ichimoku.ichimoku_b()

        # volumen indicator
        build_df['VWAP'] = ta.volume.VolumeWeightedAveragePrice(low=build_df['Low'], high=build_df['High'],
                                                                close=build_df['Close'], volume=build_df['Volume'],
                                                                n=PERIOD).volume_weighted_average_price()

        # send the dataframe to a csv
        build_df.to_csv(build_csv, index=False)

    def build_set_on_timeframe(self, ticker, timeframe):
        # use a generator to preserve memory and overuse of cpu
        klines = self.client.get_historical_klines(ticker, Client.KLINE_INTERVAL_1MINUTE, timeframe)

        records = [Record(kline) for kline in klines]

        self.add(records)

    # create a function to fill in blanks
    def fill_blanks(self, ticker):
        # check if the previous record corresponds with the next record (should be 60s apart --> 70s --> problem)
        old_df = pd.read_csv(self.raw_csv, header=0)
        # headers = old_df.columns

        timestamps = old_df['Timestamp']

        old = timestamps[0]
        for timestamp in timestamps[1:]:
            # check difference
            difference = old - timestamp
            if difference != 60000:
                # need to add data and sleep for appropriate amount --> get the amount of time (in ms)
                # necessary_records = difference / 60000

                # set a start and end time

                # get current time in miliseconds
                now = time.time() * 1000
                start_time = f"{int((old - now) / (1000 * 60)) - 1} minutes ago UTC"
                end_time = f"{int((timestamp - now) / (1000 * 60)) + 1} minutes ago UTC"

                # request data from a generator for this many minutes
                for new_slice in self.client.get_historical_klines_generator(ticker, Client.KLINE_INTERVAL_1MINUTE, start_time, end_time):
                    new_record = Record(new_slice)

                    # append the current df, drop duplicates (based on timestamp), sort it (in loop to prevent timeout)
                    self.add([new_record])
                    print(f"{new_record} added")
                    time.sleep(0.1)

            # set the current time to the old variable
            old = timestamp

    def raw_size(self):
        raw_df = pd.read_csv(self.raw_csv, header=0)

        size = len(raw_df)

        return size
<file_sep>import datetime
from time import sleep
from binance.client import Client
from secrets import KEY, SECRET

# initialize api
client = Client(KEY, SECRET)

# input symbols and quantity
symbol = 'BTCUSDT'
quantity = '0.05'

order = False

while not order:
    BTC = client.get_historical_klines(symbol=symbol, interval='1m', start_str="1 minute ago UTC")
    print(BTC)
    break
<file_sep>from DataMiner import Miner
import time
from datetime import datetime as dt
from multiprocessing import Pool
import os

TICKERS = ['BTCUSDT', 'ETHUSDT', 'BNBUSDT', 'LTCUSDT']
TIMEFRAME = '1 hour ago UTC'
PROCESSES = 2 * os.cpu_count()

# reassign the proceesses to the number of tickers if it exceeds it
if len(TICKERS) < PROCESSES:
    PROCESSES = len(TICKERS)


# build our set on current data
def inf_builder(ticker):
    miner = Miner(f"data/{ticker}_raw_4_22_20.csv")
    while True:
        miner.build_set_on_timeframe(ticker, TIMEFRAME)
        size = miner.raw_size()
        now = dt.now()

        print(f"{now.time()}  \n{ticker} records: {size}   \nDays: {round(size / 1440, 2)}    \n")

        time.sleep(3300)


# get the data
with Pool(processes=PROCESSES) as pool:
    pool.map(inf_builder, TICKERS, chunksize=1)
