def __init__(self, gdax=None, gdax_db=None, products=None, channels=None): """ :param gdax: (gdax.api.Gdax) The Gdax API object. None will attempt to create a default Gdax object. If an error happens it will continue without authentication. :param gdax_db: (gdax.db.GdaxDatabase) Recommended to configure with a MySQL/Postgres backend rather than SQLite. SQLite databases can return Disk I/O errors pretty easily due to the speed of data being received over the web socket. :param products: (list, default ['LTC-USD', 'BTC-USD', 'ETH-USD']) A list of currency pairs to subscribe to. :param channels (list, default ['ticker', 'full']) A list of websocket channels to subscribe to. """ if products is None: products = ['LTC-USD', 'BTC-USD', 'ETH-USD'] if channels is None: channels = ['ticker', 'full'] if gdax is None: # Try to authenticate using Gdax try: from stocklook.crypto.gdax import Gdax gdax = Gdax() key = gdax.api_key secret = gdax.api_secret phrase = gdax.api_passphrase auth = False # figure out why auth is broke except Exception as e: print("Ignored error configuring " "default Gdax object. " "Using public API.\n{}".format(e)) key, secret, phrase = None, None, None auth = False super(GdaxDatabaseFeed, self).__init__(products=products, api_key=key, api_secret=secret, api_passphrase=phrase, channels=channels, auth=auth) self.session = None self.db = gdax_db self.gdax = gdax self.url = "wss://ws-feed.gdax.com/" self.queues = dict() self._loaders = dict()
copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ from stocklook.crypto.gdax import Gdax, GdaxProducts, GdaxOrderBook, GdaxChartData, get_buypoint, GdaxDatabase from stocklook.utils.timetools import now_minus, now if __name__ == '__main__': g = Gdax() #for a in g.accounts.values(): # print(a) # print("\n") # print("Total account value: ${}".format(g.get_total_value())) pair = GdaxProducts.LTC_USD book = GdaxOrderBook(g, pair) product = g.get_product(pair) start = now_minus(days=5) end = now() granularity = 60 * 60 * 24 chart = GdaxChartData(g, pair, start, end, granularity) price = product.price res_price, res_qty = book.get_next_resistance()
except (IndexError, KeyError): return None if __name__ == '__main__': from stocklook.crypto.gdax import Gdax, GdaxOrder from time import sleep c = CoinbaseClient() g = Gdax() last_4 = '5118' key = 'mastercard' #method = c.get_payment_method_by_last_4(last_4, key) #cusd_acc = g.coinbase_accounts['USD'] # print(cusd_acc) gusd_acc = g.accounts['USD'] gltc_acc = g.accounts['LTC'] # Withdraw 1% of funds. amount = round(gusd_acc.balance * 0.01, 2) print("Funds amount: {}".format(amount)) try: res = g.withdraw_to_coinbase('USD', amount) print(res) print(res.status_code)
ETH_LOW = None ETH_HIGH = None SCAN_INTERVAL_SECONDS = 60 BTC_CHANGE_RATE = 0.005 ETH_CHANGE_RATE = 0.0075 LTC_CHANGE_RATE = 0.0075 if __name__ == '__main__': from time import sleep from threading import Thread from stocklook.utils.emailsender import send_message from stocklook.crypto.gdax import Gdax, scan_price, GdaxProducts as G gdax = Gdax() interval = SCAN_INTERVAL_SECONDS end_time = None print("total account value: {} ".format(gdax.get_total_value())) btc, ltc, eth = G.BTC_USD, G.LTC_USD, G.ETH_USD btc_args = (gdax, btc, send_message, BTC_LOW, BTC_HIGH, interval, end_time, BTC_CHANGE_RATE) ltc_args = (gdax, ltc, send_message, LTC_LOW, LTC_HIGH, interval, end_time, LTC_CHANGE_RATE) eth_args = (gdax, eth, send_message, ETH_LOW, ETH_HIGH, interval, end_time, ETH_CHANGE_RATE) btc_thread = Thread(target=scan_price, args=btc_args) ltc_thread = Thread(target=scan_price, args=ltc_args) eth_thread = Thread(target=scan_price, args=eth_args)
""" MIT License Copyright (c) 2017 Zeke Barge Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ if __name__ == '__main__': from stocklook.crypto.gdax import sync_database, Gdax, GdaxDatabase interval = 60 gdax = Gdax() sync_database(gdax, interval=interval)
""" MIT License Copyright (c) 2017 Zeke Barge Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject tweplpo the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ if __name__ == '__main__': from stocklook.crypto.gdax import Gdax gdax = Gdax() value = gdax.get_total_value() msg = "Account value is: ${}".format(value) print(msg)
def __init__(self, pair, size, stop_pct=None, stop_amt=None, target=None, notify=None, interval=10, gdax=None, product=None): """ :param pair: (str) LTC-USD, BTC-USD, or ETH-USD :param size: (int, float) The size of coin(s) to sell. If this size is not available in the Gdax account they'll be immediately market bought as long as :param buy_needed is True. :param stop_pct: (float, default None) The decimal (percentage) amount the currency must fall to trigger the sell order. Note: You can't use both :param stop_pct and :param stop_amt, just one or the other. :param stop_amt: (float, default None) The $ amount that the currency must fall to trigger the sell order. Note: You can't use both :param stop_pct and :param stop_amt, just one or the other. :param notify: (str, default None) An email address to notify when the stop has been triggered. :param interval (int, default 10) The number of seconds to wait between price-checks & stop calculations. :param gdax: (gdax.api.Gdax, default None) None will generate a default Gdax API object within the GdaxTrailingStop. This is used to check account balance and get the current price by default. """ assert interval >= 5 fail = all([stop_pct, stop_amt]) if fail: msg = "stop_pct and stop_amt " \ "cannot both contain values." log.error(msg) raise AttributeError(msg) Thread.__init__(self) if gdax is None: from stocklook.crypto.gdax import Gdax gdax = Gdax() if product is None: product = gdax.get_product(pair) product.sync_interval = interval - 1 self.gdax = gdax self.pair = pair self.product = product self.size = size self.stop_pct = stop_pct self.stop_amt = stop_amt self.notify = notify self.sell_mark = None self.sell_order = None self.down_diff = None self.up_diff = None self.first_price = None self.price = None self.target = target self.interval = interval
def test_get_account_history(self, gdax: Gdax): pytest.skip("Skipping obnoxiously expensive calls to API.") history = gdax.get_account_ledger_history() fp = os.path.join(os.path.dirname('__file__'), 'fixtures', 'sample_history.csv') history.to_csv(fp, index=False) print(history)
def gdax(self): return Gdax()
def run_macd_rsi_decisions(data_dir, product, start, end, granularity, overwrite=True, strat=None): # File paths to be saved at the end. out_name = '{}-BTEST-{}-{}.csv'.format(product, granularity, timestamp_to_path(end)) tout_name = out_name.split('.')[0] + '-TRADES.csv' pout_name = out_name.split('.')[0] + '-PNL.csv' out_path = os.path.join(data_dir, out_name) # Chart Data tout_path = os.path.join(data_dir, tout_name) # Trade Data pout_path = os.path.join(data_dir, pout_name) # PNL Data if os.path.exists(tout_path) and not overwrite: tdf = pd.read_csv(tout_path, parse_dates=['time']) return tout_path, tdf if os.path.exists(out_path) and not overwrite: df = pd.read_csv(out_path, parse_dates=['time']) else: data = GdaxChartData(Gdax(), product, start, end, granularity=granularity) try: df = data.df except ValueError: return None, pd.DataFrame() if strat is None: sdf = StockDataFrame.retype(df) strat = Strategy(sdf, margin=False, funds=1500, position_size=5) print("Composing decision makers.") ratios = ((0.1, 0.1), (0.1, 0.5), (0.5, 0.1), (0.2, 0.1), (0.1, 0.2), (0.25, 0.35), (0.01, 0.02), (0.09, 0.075), (1, 2), (0.005, 0.003), (0.003, 0.005), (0.9, 0.45), (0.8, 0.64), (1.3, .9), (1.5, .6)) for b, s in ratios: for i in range(1, 100): b1, s1 = b * i, s * i strat.add_decision_maker(MACDRSIMaker, buy_ratio=b1, sell_ratio=s1) for s, b in ratios: for i in range(1, 100): b1, s1 = b * i, s * i strat.add_decision_maker(MACDRSIMaker, buy_ratio=b1, sell_ratio=s1) else: if strat.stock_data_frame is None: strat.set_stock_df(StockDataFrame.retype(df)) sdf = strat.stock_data_frame print("Processing decisions.") strat.execute() print("Execution finished. Compiling results.") results, trade_list = list(), list() for idx, maker in enumerate(strat.makers): inputs = maker.inputs() tset = maker.tset inputs['profit'] = tset.get_profit() inputs['bought'] = tset.get_total_bought() inputs['trades'] = tset.trades inputs['start_funds'] = tset.start_funds inputs['end_funds'] = tset.funds inputs['pnl'] = tset.get_pnl() inputs['maker_id'] = idx tdf = tset.df if not tdf.empty: tdf.loc[:, 'maker_id'] = idx results.append(inputs) trade_list.append(tdf) print("Calculating PNL") strat_df = pd.DataFrame(data=results, index=range(len(results))) strat_df.sort_values(['profit'], ascending=[False], inplace=True) strat_df = strat_df.loc[strat_df['profit'] > -100, :] print("Composing trade data") trade_df = pd.concat(trade_list) if not trade_df.empty: trade_df = pd.merge(strat_df, trade_df, how='left', on='maker_id') sdf_bit = sdf.loc[:, [ 'open', 'low', 'high', 'close', 'rsi_6', 'macd', 'time' ]] trade_df = pd.merge(trade_df, sdf_bit, how='left', on=['time']) print("Writing files.") sdf.to_csv(out_path, index=False) strat_df.to_csv(pout_path, index=False) trade_df.to_csv(tout_path, index=False) print("Done: {}".format(out_path)) try: top_id = int(strat_df.iloc[0]['maker_id']) print("Top decision maker: {}".format(strat.makers[top_id])) except: pass return tout_path, trade_df