Last active
January 24, 2022 23:26
-
-
Save mistermichaelll/e5d0b89c3a4d557c3f767e78e82e16f7 to your computer and use it in GitHub Desktop.
This script generates the headers for making API requests to Coinbase's API, as documented here: https://docs.cloud.coinbase.com/exchange/docs/welcome
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # libraries | |
| # --------- | |
| import SHA.hmac_sha256, Base64.base64encode, Base64.base64decode | |
| # this is the URL we'll use as a base for all requests. | |
| # ----------------------------------------------------- | |
| api_url = "https://api.exchange.coinbase.com" | |
| # struct for required CB info | |
| # --------------------------- | |
| struct CoinbaseAuthClient | |
| CB_ACCESS_KEY::String | |
| CB_SECRET_KEY::String | |
| CB_ACCESS_PASSPHRASE::String | |
| end | |
| # this function generates the headers utilized | |
| # by requests to Coinbase's API. It returns a dictionary | |
| # used by the HTTP library. | |
| # ------------------------------------------------------ | |
| function Coinbase_Auth_Headers(C::CoinbaseAuthClient, method::String, path::String, body::String) | |
| #= | |
| From Coinbase Developer API Docs: | |
| All REST requests must contain the following headers: | |
| CB-ACCESS-SIGN The base64-encoded signature (see Signing a Message). | |
| CB-ACCESS-TIMESTAMP A timestamp for your request. | |
| CB-ACCESS-PASSPHRASE The passphrase you specified when creating the API key. | |
| CB-ACCESS-KEY The api key as a string. | |
| All request bodies should have content type application/json and be valid JSON. | |
| =# | |
| timestamp = string(time()) | |
| message = timestamp * method * path * body | |
| hmac_key = base64decode(C.CB_SECRET_KEY) | |
| signature = hmac_sha256(hmac_key, message) | |
| return Dict("Content-Type" => "application/json", | |
| "CB-ACCESS-KEY" => C.CB_ACCESS_KEY, | |
| "CB-ACCESS-PASSPHRASE" => C.CB_ACCESS_PASSPHRASE, | |
| "CB-ACCESS-SIGN" => base64encode(signature), | |
| "CB-ACCESS-TIMESTAMP" => timestamp | |
| ) | |
| end | |
| #= | |
| =============== | |
| EXAMPLE USE | |
| =============== | |
| As an example usecase, this function creates a small dataframe representing a snapshot of a user's portfolio at | |
| time of execution. | |
| =# | |
| using HTTP, DataFrames, JSON, Printf | |
| import Dates.DateTime, Dates.now | |
| # define our coinbase auth client info | |
| CB = CoinbaseAuthClient( | |
| "your_access_token", # access token | |
| "your_secret_key", # secret key | |
| "your_api_password" # password we defined when we created our key | |
| ) | |
| function portfolio_snapshot() | |
| # get the currencies which make up a user's account | |
| account_response = HTTP.request("GET", api_url * "/accounts", Coinbase_Auth_Headers(CB, "GET", "/accounts", "")) | |
| account = JSON.parse(String(account_response.body)) | |
| # get the currency symbol and the current balance (eg. the number of coins a user owns) | |
| currencies = [currency["currency"] for currency = account[1:length(account)] if parse(Float64, currency["balance"]) > .0001] | |
| balance = [round(parse(Float64, currency["balance"]), digits = 5) for currency = account[1:length(account)] if parse(Float64, currency["balance"]) > .0001] | |
| # get the current price of each holding, along with a timestamp of when the price was obtained. | |
| coin_price = Float64[] | |
| timestamp = DateTime[] | |
| for currency in currencies | |
| if currency == "USD" | |
| push!(coin_price, 1.0) | |
| push!(timestamp, DateTime(now())) | |
| elseif currency != "USD" | |
| ticker_response = HTTP.request("GET", api_url * "/products/" * currency * "-USD/ticker", Coinbase_Auth_Headers(CB, "GET", "/products/" * currency * "-USD/ticker", "")) | |
| tickers = JSON.parse(String(ticker_response.body)) | |
| push!(coin_price, parse(Float64, tickers["price"])) | |
| push!(timestamp, DateTime(chop(tickers["time"], tail = 4))) | |
| end | |
| end | |
| # return a dataframe which represents a users' portfolio. | |
| DataFrame("Currency" => currencies, "Balance" => balance, "Value" => coin_price .* balance, "Timestamp" => timestamp) | |
| end | |
| show(portfolio_snapshot()) | |
| @printf "\n\nThe total value of your portfolio is: \$%.2f" round(sum(portfolio_snapshot()[!, 3]), digits = 3) | |
| #>5×4 DataFrame | |
| #> Row │ Currency Balance Value Timestamp | |
| #> │ String Float64 Float64 DateTime | |
| #>─────┼──────────────────────────────────────────────────────── | |
| #> 1 │ ADA 16.9 21.4207 2022-01-12T13:46:22.610 | |
| #> 2 │ BTC 0.0048 210.576 2022-01-12T13:46:23.600 | |
| #> 3 │ ETH 0.16195 544.474 2022-01-12T13:46:23.558 | |
| #> 4 │ SOL 0.11581 16.9604 2022-01-12T13:46:23.410 | |
| #> 5 │ USD 0.00184 0.00184 2022-01-12T08:46:23.939 | |
| #> | |
| #> The total value of your portfolio is: $793.41 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment