Using Nefertiti Cryptotrader Bot

February 21, 2021 · 17 minutes read

What is Nefertiti?

Nefertiti is completely free and open source and is quite simple to use. This documentation follows the steps I took for the installation and setup of Nefertiti, and how I use tmux+tmuxp to automate the deployment of my bots and give me a sweet looking terminal:

tmux terminal

Note to Windows Users:

This guide was originally written for Linux. If you’re using Windows you can install Windows Subsystem for Linux with either Ubuntu or Debian and follow the guide exactly how it is intended, or you could use the .bat script files found in the script templates repo. Using WSL will allow you to take advantage of the tmux/p scripts at the end of the guide.

Gather Your Info

There is always risk when using an API. Please do NOT give your API withdraw/transfer permissions, and keep your keys confidential!

Nefertiti works with API access to an exchange, and offers a couple options for getting bot notifications. Before we start, gather your exchange API public and private keys (and passphrase if your exchange requires it) and make sure that the API has trading permissions.

You may also want to get notifications when your bot places or fills orders, or to monitor for debugging or errors. Nefertiti offers Pushover and Telegram for push notifications and both work just fine, but the developer currently recommends using Pushover. You can use either, or both, or none at all if you’d like (although this is not recommended as the notifications are how the bot communicates with you). Follow the steps below to gather the information you need.

Pushover Notifications Setup
  • Register for an account at Pushover.net
  • Copy your User Key. This is your --pushover-user-key
  • Create a new Application/API Token
  • The API Token/Key provided is your --pushover-app-key

You have to install the Pushover app on at least 1 device or you’ll see invalid recipient errors.

Telegram Notifications Setup
  • Create a Telegram bot:
    • Start a new chat with Telegram’s Botfather: t.me/BotFather
    • Send /newbot and follow the instructions
    • When finished you will receive a token
    • Copy the token as your --telegram-app-key
  • Create a Telegram group (where you will receive notifications)
    • Create a new group
    • Add your bot and promote it to group Admin
    • Add the @get_id_bot to the Telegram group: t.me/get_id_bot
    • Send /my_id message to the group to get your Group Chat ID
    • Copy the Group Chat ID as your --telegram-chat-id
      • This can be confusing, because the @get_id_bot will give you two different chat ID’s. Be sure you use your Group Chat ID and not your user chat ID!

Installation and Initial Setup of Nefertiti

Installation is a breeze. Just head to the Nefertiti homepage and click the download link at the top of the page. It should be as simple as clicking the large orange button to download the binary, but be sure to verify you’re downloading for the correct operating system and architecture. Once it’s downloaded just unzip it and add it to your /usr/local/bin for easy access from the command line.

Do this on Linux with just two commands:

# Download the latest stable release
wget https://bin.equinox.io/c/mvjh5YAmwCZ/cryptotrader-stable-linux-amd64.tgz
# Extract the archive into /usr/local/bin
tar xvf cryptotrader-stable-linux-amd64.tgz -C /usr/local/bin

Make sure it’s ready to go with cryptotrader about:

$ cryptotrader about
NAME:
  cryptotrader is a command-line trading bot that follows a simple but proven
  strategy: buy the dip, then sell those trades as soon as possible, preferably
  on the same day.
USAGE:
  ./cryptotrader command [options]
VERSION:
  0.0.135
AUTHOR:
  Stefan van As <svanas@runbox.com>
GLOBAL OPTIONS:
  --help     show help
  --version  print the version
PRICING:
  cryptotrader is freeware. But if the bot is making you money, then I would
  appreciate a BTC donation here: 1M4ZAsZGA89P54kAawZk8dKTcytLw33keu. Thanks!
DISCLAIMER:
  Never spend money on crypto that you cannot afford to lose. Use at your own
  risk.

Nefertiti includes an updater that will download and install any updates that are available: cryptotrader update

Basic cryptotrader Commands and Usage

Now that Nefertiti is installed we should check out the commands. Nefertiti offers a --help option for almost every command (the asterisks in the following code block represent the commands that don’t give us anything useful with --help). I’ve gone ahead and run these commands and included their output here for reference, and you can also find this in my Github repo which may be easier for searching and linking.

cryptotrader --help
$ cryptotrader --help
Usage: cryptotrader [--version] [--help] <command> [<args>]

