From 242bfa6a99c9953fc0610d509b246cca3b2c2cb3 Mon Sep 17 00:00:00 2001 From: olli Date: Tue, 2 May 2023 10:49:04 +0200 Subject: [PATCH] dockerizing --- Dockerfile | 5 +- README.md | 18 ++ analyze.conf | 5 - analyze.sh | 129 ---------- dabo-bot.conf | 130 ---------- dabo-bot.sh | 82 ------- docker-compose.yml | 20 +- docker-entrypoint.sh | 4 - functions/api-calls.sh | 14 -- functions/binance-api-call.sh | 36 --- functions/binance_convert.sh | 118 --------- functions/binance_convert_dust.sh | 46 ---- functions/binance_get_token_info.sh | 38 --- functions/check_buy_conditions.sh | 173 ------------- functions/check_for_buy.sh | 54 ---- functions/check_for_sell.sh | 230 ----------------- functions/check_sell_conditions.sh | 143 ----------- functions/do_trade.sh | 134 ---------- functions/get_asset.sh | 83 ------- functions/get_assets.sh | 150 ----------- functions/get_balances.sh | 126 ---------- functions/get_ema.sh | 27 -- functions/get_macd_indicator.sh | 118 --------- .../get_rate_percentage_min_before_and_now.sh | 63 ----- functions/get_rsi_indicator.sh | 79 ------ functions/get_vars_from_csv.sh | 47 ---- functions/market_performance.sh | 92 ------- functions/webpage.sh | 232 ------------------ htdocs/browser.css | 217 ---------------- 29 files changed, 31 insertions(+), 2582 deletions(-) delete mode 100644 analyze.conf delete mode 100755 analyze.sh delete mode 100644 dabo-bot.conf delete mode 100755 dabo-bot.sh delete mode 100755 docker-entrypoint.sh delete mode 100644 functions/api-calls.sh delete mode 100644 functions/binance-api-call.sh delete mode 100644 functions/binance_convert.sh delete mode 100644 functions/binance_convert_dust.sh delete mode 100644 functions/binance_get_token_info.sh delete mode 100644 functions/check_buy_conditions.sh delete mode 100644 functions/check_for_buy.sh delete mode 100644 functions/check_for_sell.sh delete mode 100644 functions/check_sell_conditions.sh delete mode 100644 functions/do_trade.sh delete mode 100644 functions/get_asset.sh delete mode 100644 functions/get_assets.sh delete mode 100644 functions/get_balances.sh delete mode 100644 functions/get_ema.sh delete mode 100644 functions/get_macd_indicator.sh delete mode 100644 functions/get_rate_percentage_min_before_and_now.sh delete mode 100644 functions/get_rsi_indicator.sh delete mode 100644 functions/get_vars_from_csv.sh delete mode 100644 functions/market_performance.sh delete mode 100644 functions/webpage.sh delete mode 100644 htdocs/browser.css diff --git a/Dockerfile b/Dockerfile index 2048683..dc2daa6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,9 +2,6 @@ FROM debian:latest RUN apt-get update && \ apt-get -y install curl && \ curl https://gitea.ds9.dedyn.io/olli/debian.ansible.docker/raw/branch/main/build-debian-env.sh >build-debian-env.sh && \ - bash -ex build-debian-env.sh && \ - cd / && \ - git clone https://gitea.ds9.dedyn.io/olli/dabo.git && \ - chmod 555 /dabo/dabo-bot.sh /dabo/analyze.sh + bash -ex build-debian-env.sh ENV LANG en_US.utf8 ENTRYPOINT ["/dabo/dabo-bot.sh"] diff --git a/README.md b/README.md index 3f581a1..a3c18a3 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,24 @@ Download: git clone https://gitea.ds9.dedyn.io/olli/dabo.git cd dabo ``` + +Build container: +``` +docker -l warn compose --ansi never build --progress=plain --pull --no-cache --force-rm +``` + +Run: +``` +docker-compose down # if on old instance is running +docker-compose up -d +``` + +Logs: +``` +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. 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. diff --git a/analyze.conf b/analyze.conf deleted file mode 100644 index 7d97eb1..0000000 --- a/analyze.conf +++ /dev/null @@ -1,5 +0,0 @@ - -ANALYZE_TIME="^2023-04-17" - -. bot.conf - diff --git a/analyze.sh b/analyze.sh deleted file mode 100755 index 0a5ba5c..0000000 --- a/analyze.sh +++ /dev/null @@ -1,129 +0,0 @@ -#!/bin/bash - -. /etc/bash/gaboshlib.include - -g_nice - -function g_echo_note { - [ -z "$1" ] && return 0 - echo -en "\033[97m$(tail -n1 ${g_tmp}/$tmpfile | cut -d, -f1) \033[36mNOTE:" - cat <<< "$@" - echo -en "\033[0m" -} - -function analyze { - local file=$1 - tmpfile=$(basename "${file}") - - . /etc/bash/gaboshlib/g_percentage-diff.bashfunc - . functions/check_buy_conditions.sh - . functions/check_sell_conditions.sh - . functions/get_vars_from_csv.sh - . bot.conf - . analyze.conf - - - #g_echo "Analyzing file: $file" - - # cleanup - f_SELL=1 - f_BUY="" - >${g_tmp}/${tmpfile} - >${g_tmp}/result-${tmpfile} - - rm -f ${g_tmp}/open-${tmpfile} - rm -f ${g_tmp}/interim-${tmpfile} - rm -f ${g_tmp}/output-${tmpfile} - - ORIGIFS="$IFS" - IFS=$'\n' - for line in $(egrep "^${ANALYZE_TIME}" "$file") - do - IFS="$ORIGIFS" - current=$(echo $line | cut -d, -f2) - time=$(echo $line | cut -d, -f1 | cut -d: -f1,2) - - echo "$line" >>${g_tmp}/${tmpfile} - if [ -f "${g_tmp}/open-${tmpfile}" ] - then - check_sell_conditions ${g_tmp}/${tmpfile} >>${g_tmp}/output-${tmpfile} 2>&1 - fi - if ! [ -f "${g_tmp}/open-${tmpfile}" ] - then - f_market_performance=$(grep "^$time" htdocs/botdata/MARKET_PERFORMANCE | tail -n1 | cut -d: -f4 | cut -d"%" -f1 | sed 's/ *//') - [ -z "${f_market_performance}" ] && continue - if [ $(echo "${f_market_performance} < ${GOOD_MARKET_PERFORMANCE_INDEX}" | bc -l) -eq 0 ] - then - check_buy_conditions ${g_tmp}/${tmpfile} >>${g_tmp}/output-${tmpfile} 2>&1 || break - else - g_echo_note "bad market (${f_market_performance} < ${GOOD_MARKET_PERFORMANCE_INDEX}) - Price: $current" >>${g_tmp}/output-${tmpfile} 2>&1 - fi - fi - done - - # sell at the end to have a final result. - if [ -f ${g_tmp}/open-${tmpfile} ] - then - f_SELL="SELL ${f_ASSET}: End of file/data" - echo "SELL: $(tail -n1 ${g_tmp}/${tmpfile} | cut -d, -f1) === ${f_SELL}" >>${g_tmp}/output-${tmpfile} 2>&1 - result=$(g_percentage-diff ${BUY_PRICE} ${current}) - result=$(echo "${result}-${FEE}" | bc | sed 's/^\./0./; s/^-\./-0./') - echo "$result" >>${g_tmp}/result-${tmpfile} - echo "RESULT: ${result}% (${BUY_PRICE} -> ${current})" >>${g_tmp}/output-${tmpfile} - rm -f ${g_tmp}/open-${tmpfile} - rm -f ${g_tmp}/interim-${tmpfile} - fi - - complete_result=0 - for result in $(cat ${g_tmp}/result-${tmpfile}) - do - complete_result=$(echo "$complete_result+$result" | bc -l | sed 's/^\./0./; s/^-\./-0./' | xargs printf "%.2f") - done - echo "COMPLETE RESULT $file analyze-${analyzedate}/${tmpfile}.log: ${complete_result}%" | tee -a ${g_tmp}/output-${tmpfile} - echo "=====================================" >>${g_tmp}/output-${tmpfile} - echo "${complete_result}" >>${g_tmp}/overall-result-${tmpfile} - - cat ${g_tmp}/output-${tmpfile} >"analyze-${analyzedate}/${tmpfile}.log" - -} - -. bot.conf -. analyze.conf -set | grep ^[A-Z].*=[-0-9] - -cores=$(cat /proc/cpuinfo | grep "^processor.*:" | tail -n1 | perl -pe 's/processor.*: //') -echo -n "parallel -j${cores} bash -c --" >/tmp/parallel-$$ - -analyzedate="$(date +%Y-%m-%d--%H-%M-%S)" -mkdir "analyze-${analyzedate}" -cp bot.conf analyze.conf analyze-${analyzedate}/ - -for file in $@ -do - echo "${file}" | grep -q "BALANCE" && continue - echo -n " \"analyze ${file}\"" >>/tmp/parallel-$$ -done -export -f g_echo_note -export g_tmp -export analyzedate -. /tmp/parallel-$$ - -echo "OVERALL RESULT: $(cat ${g_tmp}/overall-result-* | awk '{ SUM += $1 } END { printf("%2.2f", SUM) }')%" | tee analyze-${analyzedate}/overall-result.log -cat analyze-${analyzedate}/*.history.csv.log >analyze-${analyzedate}/analyze-overall.log - -echo Trades: "$(grep "BUY: " analyze-${analyzedate}/analyze-overall.log | wc -l)" | tee -a analyze-${analyzedate}/overall-result.log -echo Interim Results: "$(grep "INTERIM RESULT: " analyze-${analyzedate}/analyze-overall.log | wc -l)" | tee -a analyze-${analyzedate}/overall-result.log -echo Interim Results Positive: "$(grep "INTERIM RESULT: [0-9]" analyze-${analyzedate}/analyze-overall.log | wc -l)" | tee -a analyze-${analyzedate}/overall-result.log -echo Interim Results Negative: "$(grep "INTERIM RESULT: -" analyze-${analyzedate}/analyze-overall.log | wc -l)" | tee -a analyze-${analyzedate}/overall-result.log -echo " - -Complete Results" >>analyze-${analyzedate}/overall-result.log -grep "COMPLETE RESULT " analyze-${analyzedate}/analyze-overall.log | grep -v ": 0%" >>analyze-${analyzedate}/overall-result.log - -echo " - -Trades" >>analyze-${analyzedate}/overall-result.log -egrep "BUY: |SELL: " analyze-${analyzedate}/analyze-overall.log >>analyze-${analyzedate}/overall-result.log - - - diff --git a/dabo-bot.conf b/dabo-bot.conf deleted file mode 100644 index 5f3d3a8..0000000 --- a/dabo-bot.conf +++ /dev/null @@ -1,130 +0,0 @@ - -# The exchange we use for using the correct API -STOCK_EXCHANGE="BINANCE" - -# fee per trade in percentage on exchange (taker and maker added) -FEE="0.4" - -# Interval in seconds -INTERVAL="150" - -## Currency used for trading -CURRENCY="USDT" -TRANSFER_CURRENCY="EUR" - -# Only use currencies under the first X currencies sorted by market capitalization -LARGEST_MARKETCAP="250" - -# Blacklist Currencies -BLACKLIST="^DAI${CURRENCY}|^BUSD${CURRENCY}|^USDC${CURRENCY}|^USDP${CURRENCY}|^TUSD${CURRENCY}|^USDD${CURRENCY}|^GUSD${CURRENCY}|^FEI${CURRENCY}|^USTC${CURRENCY}|^FRAX${CURRENCY}|^USDJ${CURRENCY}|^LUSD${CURRENCY}|^EURS${CURRENCY}|^TRIBE${CURRENCY}|^BNB${CURRENCY}" - -## Signal Group for Notifications -SIGNAL_GROUP="Krypto-Bot" - -## Percent from balance per invest. -# Overwritten by MIN_NOTIONAL+X% from stock if lower -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="0.3" - -# Stop all trading and sell everything if the complete balance shrinks under this value in ${CURRENCY} -EMERGENCY_STOP="190" - - - -###### 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="60" -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" - diff --git a/dabo-bot.sh b/dabo-bot.sh deleted file mode 100755 index 05ceba1..0000000 --- a/dabo-bot.sh +++ /dev/null @@ -1,82 +0,0 @@ -#!/bin/bash - -. /etc/bash/gaboshlib.include - -g_lockfile - - -### CONFIG ### - -BASEPATH=/dabo/htdocs -g_tries=3 -g_tries_delay=5 - - -### FUNCTIONS ### -for bashfunc in $(find ${BASEPATH}/../functions -type f -name "*.sh") -do - . "$bashfunc" -done - -### MAIN ### - -# prepare directories -mkdir -p ${BASEPATH}/botdata/asset-histories -mkdir -p ${BASEPATH}/botdata/trade-histories -cd ${BASEPATH}/botdata - -touch firstloop - -# am I the bot (important for functions used by analyze.sh -echo $0 | grep -q "dabo-bot\.sh" && BOT=1 - -# run endless loop -while true -do - - # wait until next full minute in the beginning to be able to work with continue in this loop - if [ -f firstloop ] - then - rm -f firstloop - else - g_echo_note "NEXT LOOP - sleping until next full ${INTERVAL} seconds" - sleep $((${INTERVAL} - $(date +%s) % ${INTERVAL})) - fi - - # reload config - . ../../dabo-bot.conf - - # stock data - if [ ${STOCK_EXCHANGE} = "BINANCE" ] - then - #BINANCE_CLI_CMD="docker-compose -f /home/docker/binance-cli/docker-compose.yml exec -T binance-cli binance-cli" - # command for current token infos (function for setting var QUANTITY_LOT_CUT - TOKEN_INFO_CMD="binance_get_token_info" - # command for buying/selling a token - #TRADE_CMD="$BINANCE_CLI_CMD ACTION -s TOKEN -u QUANTITY -t market" - TRADE_CMD='binance-api-call POST /api/v3/order "&symbol=TOKEN"eOrderQty=QUANTITY&side=ACTION&type=MARKET"' - fi - - # Get current assets - get_assets || continue - - # Get current balances - get_balances || continue - - # Check the situation on the market - if ! market_performance - then - f_market_performance=$(cat MARKET_PERFORMANCE_LATEST) - fi - - ##### Sell something? #### - check_for_sell - - ##### Buy something? #### - check_for_buy - - ##### Update webpage - webpage & - -done - diff --git a/docker-compose.yml b/docker-compose.yml index 09704be..d6cb8e7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,12 +7,14 @@ services: dockerfile: Dockerfile restart: unless-stopped volumes: - - /etc/localtime:/etc/localtime + - ./dabo:/dabo:ro + - ./data:/dabo/htdocs:rw + - /etc/localtime:/etc/localtime:ro networks: - dabo--network - dabo.dedyn.io: + dabo-web: image: nginx:latest restart: unless-stopped volumes: @@ -23,14 +25,16 @@ services: labels: - traefik.enable=true # HTTPS - - traefik.http.routers.dabo.rule=Host(`dabo.ds9.dedyn.io`) - - traefik.http.routers.dabo.entrypoints=https - - traefik.http.routers.dabo.tls=true + - traefik.http.routers.dabo-web.rule=Host(`dabo.ds9.dedyn.io`) + - traefik.http.routers.dabo-web.entrypoints=https + - traefik.http.routers.dabo-web.tls=true # Proxy to service-port - - traefik.http.services.dabo.loadbalancer.server.port=80 - - traefik.http.routers.dabo.service=dabo-ds9 + - traefik.http.services.dabo-web.loadbalancer.server.port=80 + - traefik.http.routers.dabo-web.service=dabo-web # cert via letsencrypt - - traefik.http.routers.dabo.tls.certresolver=letsencrypt + - traefik.http.routers.dabo-web.tls.certresolver=letsencrypt + # activate secHeaders@file + - traefik.http.routers.dabo-web.middlewares=secHeaders@file # Traefik network - traefik.docker.network=traefik diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh deleted file mode 100755 index 428fda3..0000000 --- a/docker-entrypoint.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash -sleep 999999999 -binance-cli $@ - diff --git a/functions/api-calls.sh b/functions/api-calls.sh deleted file mode 100644 index 0a4c4b2..0000000 --- a/functions/api-calls.sh +++ /dev/null @@ -1,14 +0,0 @@ -function EXCHANGE_GET_ASSETS_CMD { - - if [ ${STOCK_EXCHANGE} = "BINANCE" ] - then - binance-api-call GET /api/v3/ticker/price || return 1 - # parse API output - cat ${g_tmp}/API_CMD_OUT | jq -r '.[] | .symbol + "," + .price' | grep "${CURRENCY}," | egrep -v "${TRANSFER_CURRENCY},|,0[\.][0]*$" | sort >${f_filename}_OUT.tmp - fi - - - - -} - diff --git a/functions/binance-api-call.sh b/functions/binance-api-call.sh deleted file mode 100644 index 48d51c5..0000000 --- a/functions/binance-api-call.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash - -function binance-api-call { - g_echo_note "RUNNING FUNCTION ${FUNCNAME} $@" - local method=$1 - local call=$2 - local params=$3 - - if [ -s /home/docker/binance-cli/.binance-secrets ] - then - . /home/docker/binance-cli/.binance-secrets - else - g_echo_error "No secrets file found" - return 1 - fi - - call=$(echo "$call" | sed "s/^\///") - if echo "${call}" | egrep -q "^sapi/|^api/v3/order" - then - params="recvWindow=60000${params}" - local timestamp=$(date +%s000) - params="${params}×tamp=${timestamp}" - local signature=$(echo -n "${params}" | openssl dgst -sha256 -hmac "${API_SECRET}" | cut -d" " -f2) - params="?${params}&signature=$signature" - fi - - echo "curl -s -H \"X-MBX-APIKEY: $API_KEY\" -X \"$method\" \"https://api.binance.com/${call}${params}\"" >${g_tmp}/API_CMD - echo "curl -s -H \"X-MBX-APIKEY: API_KEY\" -X \"$method\" \"https://api.binance.com/${call}${params}\"" >${g_tmp}/API_CMD_WO_KEY - g_runcmd g_retrycmd sh ${g_tmp}/API_CMD >${g_tmp}/API_CMD_OUT 2>&1 - if egrep -q -i '^{"code":|error' ${g_tmp}/API_CMD_OUT - then - g_echo_error "$(cat ${g_tmp}/API_CMD_WO_KEY): $(cat ${g_tmp}/API_CMD_OUT)" - return 1 - fi -} - diff --git a/functions/binance_convert.sh b/functions/binance_convert.sh deleted file mode 100644 index aee5893..0000000 --- a/functions/binance_convert.sh +++ /dev/null @@ -1,118 +0,0 @@ -function binance_convert { - # Info for log - g_echo_note "RUNNING FUNCTION ${FUNCNAME} $@" - - # needed vars - local f_ASSET=$1 - local f_CURRENCY=$2 - local f_QUANTITY=$3 - local f_ACTION=$4 # buy or sell - local f_COMMENT=$5 - local f_QUANTITY_CURRENCY=$6 - - local f_DATE=$(date '+%F_%H-%M-%S') - local f_ASSET_HIST_FILE="asset-histories/${f_ASSET}${f_CURRENCY}.history.csv" - - local f_link="https://www.coingecko.com/de/munze/$(egrep -i ^${f_ASSET}, COINGECKO_IDS | cut -d, -f2)" - - local f_CMDFILE="trade-histories/${f_DATE}-${f_CURRENCY}-BINANCE_CONVERT-TRADE_CMD" - - local f_num_converts=$(find trade-histories/*-*-BINANCE_CONVERT-TRADE_CMD -type f -mmin 60 | wc -l) - if [ $f_num_converts -ge 99 ] - then - g_echo_note "Already did 99 or more binance converts last hour." - return 1 - fi - - if [ "${f_ACTION}" = "buy" ] - then - # check for enough balance for trade - get_balances - local f_CURRENCY_BALANCE=$(egrep "^${f_CURRENCY}," EXCHANGE_GET_BALANCES_CMD_OUT | cut -d"," -f2) - g_echo_note "Checking for enough balance for trade (${f_CURRENCY_BALANCE} > ${f_QUANTITY})" - if [ $(echo "${f_CURRENCY_BALANCE} > ${f_QUANTITY}" | bc -l) -eq 0 ] - then - local f_note="Not enough balance for trade (${f_CURRENCY_BALANCE} > ${f_QUANTITY}) :${f_COMMENT} -${FUNCNAME} $@" - g_echo_note "$f_note" - g_signal-notify "$f_note" - return 1 - fi - - # get quote on buy - echo "binance-api-call POST /sapi/v1/convert/getQuote '&fromAsset=${f_CURRENCY}&toAsset=${f_ASSET}&fromAmount=${f_QUANTITY}&walletType=SPOT&validTime=10s'" >${f_CMDFILE} - fi - - if [ "${f_ACTION}" = "sell" ] - then - # get quote on sell - echo "binance-api-call POST /sapi/v1/convert/getQuote '&fromAsset=${f_ASSET}&toAsset=${f_CURRENCY}&fromAmount=${f_QUANTITY}&walletType=SPOT&validTime=10s'" >${f_CMDFILE} - fi - - echo "cat ${g_tmp}/API_CMD_OUT >${f_CMDFILE}_QUOTE_OUT -local f_quoteid=\$(cat ${g_tmp}/API_CMD_OUT | jq -r '.quoteId') -binance-api-call POST /sapi/v1/convert/acceptQuote \""eId=\${f_quoteid}\" -cat ${g_tmp}/API_CMD_OUT >${f_CMDFILE}_OUT -" >>${f_CMDFILE} - - # convert/trade - g_echo_note "Command: $(cat ${f_CMDFILE})" - . ${f_CMDFILE} - cat ${g_tmp}/API_CMD_OUT >${f_CMDFILE}_OUT - g_echo_note "Command Output: $(cat ${f_CMDFILE}_OUT)" - - - # Check return and log trade - f_STATUS=$(cat ${f_CMDFILE}_OUT | grep '^{' | jq -r .orderStatus) - - local f_trade_info_msg="CONVERT/TRADE - ${f_ACTION} ${f_ASSET}${f_CURRENCY} -${f_link} - -Complete Overview: https://bot.ds9.dedyn.io/ - -Comment: ${f_COMMENT}" - - if echo "${f_STATUS}" | egrep -q "PROCESS|ACCEPT_SUCCESS|SUCCESS" - then - g_echo_note "CONVERT/TRADE SUCCESSFUL!" - [ "${f_ACTION}" = "buy" ] && local f_PRICE=$(cat ${f_CMDFILE}_QUOTE_OUT | grep '^{' | jq -r .inverseRatio | head -n1) - [ "${f_ACTION}" = "sell" ] && local f_PRICE=$(cat ${f_CMDFILE}_QUOTE_OUT | grep '^{' | jq -r .ratio | head -n1) - local f_COMMISSION="0" - local f_COMMISSIONASSET="${f_CURRENCY}" - echo "${f_DATE},${f_ACTION},${f_CMDFILE}_OUT,${f_QUANTITY} ${f_CURRENCY},${f_PRICE},${f_COMMISSION} ${f_COMMISSIONASSET},${f_COMMENT}" | head -n1 >>trade-histories/${f_ASSET}${f_CURRENCY}.history.csv - if [ "${f_ACTION}" = "buy" ] - then - echo "${f_DATE},${f_ACTION},${f_CMDFILE}_OUT,${f_QUANTITY} ${f_CURRENCY},${f_PRICE},${f_COMMISSION} ${f_COMMISSIONASSET},${f_COMMENT}" | head -n1 >>trade-histories/trade-$(date +%F.%T. | sed 's/:/_/g')${f_ASSET}${f_CURRENCY}-open.history.csv - fi - if [ "${f_ACTION}" = "sell" ] - then - f_tradehistfile="$(ls trade-histories/trade-*${f_ASSET}${f_CURRENCY}-open.history.csv | tail -n1)" - echo "${f_DATE},${f_ACTION},${f_CMDFILE}_OUT,${f_QUANTITY_CURRENCY} ${f_CURRENCY},${f_PRICE},${f_COMMISSION} ${f_COMMISSIONASSET},${f_COMMENT}" | head -n1 >>${f_tradehistfile} - f_tradehistfileclosed=$(echo ${f_tradehistfile} | sed 's/open.history.csv/closed.history.csv/') - mv ${f_tradehistfile} ${f_tradehistfileclosed} - fi - g_signal-notify "CONVERT/TRADE SUCCESSFUL! - -${f_trade_info_msg} - -Command stored: ${f_CMDFILE}[_OUT]" - [ -f DIFF_BUY_PRICE_${f_ASSET}${f_CURRENCY} ] && [ "${f_ACTION}" = "sell" ] && rm -f DIFF_BUY_PRICE_${f_ASSET}${f_CURRENCY} - # get new balances - get_balances - return 0 - else - g_echo_note "CONVERT/TRADE FAILED! -$(cat ${f_CMDFILE}_OUT)" - g_signal-notify "CONVERT/TRADE FAILED! -${f_trade_info_msg} - -Command ${f_CMDFILE}: -$0 $@ -$(cat ${f_CMDFILE}) - -OUTPUT: -$(cat ${f_CMDFILE}_OUT) -" - return 1 - fi -} diff --git a/functions/binance_convert_dust.sh b/functions/binance_convert_dust.sh deleted file mode 100644 index 9fa1846..0000000 --- a/functions/binance_convert_dust.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/bash - -function binance_convert_dust { - - # find BNB Balance of an conversion which ran before - Balance takes a while to be shown on BNB - # get BNB balance - binance-api-call GET sapi/v1/capital/config/getall - local f_bnb_balance=$(cat ${g_tmp}/API_CMD_OUT | jq -r '.[] | .coin + "," + .free' | grep "^BNB," | cut -d, -f2) - # convert BNB to $CURRENCY - #if echo "${f_bnb_balance}" | egrep -q "[0-9]\.[0-9]" - if [ $(echo "${f_bnb_balance} > 0.004" | bc -l) -ne 0 ] - then - binance-api-call POST /sapi/v1/convert/getQuote "&fromAsset=BNB&toAsset=${CURRENCY}&fromAmount=${f_bnb_balance}&walletType=SPOT&validTime=30s" - local f_quoteid=$(cat ${g_tmp}/API_CMD_OUT | jq -r '.quoteId') - g_signal-notify "Converting dust from ${f_bnb_balance} BNB to ${CURRENCY} -$(cat ${g_tmp}/API_CMD_OUT)" - binance-api-call POST /sapi/v1/convert/acceptQuote ""eId=${f_quoteid}" - fi - - # Only run every 6 houres - binance doesn't allow to do it more often - [ -s BINANCE_LAST_DUST_RUN ] || date >BINANCE_LAST_DUST_RUN - find BINANCE_LAST_DUST_RUN -mmin +362 -delete - [ -s BINANCE_LAST_DUST_RUN ] && return 0 - date >BINANCE_LAST_DUST_RUN - - g_echo_note "RUNNING FUNCTION ${FUNCNAME} $@" - - # find dust - local f_dust_assets="" - local f_dust - binance-api-call POST /sapi/v1/asset/dust-btc - # ignore $CURRENCY and assets in open trades - for f_dust in $(cat ${g_tmp}/API_CMD_OUT | jq -r '.details[].asset' | egrep -v "${CURRENCY}") - do - ls trade-histories/trade-*.${f_dust}${CURRENCY}-open.history.csv >/dev/null 2>&1 && continue - f_dust_assets="${f_dust_assets},$f_dust" - done - f_dust_assets=$(echo ${f_dust_assets} | sed 's/^,//') - - # convert dust to BNB - if [ -n "${f_dust_assets}" ] - then - g_signal-notify "Converting dust from ${f_dust_assets} to BNB" - binance-api-call POST /sapi/v1/asset/dust "&asset=${f_dust_assets}" - fi -} diff --git a/functions/binance_get_token_info.sh b/functions/binance_get_token_info.sh deleted file mode 100644 index 8531bf5..0000000 --- a/functions/binance_get_token_info.sh +++ /dev/null @@ -1,38 +0,0 @@ -function binance_get_token_info { - g_echo_note "RUNNING FUNCTION ${FUNCNAME} $@" - local f_ASSET=$1 - local f_CURRENCY=$2 - local f_QUANTITY=$3 - # cleanup cache - [ -s BINANCE_TOKEN_INFO_CMD_OUT ] && find BINANCE_TOKEN_INFO_CMD_OUT -mmin +60 -or -empty -delete - #echo "$BINANCE_CLI_CMD info" >BINANCE_TOKEN_INFO_CMD - #[ -s BINANCE_TOKEN_INFO_CMD_OUT ] || g_runcmd g_retrycmd sh BINANCE_TOKEN_INFO_CMD >BINANCE_TOKEN_INFO_CMD_OUT - if ! [ -s BINANCE_TOKEN_INFO_CMD_OUT ] - then - binance-api-call GET /api/v3/exchangeInfo >BINANCE_TOKEN_INFO_CMD_OUT - cat ${g_tmp}/API_CMD_OUT >BINANCE_TOKEN_INFO_CMD_OUT - fi - - - # cut quantity by lot-step-size - if ! [ -z "$f_QUANTITY" ] - then - local f_LOT_STEP_SIZE=$(cat BINANCE_TOKEN_INFO_CMD_OUT | jq -c "[ .symbols[] | select( .symbol==\"${f_ASSET}${f_CURRENCY}\") ]" | jq -c '.[].filters[] | select( .filterType=="LOT_SIZE")' | jq -r '.stepSize' | perl -pe 's/0+$//; s/\.$//') - if [ -z "${f_LOT_STEP_SIZE}" ] - then - g_echo "Got no LOT_STEP_SIZE from BINANCE_TOKEN_INFO_CMD_OUT for ${f_ASSET} - Assuming 0.01" - f_LOT_STEP_SIZE="0.01" - fi - local f_LOT_DIV=$(echo "scale=0; ${f_QUANTITY}/${f_LOT_STEP_SIZE}" | bc -l) - f_QUANTITY_LOT_CUT=$(echo "${f_LOT_DIV}*${f_LOT_STEP_SIZE}" | bc -l | sed 's/^\./0./;') - fi - - # get min CURRENCY - f_MIN_NOTIONAL=$(cat BINANCE_TOKEN_INFO_CMD_OUT | jq -c "[ .symbols[] | select( .symbol==\"${f_ASSET}${f_CURRENCY}\") ]" | jq -c '.[].filters[] | select( .filterType=="MIN_NOTIONAL")' | jq -r '.minNotional' | perl -pe 's/0+$//; s/\.$//') - if [ -z "${f_MIN_NOTIONAL=}" ] - then - g_echo "Got no LOT_STEP_SIZE from BINANCE_TOKEN_INFO_CMD_OUT for ${f_ASSET} - Assuming 10.00000000" - f_MIN_NOTIONAL="10.00000000" - fi -} - diff --git a/functions/check_buy_conditions.sh b/functions/check_buy_conditions.sh deleted file mode 100644 index 0c1f5bd..0000000 --- a/functions/check_buy_conditions.sh +++ /dev/null @@ -1,173 +0,0 @@ -function check_buy_conditions { - - local f_ASSET_HIST_FILE="$1" - f_ASSET=$(basename ${f_ASSET_HIST_FILE} | cut -d\. -f1) - - if [ -n "${BOT}" ] - then - # ignore already invested asset - if ls trade-histories/trade-*${f_ASSET}-open.history.csv >/dev/null 2>&1 - then - g_echo_note "BUY ${f_ASSET}@${CURRENCY}: $f_ASSET Already invested - ignoring for more diversification" - return 0 - fi - fi - - get_vars_from_csv "${f_ASSET_HIST_FILE}" || return 1 - - ### from here: check for defined state to buy - f_BUY="${f_last_line}" - - - 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_pricediff=$(g_percentage-diff "$f_priceXago" "$f_pricenow") - if [ $(echo "${f_pricediff} < ${BUY_MINGROWTH}" | bc -l) -ne 0 ] - 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" - return 0 - 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 - # no negative or empty values - echo "${f_macd_histogram_relation}" | grep -q "^[0-9]" || return 0 - # check for conditions - if [ ${f_macd_histogram_relation} -le ${BUY_MACD_RELATION_FROM} ] || [ ${f_macd_histogram_relation} -ge ${BUY_MACD_RELATION_TO} ] - then - g_echo_note "BUY ${f_ASSET}@${CURRENCY}:${f_price}: MACD conditions NOT met" - return 0 - fi - - - # RSI - if \ - [ ${f_rsi5} -le ${BUY_RSI5_SIGNAL_UNTIL} ] && \ - [ ${f_rsi14} -le ${BUY_RSI14_SIGNAL_UNTIL} ] && \ - [ ${f_rsi21} -le ${BUY_RSI21_SIGNAL_UNTIL} ] && \ - [ ${f_rsi60} -le ${BUY_RSI60_SIGNAL_UNTIL} ] && \ - [ ${f_rsi120} -le ${BUY_RSI120_SIGNAL_UNTIL} ] && \ - [ ${f_rsi240} -le ${BUY_RSI240_SIGNAL_UNTIL} ] && \ - [ ${f_rsi420} -le ${BUY_RSI420_SIGNAL_UNTIL} ] && \ - [ ${f_rsi720} -le ${BUY_RSI720_SIGNAL_UNTIL} ] && \ - [ ${f_rsi5} -ge ${BUY_RSI5_SIGNAL_FROM} ] && \ - [ ${f_rsi14} -ge ${BUY_RSI14_SIGNAL_FROM} ] && \ - [ ${f_rsi21} -ge ${BUY_RSI21_SIGNAL_FROM} ] && \ - [ ${f_rsi60} -ge ${BUY_RSI60_SIGNAL_FROM} ] && \ - [ ${f_rsi120} -ge ${BUY_RSI120_SIGNAL_FROM} ] && \ - [ ${f_rsi240} -ge ${BUY_RSI240_SIGNAL_FROM} ] && \ - [ ${f_rsi420} -ge ${BUY_RSI420_SIGNAL_FROM} ] && \ - [ ${f_rsi720} -ge ${BUY_RSI720_SIGNAL_FROM} ] - then - echo "BUY ${f_ASSET}@${CURRENCY}:${f_price}: RSI conditions met" >/dev/null - else - g_echo_note "BUY ${f_ASSET}@${CURRENCY}:${f_price}: RSI conditions NOT met" - return 0 - fi - - - # Price change - if \ - [ $(echo "${f_price_change_1_day} > ${BUY_MIN_PRICE_CHANGE_LAST_1_DAY}" | bc -l) -ne 0 ] && \ - [ $(echo "${f_price_change_7_day} > ${BUY_MIN_PRICE_CHANGE_LAST_7_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 ] - then - echo "BUY ${f_ASSET}@${CURRENCY}:${f_price}: Price change conditions met" >/dev/null - else - g_echo_note "BUY ${f_ASSET}@${CURRENCY}:${f_price}: Price change conditions NOT met" - return 0 - fi - - - if [ -n "$f_BUY" ] - then - # Check for beginning MACD Trend - if ! tail -n3 ${f_ASSET_HIST_FILE} | grep -q '|buy,' - then - g_echo_note "BUY ${f_ASSET}@${CURRENCY}:${f_price}: MACD Trend not near (3 timeframes) the beginning buy signal" - return 0 - fi - - # Check for growing MACD trend - local f_macd_histogram_before=$(tail -n2 ${f_ASSET_HIST_FILE} | head -n1 | cut -d, -f8) - local f_macd_histogram_2before=$(tail -n3 ${f_ASSET_HIST_FILE} | head -n1 | cut -d, -f8) - local f_macd_histogram_3before=$(tail -n4 ${f_ASSET_HIST_FILE} | head -n1 | cut -d, -f8) - local f_macd_histogram_4before=$(tail -n5 ${f_ASSET_HIST_FILE} | head -n1 | cut -d, -f8) - local f_macd_histogram_5before=$(tail -n6 ${f_ASSET_HIST_FILE} | head -n1 | cut -d, -f8) - if \ - [ $(echo "${f_macd_histogram} < ${f_macd_histogram_before}" | bc -l) -ne 0 ] && \ - [ $(echo "${f_macd_histogram_before} < ${f_macd_histogram_2before}" | bc -l) -ne 0 ] && \ - [ $(echo "${f_macd_histogram_2before} < ${f_macd_histogram_3before}" | bc -l) -ne 0 ] && \ - [ $(echo "${f_macd_histogram_3before} < ${f_macd_histogram_4before}" | bc -l) -ne 0 ] && \ - [ $(echo "${f_macd_histogram_4before} < ${f_macd_histogram_5before}" | bc -l) -ne 0 ] - then - g_echo_note "BUY ${f_ASSET}@${CURRENCY}:${f_price} MACD Histogram not rising (now ${f_macd_histogram} < 1 before ${f_macd_histogram_before} < 2 before ${f_macd_histogram_2before} < 3 before ${f_macd_histogram_3before} < 4 before ${f_macd_histogram_4before} < 5 before ${f_macd_histogram_5before}) - trend loses strength / not growing - don't buy" - return 0 - fi - - fi - - - - ### Buy or not buy? - # BOT - if [ -n "$f_BUY" ] && [ -n "${BOT}" ] - then - echo "${f_last_line},${f_ASSET}" >>trade.log - - f_BUY="BUY ${f_ASSET}@${CURRENCY}:${f_price}: All BUY conditions met!!! -${f_BUY}" - g_echo_note "${f_BUY}" - - # calculate quantity from balance for potentially invest - local f_INVEST_QUANTITY=$(echo "scale=2; ${CURRENCY_BALANCE}/100*${INVEST}" | bc -l | sed 's/^\./0./;' | cut -d\. -f1) - g_echo_note "BUY current investment quantity is ${f_INVEST_QUANTITY} ${CURRENCY}" - - # remove CURRENCY from asset - f_ASSET=$(echo ${f_ASSET} | sed "s/${CURRENCY}//") - - # get stock exchange specific infos for trade (e.g. MIN_NOTIONAL) - $TOKEN_INFO_CMD ${f_ASSET} ${CURRENCY} - - # use MIN_NOTIONAL+5% as INVEST_QUANTITY if INVEST_QUANTITY is under MIN_NOTIONAL - # +5% in spite of MIN_NOTIONAL to be able to sell when the price falls a little bit - [ $(echo "${f_INVEST_QUANTITY} < ${f_MIN_NOTIONAL}" | bc -l) -eq 0 ] || f_INVEST_QUANTITY=$(echo "scale=2; $f_MIN_NOTIONAL/100*105" | bc -l) - - # if there is not enough balance for buying because ${f_MIN_NOTIONAL} needed for buying to sell (workaround) - if [ $(echo "${CURRENCY_BALANCE} < ${f_MIN_NOTIONAL}*2" | bc -l) -ne 0 ] - then - g_echo_note "BUY ${f_ASSET} not enough balance ${CURRENCY_BALANCE} for buying because of MIN_NOTIONAL (${f_MIN_NOTIONAL}*2) needed for buying-to-sell (workaround)" - return 1 - fi - - # continue if not balance enough for lowest quantity (MIN_NOTIONAL) - if [ $(echo "${CURRENCY_BALANCE} > ${f_INVEST_QUANTITY}" | bc -l) -eq 0 ] - then - g_echo_note "BUY ${f_ASSET} not enough balance (${CURRENCY_BALANCE}) for lowest quantity (MIN_NOTIONAL - ${f_INVEST_QUANTITY})" - return 1 - fi - - #g_echo_note "BUY BUY BUY ${f_ASSET} ${CURRENCY} ${f_INVEST_QUANTITY} buy \"$f_BUY\"" - if [ ${STOCK_EXCHANGE} = "BINANCE" ] - then - binance_convert ${f_ASSET} ${CURRENCY} ${f_INVEST_QUANTITY} buy "$f_BUY" || \ - do_trade ${f_ASSET} ${CURRENCY} ${f_INVEST_QUANTITY} buy "$f_BUY" - else - do_trade ${f_ASSET} ${CURRENCY} ${f_INVEST_QUANTITY} buy "$f_BUY" - fi - f_BUY="" - fi - - # ANALYZE - if [ -n "$f_BUY" ] && [ -z "${BOT}" ] - then - echo "BUY: $(echo ${f_last_line} | cut -d, -f1) === $f_BUY" - echo "$f_BUY" >${g_tmp}/open-${tmpfile} - BUY_PRICE=$current - fi -} - diff --git a/functions/check_for_buy.sh b/functions/check_for_buy.sh deleted file mode 100644 index e4f52a4..0000000 --- a/functions/check_for_buy.sh +++ /dev/null @@ -1,54 +0,0 @@ -function check_for_buy { - - g_echo_note "RUNNING FUNCTION ${FUNCNAME} $@" - - g_echo_ok "Investmentbudget: $CURRENCY_BALANCE $CURRENCY" - - # check for emergency stop - local f_COMPLETE_BALANCE=$(tail -n1 "asset-histories/BALANCECOMPLETE${CURRENCY}.history.csv" | cut -d, -f2) - if [ $(echo "${f_COMPLETE_BALANCE} < ${EMERGENCY_STOP}" | bc -l) -ne 0 ] - then - g_echo_note "BUY ATTENTION! EMERGENCY STOP DUE TO POOR PERFORMANCE: BALANCE (${f_COMPLETE_BALANCE}) LOWER THEN EMERGENCY_STOP-VALUE (${EMERGENCY_STOP})" - return 0 - fi - - ## Generate grep regex for already invested assets - #f_investedassets_regex=$(cat EXCHANGE_GET_BALANCES_CMD_OUT | cut -d, -f1 | perl -pe 's/^/\^/; s/\n/\|/' | perl -pe 's/\|$//') - - if ! [ -s ASSETS ] - then - g_echo_note "BUY file ASSETS empty $(ls -l ASSETS)" - return 0 - 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 - local f_line - for f_ASSET in $(cat ASSETS | egrep -v "${BLACKLIST}") - do - - f_ASSET_HIST_FILE="asset-histories/${f_ASSET}.history.csv" - - if [ $(tail -n 6 "$f_ASSET_HIST_FILE" | egrep -v ",,|,$" | wc -l) -ge 5 ] - then - check_buy_conditions "$f_ASSET_HIST_FILE" - else - g_echo_note "BUY $f_ASSET_HIST_FILE not enough data - waiting for complete values" - fi - - done -} - - - - diff --git a/functions/check_for_sell.sh b/functions/check_for_sell.sh deleted file mode 100644 index 7a1299b..0000000 --- a/functions/check_for_sell.sh +++ /dev/null @@ -1,230 +0,0 @@ -function check_for_sell { - 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 - for f_EXCHANGE_GET_BALANCES_CMD_OUT in $(cat EXCHANGE_GET_BALANCES_CMD_OUT | egrep -v "^${CURRENCY},") - do - f_ASSET=$(echo ${f_EXCHANGE_GET_BALANCES_CMD_OUT} | cut -d, -f1) - f_QUANTITY=$(echo ${f_EXCHANGE_GET_BALANCES_CMD_OUT} | cut -d, -f2) - f_QUANTITY_CURRENCY=$(echo ${f_EXCHANGE_GET_BALANCES_CMD_OUT} | cut -d, -f3) - f_LAST_EXCHANGE_RATE=$(echo ${f_EXCHANGE_GET_BALANCES_CMD_OUT} | cut -d, -f4) - f_ASSET_HIST_FILE="asset-histories/${f_ASSET}${CURRENCY}.history.csv" - - # State for currency - g_echo "SELL ${f_ASSET}: Balance: $f_QUANTITY ($f_QUANTITY_CURRENCY $CURRENCY)" - - # check for emergency stop - local f_COMPLETE_BALANCE=$(tail -n1 "asset-histories/BALANCECOMPLETE${CURRENCY}.history.csv" | cut -d, -f2) - if [ $(echo "${f_COMPLETE_BALANCE} < ${EMERGENCY_STOP}" | bc -l) -ne 0 ] - then - local f_msg="ATTENTION! EMERGENCY STOP DUE TO POOR PERFORMANCE: BALANCE (${f_COMPLETE_BALANCE}) LOWER THEN EMERGENCY_STOP-VALUE (${EMERGENCY_STOP})" - g_echo_error "$f_msg" - do_trade ${f_ASSET} ${CURRENCY} ${f_QUANTITY_CURRENCY} sell "${f_msg}" - continue - fi - - check_sell_conditions ${f_ASSET_HIST_FILE} - - #local f_perf - #for f_perf in ${f_perf_week} ${f_perf_month} - #do - # [ -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 - - - -} diff --git a/functions/check_sell_conditions.sh b/functions/check_sell_conditions.sh deleted file mode 100644 index c77012e..0000000 --- a/functions/check_sell_conditions.sh +++ /dev/null @@ -1,143 +0,0 @@ -function check_sell_conditions { - - local f_ASSET_HIST_FILE="$1" - f_ASSET=$(basename ${f_ASSET_HIST_FILE} | cut -d\. -f1) - - ### from here: check for defined state to sell - f_SELL="" - - # get data - get_vars_from_csv ${f_ASSET_HIST_FILE} || return 1 - - ### check current result - if [ -n "${BOT}" ] - then - f_TRADE_HIST_FILE="$(ls -1tr trade-histories/trade-*${f_ASSET}-open.history.csv | tail -n1)" - if ! [ -s "${f_TRADE_HIST_FILE}" ] - then - g_echo_note "SELL ${f_ASSET}: No trade history file (${f_TRADE_HIST_FILE}) found - ignoring" - return 0 - fi - f_TRADE_HIST_FILE_INTERIM=$(echo ${f_TRADE_HIST_FILE} | sed 's/-open\.history\.csv$/-interim.history.csv/') - local f_BUY_PRICE=$(grep ',BUY' $f_TRADE_HIST_FILE | tail -n1 | cut -d, -f5) - local f_BUY_PRICE_LAST_RATE_DIFF=$(g_percentage-diff ${f_BUY_PRICE} ${f_price}) - # Store for overview - echo ${f_BUY_PRICE_LAST_RATE_DIFF} >DIFF_BUY_PRICE_${f_ASSET} - else - f_TRADE_HIST_FILE="${g_tmp}/open-${tmpfile}" - f_TRADE_HIST_FILE_INTERIM="${g_tmp}/interim-${tmpfile}" - f_BUY_PRICE_LAST_RATE_DIFF=$(g_percentage-diff ${BUY_PRICE} ${f_price}) - f_BUY_PRICE=${BUY_PRICE} - result=${f_BUY_PRICE_LAST_RATE_DIFF} - echo "${f_last_line}" - echo "INTERIM RESULT: ${f_BUY_PRICE_LAST_RATE_DIFF}%" - fi - - - # check if the result (profit/loss until now) is lowering and sell if too low () - if [ -f ${f_TRADE_HIST_FILE_INTERIM} ] - then - local f_BUY_PRICE_2ND_LAST_RATE_DIFF=$(tail -n1 ${f_TRADE_HIST_FILE_INTERIM}) - local f_diff_result=$(echo "${f_BUY_PRICE_LAST_RATE_DIFF} - (${f_BUY_PRICE_2ND_LAST_RATE_DIFF})" | bc | sed 's/^\./0./; s/^-\./-0./') - if [ $(echo "${f_diff_result} < ${SELL_IF_LAST_RATE_LOWER_THEN}" | bc -l) -ne 0 ] && [ $(echo "${f_BUY_PRICE_LAST_RATE_DIFF} > ${FEE}" | bc -l) -ne 0 ] - then - f_SELL="Loss between last (${f_BUY_PRICE_LAST_RATE_DIFF}%) and 2nd last (${f_BUY_PRICE_2ND_LAST_RATE_DIFF}%) rate/result more then ${SELL_IF_LAST_RATE_LOWER_THEN}% (${f_diff_result}%)" - fi - - # Sell if the last X time units is lower then FEE - if [ $(cat ${f_TRADE_HIST_FILE_INTERIM} | wc -l) -ge ${SELL_IF_LOWER_THEN_FEE_AFTER_PERIOD} ] - then - local f_BUY_PRICE_XND_LAST_RATE_DIFF=$(tail -n${SELL_IF_LOWER_THEN_FEE_AFTER_PERIOD} ${f_TRADE_HIST_FILE_INTERIM} | head -n1) - local f_diff_result=$(echo "${f_BUY_PRICE_LAST_RATE_DIFF} - (${f_BUY_PRICE_XND_LAST_RATE_DIFF})" | bc) - if [ $(echo "${f_diff_result} < ${FEE}" | bc -l) -ne 0 ] - then - f_SELL="Loss between last rate (${f_BUY_PRICE_LAST_RATE_DIFF}%) in ${SELL_IF_LOWER_THEN_FEE_AFTER_PERIOD} time units before more then ${FEE} (${f_diff_result}%)" - fi - fi - fi - - # store new interim result - echo ${f_BUY_PRICE_LAST_RATE_DIFF} >>${f_TRADE_HIST_FILE_INTERIM} - - - # Sell on MACD Condition - if [ $(echo "${f_macd_histogram_relation} < ${SELL_MACD_RELATION_FROM}" | bc -l) -ne 0 ] - then - f_SELL="MACD condition met" - fi - - - # Sell on RSI conditions - if \ - [ ${f_rsi5} -le ${SELL_RSI5_SIGNAL_UNTIL} ] && \ - [ ${f_rsi14} -le ${SELL_RSI14_SIGNAL_UNTIL} ] && \ - [ ${f_rsi21} -le ${SELL_RSI21_SIGNAL_UNTIL} ] && \ - [ ${f_rsi60} -le ${SELL_RSI60_SIGNAL_UNTIL} ] && \ - [ ${f_rsi120} -le ${SELL_RSI120_SIGNAL_UNTIL} ] && \ - [ ${f_rsi240} -le ${SELL_RSI240_SIGNAL_UNTIL} ] && \ - [ ${f_rsi420} -le ${SELL_RSI420_SIGNAL_UNTIL} ] && \ - [ ${f_rsi720} -le ${SELL_RSI720_SIGNAL_UNTIL} ]&& \ - [ ${f_rsi5} -ge ${SELL_RSI5_SIGNAL_FROM} ] && \ - [ ${f_rsi14} -ge ${SELL_RSI14_SIGNAL_FROM} ] && \ - [ ${f_rsi21} -ge ${SELL_RSI21_SIGNAL_FROM} ] && \ - [ ${f_rsi60} -ge ${SELL_RSI60_SIGNAL_FROM} ] && \ - [ ${f_rsi120} -ge ${SELL_RSI120_SIGNAL_FROM} ] && \ - [ ${f_rsi240} -ge ${SELL_RSI240_SIGNAL_FROM} ] && \ - [ ${f_rsi420} -ge ${SELL_RSI420_SIGNAL_FROM} ] && \ - [ ${f_rsi720} -ge ${SELL_RSI720_SIGNAL_FROM} ] - then - f_SELL="RSI conditions met" - fi - - - # hold on negative result - if [ "${SELL_HOLD_IF_RESULT_NEGATIVE}" -gt 0 ] - then - if [ $(echo "(${f_BUY_PRICE_LAST_RATE_DIFF} - ${FEE}) < 0" | bc -l) -ne 0 ] - then - g_echo_note "Result negative - holding (INTERIM RESULT ${f_BUY_PRICE_LAST_RATE_DIFF}% - FEE ${FEE}% < 0" - f_SELL="" - fi - fi - - - # 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="SELL_PERCENTAGE_FROM_LAST_PURCHASE_NEGATIVE(${SELL_PERCENTAGE_FROM_LAST_PURCHASE_NEGATIVE}%) > Last rate (${f_BUY_PRICE_LAST_RATE_DIFF}%)" - fi - - - - [ -n "$f_SELL" ] && f_SELL="SELL ${f_ASSET}@${CURRENCY}:${f_price}: $f_SELL" - - ### Sell or not sell? - # BOT - if [ -n "$f_SELL" ] && [ -n "${BOT}" ] - then - g_echo_note "$f_SELL" - echo "${f_last_line},${f_ASSET}" >>trade.log - f_ASSET=$(echo ${f_ASSET} | sed "s/${CURRENCY}//") - # binance_convert ${f_ASSET} ${CURRENCY} ${f_QUANTITY} sell "${f_SELL}" - if [ ${STOCK_EXCHANGE} = "BINANCE" ] - then - binance_convert ${f_ASSET} ${CURRENCY} ${f_QUANTITY} sell "${f_SELL}" ${f_QUANTITY_CURRENCY} || \ - do_trade ${f_ASSET} ${CURRENCY} ${f_QUANTITY_CURRENCY} sell "${f_SELL}" - else - do_trade ${f_ASSET} ${CURRENCY} ${f_QUANTITY_CURRENCY} sell "${f_SELL}" - fi - fi - - # ANALYZE - if [ -n "${f_SELL}" ] && [ -z "${BOT}" ] - then - echo "SELL: $(tail -n1 ${f_ASSET_HIST_FILE} | cut -d, -f1) === $f_SELL" - result=$(g_percentage-diff ${BUY_PRICE} ${current}) - result=$(echo "${result}-${FEE}" | bc | sed 's/^\./0./; s/^-\./-0./') - echo "${result}" >>${g_tmp}/result-${tmpfile} - rm -f "${f_TRADE_HIST_FILE}" - rm -f "${f_TRADE_HIST_FILE_INTERIM}" - echo "RESULT: ${result}% (${BUY_PRICE} -> ${current})" - fi - -} diff --git a/functions/do_trade.sh b/functions/do_trade.sh deleted file mode 100644 index 7012efc..0000000 --- a/functions/do_trade.sh +++ /dev/null @@ -1,134 +0,0 @@ -function do_trade { - # Info for log - g_echo_note "RUNNING FUNCTION ${FUNCNAME} $@" - - # needed vars - local f_ASSET=$1 - local f_CURRENCY=$2 - local f_QUANTITY=$3 - local f_ACTION=$4 # buy or sell - local f_COMMENT=$5 - - local f_DATE=$(date '+%F_%H-%M-%S') - local f_ASSET_HIST_FILE="asset-histories/${f_ASSET}${f_CURRENCY}.history.csv" - - local f_link="https://www.coingecko.com/de/munze/$(egrep -i ^${f_ASSET}, COINGECKO_IDS | cut -d, -f2)" - - # get stock exchange specific infos for trade (e.g. f_QUANTITY_LOT_CUT; f_MIN_NOTIONAL) - $TOKEN_INFO_CMD $f_ASSET $f_CURRENCY $f_QUANTITY - local f_QUANTITY=${f_QUANTITY_LOT_CUT} - - #### Workaround for f_QUANTITY_LOT_CUT by buy more and directly sell - g_echo_note "Checking for need of QUANTITY_LOT_CUT Workaround (${f_QUANTITY_LOT_CUT} > ${f_MIN_NOTIONAL})" - if [ $(echo "${f_QUANTITY_LOT_CUT} > ${f_MIN_NOTIONAL}" | bc -l) -eq 0 ] && [ ${f_ACTION} = sell ] - then - # add 0.5 to f_MIN_NOTIONAL and trading fee - local f_MIN_NOTIONAL_WITH_FEE=$(echo "${f_MIN_NOTIONAL}+${FEE}+0.5" | bc -l) - g_echo_note "Doing QUANTITY_LOT_CUT Workaround - buying ${f_MIN_NOTIONAL_WITH_FEE} ${f_ASSET} ${f_CURRENCY}" - do_trade ${f_ASSET} ${f_CURRENCY} ${f_MIN_NOTIONAL_WITH_FEE} buy "Workaround for selling values under QUANTITY_LOT_CUT - buy +MIN_NOTIONAL" || return 1 - local f_QUANTITY=$(echo "${f_QUANTITY}+${f_MIN_NOTIONAL}" | bc -l) - fi - - if [ "${f_ACTION}" = "buy" ] - then - # check for enough balance for trade - get_balances - local f_CURRENCY_BALANCE=$(egrep "^${f_CURRENCY}," EXCHANGE_GET_BALANCES_CMD_OUT | cut -d"," -f2) - g_echo_note "Checking for enough balance for trade (${f_CURRENCY_BALANCE} > ${f_QUANTITY})" - if [ $(echo "${f_CURRENCY_BALANCE} > ${f_QUANTITY}" | bc -l) -eq 0 ] - then - local f_note="Not enough balance for trade (${f_CURRENCY_BALANCE} > ${f_QUANTITY}) :${f_COMMENT} -${FUNCNAME} $@" - g_echo_note "$f_note" - g_signal-notify "$f_note" - return 1 - fi - fi - - # prepare trading command - local f_CMDFILE="trade-histories/${f_DATE}-${f_CURRENCY}-${f_MIN_NOTIONAL}-TRADE_CMD" - echo "${TRADE_CMD}" | perl -pe "s/ACTION/${f_ACTION}/; s/TOKEN/${f_ASSET}${f_CURRENCY}/; s/QUANTITY/${f_QUANTITY}/" >${f_CMDFILE} - # trade - g_echo_note "Command: $(cat ${f_CMDFILE})" - #g_runcmd g_retrycmd sh ${f_CMDFILE} >${f_CMDFILE}_OUT - . ${f_CMDFILE} - cat ${g_tmp}/API_CMD_OUT >${f_CMDFILE}_OUT - g_echo_note "Command Output: $(cat ${f_CMDFILE}_OUT)" - - # workaround for "insufficient balance" error. lower quantity in 0.1 steps and try again (for values loosing while selling) - if [ "${f_ACTION}" = "sell" ] && grep -q "Account has insufficient balance for requested action." ${f_CMDFILE}_OUT - then - g_echo_note "workaround for \"insufficient balance\" error." - local f_tries=10 - local f_try=1 - until (grep -q "FILLED" ${f_CMDFILE}_OUT) - do - sleep 1 - f_QUANTITY=$(echo "$f_QUANTITY-0.1" | bc -l | sed 's/^\./0./;') - g_echo_note "lower $f_QUANTITY by -0.1" - echo "${TRADE_CMD}" | perl -pe "s/ACTION/${f_ACTION}/; s/TOKEN/${f_ASSET}${f_CURRENCY}/; s/QUANTITY/${f_QUANTITY}/" >${f_CMDFILE} - #g_runcmd g_retrycmd sh ${f_CMDFILE} >${f_CMDFILE}_OUT - . ${f_CMDFILE} - cat ${g_tmp}/API_CMD_OUT >${f_CMDFILE}_OUT - [ $f_try -eq $f_tries ] && break - ((f_try=f_try+1)) - done - fi - - - # Check return and log trade - f_STATUS=$(cat ${f_CMDFILE}_OUT | grep '^{' | jq -r .status) - - local f_trade_info_msg="TRADE - ${f_ACTION} ${f_ASSET}${f_CURRENCY} -${f_link} - -Complete Overview: https://bot.ds9.dedyn.io/ - -Comment: ${f_COMMENT}" - - if [ "${f_STATUS}" = "FILLED" ] - then - g_echo_note "TRADE SUCCESSFUL!" - local f_PRICE=$(cat ${f_CMDFILE}_OUT | grep '^{' | jq -r .fills[].price | head -n1) - local f_COMMISSION=$(cat ${f_CMDFILE}_OUT | grep '^{' | jq -r .fills[].commission) | head -n1 - local f_COMMISSIONASSET=$(cat ${f_CMDFILE}_OUT | grep '^{' | jq -r .fills[].commissionAsset | head -n1) - echo "${f_DATE},${f_ACTION},${f_CMDFILE}_OUT,${f_QUANTITY} ${f_CURRENCY},${f_PRICE},${f_COMMISSION} ${f_COMMISSIONASSET},${f_COMMENT}" | head -n1 >>trade-histories/${f_ASSET}${f_CURRENCY}.history.csv - if [ "${f_ACTION}" = "buy" ] - then - if echo ${f_COMMENT} | grep -q "Workaround for selling values under QUANTITY_LOT_CUT" - then - echo "${f_DATE},${f_ACTION},${f_CMDFILE}_OUT,${f_QUANTITY} ${f_CURRENCY},${f_PRICE},${f_COMMISSION} ${f_COMMISSIONASSET},${f_COMMENT}" | head -n1 >>trade-histories/trade-*${f_ASSET}${f_CURRENCY}-open.history.csv - else - echo "${f_DATE},${f_ACTION},${f_CMDFILE}_OUT,${f_QUANTITY} ${f_CURRENCY},${f_PRICE},${f_COMMISSION} ${f_COMMISSIONASSET},${f_COMMENT}" | head -n1 >>trade-histories/trade-$(date +%F.%T. | sed 's/:/_/g')${f_ASSET}${f_CURRENCY}-open.history.csv - fi - fi - if [ "${f_ACTION}" = "sell" ] - then - f_tradehistfile="$(ls trade-histories/trade-*${f_ASSET}${f_CURRENCY}-open.history.csv | tail -n1)" - echo "${f_DATE},${f_ACTION},${f_CMDFILE}_OUT,${f_QUANTITY} ${f_CURRENCY},${f_PRICE},${f_COMMISSION} ${f_COMMISSIONASSET},${f_COMMENT}" | head -n1 >>${f_tradehistfile} - f_tradehistfileclosed=$(echo ${f_tradehistfile} | sed 's/open.history.csv/closed.history.csv/') - mv ${f_tradehistfile} ${f_tradehistfileclosed} - fi - g_signal-notify "TRADE SUCCESSFUL! - -${f_trade_info_msg} - -Command stored: ${f_CMDFILE}[_OUT]" - [ -f DIFF_BUY_PRICE_${f_ASSET}${f_CURRENCY} ] && [ "${f_ACTION}" = "sell" ] && rm -f DIFF_BUY_PRICE_${f_ASSET}${f_CURRENCY} - # get new balances - get_balances - else - g_echo_note "TRADE FAILED! -$(cat ${f_CMDFILE}_OUT)" - g_signal-notify "TRADE FAILED! -${f_trade_info_msg} - -Command ${f_CMDFILE}: -$0 $@ -$(cat ${f_CMDFILE}) - -OUTPUT: -$(cat ${f_CMDFILE}_OUT) -" - fi -} diff --git a/functions/get_asset.sh b/functions/get_asset.sh deleted file mode 100644 index e7133ca..0000000 --- a/functions/get_asset.sh +++ /dev/null @@ -1,83 +0,0 @@ -function get_asset { - - g_echo_note "RUNNING FUNCTION ${FUNCNAME} $@" - local f_ASSET="$1" - - # write asset hist file with macd and rsi - local f_ASSET_HIST_FILE="asset-histories/${f_ASSET}.history-raw.csv" - [ -f "${f_ASSET_HIST_FILE}" ] || echo "Date and Time,Price" >"${f_ASSET_HIST_FILE}" - if ! grep -q "^$(echo "${f_timestamp}" | cut -d: -f1,2)" "${f_ASSET_HIST_FILE}" - then - local f_line="${f_timestamp},$(egrep "^${f_ASSET}," EXCHANGE_GET_ASSETS_CMD_OUT | cut -d, -f2)" - echo "${f_line}" >>${f_ASSET_HIST_FILE} - - local f_linecount=0 - local f_last_price=0 - local f_lines="$(tail -n 51 "${f_ASSET_HIST_FILE}" | wc -l)" - - for f_price in $(tail -n 50 "${f_ASSET_HIST_FILE}" | grep "^[0-9]" | cut -d, -f2) - do - if [ "$f_last_price" == "$f_price" ] - then - continue - fi - let "f_linecount+=1" - f_last_price=$f_price - done - - if [ ${f_linecount} -le 3 ] && [ ${f_lines} -ge 50 ] - then - g_echo_note "${f_ASSET_HIST_FILE}: price seems not to change - ignoring" - return 0 - fi - - f_ASSET_HIST_FILE="asset-histories/${f_ASSET}.history.csv" - if [ ${f_linecount} -lt 30 ] && [ ${f_lines} -ge 50 ] - then - g_echo_note "${f_ASSET_HIST_FILE}: set price to 5 minute period" - if ! echo "${f_timestamp}" | egrep -q ":[0-5]0:|:[0-5]5:" - then - return 0 - fi - fi - - # headline - [ -s "${f_ASSET_HIST_FILE}" ] || echo 'Date and Time,Price,Price Change,EMA12,EMA26,MACD,EMA9 MACD (Signal),MACD Histogram,MACD Signal,RSI5,RSI14,RSI21,RSI720,RSI60,RSI120,RSI240,RSI420,Price Change 24h,Price Change 7d,Price Change 14d,Price Change 30d' >"${f_ASSET_HIST_FILE}" - - # date and price - echo -n "${f_line}" >>${f_ASSET_HIST_FILE} - - # calculate price change percentage - f_last_price=$(tail -n2 ${f_ASSET_HIST_FILE} | head -n1 | cut -d, -f2) - if echo $f_last_price | grep -q "^[0-9]" - then - f_price=$(tail -n1 ${f_ASSET_HIST_FILE} | cut -d, -f2) - local f_price_change=$(g_percentage-diff ${f_last_price} ${f_price}) - else - local f_price_change="" - fi - echo -n ",${f_price_change}" >>"${f_ASSET_HIST_FILE}" - - # calculate macd and rsi - get_macd_indicator ${f_ASSET_HIST_FILE} - get_rsi_indicator ${f_ASSET_HIST_FILE} 5 - get_rsi_indicator ${f_ASSET_HIST_FILE} 14 - get_rsi_indicator ${f_ASSET_HIST_FILE} 21 - get_rsi_indicator ${f_ASSET_HIST_FILE} 720 - get_rsi_indicator ${f_ASSET_HIST_FILE} 60 - get_rsi_indicator ${f_ASSET_HIST_FILE} 120 - get_rsi_indicator ${f_ASSET_HIST_FILE} 240 - get_rsi_indicator ${f_ASSET_HIST_FILE} 480 - - # get coingecko price change - local f_asset=$(echo ${f_ASSET} | sed "s/${CURRENCY}\$//" | tr '[:upper:]' '[:lower:]') - echo -n ,$(jq -r ".[] |select(.symbol==\"${f_asset}\")|\"\\(.price_change_percentage_24h_in_currency)\"" COINGECKO_GET_ASSETS_CMD_OUT) >>${f_ASSET_HIST_FILE} - echo -n ,$(jq -r ".[] |select(.symbol==\"${f_asset}\")|\"\\(.price_change_percentage_7d_in_currency)\"" COINGECKO_GET_ASSETS_CMD_OUT) >>${f_ASSET_HIST_FILE} - echo -n ,$(jq -r ".[] |select(.symbol==\"${f_asset}\")|\"\\(.price_change_percentage_14d_in_currency)\"" COINGECKO_GET_ASSETS_CMD_OUT) >>${f_ASSET_HIST_FILE} - echo -n ,$(jq -r ".[] |select(.symbol==\"${f_asset}\")|\"\\(.price_change_percentage_30d_in_currency)\"" COINGECKO_GET_ASSETS_CMD_OUT) >>${f_ASSET_HIST_FILE} - - # end with newline - echo "" >>${f_ASSET_HIST_FILE} - fi -} - diff --git a/functions/get_assets.sh b/functions/get_assets.sh deleted file mode 100644 index 50a0874..0000000 --- a/functions/get_assets.sh +++ /dev/null @@ -1,150 +0,0 @@ -function get_assets { - - g_echo_note "RUNNING FUNCTION ${FUNCNAME} $@" - - ## determine assets with prices - local f_filename="EXCHANGE_GET_ASSETS_CMD" - # Try to collect assets - # get data from API - if [ ${STOCK_EXCHANGE} = "BINANCE" ] - then - binance-api-call GET /api/v3/ticker/price || return 1 - # parse API output - cat ${g_tmp}/API_CMD_OUT | jq -r '.[] | .symbol + "," + .price' | grep "${CURRENCY}," | egrep -v "${TRANSFER_CURRENCY},|,0[\.][0]*$" >${f_filename}_OUT.tmp - fi - # timestamp for data - f_timestamp=$(g_date_print) - # check output - if [ -s ${f_filename}_OUT.tmp ] && egrep -q "^[A-Z]+${CURRENCY},[0-9]*\.[0-9]+$" ${f_filename}_OUT.tmp - then - mv ${f_filename}_OUT.tmp ${f_filename}_OUT - else - g_echo_warn "${f_filename}_OUT.tmp has wrong Syntax. - Not updating ${f_filename}_OUT $(tail -n 10 ${f_filename}_OUT.tmp)" - return 2 - fi - - ## write assets list and filter by marketcap and sort by price - # get krypto symbol list sorted by marketcap - echo "curl -s -X 'GET' \"https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&order=market_cap_desc&per_page=250&page=1&sparkline=false&price_change_percentage=1h,24h,7d,14d,30d\" -H 'accept: application/json'" >COINGECKO_GET_ASSETS_CMD - g_runcmd g_retrycmd sh COINGECKO_GET_ASSETS_CMD >COINGECKO_GET_ASSETS_CMD_OUT || return 1 -#ASSET_MARKETCAP_OUT.tmp || return 1 - if [ -s COINGECKO_GET_ASSETS_CMD_OUT ] && grep -q "market_cap_rank" COINGECKO_GET_ASSETS_CMD_OUT - then - - # get marketcap sort - jq -r '.[].symbol' COINGECKO_GET_ASSETS_CMD_OUT | tr [:lower:] [:upper:] | head -n $LARGEST_MARKETCAP >ASSET_MARKETCAP_OUT.tmp-sort - if [ -s ASSET_MARKETCAP_OUT.tmp-sort ] && egrep -q "^[A-Z0-9]+$" ASSET_MARKETCAP_OUT.tmp-sort - then - mv ASSET_MARKETCAP_OUT.tmp-sort SORTMARKETCAP - else - g_echo_warn "ASSET_MARKETCAP_OUT.tmp-sort has wrong Syntax. - Not updating ASSET_MARKETCAP_OUT.tmp-sort $(tail -n 10 ASSET_MARKETCAP_OUT.tmp-sort)" - return 2 - fi - - # write down 24h pricechange - cat COINGECKO_GET_ASSETS_CMD_OUT | jq -r '.[] | .symbol + "," + (.price_change_percentage_24h|tostring)' | tr [:lower:] [:upper:] >ASSET_PRICE_CHANGE_PERCENTAGE_24H - - # store coingecko symbolids for coingecko info URLs - jq -r '.[] | .symbol + "," + .id' COINGECKO_GET_ASSETS_CMD_OUT >COINGECKO_IDS.tmp - if [ -s COINGECKO_IDS.tmp ] - then - mv COINGECKO_IDS.tmp COINGECKO_IDS - else - g_echo_warn "COINGECKO_IDS.tmp has wrong Syntax. - Not updating COINGECKO_IDS $(tail -n 10 COINGECKO_IDS.tmp)" - return 2 - fi - fi - - - # Write file with asset list and ignore marketcap under LARGEST_MARKETCAP - cat EXCHANGE_GET_ASSETS_CMD_OUT | cut -d"," -f1 | while read f_ASSET - do - # ignore marketcap under LARGEST_MARKETCAP - f_assetwocurrency=$(echo ${f_ASSET} | sed "s/$CURRENCY$//") - if ! egrep -q "^${f_assetwocurrency}$" SORTMARKETCAP - then - #g_echo_note "Ignoring $f_ASSET because of lower marketcap then Top ${LARGEST_MARKETCAP}" - continue - fi - echo ${f_ASSET} >>ASSETS.tmp - done - mv ASSETS.tmp ASSETS - - - ## write histfiles by having a look on marketcap - #>ASSETS_HIGHEST.tmp - # get alread invested assets - #f_investedassets_regex=$(cat EXCHANGE_GET_BALANCES_CMD_OUT | cut -d, -f1 | perl -pe 's/^/\^/; s/\n/\|/' | perl -pe 's/\|$//') - local f_ASSET - - - local f_parallel_arg - echo -n "parallel -j3 bash -c --" >/tmp/parallel - for f_ASSET in $(cat ASSETS | egrep -v "${BLACKLIST}") - do - #get_asset "${f_ASSET}" - echo -n " \"get_asset ${f_ASSET}\"" >>/tmp/parallel - done - export -f get_asset - export f_timestamp - . /tmp/parallel - - # cleanup trashlines (possibly generated by kill further of this progress) - sed -i "/[0-9]$(date +%Y)-/d" asset-histories/* - - #cat ASSETS | while read f_ASSET - #do - # # write asset hist file with macd and rsi - # local f_ASSET_HIST_FILE="asset-histories/${f_ASSET}.history.csv" - # [ -f "${f_ASSET_HIST_FILE}" ] || touch "${f_ASSET_HIST_FILE}" - # if ! grep -q "^$(echo "${f_timestamp}" | cut -d: -f1,2)" "${f_ASSET_HIST_FILE}" - # then - # local f_line="${f_timestamp},$(egrep "^${f_ASSET}," EXCHANGE_GET_ASSETS_CMD_OUT | cut -d, -f2)" - # #g_echo_note "Writing new line (${f_line}) to history ${ASSET_HIST_FILE}" - # echo -n "${f_line}" >>${f_ASSET_HIST_FILE} - # get_macd_indicator ${f_ASSET_HIST_FILE} - # get_rsi_indicator ${f_ASSET_HIST_FILE} 30 - # echo ",${f_macd},${f_rsi}" >>${f_ASSET_HIST_FILE} - # fi - - -# cat ASSETS | while read f_ASSET -# do -# # ignore already invested asset -# if echo "$f_ASSET" | egrep -q "$f_investedassets_regex" -# then -# g_echo_note "Already invested in $f_ASSET - ignoring for more diversification" -# continue -# fi -# -# # sort latest assets prices by highest in last timeframe (ignore - or 0) -# get_rate_percentage_min_before_and_now $(echo ${f_ASSET} | sed "s/${CURRENCY}\$//") ${CURRENCY} 1 || continue -# local f_ASSET_PERCENTAGE=${f_exchange_rate_diff_percentage} -# echo "$f_ASSET_PERCENTAGE" | egrep -q '^-|^0.0' && continue -# g_echo "adding ${f_ASSET}({$f_ASSET_PERCENTAGE}) to ASSETS_HIGHEST because marketcap in Top ${LARGEST_MARKETCAP}" -# echo "${f_ASSET_PERCENTAGE},${f_ASSET}" >>ASSETS_HIGHEST.tmp -# done -# cat ASSETS_HIGHEST.tmp | sort -r >ASSETS_HIGHEST.tmp2 -# mv ASSETS_HIGHEST.tmp2 ASSETS_HIGHEST -# rm ASSETS_HIGHEST.tmp - - # get MSCI World Index for analysis - echo "wget -q -O - https://www.boerse.de/realtime-kurse/MSCI-World/XC0009692739 | egrep 'itemprop=\"price\" content=\"[0-9]+\.[0-9]+\"' | cut -d\\\" -f6" >MSCI_WORLD_CMD - g_runcmd g_retrycmd sh MSCI_WORLD_CMD >MSCI_WORLD_CMD_OUT.tmp - # check output - if [ -s MSCI_WORLD_CMD_OUT.tmp ] && egrep -q "^[0-9]*\.[0-9]+$" MSCI_WORLD_CMD_OUT.tmp - then - if egrep -q "^0\.00$" MSCI_WORLD_CMD_OUT.tmp - then - g_echo_note "Ignoring MSCI World $(tail -n 10 MSCI_WORLD_CMD_OUT.tmp) - maybe out of business day" - else - mv MSCI_WORLD_CMD_OUT.tmp MSCI_WORLD_CMD_OUT - fi - else - g_echo_warn "MSCI_WORLD_CMD_OUT.tmp has wrong Syntax. - Not updating MSCI WORLD Index $(tail -n 10 MSCI_WORLD_CMD_OUT.tmp)" - fi - echo "${f_timestamp},$(cat MSCI_WORLD_CMD_OUT)" >>asset-histories/MSCI-WORLD-INDEX.history.csv - - -} - diff --git a/functions/get_balances.sh b/functions/get_balances.sh deleted file mode 100644 index c95079b..0000000 --- a/functions/get_balances.sh +++ /dev/null @@ -1,126 +0,0 @@ -function get_balances { - - g_echo_note "RUNNING FUNCTION ${FUNCNAME} $@" - - local f_filename="EXCHANGE_GET_BALANCES_CMD" - - # get data from API - if [ ${STOCK_EXCHANGE} = "BINANCE" ] - then - binance_convert_dust - binance-api-call GET sapi/v1/capital/config/getall || return 1 - # parse outout - cat ${g_tmp}/API_CMD_OUT | jq -r '.[] | .coin + "," + .free' | egrep -v ",0$|,0[\.][0]*$|${TRANSFER_CURRENCY}" | sort >${f_filename}_OUT.tmp_raw - fi - - if ! [ -s ${f_filename}_OUT.tmp_raw ] && egrep -q "^[A-Z]+,[0-9]*\.[0-9]+$" ${f_filename}_OUT.tmp_raw - then - g_echo_warn "${f_filename}_OUT.tmp_raw has wrong Syntax or is empty. - Not updating ${f_filename}_OUT $(tail -n 10 ${f_filename}_OUT.tmp_raw)" - return 2 - fi - - # CURRENCY is defined - if [ -n "${CURRENCY}" ] - then - - # put balance of (main) currency in global CURRENCY_BALANCE - local f_CURRENCY_BALANCE=$(egrep "^${CURRENCY}," ${f_filename}_OUT.tmp_raw | cut -d"," -f2) - if echo "${f_CURRENCY_BALANCE}" | egrep -q "^[0-9]*\.[0-9]*" - then - CURRENCY_BALANCE=${f_CURRENCY_BALANCE} - g_echo_note "Investmentbudget: $CURRENCY_BALANCE $CURRENCY" - else - g_echo_warn "Could not determine CURRENCY_BALANCE (${f_CURRENCY_BALANCE} ${CURRENCY}) from file ${f_filename}_OUT.tmp_raw $(cat ${f_filename}_OUT.tmp_raw)" - return 3 - fi - - # add balance in CURRNCY - local f_line - for f_line in $(cat ${f_filename}_OUT.tmp_raw) - do - local f_ASSET=$(echo ${f_line} | cut -d, -f1) - local f_QUANTITY=$(echo ${f_line} | cut -d, -f2) - - if [ "${f_ASSET}" = "${CURRENCY}" ] - then - g_echo_note "own currency line $f_line" - echo "${f_ASSET},${f_QUANTITY},$f_QUANTITY,1.00000000" >>${f_filename}_OUT.tmp - continue - fi - - local f_ASSET_HIST_FILE="asset-histories/${f_ASSET}${CURRENCY}.history.csv" - if ! [ -s ${f_ASSET_HIST_FILE} ] - then - g_echo_note "No history file (${f_ASSET_HIST_FILE}) found for asset (${f_ASSET}) - ignoring $f_line." - continue - fi - - # ignore non traded currencies by bot - ls trade-histories/trade-*.${f_ASSET}${CURRENCY}-open.history.csv >/dev/null 2>&1 || continue - - # get last prices - local f_LAST_EXCHANGE_PRICE=$(tail -n1 ${f_ASSET_HIST_FILE} | head -n1 | cut -d, -f2) - if ! echo "$f_LAST_EXCHANGE_PRICE" | egrep -q "^[0-9]" - then - g_echo_warn "didn't get latest price from ${f_ASSET_HIST_FILE}" - continue - fi - - # calculate quantity in CURRENCY - local f_QUANTITY_CURRENCY=$(echo "scale=8; $f_LAST_EXCHANGE_PRICE*$f_QUANTITY" | bc -l | sed 's/^\./0./;') - if ! echo "$f_QUANTITY_CURRENCY" | egrep -q "^[0-9]" - then - g_echo_warn "could not calculate quantity in ${CURRENCY}" - continue - fi - - # ignore low values - if [ $(echo "$f_QUANTITY_CURRENCY < 2" | bc -l) -ne 0 ] - then - g_echo_note "${f_ASSET}: Ignore low quantity asset ${f_ASSET}(${f_QUANTITY})" - continue - else - g_echo_note "${f_ASSET}: Going on with non-low quantity (>1) asset ${f_ASSET}(${f_QUANTITY})" - fi - - echo "${f_ASSET},${f_QUANTITY},${f_QUANTITY_CURRENCY},${f_LAST_EXCHANGE_PRICE}" >>${f_filename}_OUT.tmp - done - fi - - if [ -s ${f_filename}_OUT.tmp ] && egrep -q "^[A-Z]+,[0-9]*\.[0-9]+,[0-9]*\.[0-9]+,[0-9]*\.[0-9]+$" ${f_filename}_OUT.tmp - then - mv ${f_filename}_OUT.tmp ${f_filename}_OUT - else - g_echo_warn "${f_filename}_OUT.tmp has wrong Syntax or is empty. - Not updating ${f_filename}_OUT $(tail -n 10 ${f_filename}_OUT.tmp)" - return 2 - fi - - # get complete spot balance - local f_SPOT_BALANCE=0 - local f_EXCHANGE_GET_BALANCES_CMD_OUT - for f_EXCHANGE_GET_BALANCES_CMD_OUT in $(cat EXCHANGE_GET_BALANCES_CMD_OUT | grep -v ^$CURRENCY,) - do - #local f_ASSET=$(echo ${f_EXCHANGE_GET_BALANCES_CMD_OUT} | cut -d"," -f1) - local f_QUANTITY_CURRENCY=$(echo ${f_EXCHANGE_GET_BALANCES_CMD_OUT} | cut -d"," -f3) - local f_SPOT_BALANCE=$(echo "scale=2; $f_SPOT_BALANCE+$f_QUANTITY_CURRENCY" | bc -l) - done - - # calculate complete balance - local f_COMPLETE_BALANCE=$(echo "scale=2; $CURRENCY_BALANCE+$f_SPOT_BALANCE" | bc -l) - local f_timestamp=$(g_date_print) - - # write balance history - echo "$f_timestamp,$f_COMPLETE_BALANCE" >>"asset-histories/BALANCECOMPLETE${CURRENCY}.history.csv" - echo "$f_timestamp,$f_SPOT_BALANCE" >>"asset-histories/BALANCESPOT${CURRENCY}.history.csv" - echo "$f_timestamp,$CURRENCY_BALANCE" >>"asset-histories/BALANCE${CURRENCY}.history.csv" - - ### global vars for overall performance last day, week, month - #get_rate_percentage_min_before_and_now BALANCECOMPLETE ${CURRENCY} 1440 - #f_perf_day=${f_exchange_rate_diff_percentage} - #get_rate_percentage_min_before_and_now BALANCECOMPLETE ${CURRENCY} 10080 - #f_perf_week=${f_exchange_rate_diff_percentage} - #get_rate_percentage_min_before_and_now BALANCECOMPLETE ${CURRENCY} 43200 - #f_perf_month=${f_exchange_rate_diff_percentage} - -} - diff --git a/functions/get_ema.sh b/functions/get_ema.sh deleted file mode 100644 index a26272e..0000000 --- a/functions/get_ema.sh +++ /dev/null @@ -1,27 +0,0 @@ -function get_ema { - - local f_hist_file="$1" - local f_hist_file_column="$2" - local f_period="$3" - local f_last_ema="$4" - local f_lastvalue="$5" - - f_ema="" - - # calculate EMA if last EMA is given - if [ -n "$f_last_ema" ] - then - f_ema=$(echo "scale=10; ${f_lastvalue}*(2/(${f_period}+1))+${f_last_ema}*(1-(2/(${f_period}+1)))" | bc | sed 's/^\./0./; s/^-\./-0./' ) - # calculate SMA12 only for first time as base for EMA and call it EMA if there are enough value periods - else - local f_period_sum=$(tail -n${f_period} "${f_hist_file}" | cut -d, -f${f_hist_file_column} | egrep "^[0-9]|-[0-9]" | wc -l) - if [ ${f_period_sum} -eq ${f_period} ] - then - f_ema=$(tail -n ${f_period} "${f_hist_file}" | cut -d"," -f${f_hist_file_column} | awk "{ SUM += \$1} END { printf(\"%10.10f\", SUM/${f_period}) }") - else - g_echo_note "${FUNCNAME} $@: Not enough data - waiting for more values. (${f_period} needed; ${f_period_sum} given)" - return 0 - fi - fi -} - diff --git a/functions/get_macd_indicator.sh b/functions/get_macd_indicator.sh deleted file mode 100644 index d11188b..0000000 --- a/functions/get_macd_indicator.sh +++ /dev/null @@ -1,118 +0,0 @@ -function get_macd_indicator { - - #g_echo_note "RUNNING FUNCTION ${FUNCNAME} $@" - # get histfile - local f_hist_file="$1" - - # define or clean gloval macdvars - f_macd_ema12="" - f_macd_ema26="" - f_macd="" - f_macd_ema9_signal="" - f_macd_signal="" - - if ! [ -s "$f_hist_file" ] - then - g_echo_warn "${FUNCNAME} $@: Histfile $f_hist_file does not exist or is empty" - return 1 - fi - - # read last two lines - local f_lastline=$(tail -n1 "$f_hist_file" | grep ^2) - local f_second_lastline=$(tail -n2 "$f_hist_file" | head -n1 | grep ^2) - - # Try to get current MACD values - local f_macd_lastprice=$(echo "$f_lastline" | cut -d, -f2) - f_macd_ema12=$(echo "$f_lastline" | cut -d, -f4) - f_macd_ema26=$(echo "$f_lastline" | cut -d, -f5) - f_macd=$(echo "$f_lastline" | cut -d, -f6) - f_macd_ema9_signal=$(echo "$f_lastline" | cut -d, -f7) - - # if data is complete - if [ -n "${f_macd_ema12}" ] && [ -n "${f_macd_ema26}" ] && [ -n "${f_macd}" ] && [ -n "${f_macd_ema9_signal}" ] - then - g_echo_note "${FUNCNAME} $@: Looks like current MACD was already calculated" - return 1 - fi - - # Try to get last MACD values - f_macd_last_ema12=$(echo "$f_second_lastline" | cut -d, -f4) - f_macd_last_ema26=$(echo "$f_second_lastline" | cut -d, -f5) - f_macd_last=$(echo "$f_second_lastline" | cut -d, -f6) - f_macd_last_ema9_signal=$(echo "$f_second_lastline" | cut -d, -f7) - f_macd_last_histogram=$(echo "$f_second_lastline" | cut -d, -f8) - - # calc EMA12 - get_ema "${f_hist_file}" 2 12 "${f_macd_last_ema12}" "${f_macd_lastprice}" - if [ -z "${f_ema}" ] - then - g_echo_note "${FUNCNAME} $@: Not enough data for calculating EMA12 - waiting for more values" - echo -n ",,,,,," >>"${f_hist_file}" - return 0 - fi - f_macd_ema12=${f_ema} - echo -n ",${f_macd_ema12}" >>"${f_hist_file}" - - # calc EMA26 - if [ -z "${f_macd_last_ema12}" ] - then - echo -n ",,,,," >>"${f_hist_file}" - return 0 - fi - get_ema "${f_hist_file}" 2 26 "${f_macd_last_ema26}" "${f_macd_lastprice}" - if [ -z "${f_ema}" ] - then - g_echo_note "${FUNCNAME} $@: Not enough data for calculating EMA26 - waiting for more values" - echo -n ",,,,," >>"${f_hist_file}" - return 0 - fi - f_macd_ema26=${f_ema} - echo -n ",${f_macd_ema26}" >>"${f_hist_file}" - - # calc MACD - if [ -z "${f_macd_ema26}" ] - then - echo -n ",,,," >>"${f_hist_file}" - return 0 - fi - #[ -z "${f_macd_ema12}" ] && return 0 - f_macd=$(echo "scale=8; ${f_macd_ema12}-${f_macd_ema26}" | bc | sed 's/^\./0./; s/^-\./-0./') - echo -n ",${f_macd}" >>"${f_hist_file}" - - # calc MACD Signal - if [ -z "${f_macd}" ] - then - echo -n ",,," >>"${f_hist_file}" - return 0 - fi - get_ema "${f_hist_file}" 6 9 "${f_macd_last_ema9_signal}" "${f_macd}" - if [ -z "${f_ema}" ] - then - g_echo_note "${FUNCNAME} $@: Not enough data for calculating EMA9 Signal - waiting for more values" - echo -n ",,," >>"${f_hist_file}" - return 0 - fi - f_macd_ema9_signal=${f_ema} - echo -n ",${f_macd_ema9_signal}" >>"${f_hist_file}" - - # calc MACD Histogram - f_macd_histogram=$(echo "scale=10; ${f_macd}-(${f_macd_ema9_signal})" | bc | sed 's/^\./0./; s/^-\./-0./') - echo -n ",${f_macd_histogram}" >>"${f_hist_file}" - - # check for MACD buy or sell signal - echo ${f_macd_histogram} | grep -q "^-" && echo ${f_macd_last_histogram} | grep -q "^[0-9]" && f_macd_signal="sell" - echo ${f_macd_histogram} | grep -q "^[0-9]" && echo ${f_macd_last_histogram} | grep -q "^-" && f_macd_signal="buy" - - # calculate MACD Histogram relation - if [ $(tail -n36 "${f_hist_file}" | wc -l) -ge 35 ] - then - local f_macd_histogram_max=$(tail -n60 "${f_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 | sed 's/^\./0./; s/^-\./-0./' | cut -d\. -f1) - fi - - echo -n ",${f_macd_histogram_relation}|${f_macd_signal}" >>"${f_hist_file}" - - - -} - diff --git a/functions/get_rate_percentage_min_before_and_now.sh b/functions/get_rate_percentage_min_before_and_now.sh deleted file mode 100644 index 2e63f0b..0000000 --- a/functions/get_rate_percentage_min_before_and_now.sh +++ /dev/null @@ -1,63 +0,0 @@ -function get_rate_percentage_min_before_and_now { - g_echo_note "RUNNING FUNCTION ${FUNCNAME} $@" - # get vars - local f_asset=$1 - local f_currency=$2 - local f_min=$3 - # Optional time from min before sould be calculated (to be able to calculate from 5 min before to 10 minutes before) - local f_min_from=$4 - - # clean up global variable (maybe used in runs before) - f_exchange_rate_diff_percentage="" - - local f_asset_hist_file="asset-histories/${f_asset}${f_currency}.history.csv" - if [ -s "f_asset_hist_file" ] - then - g_echo_note "${f_asset}: No or empty histfile(${f_asset_hist_file}) found" - return 1 - fi - - # prepare date - if [ -n "${f_min_from}" ] - then - local f_min_date_from=$(date "+%F %H:%M:" --date="-${f_min_from} minutes") - f_min=$((f_min+f_min_from)) - else - local f_min_date_from=$(date "+%F %H:%M:") - fi - local f_min_date=$(date "+%F %H:%M:" --date="-${f_min} minutes") - - if [ -z "${f_min_date}" ] - then - g_echo_warn "${f_asset}: Error while calculating date ${f_min} before" - return 1 - fi - - # get current exchange rate - local f_current_exchange_rate=$(egrep "^${f_min_date_from}" ${f_asset_hist_file} | cut -d, -f2) - if [ -z "${f_current_exchange_rate}" ] - then - g_echo_note "${f_asset}: From rate $f_min_from ${f_min_date_from} not found in ${f_asset_hist_file}" - return 1 - fi - - # get exchange rate defined minutes before - local f_min_before_exchange_rate=$(egrep "^${f_min_date}" ${f_asset_hist_file} | cut -d, -f2) - if [ -z "${f_min_before_exchange_rate}" ] - then - g_echo_note "${f_asset}: Rate ${f_min} minutes ago not found in ${f_asset_hist_file}" - return 2 - fi - - # calculate difference in percentage between current rate and rate defined minutes before - f_exchange_rate_diff_percentage=$(g_percentage-diff ${f_min_before_exchange_rate} ${f_current_exchange_rate}) - if [ -z "$f_exchange_rate_diff_percentage" ] - then - g_echo_warn "${f_asset}: Calculating difference between rate ${f_min} minutes ago (${min_before_exchange_rate}) and current (${m_current_exchange_rate}) in percentage failed" - return 3 - fi - - # give back percentage - g_echo_note "${f_asset}: difference from ${f_current_exchange_rate} from ${f_min_date_from} and ${f_min_date} ${f_min_before_exchange_rate}: ${f_exchange_rate_diff_percentage}%" - return 0 -} diff --git a/functions/get_rsi_indicator.sh b/functions/get_rsi_indicator.sh deleted file mode 100644 index 89177fe..0000000 --- a/functions/get_rsi_indicator.sh +++ /dev/null @@ -1,79 +0,0 @@ -function get_rsi_indicator { - #g_echo_note "RUNNING FUNCTION ${FUNCNAME} $@" - # get histfile - local f_hist_file="$1" - local f_last_minutes="$2" - - # calculate change of lastest f_last_minutes+1 prices for calculating rsi over the last f_last_minutes periods - local f_price - local f_last_price - local f_positive_sum=0 - local f_negative_sum=0 - f_rsi="" - - local f_period=$((f_last_minutes+1)) - local f_period_sum=$(tail -n${f_period} "${f_hist_file}" | cut -d, -f2 | grep "^[0-9]" | wc -l) - if ! [ ${f_period_sum} -ge ${f_period} ] - then - g_echo_note "${FUNCNAME} $@: Not enough data - waiting for more values. (${f_period} needed; ${f_period_sum} given)" - echo -n ",${f_rsi}" >>"${f_hist_file}" - return 0 - fi - -# for f_price in $(tail -n${f_period} "${f_hist_file}" | cut -d"," -f2) -# do -# # not for the first line because a comparative value is missing -# if [ -z "${f_last_price}" ] -# then -# f_last_price=${f_price} -# continue -# fi -# -# # calculate each change -# local f_price_change=$(g_percentage-diff ${f_last_price} ${f_price}) -# f_last_price=${f_price} -# -# # add positive/negative changes -# if echo "${f_price_change}" | grep -q '^-' -# then -# f_negative_sum=$(echo "${f_negative_sum}+${f_price_change}" | bc -l) -# else -# f_positive_sum=$(echo "${f_positive_sum}+${f_price_change}" | bc -l) -# fi -# done - - f_positive_sum=$(tail -n${f_period} "${f_hist_file}" | cut -d"," -f3 | grep "^[0-9]" | awk "{ SUM += \$1} END { printf(\"%10.10f\", SUM/${f_period}) }") - f_negative_sum=$(tail -n${f_period} "${f_hist_file}" | cut -d"," -f3 | grep "^-[0-9]" | awk "{ SUM += \$1} END { printf(\"%10.10f\", SUM/${f_period}) }") - - - # if one of both is "0" then fix results - if [ ${f_negative_sum} == "0.0000000000" ] - then - f_rsi=100 - #g_echo_note "RSI-Indicator RSI: ${f_rsi}%" - echo -n ",${f_rsi}" >>"${f_hist_file}" - return 0 - fi - - if [ ${f_positive_sum} == "0.0000000000" ] - then - f_rsi=0 - #g_echo_note "RSI-Indicator RSI: ${f_rsi}%" - echo -n ",${f_rsi}" >>"${f_hist_file}" - return 0 - fi - - # calculate positive/negative change averages - local f_negative_sum_average=$(echo "${f_negative_sum}/${f_last_minutes}" | bc -l | sed 's/-//') - local f_positive_sum_average=$(echo "${f_positive_sum}/${f_last_minutes}" | bc -l) - - # calculate RS and RSI - local f_rs=$(echo "${f_positive_sum_average}/${f_negative_sum_average}" | bc -l) - f_rsi=$(echo "100-(100/(1+${f_rs}))" | bc -l | xargs printf "%.0f") - - echo -n ",${f_rsi}" >>"${f_hist_file}" - - #g_echo_note "RSI-Indicator RSI: ${f_rsi}%" - -} - diff --git a/functions/get_vars_from_csv.sh b/functions/get_vars_from_csv.sh deleted file mode 100644 index 48ad240..0000000 --- a/functions/get_vars_from_csv.sh +++ /dev/null @@ -1,47 +0,0 @@ -function get_vars_from_csv { - - local f_ASSET_HIST_FILE="$1" - if ! [ -s "${f_ASSET_HIST_FILE}" ] - then - g_echo_warn "${f_ASSET_HIST_FILE} does not exist or is empty" - return 1 - fi - - f_last_line="$(tail -n1 "${f_ASSET_HIST_FILE}")" - - readarray -d "," -t f_last_line_array < <(echo "0,${f_last_line}") - - get_var_from_line date 1 - get_var_from_line price 2 - get_var_from_line price_change 3 - - get_var_from_line macd_histogram 8 - get_var_from_line macd_signal_relation 9 - f_macd_histogram_relation=$(echo "${f_macd_signal_relation}" | cut -d\| -f1) - f_macd_histogram_signal=$(echo "${f_macd_signal_relation}" | cut -d\| -f2) - - get_var_from_line rsi5 10 - get_var_from_line rsi14 11 - get_var_from_line rsi21 12 - get_var_from_line rsi720 13 - get_var_from_line rsi60 14 - get_var_from_line rsi120 15 - get_var_from_line rsi240 16 - get_var_from_line rsi420 17 - - get_var_from_line price_change_1_day 18 - get_var_from_line price_change_7_day 19 - get_var_from_line price_change_14_day 20 - get_var_from_line price_change_30_day 21 - -} - -function get_var_from_line { - if [ -z "${f_last_line_array[$2]}" ] - then - g_echo_note "Didn't get $1 in position $2" - return 1 - fi - declare -g f_$1="$(echo ${f_last_line_array[$2]})" -} - diff --git a/functions/market_performance.sh b/functions/market_performance.sh deleted file mode 100644 index 2b2722e..0000000 --- a/functions/market_performance.sh +++ /dev/null @@ -1,92 +0,0 @@ -function market_performance { - g_echo_note "RUNNING FUNCTION ${FUNCNAME} $@" - - - ## function for scoring limits set in config up or down by specific (market) facts - # generates variable f_market_performance - # forecast bitcoin (is quartered because uncertain) - f_url="https://30rates.com/btc-to-usd-forecast-today-dollar-to-bitcoin" - [ -e btc-forecast ] && find btc-forecast -mmin +60 -delete - if ! [ -s btc-forecast ] - then - g_runcmd g_retrycmd curl -s "$f_url" >btc-forecast || return 1 - fi - local f_forecast=$(cat btc-forecast | hxnormalize -x | hxselect 'table' | grep "" | grep -A1 "Price" -m1 | tail -n1 | cut -d'>' -f3 | cut -d'<' -f1) - if ! echo "$f_forecast" | egrep -q '^[0-9]*\.[0-9]*$|^[0-9]*$' - then - g_echo_warn "Didn't get correct forecast from $f_url" - return 1 - fi - local f_today=$(cat btc-forecast | hxnormalize -x | hxselect 'table' | egrep '' | head -n1 | cut -d'>' -f3 | cut -d'<' -f1) - if ! echo "$f_today" | egrep -q '^[0-9]*\.[0-9]*$|^[0-9]*$' - then - g_echo_warn "Didn't get correct forecast from $f_url" - return 1 - fi - local f_btc_forecast=$(g_percentage-diff ${f_today} ${f_forecast}) - echo $f_btc_forecast | egrep -q '[0-9]\.[0-9]' || return 1 - g_echo_note "BTC forecast: $f_btc_forecast" - f_btc_forecast=$(echo "scale=2; ${f_btc_forecast}/3" | bc -l | sed -r 's/^(-?)\./\10./') - - - # forecast ethereum (is quartered because uncertain) - local f_url="https://30rates.com/ethereum-price-prediction-tomorrow-week-month-eth-forecast" - [ -e eth-forecast ] && find eth-forecast -mmin +60 -delete - if ! [ -s eth-forecast ] - then - g_runcmd g_retrycmd curl -s "$f_url" >eth-forecast || return 1 - fi - f_forecast=$(cat eth-forecast | hxnormalize -x | hxselect 'table' | grep "" | grep -A1 "Price" -m1 | tail -n1 | cut -d'>' -f3 | cut -d'<' -f1) - if ! echo "$f_forecast" | egrep -q '^[0-9]*\.[0-9]*$|^[0-9]*$' - then - g_echo_warn "Didn't get correct forecast $f_forecast from $f_url" - return 1 - fi - f_today=$(cat eth-forecast | hxnormalize -x | hxselect 'table' | egrep '' | head -n1 | cut -d'>' -f3 | cut -d'<' -f1) - if ! echo "$f_today" | egrep -q '^[0-9]*\.[0-9]*$|^[0-9]*$' - then - g_echo_warn "Didn't get correct forecast from $f_url" - return 1 - fi - local f_eth_forecast=$(g_percentage-diff ${f_today} ${f_forecast}) - echo $f_eth_forecast | egrep -q '[0-9]\.[0-9]' || return 1 - g_echo_note "ETH forecast: $f_eth_forecast" - f_eth_forecast=$(echo "scale=2; ${f_eth_forecast}/3" | bc -l | sed -r 's/^(-?)\./\10./') - - - # price performance msci world (last week and halved because of the long time) - #local f_back=240 - #[[ $(date +%u) -eq 6 ]] && f_back=1500 - #[[ $(date +%u) -eq 7 ]] && f_back=2940 - local f_from=$(tail -n 10080 asset-histories/MSCI-WORLD-INDEX.history.csv | grep -v ^[A-Z] | head -n1 | cut -d, -f2) - local f_to=$(tail -n 1 asset-histories/MSCI-WORLD-INDEX.history.csv | cut -d, -f2) - local f_exchange_rate_diff_percentage=$(g_percentage-diff ${f_from} ${f_to}) - #local f_back=10080 - #get_rate_percentage_min_before_and_now MSCI-WORLD- INDEX $f_back || return 1 - local f_msci_world_performance=$(echo "scale=2; ${f_exchange_rate_diff_percentage}/2" | bc -l | sed -r 's/^(-?)\./\10./') - - # price performance bitcoin (last 30 minutes) - local f_from=$(tail -n 30 asset-histories/BTC${CURRENCY}.history.csv | grep -v ^[A-Z] | head -n1 | cut -d, -f2) - local f_to=$(tail -n 1 asset-histories/BTC${CURRENCY}.history.csv | cut -d, -f2) - local f_exchange_rate_diff_percentage=$(g_percentage-diff ${f_from} ${f_to}) - #get_rate_percentage_min_before_and_now BTC ${CURRENCY} 360 || return 1 - local f_btc_performance=${f_exchange_rate_diff_percentage} - - # price performance ethereum (last 30 minutes) - #get_rate_percentage_min_before_and_now ETH ${CURRENCY} 360 || return 1 - local f_from=$(tail -n 30 asset-histories/ETH${CURRENCY}.history.csv | grep -v ^[A-Z] | head -n1 | cut -d, -f2) - local f_to=$(tail -n 1 asset-histories/ETH${CURRENCY}.history.csv | cut -d, -f2) - local f_exchange_rate_diff_percentage=$(g_percentage-diff ${f_from} ${f_to}) - local f_eth_performance=${f_exchange_rate_diff_percentage} - - # hourly price performance over TOP 250 marketcap by coingecko - local f_top250_marketcap_performance=$(jq -r ".[].price_change_percentage_1h_in_currency" COINGECKO_GET_ASSETS_CMD_OUT | awk '{ SUM += $1} END { printf("%.2f", SUM/250) }') - - ## calculate market performance - f_market_performance=$(echo "scale=2; (${f_btc_forecast} + ${f_eth_forecast} + ${f_msci_world_performance} + ${f_btc_performance} + ${f_eth_performance} + ${f_top250_marketcap_performance})/6" | bc -l | sed -r 's/^(-?)\./\10./') - local f_date=$(g_date_print) - echo "${f_date} Market Performance: ${f_market_performance}%; BTC forecast: ${f_btc_forecast}%; ETH forecast: ${f_eth_forecast}%; MSCI WORLD: ${f_msci_world_performance}%; BTC: ${f_btc_performance}%; ETH: ${f_eth_performance}%; TOP250 Marketcap: ${f_top250_marketcap_performance}%" >>MARKET_PERFORMANCE - echo -n "${f_market_performance}" >MARKET_PERFORMANCE_LATEST - -} - diff --git a/functions/webpage.sh b/functions/webpage.sh deleted file mode 100644 index 8cbc66b..0000000 --- a/functions/webpage.sh +++ /dev/null @@ -1,232 +0,0 @@ -function webpage { - - - g_echo_note "RUNNING FUNCTION ${FUNCNAME} $@" - # create status webpage - echo ' - - - - -Statuspage Crypto Bot -' >../index.html.tmp - echo "

