multiple strategies, default config

This commit is contained in:
olli 2023-05-09 17:04:02 +02:00
parent 1e5b8cff15
commit b223747c3e
16 changed files with 233 additions and 355 deletions

2
.gitignore vendored
View File

@ -1,4 +1,6 @@
docker-compose.override.yml docker-compose.override.yml
dabo-bot.conf
analyze.conf
data/botdata data/botdata
data/index.html data/index.html
data/index.html.tmp data/index.html.tmp

View File

@ -27,7 +27,8 @@ I thought this fits quite well to the cryptotrading world and that's why i chose
- Recording of available price values incl. RSI and MACD indicators of available cryptocurrencies - Recording of available price values incl. RSI and MACD indicators of available cryptocurrencies
- Analysis tool for collected historical values to try out buy or sell conditions based on them - Analysis tool for collected historical values to try out buy or sell conditions based on them
- ReadOnly web interface for overview - ReadOnly web interface for overview
- Runnable in a non-root docker container - Runnable in a non-root docker containe
- multiple different buy and sell strategies possible at the same time
## Buy conditions ## Buy conditions
- definable RSI Indicator signals min/max (RSI5, 14 and 21) - definable RSI Indicator signals min/max (RSI5, 14 and 21)
@ -51,17 +52,18 @@ https://gitea.ds9.dedyn.io/olli/debian.ansible.docker
https://gitea.ds9.dedyn.io/olli/debian.ansible.traefik.server https://gitea.ds9.dedyn.io/olli/debian.ansible.traefik.server
Download: ## Download
``` ```
git clone https://gitea.ds9.dedyn.io/olli/dabo.git git clone https://gitea.ds9.dedyn.io/olli/dabo.git
cd dabo cd dabo
``` ```
Build container: ## Build container
``` ```
docker -l warn compose --ansi never build --progress=plain --pull --no-cache --force-rm docker -l warn compose --ansi never build --progress=plain --pull --no-cache --force-rm
``` ```
## Configure
Edit docker-compose.yml or create docker-compose.override.yml to fit yout needs e.g. domain and network settings or basic auth, e.g. for traefik and letsencrypt: Edit docker-compose.yml or create docker-compose.override.yml to fit yout needs e.g. domain and network settings or basic auth, e.g. for traefik and letsencrypt:
``` ```
echo ' echo '
@ -126,40 +128,67 @@ local API_KEY="YOUR_LONG_API_KEY_FROM_BINANCE" '>dabo/.binance-secrets
chmod 400 dabo/.binance-secrets chmod 400 dabo/.binance-secrets
``` ```
Edit your Config Create Config
Especially change URL, STOCK_EXCHANGE, FEE, CURRENCY,... to fit your needs. Especially set URL, STOCK_EXCHANGE, FEE, CURRENCY,... to fit your needs.
``` ```
vim dabo/dabo-bot.conf vim dabo-bot.conf
```
Defaults in dabo/dabo-bot.conf
## Prepare/Create a stretegy
IMPORTANT!!!
THE DEFAULT STRATEGY MAY NOT FIT YOUR NEEDS OR WORK PROPERLY. SO YOU CAN LOOSE ALL YOUR MONEY!!! USE ON YOUR OWN RISK!!!
TEST YOUR OWN STRATEGY COMPREHENSIVELY AND OVER A LOGNER PERIOD OF TIME WITH analyze.sh!!! USE ON YOUR OWN RISK!!!
Strategie files can be put in the "strategies"-directory the defaults
There is an example for a buy and a sell strategy file (deactivated by "return 0" in the forst line):
```
ls strategies/buy.example.conf
ls strategies/sell.example.conf
```
Aditional strategies can be created with Name
```
strategies/buy.<name>.conf
strategies/sell.<name>.conf
```
e.g named "mannover-sulu-1" for buy strategy and "command-kirk-3" for sell strategy
```
strategies/buy.mannover-sulu-1.conf
strategies/sell.command-kirk-3.conf
``` ```
## Set Rights
Prepare/Create a stretegy
IMPORTANT!!! THE DEFAULT STRATEGY MAY NOT FIT YOUR NEEDS OR WORK FPR YOU PROPERLY. SO YOU CAN LOOSE ALL YOUR MONEY!!! USE ON YOUR OWN RISK!!!
Set Rights (UID 10000 for non-root-User in running container): Set Rights (UID 10000 for non-root-User in running container):
``` ```
chown -R 10000:10000 dabo data home chown -R 10000:10000 dabo data home strategy
``` ```
## Operational commands
Run/Restart: Run/Restart:
``` ```
docker-compose down # if an old instance is running docker compose down # if an old instance is running
docker-compose up -d docker compose up -d
``` ```
Check
```
docker compose ps
```
Logs/Output: Logs/Output:
``` ```
docker-compose logs -f docker compose logs -f
``` ```
bot.sh is the bot that trades and collects the quotes and analyze.sh is the tool with which you can try out strategies with the historical data. dabo-bot.sh is the bot that trades and collects the quotes and analyze.sh is the tool with which you can try out strategies with the historical data.
The configuration files are called bot.conf and analyze.conf. analyze.sh also uses bot.conf but its variables are overwritten by analyze.conf if duplicated. The configuration files are called dabo-bot.conf and analyze.conf. analyze.sh also uses bot.conf but its variables are overwritten by analyze.conf if duplicated.
A Binance or Bitpanda account must exist and the API must be enabled. A Binance or Bitpanda account must exist and the API must be enabled.
The access data is stored in the file .binance-secrets in the project directory in the variables API_SECRET and API_KEY. The access data is stored in the file .binance-secrets in the project directory in the variables API_SECRET and API_KEY.
@ -169,4 +198,6 @@ The access rights to this file should be set to the minimum necessary for securi
- Crypto preferences (While/Blacklist for certain currencies) - Crypto preferences (While/Blacklist for certain currencies)
- Overview trades/profits/losses for tax declaration - Overview trades/profits/losses for tax declaration
- Support for decentralized exchanges like uniswap to gain more "security" - Support for decentralized exchanges like uniswap to gain more "security"
- mutliple trading strategies - updatemanagement - immuteable .config
- archive old or large csv files