Available commands are:
    about        About cryptotrader.
    agg          Calculates the aggregation level for a given market pair.
    base         Get the base symbol for a given market pair.
    book         Get a list of all public orders on a market.
    buy          Opens new limit buy orders on the specified exchange/market.
    cancel       Cancels all your buy or sell orders on a given market.
  * exchanges    Get a list of supported exchanges.
  * listen       Starts a server listening to the specified port.
    markets      Get a list of available currency pairs for trading.
    notify       Send a notification.
    order        Place an order with the specified exchange.
    quote        Get the quote symbol for a given market pair.
    sell         Automatically opens new sell orders on the specified exchange/market.
    stoploss     Place a stop-loss order with the specified exchange.
  * update       Check for a new version.
cryptotrader buy --help
$ cryptotrader buy --help
Usage: ./cryptotrader buy [options]

The buy command opens new limit buy orders on the specified exchange/market.

Options:
  --exchange = name, for example: Bittrex
  --market   = a valid market pair.
  --size     = amount of cryptocurrency to buy per order. please note --size is
               mutually exclusive with --price, eg. the price in quote currency
               you will want to pay for an order.
  --agg      = aggregate public order book to nearest multiple of agg.
               (optional)
  --dip      = percentage that will kick the bot into action.
               (optional, defaults to 5%)
  --pip      = range in where the market is suspected to move up and down.
               the bot will ignore supports outside of this range.
               (optional, defaults to 30%)  
  --dist     = distribution/distance between your orders.
               (optional, defaults to 2%)
  --top      = number of orders to place in your book.
               (optional, defaults to 2)
  --max      = maximum price that you will want to pay for the coins.
               (optional)
  --min      = minimum price that you will want to pay for the coins.
               (optional)
  --dca      = if included, then slowly but surely, the bot will proportionally
               increase your stack while lowering your average buying price.
               (optional)
  --test     = if included, merely reports what it would do.
               (optional, defaults to false)
  --repeat   = if included, repeats this command every X hours.
               (optional, defaults to false)

Alternative Strategy:
  The trading bot can listen to signals (for example: Telegram bots) as an
  alternative to the built-in strategy. Please refer to the below options.

Alternative Strategy Options:
  --exchange = name, for example: Bittrex
  --signals  = provider, for example: MiningHamster 
  --price    = price (in quote currency) that you will want to pay for an order
  --quote    = currency that is used as the reference, for example: BTC or USDT
  --min      = minimum price for a unit of quote currency.
               optional, for example: 0.00000050
  --volume   = minimum BTC volume over the last 24 hours.
               optional, for example: --volume=10
  --devn     = buy price deviation. this multiplier is applied to the suggested
               price from the signal, to calculate your actual limit price.
               optional, for example: --devn=1.01
  --valid    = if included, specifies the time (in hours, defaults to 1 hour)
               that the signal is "active". after this timeout elapses, the
               bot will cancel the (non-filled) limit buy order(s) associated
               with the signal.
               (optional, defaults to 1 hour)
  --repeat   = if included, repeats this command every X hours.
               (optional, defaults to false)
cryptotrader sell --help
$ cryptotrader sell --help
Usage: ./cryptotrader sell [options]

The sell command listens for buy orders getting filled, and then opens new sell orders for them.

Options:
  --exchange = [name]
  --sandbox  = [Y|N] (optional)
  --strategy = [0|1|2|3|4] (see below)
  --notify   = [0|1|2|3] (see below)
  --mult     = multiplier, for example: 1.05 (aka 5 percent, optional)
  --hold     = name of the market not to sell, for example: BTC-EUR (optional)

Strategy:
  0 = Standard. No trailing. No stop-loss. Recommended, default strategy.
  1 = Trailing. As strategy #0, but includes trailing. Never sells at a loss.
  2 = Trailing Stop-Loss. As strategy #1, but potentially sells at a loss.
  3 = Trailing Stop-Loss Short/Mid Term. As strategy #2, but does not trail
      forever. Sells as soon as ticker >= mult.
  4 = Stop-Loss. No trailing. As strategy #0, but potentially sells at a loss.

Notify:
  0 = nothing, ever
  1 = errors only
  2 = errors + filled orders (default)
  3 = everything (including opened and cancelled orders)
cryptotrader agg --help
$ cryptotrader agg --help
Usage: ./cryptotrader agg [options]

The agg command calculates the aggregation level for a given market pair.

Options:
  --exchange = name
  --market   = a valid market pair
  --dip      = percentage that will kick the bot into action.
               (optional, defaults to 5%)
  --pip      = range in where the market is suspected to move up and down.
               the bot will ignore supports outside of this range.
               (optional, defaults to 30%)  
  --max      = maximum price that you will want to pay for the coins.
               (optional)
  --min      = minimum price that you will want to pay for the coins.
               (optional)
cryptotrader base --help
$ cryptotrader base --help
Usage: ./cryptotrader base [options]