Statuspage Crypto Bot (ReadOnly)

-

Last update $(date "+%F %T")

" >>../index.html.tmp - - - local f_SPOT_BALANCE=$(tail -n1 "asset-histories/BALANCESPOT${CURRENCY}.history.csv" | cut -d, -f2) - local f_COMPLETE_BALANCE=$(tail -n1 "asset-histories/BALANCECOMPLETE${CURRENCY}.history.csv" | cut -d, -f2) - echo '

Overview

' >>../index.html.tmp - echo " - - - - - - - - - - - - -
Overall Balance:${CURRENCY} ${f_COMPLETE_BALANCE}
SPOT Balance (invested):${CURRENCY} $f_SPOT_BALANCE
Free Balance (not invested):${CURRENCY} ${CURRENCY_BALANCE}
" >>../index.html.tmp - - echo "

Trade Performance (overall closed trades)

" >>../index.html.tmp - - echo " - - - - - - - - - - - - - - - - -
Performance day (last 24 hours): $(find trade-histories -name "*-closed.history.csv.result" -mtime -1 -exec cat {} \; | awk '{ SUM += $1} END { printf("%.2f", SUM) }')%
Performance week (last 7 days): $(find trade-histories -name "*-closed.history.csv.result" -mtime -7 -exec cat {} \; | awk '{ SUM += $1} END { printf("%.2f", SUM) }')%
Performance month (last 30 days): $(find trade-histories -name "*-closed.history.csv.result" -mtime -31 -exec cat {} \; | awk '{ SUM += $1} END { printf("%.2f", SUM) }')%
Performance complete): $(find trade-histories -name "*-closed.history.csv.result" -exec cat {} \; | awk '{ SUM += $1} END { printf("%.2f", SUM) }')%
" >>../index.html.tmp - - - echo '