View File

@ -1,3 +1,4 @@
# Default Config file for Dabo-Bot. Pleasse don't change!
ANALYZE_TIME="^2023-04-17" ANALYZE_TIME="^2023-04-17"

View File

@ -19,7 +19,8 @@ function analyze {
. functions/check_buy_conditions.sh . functions/check_buy_conditions.sh
. functions/check_sell_conditions.sh . functions/check_sell_conditions.sh
. functions/get_vars_from_csv.sh . functions/get_vars_from_csv.sh
. bot.conf . dabo-bot.conf
. dabo-bot.override.conf
. analyze.conf . analyze.conf

View File

@ -1,12 +1,13 @@
# Default Config file for Dabo-Bot. Pleasse don't change!
# Webpage URL # Webpage URL
URL="dabo-bitpanda.ds9.dedyn.io" URL="mydabobot.mydomain"
# The exchange we use for using the correct API (BINANCE or BITPANDA) # The exchange we use for using the correct API (BINANCE or BITPANDA)
STOCK_EXCHANGE="BITPANDA" STOCK_EXCHANGE="BITPANDA"
# fee per trade in percentage on exchange (taker and maker added) # fee per trade in percentage on exchange (taker and maker added)
FEE="0.4" FEE="0.5"
# Interval in seconds # Interval in seconds
INTERVAL="150" INTERVAL="150"
@ -28,106 +29,6 @@ SIGNAL_GROUP="Krypto-Bot"
# Overwritten by MIN_NOTIONAL+X% from stock if lower # Overwritten by MIN_NOTIONAL+X% from stock if lower
INVEST="5" INVEST="5"
# GOOD_MARKET_PERFORMANCE_INDEX defines from fwhich growth the market is considered good/favorable for investment.
# The market performance is calculated from the average percentage development of various indicators such as development MSCI World, Bitcoin and Ethereum as well as forecasts.
# for details see functions/market_performance.sh
# If the market performance is under this value no buying will be done
GOOD_MARKET_PERFORMANCE_INDEX="-1"
# Stop all trading and sell everything if the complete balance shrinks under this value in ${CURRENCY} # Stop all trading and sell everything if the complete balance shrinks under this value in ${CURRENCY}
EMERGENCY_STOP="90" EMERGENCY_STOP="1000"
###### BUY CONDITIONS ######
### RSI Indicator checks
# Don't buy if the RSI-XX value is >= BUY_RSIXX_BUY_SIGNAL_UNTIL
BUY_RSI5_SIGNAL_UNTIL="99"
BUY_RSI14_SIGNAL_UNTIL="99"
BUY_RSI21_SIGNAL_UNTIL="99"
BUY_RSI60_SIGNAL_UNTIL="99"
BUY_RSI120_SIGNAL_UNTIL="99"
BUY_RSI240_SIGNAL_UNTIL="99"
BUY_RSI420_SIGNAL_UNTIL="99"
BUY_RSI720_SIGNAL_UNTIL="99"
# Don't buy if the RSI-XX value is <= BUY_RSIXX_BUY_SIGNAL_FROM
BUY_RSI5_SIGNAL_FROM="0"
BUY_RSI14_SIGNAL_FROM="0"
BUY_RSI21_SIGNAL_FROM="0"
BUY_RSI60_SIGNAL_FROM="0"
BUY_RSI120_SIGNAL_FROM="0"
BUY_RSI240_SIGNAL_FROM="0"
BUY_RSI420_SIGNAL_FROM="0"
BUY_RSI720_SIGNAL_FROM="0"
### MACD Indicator Checks
# Don't buy if MACD Histogram Relation is not between this values.
# The ratio is calculated by the difference between the maximum positive Histogram value (of the defined time period) and the current value.
# Here you can specify a percentage range.
# If only the buy signal should be considered, simply specify the range 0 and 100.
# decimal numbers are not allowed here.
BUY_MACD_RELATION_FROM="40"
BUY_MACD_RELATION_TO="95"
# Don't buy if price change is under this percentage values
BUY_MIN_PRICE_CHANGE_LAST_1_DAY="0.25"
BUY_MIN_PRICE_CHANGE_LAST_7_DAY="-1"
BUY_MIN_PRICE_CHANGE_LAST_14_DAY="-2"
BUY_MIN_PRICE_CHANGE_LAST_30_DAY="-5"
# Dont buy if growth in the last defined time period <= BUY_MINGROWTH
BUY_MINGROWTH_PERIOD="30"
BUY_MINGROWTH="-10"
###### SELL CONDITIONS ######
# Force hold if result negative expect SELL_PERCENTAGE_FROM_LAST_PURCHASE_NEGATIVE. Boolean 1 for true 0 for false.
SELL_HOLD_IF_RESULT_NEGATIVE="1"
# If the price falls by this percentage value from the purchase price, then sell in any case
SELL_PERCENTAGE_FROM_LAST_PURCHASE_NEGATIVE="-10"
# from here only if SELL_HOLD_IF_RESULT_NEGATIVE doesn't match
# If the price falls by this percentage value from the last rate
SELL_IF_LAST_RATE_LOWER_THEN="-0.25"
### RSI Indicator checks
# SELL if the RSI-XX value is <= SELL_RSIXX_SELL_SIGNAL_UNTIL
SELL_RSI5_SIGNAL_UNTIL="99"
SELL_RSI14_SIGNAL_UNTIL="99"
SELL_RSI21_SIGNAL_UNTIL="99"
SELL_RSI60_SIGNAL_UNTIL="99"
SELL_RSI120_SIGNAL_UNTIL="99"
SELL_RSI240_SIGNAL_UNTIL="99"
SELL_RSI420_SIGNAL_UNTIL="99"
SELL_RSI720_SIGNAL_UNTIL="99"
# SELL if the RSI-XX value is >= SELL_RSIXX_SELL_SIGNAL_FROM
SELL_RSI5_SIGNAL_FROM="90"
SELL_RSI14_SIGNAL_FROM="90"
SELL_RSI21_SIGNAL_FROM="90"
SELL_RSI60_SIGNAL_FROM="70"
SELL_RSI120_SIGNAL_FROM="50"
SELL_RSI240_SIGNAL_FROM="50"
SELL_RSI420_SIGNAL_FROM="50"
SELL_RSI720_SIGNAL_FROM="50"
# If the price after this time periods is lower the the trading fee, then sell if SELL_HOLD_IF_RESULT_NEGATIVE is fine with it
SELL_IF_LOWER_THEN_FEE_AFTER_PERIOD="9999999"
### MACD Indicator Checks
# Sell if MACD Histogram relation is < this value
# The ratio is calculated by the difference between the maximum negative Histogram value (of the defined time period) and the current value.
# Here you can specify a percentage range.
# If only the sell signal should be considered, simply specify 0
# decimal numbers are not allowed here.
SELL_MACD_RELATION_FROM="25"

View File

@ -0,0 +1 @@
keep

View File

@ -49,6 +49,7 @@ do
# reload config # reload config
. ../../dabo-bot.conf . ../../dabo-bot.conf
. ../../dabo-bot.override.conf
# stock data # stock data
if [ ${STOCK_EXCHANGE} = "BINANCE" ] if [ ${STOCK_EXCHANGE} = "BINANCE" ]

View File

@ -1,6 +1,7 @@
function check_buy_conditions { function check_buy_conditions {
local f_ASSET_HIST_FILE="$1" local f_ASSET_HIST_FILE="$1"
local f_strategy="$2"
f_ASSET=$(basename ${f_ASSET_HIST_FILE} | cut -d\. -f1) f_ASSET=$(basename ${f_ASSET_HIST_FILE} | cut -d\. -f1)
if [ -n "${BOT}" ] if [ -n "${BOT}" ]
@ -13,32 +14,47 @@ function check_buy_conditions {
fi fi
fi fi
# get asset vars
get_vars_from_csv "${f_ASSET_HIST_FILE}" || return 1 get_vars_from_csv "${f_ASSET_HIST_FILE}" || return 1
### from here: check for defined state to buy ### from here: check for defined state to buy
f_BUY="${f_last_line}" f_BUY="${f_last_line}"
# load strategy
local f_echo_prefix="BUY ${f_ASSET}@${CURRENCY}:${f_price}:${f_strategy} - "
if [ -s "${f_strategy}" ]
then
. "${f_strategy}" || return 0
else
g_echo_note "${f_echo_prefix}Strategy file not found"
return 1
fi
g_echo_note "${f_echo_prefix}Running BUY checks"
# Check market-performance
if [ $(echo "${f_market_performance} > ${GOOD_MARKET_PERFORMANCE_INDEX}" | bc -l) -eq 0 ]
then
g_echo_note "${f_echo_prefix}BUY market performance ${f_market_performance}% looks bad - Dont buy anything"
return 0
fi
local f_priceXago=$(tail -n${BUY_MINGROWTH_PERIOD} ${f_ASSET_HIST_FILE} | grep ^[0-9] | head -n1 | cut -d, -f2) local f_priceXago=$(tail -n${BUY_MINGROWTH_PERIOD} ${f_ASSET_HIST_FILE} | grep ^[0-9] | head -n1 | cut -d, -f2)
local f_pricenow=$(echo ${f_last_line} | grep ^[0-9] | cut -d, -f2) local f_pricenow=$(echo ${f_last_line} | grep ^[0-9] | cut -d, -f2)
local f_pricediff=$(g_percentage-diff "$f_priceXago" "$f_pricenow") local f_pricediff=$(g_percentage-diff "$f_priceXago" "$f_pricenow")
if [ $(echo "${f_pricediff} < ${BUY_MINGROWTH}" | bc -l) -ne 0 ] if [ $(echo "${f_pricediff} < ${BUY_MINGROWTH}" | bc -l) -ne 0 ]
then then
g_echo_note "BUY ${f_ASSET}@${CURRENCY}:${f_price}: With ${f_pricediff} under ${BUY_MINGROWTH}% growth in the last ${BUY_MINGROWTH_PERIOD} time periods" g_echo_note "${f_echo_prefix}With ${f_pricediff} under ${BUY_MINGROWTH}% growth in the last ${BUY_MINGROWTH_PERIOD} time periods"
return 0 return 0
fi fi
#local f_macd_histogram_max=$(tail -n26 "${f_ASSET_HIST_FILE}" | cut -d"," -f8 | egrep "^[0-9]|^-[0-9]" | sed 's/^-//' | sort -n | tail -n1)
#local f_macd_histogram_relation=$(echo "100+$(g_percentage-diff ${f_macd_histogram_max} ${f_macd_histogram})" | bc | cut -d\. -f1)
# MACD # MACD
# no negative or empty values # no negative or empty values
echo "${f_macd_histogram_relation}" | grep -q "^[0-9]" || return 0 echo "${f_macd_histogram_relation}" | grep -q "^[0-9]" || return 0
# check for conditions # check for conditions
if [ ${f_macd_histogram_relation} -le ${BUY_MACD_RELATION_FROM} ] || [ ${f_macd_histogram_relation} -ge ${BUY_MACD_RELATION_TO} ] if [ ${f_macd_histogram_relation} -le ${BUY_MACD_RELATION_FROM} ] || [ ${f_macd_histogram_relation} -ge ${BUY_MACD_RELATION_TO} ]
then then
g_echo_note "BUY ${f_ASSET}@${CURRENCY}:${f_price}: MACD conditions NOT met" g_echo_note "${f_echo_prefix}MACD conditions NOT met"
return 0 return 0
fi fi
@ -62,9 +78,9 @@ function check_buy_conditions {
[ ${f_rsi420} -ge ${BUY_RSI420_SIGNAL_FROM} ] && \ [ ${f_rsi420} -ge ${BUY_RSI420_SIGNAL_FROM} ] && \
[ ${f_rsi720} -ge ${BUY_RSI720_SIGNAL_FROM} ] [ ${f_rsi720} -ge ${BUY_RSI720_SIGNAL_FROM} ]
then then
echo "BUY ${f_ASSET}@${CURRENCY}:${f_price}: RSI conditions met" >/dev/null echo "${f_echo_prefix}RSI conditions met" >/dev/null
else else
g_echo_note "BUY ${f_ASSET}@${CURRENCY}:${f_price}: RSI conditions NOT met" g_echo_note "${f_echo_prefix}RSI conditions NOT met"
return 0 return 0
fi fi
@ -76,9 +92,9 @@ function check_buy_conditions {
[ $(echo "${f_price_change_14_day} > ${BUY_MIN_PRICE_CHANGE_LAST_14_DAY}" | bc -l) -ne 0 ] && \ [ $(echo "${f_price_change_14_day} > ${BUY_MIN_PRICE_CHANGE_LAST_14_DAY}" | bc -l) -ne 0 ] && \
[ $(echo "${f_price_change_30_day} > ${BUY_MIN_PRICE_CHANGE_LAST_30_DAY}" | bc -l) -ne 0 ] [ $(echo "${f_price_change_30_day} > ${BUY_MIN_PRICE_CHANGE_LAST_30_DAY}" | bc -l) -ne 0 ]
then then
echo "BUY ${f_ASSET}@${CURRENCY}:${f_price}: Price change conditions met" >/dev/null echo "${f_echo_prefix}Price change conditions met" >/dev/null
else else
g_echo_note "BUY ${f_ASSET}@${CURRENCY}:${f_price}: Price change conditions NOT met" g_echo_note "${f_echo_prefix}Price change conditions NOT met"
return 0 return 0
fi fi
@ -88,7 +104,7 @@ function check_buy_conditions {
# Check for beginning MACD Trend # Check for beginning MACD Trend
if ! tail -n3 ${f_ASSET_HIST_FILE} | grep -q '|buy,' if ! tail -n3 ${f_ASSET_HIST_FILE} | grep -q '|buy,'
then then
g_echo_note "BUY ${f_ASSET}@${CURRENCY}:${f_price}: MACD Trend not near (3 timeframes) the beginning buy signal" g_echo_note "${f_echo_prefix}MACD Trend not near (3 timeframes) the beginning buy signal"
return 0 return 0
fi fi
@ -119,7 +135,7 @@ function check_buy_conditions {
then then
echo "${f_last_line},${f_ASSET}" >>trade.log echo "${f_last_line},${f_ASSET}" >>trade.log
f_BUY="BUY ${f_ASSET}@${CURRENCY}:${f_price}: All BUY conditions met!!! f_BUY="${f_echo_prefix}All BUY conditions met!!!
${f_BUY}" ${f_BUY}"
g_echo_note "${f_BUY}" g_echo_note "${f_BUY}"

View File

@ -21,17 +21,6 @@ function check_for_buy {
return 0 return 0
fi fi
## use BUY_CONDITION_RISK if market is bad
if [ $(echo "${f_market_performance} > ${GOOD_MARKET_PERFORMANCE_INDEX}" | bc -l) -eq 0 ]
then
#g_echo_note "BUY market performance ${f_market_performance}% looks bad - Using BUY_CONDITION_RISK (${BUY_CONDITION_RISK}) as BUY_CONDITION"
#BUY_CONDITION=${BUY_CONDITION_RISK}
g_echo_note "BUY market performance ${f_market_performance}% looks bad - Dont buy anything"
return 0
else
g_echo_note "BUY market performance ${f_market_performance}% looks ok - going on buying with BUY_CONDITION (${BUY_CONDITION})"
fi
# go through highest assets # go through highest assets
local f_line local f_line
for f_ASSET in $(cat ASSETS | egrep -v "${BLACKLIST}") for f_ASSET in $(cat ASSETS | egrep -v "${BLACKLIST}")
@ -41,7 +30,11 @@ function check_for_buy {
if [ $(tail -n 6 "$f_ASSET_HIST_FILE" | egrep -v ",,|,$" | wc -l) -ge 5 ] if [ $(tail -n 6 "$f_ASSET_HIST_FILE" | egrep -v ",,|,$" | wc -l) -ge 5 ]
then then
check_buy_conditions "$f_ASSET_HIST_FILE" local f_strategy
for f_strategy in $(find ../../strategies -name "buy.*.conf" -type f)
do
check_buy_conditions "${f_ASSET_HIST_FILE}" "${f_strategy}"
done
else else
g_echo_note "BUY $f_ASSET_HIST_FILE not enough data - waiting for complete values" g_echo_note "BUY $f_ASSET_HIST_FILE not enough data - waiting for complete values"
fi fi

View File

@ -1,18 +1,6 @@
function check_for_sell { function check_for_sell {
g_echo_note "RUNNING FUNCTION ${FUNCNAME} $@" g_echo_note "RUNNING FUNCTION ${FUNCNAME} $@"
## sell earlier if market is bad
if [ $(echo "${f_market_performance} > ${GOOD_MARKET_PERFORMANCE_INDEX}" | bc -l) -eq 0 ]
then
g_echo_note "SELL market performance ${f_market_performance}% bad - sell earlier"
#SELL_PERCENTAGE_FROM_LAST_PURCHASE_NEGATIVE="${SELL_PERCENTAGE_FROM_LAST_PURCHASE_NEGATIVE_BAD_MARKET}"
#SELL_PERCENTAGE_FROM_LAST_PURCHASE_POSITIVE="${SELL_PERCENTAGE_FROM_LAST_PURCHASE_POSITIVE_BAD_MARKET}"
else
g_echo_note "SELL market performance ${f_market_performance}% ok"
fi
# Check all balances # Check all balances
for f_EXCHANGE_GET_BALANCES_CMD_OUT in $(cat EXCHANGE_GET_BALANCES_CMD_OUT | egrep -v "^${CURRENCY},") for f_EXCHANGE_GET_BALANCES_CMD_OUT in $(cat EXCHANGE_GET_BALANCES_CMD_OUT | egrep -v "^${CURRENCY},")
do do
@ -35,196 +23,11 @@ function check_for_sell {
continue continue
fi fi
check_sell_conditions ${f_ASSET_HIST_FILE} local f_strategy
for f_stragegy in $(find ../../strategies -name "sell.*.conf" -type f)
#local f_perf do
#for f_perf in ${f_perf_week} ${f_perf_month} check_sell_conditions "${f_ASSET_HIST_FILE}" "${f_strategy}"
#do done
# [ -z "${f_perf}" ] && continue
# if [ $(echo "${f_perf} < ${EMERGENCY_STOP}" | bc -l) -ne 0 ]
# then
# local f_msg="ATTENTION! EMERGENCY STOP DUE TO POOR PERFORMANCE: LOWER THEN EMERGENCY_STOP-VALUE (${EMERGENCY_STOP}) (WEEK: ${f_perf_week}; MONTH: ${f_perf_month})"
# g_echo_error "$f_msg"
# do_trade ${f_ASSET} ${CURRENCY} ${f_QUANTITY_CURRENCY} sell "${f_msg}"
# continue 2
# fi
#done
## check for DONT_SELL_IF_GROWTH_OVER
#local f_condition
#for f_condition in $DONT_SELL_IF_GROWTH_OVER
#do
# local f_min=$(echo ${f_condition} | cut -d'>' -f1)
# local f_percentage=$(echo ${f_condition} | cut -d'>' -f1)
# get_rate_percentage_min_before_and_now ${f_ASSET} ${CURRENCY} ${f_min} || continue
# if [ $(echo "${f_exchange_rate_diff_percentage} > ${f_percentage}" | bc -l) -ne 0 ]
# then
# g_echo_note "SELL ${f_ASSET}: growth rate last ${f_min} minute(s) was over ${f_percentage}% (${f_exchange_rate_diff_percentage})"
# continue 2
# fi
#done
### from here: check for defined state to sell
# Reset g_SELL for next round
# f_SELL=""
#
#
# ## check current result
# f_TRADE_HIST_FILE="trade-histories/${f_ASSET}${CURRENCY}.history.csv"
# if [ -s "${f_TRADE_HIST_FILE}" ]
# then
# f_BUY_PRICE=$(grep ",buy," $f_TRADE_HIST_FILE | tail -n1 | cut -d, -f5)
# f_BUY_PRICE_LAST_RATE_DIFF=$(g_percentage-diff $f_BUY_PRICE $f_LAST_EXCHANGE_RATE)
# # Store for overview
# echo ${f_BUY_PRICE_LAST_RATE_DIFF} >DIFF_BUY_PRICE_${f_ASSET}${CURRENCY}
#
#
# # check for SELL_PERCENTAGE_FROM_LAST_PURCHASE_NEGATIVE
# if [ $(echo "${f_BUY_PRICE_LAST_RATE_DIFF} < ${SELL_PERCENTAGE_FROM_LAST_PURCHASE_NEGATIVE}" | bc -l) -ne 0 ]
# then
# f_SELL="Selling ${f_QUANTITY_CURRENCY} ${CURRENCY} - SELL_PERCENTAGE_FROM_LAST_PURCHASE_NEGATIVE(${SELL_PERCENTAGE_FROM_LAST_PURCHASE_NEGATIVE}%) > Last rate (${f_BUY_PRICE_LAST_RATE_DIFF}%)"
# do_trade ${f_ASSET} ${CURRENCY} ${f_QUANTITY_CURRENCY} sell "${f_SELL}"
# continue
# else
# g_echo_note "SELL ${f_ASSET}: compare current price $f_LAST_EXCHANGE_RATE and price at the time of purchase $f_BUY_PRICE (${f_BUY_PRICE_LAST_RATE_DIFF}): over SELL_PERCENTAGE_FROM_LAST_PURCHASE_NEGATIVE(${SELL_PERCENTAGE_FROM_LAST_PURCHASE_NEGATIVE}%)"
# fi
# # check for SELL_PERCENTAGE_FROM_LAST_PURCHASE_POSITIVE
# if [ $(echo "${f_BUY_PRICE_LAST_RATE_DIFF} < ${SELL_PERCENTAGE_FROM_LAST_PURCHASE_POSITIVE}" | bc -l) -ne 0 ]
# then
# g_echo_note "SELL ${f_ASSET}: Not doing further checking - compare current price $f_LAST_EXCHANGE_RATE and price at the time of purchase $f_BUY_PRICE (${f_BUY_PRICE_LAST_RATE_DIFF}): under SELL_PERCENTAGE_FROM_LAST_PURCHASE_POSITIVE(${SELL_PERCENTAGE_FROM_LAST_PURCHASE_POSITIVE}%)"
# continue
# elif [ $(echo "${f_market_performance} > ${GOOD_MARKET_PERFORMANCE_INDEX}" | bc -l) -eq 0 ]
# then
# # check for SELL_PERCENTAGE_FROM_LAST_PURCHASE_POSITIVE if on bad market
# local f_msg="SELL ${f_ASSET}: Sell because over SELL_PERCENTAGE_FROM_LAST_PURCHASE_POSITIVE_BAD_MARKET (${SELL_PERCENTAGE_FROM_LAST_PURCHASE_POSITIVE_BAD_MARKET}) $f_BUY_PRICE (${f_BUY_PRICE_LAST_RATE_DIFF} in bad market"
# g_echo_note "$f_msg"
# do_trade ${f_ASSET} ${CURRENCY} ${f_QUANTITY_CURRENCY} sell "${f_msg}"
# continue
# fi
# # check for SELL_PERCENTAGE_FROM_LAST_PURCHASE_SOFT
# if [ $(echo "${f_BUY_PRICE_LAST_RATE_DIFF} > ${SELL_PERCENTAGE_FROM_LAST_PURCHASE_SOFT}" | bc -l) -ne 0 ]
# then
# f_SELL="Selling ${f_QUANTITY_CURRENCY} ${CURRENCY} - SELL_PERCENTAGE_FROM_LAST_PURCHASE_SOFT(${SELL_PERCENTAGE_FROM_LAST_PURCHASE_SOFT}%) > Last rate (${f_BUY_PRICE_LAST_RATE_DIFF}%)"
# else
# g_echo_note "SELL ${f_ASSET}: compare current price $f_LAST_EXCHANGE_RATE and price at the time of purchase $f_BUY_PRICE (${f_BUY_PRICE_LAST_RATE_DIFF}) not over SELL_PERCENTAGE_FROM_LAST_PURCHASE_SOFT(${SELL_PERCENTAGE_FROM_LAST_PURCHASE_SOFT}%)"
# fi
# else
# g_echo_warn "SELL ${f_ASSET}: Missing TRADE_HIST_FILE (${f_TRADE_HIST_FILE})"
# fi
# ## check for SELL_PERCENTAGE_HARD
# get_rate_percentage_min_before_and_now $f_ASSET $CURRENCY 15 || continue
# if [ $(echo "${f_exchange_rate_diff_percentage} < ${SELL_PERCENTAGE_HARD}" | bc -l) -ne 0 ]
# then
# f_SELL="SELLING ${f_QUANTITY_CURRENCY} ${CURRENCY} - SELL_PERCENTAGE_HARD(${SELL_PERCENTAGE_HARD}%) > 15 minutes rate (${f_exchange_rate_diff_percentage}%)"
# else
# g_echo_note "SELL ${f_ASSET}: Rate change 15 minutes ago (${f_exchange_rate_diff_percentage}) not over SELL_PERCENTAGE_HARD(${SELL_PERCENTAGE_HARD}%)"
# fi
## check for SELL_PERCENTAGE_SOFT
# go through time intervals
# for f_min in ${MINUTE_STEPS_SELL}
# do
# # calculate rate change last defined minutes
# get_rate_percentage_min_before_and_now $f_ASSET $CURRENCY $f_min || continue
# if [ $(echo "${f_exchange_rate_diff_percentage} < ${SELL_PERCENTAGE_SOFT}" | bc -l) -ne 0 ]
# then
# f_SELL="SELLING ${f_QUANTITY_CURRENCY} ${CURRENCY} - SELL_PERCENTAGE_SOFT(${SELL_PERCENTAGE_SOFT}%) > $f_min minutes rate (${f_exchange_rate_diff_percentage}%)"
# break
# else
# g_echo_note "SELL ${f_ASSET}: Rate change $f_min ago (${f_exchange_rate_diff_percentage}) not over SELL_PERCENTAGE_SOFT(${SELL_PERCENTAGE_SOFT}%)"
# fi
# done
# dont sell if lock exists
#if [ -s "${f_ASSET}${CURRENCY}-sell.lock" ]
#then
# g_echo_note "SELL ${f_ASSET}: Not doing further checking - ${f_ASSET}${CURRENCY}-sell.lock exists and not older then 30 minutes"
# continue
#fi
# check last 5 minutes - if growth over 0.5% then hold (important for rally prices
#get_rate_percentage_min_before_and_now ${f_ASSET} ${CURRENCY} 5 || continue
#[ $(echo "${f_exchange_rate_diff_percentage} > 0.5" | bc -l) -ne 0 ] && continue
# # check last 10 minutes - if loss over -1% then sell
# get_rate_percentage_min_before_and_now ${f_ASSET} ${CURRENCY} 10
# if [ $(echo "${f_exchange_rate_diff_percentage} < -1" | bc -l) -ne 0 ]
# then
# f_SELL="SELL ${f_ASSET}: 10min Loss ${f_exchange_rate_diff_percentage} higher then -1%"
# g_echo_note "$f_SELL"
# fi
#
# # Sell on RSI higher then RSI_SELL_SIGNAL_FROM_FORCE
# local f_rsi=$(tail -n1 ${f_ASSET_HIST_FILE} | cut -d, -f3)
# if [ ${f_rsi} -ge ${RSI_SELL_SIGNAL_FROM_FORCE} ] && [ ${f_rsi} -lt 100 ]
# then
# f_SELL="SELL ${f_ASSET}: RSI: $f_rsi"
# g_echo_note "$f_SELL"
# fi
#
#
# # check MACD and RSI
# local f_macd=$(tail -n1 ${f_ASSET_HIST_FILE} | cut -d, -f7)
# g_echo_note "SELL ${f_ASSET}: Checking for indicators: RSI $f_rsi ; MACD: $f_macd"
# if [ $(echo "${f_macd} < 0" | bc -l) -ne 0 ]
# then
# g_echo_note "SELL ${f_ASSET}: trend change RSI $f_rsi ; MACD: $f_macd"
# if [ $(echo "${f_rsi} > 60" | bc -l) -ne 0 ]
# then
# f_SELL="SELL ${f_ASSET}: RSI: $f_rsi ; MACD: $f_macd"
# g_echo_note "$f_SELL"
# fi
# fi
# # check for SELL_CONDITION and RSI Indicator
# local f_condition
# local f_loopcount=0
# local f_conditioncount=0
# for f_condition in $SELL_CONDITION
# do
# local f_min=$(echo ${f_condition} | cut -d'<' -f1)
# local f_percentage=$(echo ${f_condition} | cut -d'<' -f2)
# get_rate_percentage_min_before_and_now ${f_ASSET} ${CURRENCY} ${f_min} || continue 2
# if [ $(echo "${f_exchange_rate_diff_percentage} < ${f_percentage}" | bc -l) -ne 0 ]
# then
# g_echo_note "SELL ${f_ASSET}: Price change met SELL_CONDITION (decrease of ${f_exchange_rate_diff_percentage}% higher then ${f_percentage}% in ${f_min} minutes."
# ((f_conditioncount=f_conditioncount+1))
# else
# g_echo_note "SELL ${f_ASSET}: Price change didn't meet SELL_CONDITION (decrease of ${f_exchange_rate_diff_percentage}% lower then ${f_percentage}% in ${f_min} minutes."
# fi
# ((f_loopcount=f_loopcount+1))
# done
# if [ $f_conditioncount -eq $f_loopcount ]
# then
# if [ ${f_rsi} -ge ${RSI_SELL_SIGNAL_FROM} ]
# then
# f_SELL="SELL ${f_ASSET}: Price change met all SELL_CONDITIONs ${SELL_CONDITION} ($f_conditioncount of $f_loopcount) with RSI ${f_rsi}"
# g_echo_note "$f_SELL"
# fi
# else
# g_echo_note "SELL ${f_ASSET}: Price change didn't meet SELL_CONDITIONs ${SELL_CONDITION} ($f_conditioncount of $f_loopcount)"
# fi
# # Sell or not sell?
# if [ -n "$f_SELL" ]
# then
# do_trade ${f_ASSET} ${CURRENCY} ${f_QUANTITY_CURRENCY} sell "${f_SELL}"
# fi
done done
} }

View File

@ -1,6 +1,7 @@
function check_sell_conditions { function check_sell_conditions {
local f_ASSET_HIST_FILE="$1" local f_ASSET_HIST_FILE="$1"
local f_strategy="$2"
f_ASSET=$(basename ${f_ASSET_HIST_FILE} | cut -d\. -f1) f_ASSET=$(basename ${f_ASSET_HIST_FILE} | cut -d\. -f1)
### from here: check for defined state to sell ### from here: check for defined state to sell
@ -9,6 +10,18 @@ function check_sell_conditions {
# get data # get data
get_vars_from_csv ${f_ASSET_HIST_FILE} || return 1 get_vars_from_csv ${f_ASSET_HIST_FILE} || return 1
# load strategy
local f_echo_prefix="SELL ${f_ASSET}@${CURRENCY}:${f_price}:${f_strategy} - "
if [ -s "${f_strategy}" ]
then
. "${f_strategy}" || return 0
else
g_echo_note "${f_echo_prefix}Strategy file not found"
return 1
fi
g_echo_note "${f_echo_prefix}Running BUY checks"
### check current result ### check current result
if [ -n "${BOT}" ] if [ -n "${BOT}" ]
then then

View File

@ -7,10 +7,10 @@ function webpage {
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta http-equiv="refresh" content="60" /> <meta http-equiv="refresh" content="60" />
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="/browser.css"> <link rel="stylesheet" type="text/css" href="/browser.css">' >../index.html.tmp
<title>Statuspage Crypto Bot</title> echo "<title>Dabo! on ${STOCK_EXCHANGE} - ${URL}</title>
</head><body>' >../index.html.tmp </head><body>" >>../index.html.tmp
echo "<h1>Statuspage Crypto Bot (ReadOnly)</h1> echo "<h1>State of Dabo-Bot! on ${STOCK_EXCHANGE} - ${URL} (ReadOnly)</h1>
<h1>Last update $(date "+%F %T")</h1>" >>../index.html.tmp <h1>Last update $(date "+%F %T")</h1>" >>../index.html.tmp

1
dabo/strategies/.keep Normal file
View File

@ -0,0 +1 @@
needed-dir

View File

@ -9,6 +9,8 @@ services:
user: 10000:10000 user: 10000:10000
volumes: volumes:
- ./dabo:/dabo:ro - ./dabo:/dabo:ro
- ./strategies:/dabo/strategies:ro
- ./dabo-bot.conf:/dabo/dabo-bot.override.conf
- ./data:/dabo/htdocs:rw - ./data:/dabo/htdocs:rw
- ./home:/dabo/home:rw - ./home:/dabo/home:rw
- /usr/local/bin/notify.sh:/usr/local/bin/notify.sh:ro - /usr/local/bin/notify.sh:/usr/local/bin/notify.sh:ro

56
strategies/buy.example.conf Executable file
View File

@ -0,0 +1,56 @@
# remove this line if you are fine with this settings and want to use them on your own risk!!!
# It is strongly recommended to test this strategy first via analyze.sh!!!
return 1
# GOOD_MARKET_PERFORMANCE_INDEX defines from fwhich growth the market is considered good/favorable for investment.
# The market performance is calculated from the average percentage development of various indicators such as development MSCI World, Bitcoin and Ethereum as well as forecasts.
# for details see functions/market_performance.sh
# If the market performance is under this value no buying will be done
local GOOD_MARKET_PERFORMANCE_INDEX="100"
###### BUY CONDITIONS ######
### RSI Indicator checks
# Don't buy if the RSI-XX value is >= BUY_RSIXX_BUY_SIGNAL_UNTIL
local BUY_RSI5_SIGNAL_UNTIL="0"
local BUY_RSI14_SIGNAL_UNTIL="0"
local BUY_RSI21_SIGNAL_UNTIL="0"
local BUY_RSI60_SIGNAL_UNTIL="0"
local BUY_RSI120_SIGNAL_UNTIL="0"
local BUY_RSI240_SIGNAL_UNTIL="0"
local BUY_RSI420_SIGNAL_UNTIL="0"
local BUY_RSI720_SIGNAL_UNTIL="0"
# Don't buy if the RSI-XX value is <= BUY_RSIXX_BUY_SIGNAL_FROM
local BUY_RSI5_SIGNAL_FROM="0"
local BUY_RSI14_SIGNAL_FROM="0"
local BUY_RSI21_SIGNAL_FROM="0"
local BUY_RSI60_SIGNAL_FROM="0"
local BUY_RSI120_SIGNAL_FROM="0"
local BUY_RSI240_SIGNAL_FROM="0"
local BUY_RSI420_SIGNAL_FROM="0"
local BUY_RSI720_SIGNAL_FROM="0"
### MACD Indicator Checks
# Don't buy if MACD Histogram Relation is not between this values.
# The ratio is calculated by the difference between the maximum positive Histogram value (of the defined time period) and the current value.
# Here you can specify a percentage range.
# If only the buy signal should be considered, simply specify the range 0 and 100.
# decimal numbers are not allowed here.
local BUY_MACD_RELATION_FROM="0"
local BUY_MACD_RELATION_TO="0"
# Don't buy if price change is under this percentage values
local BUY_MIN_PRICE_CHANGE_LAST_1_DAY="0.25"
local BUY_MIN_PRICE_CHANGE_LAST_7_DAY="-1"
local BUY_MIN_PRICE_CHANGE_LAST_14_DAY="-2"
local BUY_MIN_PRICE_CHANGE_LAST_30_DAY="-5"
# Dont buy if growth in the last defined time period <= BUY_MINGROWTH
local BUY_MINGROWTH_PERIOD="30"
local BUY_MINGROWTH="-10"

56
strategies/sell.example.conf Executable file
View File

@ -0,0 +1,56 @@
# remove this line if you are fine with this settings and want to use them on your own risk!!!
# It is strongly recommended to test this strategy first via analyze.sh!!!
return 1
# GOOD_MARKET_PERFORMANCE_INDEX defines from fwhich growth the market is considered good/favorable for investment.
# The market performance is calculated from the average percentage development of various indicators such as development MSCI World, Bitcoin and Ethereum as well as forecasts.
# for details see functions/market_performance.sh
# If the market performance is under this value no buying will be done
local GOOD_MARKET_PERFORMANCE_INDEX="-1"
# Force hold if result negative expect SELL_PERCENTAGE_FROM_LAST_PURCHASE_NEGATIVE. Boolean 1 for true 0 for false.
local SELL_HOLD_IF_RESULT_NEGATIVE="1"
# If the price falls by this percentage value from the purchase price, then sell in any case
local SELL_PERCENTAGE_FROM_LAST_PURCHASE_NEGATIVE="-10"
# from here only if SELL_HOLD_IF_RESULT_NEGATIVE doesn't match
# If the price falls by this percentage value from the last rate
local SELL_IF_LAST_RATE_LOWER_THEN="-0.25"
### RSI Indicator checks
# SELL if the RSI-XX value is <= SELL_RSIXX_SELL_SIGNAL_UNTIL
local SELL_RSI5_SIGNAL_UNTIL="99"
local SELL_RSI14_SIGNAL_UNTIL="99"
local SELL_RSI21_SIGNAL_UNTIL="99"
local SELL_RSI60_SIGNAL_UNTIL="99"
local SELL_RSI120_SIGNAL_UNTIL="99"
local SELL_RSI240_SIGNAL_UNTIL="99"
local SELL_RSI420_SIGNAL_UNTIL="99"
local SELL_RSI720_SIGNAL_UNTIL="99"
# SELL if the RSI-XX value is >= SELL_RSIXX_SELL_SIGNAL_FROM
local SELL_RSI5_SIGNAL_FROM="90"
local SELL_RSI14_SIGNAL_FROM="90"
local SELL_RSI21_SIGNAL_FROM="90"
local SELL_RSI60_SIGNAL_FROM="70"
local SELL_RSI120_SIGNAL_FROM="50"
local SELL_RSI240_SIGNAL_FROM="50"
local SELL_RSI420_SIGNAL_FROM="50"
local SELL_RSI720_SIGNAL_FROM="50"
# If the price after this time period is lower the the trading fee, then sell if SELL_HOLD_IF_RESULT_NEGATIVE is fine with it
local SELL_IF_LOWER_THEN_FEE_AFTER_PERIOD="7200"
### MACD Indicator Checks
# Sell if MACD Histogram relation is < this value
# The ratio is calculated by the difference between the maximum negative Histogram value (of the defined time period) and the current value.
# Here you can specify a percentage range.
# If only the sell signal should be considered, simply specify 0
# decimal numbers are not allowed here.
local SELL_MACD_RELATION_FROM="25"