The base command returns the base symbol for a given market pair.

Options:
  --exchange = name
  --market   = a valid market pair
cryptotrader book --help
$ cryptotrader book --help
Usage: ./cryptotrader book [options]

The book command returns a list of all public orders on a market.

Options:
  --exchange = name
  --market   = a valid market pair
  --side     = [bids|asks] (optional, defaults to bids)
  --agg      = aggregate the book to nearest multiple of agg
cryptotrader cancel --help
$ cryptotrader cancel --help
Usage: ./cryptotrader cancel [options]

The cancel command cancels all your buy or sell orders on a given market.

Options:
  --exchange = name
  --market   = a valid market pair
  --side     = [buy|sell]
cryptotrader markets --help
$ cryptotrader markets --help
Usage: ./cryptotrader markets [options]

The markets command returns a list of available currency pairs for trading.

Options:
  --exchange=[name]
cryptotrader notify --help
$ cryptotrader notify --help
Usage: ./cryptotrader notify [options]

The notify command sends a notification.

Options:
  --pushover-app-key=X
  --pushover-user-key=Y
or:
  --telegram-app-key=X
  --telegram-chat-id=Y
and:
  --msg="blah blah blah"
cryptotrader order --help
$ cryptotrader order --help
Usage: ./cryptotrader order [options]

The order command places an order with the specified exchange.

Options:
  --exchange = name
  --side     = [buy|sell]
  --type     = [limit|market]
  --market   = a valid market pair
  --size     = amount of cryptocurrency to buy or sell
  --price    = price per unit (optional, not needed for market orders)
  --mult     = vector to multiply price with (optional, defaults to 1.0)
cryptotrader quote --help
$ cryptotrader quote --help
Usage: ./cryptotrader quote [options]

The quote command returns the quote symbol for a given market pair.

Options:
  --exchange = name
  --market   = a valid market pair
cryptotrader stoploss --help
$ cryptotrader stoploss --help
Usage: ./cryptotrader stoploss [options]

The stoploss command places a stop-loss order with the specified exchange.

Options:
  --exchange = name
  --type     = [limit|market]
  --market   = a valid market pair
  --size     = amount of cryptocurrency to sell
  --price    = price per unit

How to Check Exchanges and Markets

Before we set up Nefertiti it’s a good idea to try a few commands to get familiar with the application, and to verify some information we’ll need in order to run the bots properly.

We’ll start off with checking which exchanges Nefertiti currently supports and getting the exchange short-codes that we’ll need later. I’ve piped the output of this command to jq so that it’s easier to read, but you can run it without jq if you’d like. Be sure to keep note of the code used by your exchanges as we’ll need them for the next command.

cryptotrader exchanges | jq '.[] | {name: .name, code: .code}'
$ cryptotrader exchanges | jq '.[] | {name: .name, code: .code}'
{
  "name": "Coinbase Pro",
  "code": "GDAX"
}
{
  "name": "Bittrex",
  "code": "BTRX"
}
{
  "name": "Bitstamp",
  "code": "BITS"
}
{
  "name": "CEX.IO",
  "code": "CXIO"
}
{
  "name": "Binance",
  "code": "BINA"
}
{
  "name": "BinanceUS",
  "code": "BIUS"
}
{
  "name": "HitBTC",
  "code": "HITB"
}
{
  "name": "KuCoin",
  "code": "KUCN"
}
{
  "name": "crypto.com",
  "code": "CRO"
}

Now that we have the exchange codes, we can run the markets command to get a list of all the coins available to trade on an exchange.

$ cryptotrader markets --exchange=GDAX

We can also pipe this command through jq to filter the array if you’re looking for a specific coin or base currency:

cryptotrader markets --exchange=GDAX | jq '.[] | select(.name | contains(COIN))'
$ cryptotrader markets --exchange=GDAX | jq '.[] | select(.name | contains("USDC"))'
{
  "name": "USDT-USDC"
}
{
  "name": "ETH-USDC"
}
{
  "name": "BTC-USDC"
}
{
  "name": "USDC-USDT"
}
{
  "name": "USDC-UST"
}
{
  "name": "LTC-USDC"
}
{
  "name": "BCH-USDC"
}
{
  "name": "EOS-USDC"
}
{
  "name": "BCHSV-USDC"
}
{
  "name": "ADA-USDC"
}
{
  "name": "LINK-USDC"
}
{
  "name": "DOGE-USDC"
}
{
  "name": "XRP-USDC"
}