Open Trades (Invested Assets)

' >>../index.html.tmp - echo "" >>../index.html.tmp - local line - cat EXCHANGE_GET_BALANCES_CMD_OUT | grep -v ${CURRENCY} | sort | while read line - do - local spot_balances=($(echo $line | sed 's/,/ /g')) - echo " - - - - " >>../index.html.tmp - done - echo "
${spot_balances[0]} πŸ”—${spot_balances[1]}${CURRENCY} ${spot_balances[2]} ( $(cat DIFF_BUY_PRICE_${spot_balances[0]}${CURRENCY})%)
" >>../index.html.tmp - - echo "

Market Performance ( $(cat MARKET_PERFORMANCE_LATEST)%)

" >>../index.html.tmp - echo -e "
$(egrep ":00:" MARKET_PERFORMANCE | tail -n10)\n$(tail -n1 MARKET_PERFORMANCE)
" >>../index.html.tmp - echo "Complete list" >>../index.html.tmp - - echo '

Latest trades

' >>../index.html.tmp - echo '

Open

' >>../index.html.tmp - - echo "" >>../index.html.tmp - echo " - - - - - - " >>../index.html.tmp - - local f_trade_file - for f_trade_file in $(ls -t trade-histories/trade-*-open.history.csv 2>/dev/null) - do - local tradeline=$(tail -n1 ${f_trade_file}) - local asset=$(echo ${f_trade_file} | cut -d. -f3 | cut -d- -f1) - echo " - - - - - - - " >>../index.html.tmp - done - echo "
DateAssetAction${CURRENCY} Quantity${CURRENCY} PriceCommissionComment
$(echo ${tradeline} | cut -d, -f1)${asset} πŸ”—$(echo ${tradeline} | cut -d, -f2)$(echo ${tradeline} | cut -d, -f4)$(echo ${tradeline} | cut -d, -f5)$(echo ${tradeline} | cut -d, -f6)$(echo ${tradeline} | cut -d, -f7,8,9,10,11,12,13,14,15)
" >>../index.html.tmp - - echo '