The ultimate purpose of this is to make sure that the coin pairs we want to trade are available, and that we get the correct formatting before we run the bots. For example: Some exchanges have a “-” in the market name - some don’t. Some exchanges also list the base currency first (USDT-ETH) - some don’t (ETH-USDT). It is important to get the market formatting correct or the bots will error and not run properly.

Running Nefertiti

Nefertiti has both a buy and a sell bot that have to be run simultaneously, and it is important that the sell bot is started first. In their most basic form the bots are quite simple to run and only require a few arguments. The commands to run Nefertiti can be as simple as:

cryptotrader sell --exchange=GDAX
cryptotrader buy --exchange=GDAX --market=ETH-USD

If you go through the Nefertiti documentation, you’ll come to a post that describes how to use the bot on more than one pair and an old script example that only runs on MacOS. Thankfully we don’t have to mess with that since Nefertiti now allows multiple markets passed to the cryptotrader buy command with a simple comma separator:

cryptotrader buy --exchange=GDAX --market=ETH-USD,BTC-USD,ADA-USD

Since the --help documentation is easy to access, the rest of the buy/sell bot arguments should be easy to understand and use if you want to modify anything about the default behavior. However, I’ve found that the bots do quite well with their defaults, so I’ll typically only add a few arguments:

  • Inputting API and notifications information through the command line. This simplifies scripting and startup (be warned: this does expose your keys in the terminal log):
    cryptotrader sell --exchange=GDAX \
        --api-key= \
        --api-secret= \
        --api-passphrase= \
        --telegram-app-key=	--telegram-chat-id= \
        --pushover-app-key= --pushover-user-key= \
    
  • Using the --price and --repeat arguments allow us to fine tune our order sizes and ensure the bot updates orders on a timed interval
    cryptotrader buy \
        --exchange= --market= \
        --api-key= \
        --api-secret= \
        --api-passphrase= \
        --telegram-app-key= --telegram-chat-id= \
        --pushover-app-key= --pushover-user-key= \
        --price= \ 
        --repeat=1 \
    

Scripting Neferitit Bots for Easy Startups

The easiest way to run Nefertiti is to save all of your information and settings into startup scripts. This allows you to get Nefertiti running without having to input your API information or type out the commands and any adjustments you want to make.

I’ve created a couple of scripting templates that should be easy to follow. I start off with the basic commands from above, add a few variables so they’re easy to adjust, and save them as an executable script. You can download these from my Github, from the gist repository, or just copy and paste the examples below into a new file.

sell-script.sh
#!/bin/bash
set -eu
##########
# Buy Scripting Template for Nefertiti Cryptotrader Bot
# Created by github.com/d00vy
#
# More information at: https://d00vy.com/blog/how_setup_nefertiti_cryptotrader_bot/
# Nefertiti Documentation: https://nefertiti-tradebot.com/
##########

## Define variables
EXCHANGE="BTRX" #Exchange you want to run
API_KEY="XXX" #Exchange API Key
API_SECRET="XXX" #Exchange API Secret
API_PASS="XXX" #Exchange API Passphrase
PUSHOVER_APP_KEY="NONE" #Pushover App Key
PUSHOVER_USER_KEY="NONE" #Pushover User Key
TELEGRAM_KEY="XXX" #Telegram Bot Token
TELEGRAM_ID="XXX" #Telegram channel ID
STRATEGY="0" #Selling strategy to use [0*|1|2|3|4]
NOTIFY="2" #Notification verbosity [0|1|2*|3]
MULT="1.05" #Set sell price multiplier, default is 5% (1.05*)
#HOLD=BTC-USD,BTC-USDT #Name of markets not to sell

## Execute sell bot
echo "Loaded Variables - Starting Sell Bot on $EXCHANGE"
cryptotrader sell \
	--exchange=$EXCHANGE \
	--api-key=$API_KEY \
	--api-secret=$API_SECRET \
	--api-passphrase=$API_PASS \
	--telegram-app-key=$TELEGRAM_KEY \
	--telegram-chat-id=$TELEGRAM_ID \
	--pushover-app-key=$PUSHOVER_APP_KEY \
	--pushover-user-key=$PUSHOVER_USER_KEY \
	--strategy=$STRATEGY \
	--notify=$NOTIFY \
	--mult=$MULT \
	--ignore-error
buy-script.sh
#!/bin/bash
set -eu
##########
# Buy Scripting Template for Nefertiti Cryptotrader Bot
# Created by github.com/d00vy
#
# More information at: https://d00vy.com/blog/how_setup_nefertiti_cryptotrader_bot/
# Nefertiti Documentation: https://nefertiti-tradebot.com/
##########

## Define buy bot variables
EXCHANGE="BTRX" #Exchange you want to run
PRICE="XX" #Amount of base currency to spend per order
MARKET="USD-ETH" #Markets to trade (USD-ETH,USD-BTC)
API_KEY="XXX" #Exchange API Key
API_SECRET="XXX" #Exchange API Secret
API_PASS="XXX" #Exchange API Passphrase (remove if not required)
PUSHOVER_APP_KEY="NONE" #Pushover App Key
PUSHOVER_USER_KEY="NONE" #Pushover User Key
TELEGRAM_KEY="XXX" #Telegram Bot Token
TELEGRAM_ID="XXX" #Telegram channel ID
REPEAT=1 #Repeat interval (Default is 1 hour)

## Execute buy bots
echo "Loaded variables - Starting Buy Bot for $MARKET"
	cryptotrader buy \
	--exchange=$EXCHANGE \
	--market=$MARKET \
	--api-key=$API_KEY \
	--api-secret=$API_SECRET \
	--api-passphrase=$API_PASS \
	--telegram-app-key=$TELEGRAM_KEY \
	--telegram-chat-id=$TELEGRAM_ID \
	--pushover-app-key=$PUSHOVER_APP_KEY \
	--pushover-user-key=$PUSHOVER_USER_KEY \
	--price=$PRICE \
	--repeat=$REPEAT \
	--ignore-error

Automating Nefertiti Deployment with tmux & tmuxp

tmux is an open-source terminal multiplexer that’s really handy for managing multiple terminal sessions. Using tmux with tmuxp allows very easy scripting with YAML files. This has been the best way for me to launch and manage multiple bots.

I start off with the scripting templates from above, add in all of my information, and save them into a directory structure for easy organization like this:

cryptotrader/
├── exchange1/
│   ├── exchange1_sell_bot.sh
│   └── exchange1_buy_bot.sh
├── exchange2/
│   ├── exchange2_sell_bot.sh
│   └── exchange2_buy_bot.sh
└── exchange3/
    ├── exchange3_sell_bot.sh
    └── exchange3_buy_bot.sh

With all of the bot scripts ready to go, we create a .yaml configuration file to load with tmuxp. Create a new file in the root cryptotrader/ directory and create the launch_bots.yaml script:

session_name: cryptobots # Name your session
windows: 
  - window_name: bots # Name the window
    layout: tiled 
    panes:
      # 1 Sell bots load first
      - ./exchange1/exchange1_sell_bot.sh

      # 2 Delay buy bots 10s then load
      - shell_command:
        - sleep 10
        - ./exchange1/exchange1_buy_bot.sh

      # 3 Second exchange sell bot
      - ./exchange2/exchange2_sell_bot.sh

      # 4 Delay second exchange buy bots 10s then load
      - shell_command:
        - sleep 10
        - ./exchange2/exchange2_buy_bot.sh

      # 5 Third exchange sell bot
      - ./exchange3/exchange3_sell_bot.sh

      # 6 Delay third exchange buy bots 10s then load
      - shell_command:
        - sleep 10
        - ./exchange3/exchange3_buy_bot.sh

      # LAST - Load a blank shell and focus it
      -
        focus: true

The .yaml file is quite easy to adjust to fit your needs. Be sure to use a session name that you will remember. With layout: tiled set, tmux will keep splitting the main window to create new panes, creating the nice tiled effect seen in the opening picture:

tmux terminal

Once you’ve executed the tmuxp script, check to be sure that each bot has started up successfully. If any of your panes are blank or showing a command prompt (unless you specified a pane to be blank) then you’ll need to readjust either the tmuxp or bot scripts to fix the error. Using nested directories like I do can lead to some issues if you do not have the correct path for the bot scripts, so this is usually the first thing to check. Also make sure that all of your scripts are executable! This can easily be done with chmod -R +x /your/Path/

  • With tmux open, you can (usually) move between panels by entering command mode with CTRL+b and using the arrow keys to navigate the panels.
  • You can minimize tmux to the background with command mode CTRL+b and d (for detach). Recall the window with tmux attach -t yourSessionName

Getting any further into tmux is beyond the scope of this guide. My use of tmux/p here is simply to allow easy scripting for loading the bots and providing a way to check the status of all of them on one screen. Please see the additional links at the bottom of the page for more tmux resources.

Advanced Nefertiti Features

Nefertiti Exchanges w/ Strategies Nefertiti Strategies

Support

Buy me a beer (or a coffee):
bc1qtmk4d55aewz8m3f8vjew45fjhllwkgmn67av44
0xC18FCE537845E055F57F94eC8C45A0c096fd0F5f