Closed

' >>../index.html.tmp - - echo "" >>../index.html.tmp - echo " - - - - - - " >>../index.html.tmp - - for f_trade_file in $(ls -t trade-histories/trade-*-closed.history.csv 2>/dev/null | head -n 50) - do - local tradeline - cat ${f_trade_file} | while read tradeline - do - local f_action=$(echo ${tradeline} | cut -d, -f2) - local f_price=$(echo ${tradeline} | cut -d, -f5) - - if echo ${f_action} | grep -q buy - then - echo ${f_price} >${g_tmp}/buyprice - fi - - if echo ${f_action} | grep -q sell - then - if [ -s "${f_trade_file}.result" ] - then - local f_profit=$(cat "${f_trade_file}.result") - f_price="${f_price} ( ${f_profit}%)" - else - local f_profit=$(g_percentage-diff $(cat ${g_tmp}/buyprice) ${f_price}) - f_price="${f_price} ( ${f_profit}%)" - echo "${f_profit}" >"${f_trade_file}.result" - fi - fi - local asset=$(echo ${f_trade_file} | cut -d. -f3 | cut -d- -f1) - echo " - - - - - - - " >>../index.html.tmp - done - done - echo "
DateAssetAction${CURRENCY} Quantity${CURRENCY} Price (result)CommissionComment
$(echo ${tradeline} | cut -d, -f1)${asset} πŸ”—${f_action}$(echo ${tradeline} | cut -d, -f4)${f_price}$(echo ${tradeline} | cut -d, -f6)$(echo ${tradeline} | cut -d, -f7,8,9,10,11,12,13,14,15)
" >>../index.html.tmp - - - -# echo "" >>../index.html.tmp -# echo " -# -# -# -# -# -# " >>../index.html.tmp -# grep ^20 trade-histories/*history.csv | sed 's/\// /; s/\./ /; s/:/ /; s/,/ /g' | sort -r -k3 >${g_tmp}/trade-hist-complete -# local tradeline -# cat ${g_tmp}/trade-hist-complete | while read tradeline -# do -# # use array trade -# local trade=($tradeline) -# local f_trace_price=${trade[8]} -# if [ ${trade[4]} = "sell" ] -# then -# local f_trade_date=${trade[3]} -# local f_trade_currency=${trade[1]} -# local f_trade_sell_for=${trade[6]} -# local f_trade_buy_for=$(grep -B1 "^${f_trade_date},sell," "trade-histories/${f_trade_currency}.history.csv" | grep ",buy," | cut -d, -f4 | cut -d" " -f1) -# local f_result=$(echo "scale=2; ${f_trade_sell_for}-$f_trade_buy_for" | bc -l | sed 's/^\./0./; s/^-\./-0./' | xargs printf "%.2f") -# local f_result_percentage=$(g_percentage-diff $f_trade_buy_for ${f_trade_sell_for}) -# f_trace_price="$f_trace_price ($f_result( ${f_result_percentage}%))" -# #echo "${trade[1]} $f_trade_buy_for -- ${f_trade_sell_for} == $f_result(${f_result_percentage}%)" -# fi -# echo " -# -# -# -# -# -# -# " >>../index.html.tmp -# -# done -# echo "
DateAssetAction${CURRENCY} Quantity${CURRENCY} Price (profit/loss)CommissionComment
${trade[3]}${trade[1]} πŸ”—${trade[4]}${trade[6]}${f_trace_price}${trade[9]} ${trade[10]}${trade[@]:11:30}
" >>../index.html.tmp - - - - - - echo "

Current config

" >>../index.html.tmp - echo "
$(cat ../../bot.conf | perl -pe 's/\/>/g;')
" >>../index.html.tmp - - - - echo '

Available Assets and histories

' >>../index.html.tmp - echo "" >>../index.html.tmp - echo "" >>../index.html.tmp - local asset - cat ASSETS | egrep -v "${BLACKLIST}" | sort | while read asset - do - [ -s asset-histories/${asset}.history.csv ] || continue - echo "" >>../index.html.tmp - kcurrency=$(echo ${asset} | sed "s/${CURRENCY}//") - #get_rate_percentage_min_before_and_now ${kcurrency} ${CURRENCY} 1440 - local asset=($(cat asset-histories/${asset}.history.csv | egrep -v "0.00000000$" | tail -n2 | head -n1 | sed 's/,/ /g')) - echo " - - - - " >>../index.html.tmp - done - echo "
AssetDatePrice ${CURRENCY}24h change (USD)
${asset} πŸ”—${asset[0]} ${asset[1]}${CURRENCY} ${asset[2]} $(grep "^$kcurrency," ASSET_PRICE_CHANGE_PERCENTAGE_24H | cut -d, -f2)%
" >>../index.html.tmp - - echo '

Complete trading histories

' >>../index.html.tmp - echo "" >>../index.html.tmp - find trade-histories -type f -name *.history.csv | cut -d/ -f2 | cut -d. -f1 | sort | while read asset - do - [ -s trade-histories/${asset}.history.csv ] || continue - echo "" >>../index.html.tmp - done - echo "
${asset} πŸ”—
" >>../index.html.tmp - - # color magic - cat ../index.html.tmp | perl -pe 's/ (\-[0-9]+\.[0-9]+\%)/$1<\/font>/g; s/ ([0-9]+\.[0-9]+\%)/$1<\/font>/g;' >../index.html - #mv ../index.html.tmp ../index.html -} diff --git a/htdocs/browser.css b/htdocs/browser.css deleted file mode 100644 index 9e2b86b..0000000 --- a/htdocs/browser.css +++ /dev/null @@ -1,217 +0,0 @@ - -.container { position:relative; margin:0 auto; width:959px; } -.column { width:100%; } - - -/* Mobile (Portrait) -================================================== */ - -@media only screen and (max-width: 767px) { -.container { width:100%; } -} - - -/* CSS Reset -================================================== */ - -html,body,div,span,h1,h6,p,a,ul,li,audio { -border:0; -font:inherit; -font-size:25px; -margin:0; -padding:0; -vertical-align:baseline; -} - -body { line-height:1; } -/* ul { list-style:none; } - - -/* Basic Styles -================================================== */ - -html,body { -background-color:#000000; -color:#808080; -font:24px Helvetica, Arial, sans-serif; -font-weight:300; -padding:5px 0; -} - - -/* Typography -================================================== */ - -h1 { font-size:42px; line-height:44px; margin:20px 0 0; text-align: center; font-weight: bold; text-decoration:underline; } -h2 { font-size:32px; line-height:44px; margin:20px 0 0; text-align: left; font-weight: bold; } - -/* Links -================================================== */ - -a,a:visited { color:#808080; outline:0; text-decoration:none; } -a:hover,a:focus,li:hover,li:focus,label:hover { color:#bbb; } -p a,p a:visited { line-height:inherit; } - - -/* Misc. -================================================== */ - -.add-bottom { margin-bottom:20px !important; } -.left { float:left; } -.right { float:right; } -.center { text-align:center; } - - - -/* Audio Player Styles -================================================== */ - -/* Default / Desktop / Firefox */ -audio { margin:0 15px 0 14px; width:670px; } -#mainwrap { box-shadow:0 0 6px 1px rgba(0,0,0,.25); } -#audiowrap { background-color:#111111; margin:0 auto; } -#plwrap { margin:0 auto; } -#tracks { position:relative; text-align:center; } -#nowPlay { display:inline; } -#npTitle { margin:0; padding:21px; text-align:right; } -#npAction { padding:21px; position:absolute; } -#plList { margin:0; } -#plList li { background-color:#111111; cursor:pointer; display:block; margin:0; padding:10px 0; } -.plItem { position:relative; } -.plTitle { left:38px; overflow:hidden; position:absolute; right:1px; text-overflow:ellipsis; top:0; white-space:nowrap; } -.plNum { padding-left:2px; width:25px; } -.plLength { padding-left:21px; position:absolute; right:21px; top:0; } -.plSel,.plSel:hover { background-color:#222222!important; cursor:default!important; } -a[id^="btn"] { background-color:#111111; cursor:pointer; display:inline-block; font-size:50px; margin:0; padding:21px 27px; text-decoration:none; } -a[id^="btn"]:last-child { margin-left:-4px; } -a[id^="btn"]::-moz-focus-inner { border:0; padding:0; } - -/* Chrome / Android / Tablet -html[data-useragent*="Chrome"][data-useragent*="Android"] body { color:#373837; } -html[data-useragent*="Chrome"][data-useragent*="Android"] audio { margin-left:4px; width:689px; } -html[data-useragent*="Chrome"][data-useragent*="Android"] #audiowrap { background-color:#fafafa; } -html[data-useragent*="Chrome"][data-useragent*="Android"] a[id^="btn"] { background-color:#fafafa; color:#373837; } -html[data-useragent*="Chrome"][data-useragent*="Android"] a[id^="btn"]:hover { background-color:#eee; } -html[data-useragent*="Chrome"][data-useragent*="Android"] #plList li { background-color:#fafafa; } -html[data-useragent*="Chrome"][data-useragent*="Android"] #plList li:hover { background-color:#eee; } -html[data-useragent*="Chrome"][data-useragent*="Android"] .plSel, -html[data-useragent*="Chrome"][data-useragent*="Android"] .plSel:hover { background-color:#eee!important; } -*/ - -/* Audio Player Media Queries -================================================== */ - -/* Tablet Portrait -@media only screen and (min-width: 768px) and (max-width: 959px) { -audio { width:526px; } -html[data-useragent*="MSIE 9.0"] audio { width:536px; } -html[data-useragent*="MSIE 10.0"] audio { width:543px; } -html[data-useragent*="rv:11.0"] audio { width:551px; } -html[data-useragent*="OS 7"] audio { width:546px; } -html[data-useragent*="OS 8"] audio { width:550px; } -html[data-useragent*="OS 9"] audio { width:550px; } -html[data-useragent*="Chrome"] audio { width:533px; } -html[data-useragent*="Chrome"][data-useragent*="Android"] audio { margin-left:4px; width:545px; } -} - -/* Mobile Landscape -@media only screen and (min-width: 480px) and (max-width: 767px) { -audio { width:390px; } -html[data-useragent*="MSIE 9.0"] audio { width:400px; } -html[data-useragent*="MSIE 10.0"] audio { width:407px; } -html[data-useragent*="rv:11.0"] audio { width:415px; } -html[data-useragent*="OS 7"] audio { width:410px; } -html[data-useragent*="OS 8"] audio { width:414px; } -html[data-useragent*="OS 9"] audio { width:414px; } -html[data-useragent*="Chrome"] audio { width:397px; } -html[data-useragent*="Chrome"][data-useragent*="Mobile"] audio { margin-left:4px; width:410px; } -#npTitle { width:245px; } -} - -/* Mobile Portrait -@media only screen and (max-width: 479px) { -audio { width:270px; } -html[data-useragent*="MSIE 9.0"] audio { width:280px; } -html[data-useragent*="MSIE 10.0"] audio { width:287px; } -html[data-useragent*="rv:11.0"] audio { width:295px; } -html[data-useragent*="OS 7"] audio { width:290px; } -html[data-useragent*="OS 8"] audio { width:294px; } -html[data-useragent*="OS 9"] audio { width:294px; } -html[data-useragent*="Chrome"] audio { width:277px; } -html[data-useragent*="Chrome"][data-useragent*="Mobile"] audio { margin-left:4px; width:290px; } -#npTitle { width:167px; } -} -*/ - -audio { width:92%; } - -/* z.B. für VPN Login */ -input { - width: 100%; - font-size:25px; - padding: 12px 20px; - margin: 8px 0; - box-sizing: border-box; - border: 4px solid #808080; - background-color: #222222; - color: #808080; -} - -textarea { - width: 100%; - height: 500px; - font-size:12px; - padding: 12px 20px; - margin: 8px 0; - box-sizing: border-box; - border: 4px solid #808080; - background-color: #222222; - color: #808080; -} - -pre,#footer { - font:16px sans-serif; -} - -.statusok { - font:18px sans-serif; - background-color: #00BF40; - color: black; -} - -.statusnok { - font:18px sans-serif; - background-color: #E10020; - color: black; -} - -/*Ausblenden des input-Feldes */ -.toggleBox input[type="checkbox"] { - position: absolute; - left: -99999px; -} -/* Der Aufklappmechanismus */ -.toggleBox input:checked ~ div { - opacity: 0; - height: 0; - display: none; -} - -.toggleBox input:not(:checked) ~ div { - opacity: 1; -} - -/* Steuerung der Sichtbarkeit der labels */ -.toggleBox input:not(:checked) ~ .open, -.toggleBox input:checked ~ .close { - display: none; -} - -tr:hover {background-color: coral;} - -table, th, td { - border: 1px solid; - border-collapse: collapse; - padding: 5px; -} -