dockerizing

This commit is contained in:
olli 2023-05-02 10:49:04 +02:00
parent 8940810ac6
commit 242bfa6a99
29 changed files with 31 additions and 2582 deletions

View File

@ -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"]

View File

@ -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.

View File

@ -1,5 +0,0 @@
ANALYZE_TIME="^2023-04-17"
. bot.conf

View File

@ -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

View File

@ -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"

View File

@ -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&quoteOrderQty=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

View File

@ -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

View File

@ -1,4 +0,0 @@
#!/bin/bash
sleep 999999999
binance-cli $@

View File

@ -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
}

View File

@ -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}&timestamp=${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
}

View File

@ -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 \"&quoteId=\${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
}

View File

@ -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 "&quoteId=${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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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}
}

View File

@ -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
}

View File

@ -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}"
}

View File

@ -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
}

View File

@ -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}%"
}

View File

@ -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]})"
}

View File

@ -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 "<strong>" | 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 '<strong>' | 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 "<strong>" | 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 '<strong>' | 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
}

View File

@ -1,232 +0,0 @@
function webpage {
g_echo_note "RUNNING FUNCTION ${FUNCNAME} $@"
# create status webpage
echo '<html><head>
<meta charset="UTF-8">
<meta http-equiv="refresh" content="60" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="/browser.css">
<title>Statuspage Crypto Bot</title>
</head><body>' >../index.html.tmp
echo "<h1>Statuspage Crypto Bot (ReadOnly)</h1>
<h1>Last update $(date "+%F %T")</h1>" >>../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 '<h2>Overview</h2>' >>../index.html.tmp
echo "<table>
<tr>
<td><b>Overall Balance:</b></td>
<td><font color=green><b>${CURRENCY} ${f_COMPLETE_BALANCE}</b></font></td>
</td>
<tr>
<td>SPOT Balance (invested):</td>
<td><font color=blue>${CURRENCY} $f_SPOT_BALANCE</font></td>
</tr>
<tr>
<td>Free Balance (not invested):</td>
<td><font color=yellow>${CURRENCY} ${CURRENCY_BALANCE}</font></td>
</tr>
</table>" >>../index.html.tmp
echo "<h2>Trade Performance (overall closed trades)</h2>" >>../index.html.tmp
echo "<table>
<tr>
<td>Performance day (last 24 hours):</td>
<td> $(find trade-histories -name "*-closed.history.csv.result" -mtime -1 -exec cat {} \; | awk '{ SUM += $1} END { printf("%.2f", SUM) }')%</td>
</td>
<tr>
<td>Performance week (last 7 days):</td>
<td> $(find trade-histories -name "*-closed.history.csv.result" -mtime -7 -exec cat {} \; | awk '{ SUM += $1} END { printf("%.2f", SUM) }')%</td>
</tr>
<tr>
<td>Performance month (last 30 days):</td>
<td> $(find trade-histories -name "*-closed.history.csv.result" -mtime -31 -exec cat {} \; | awk '{ SUM += $1} END { printf("%.2f", SUM) }')%</td>
</tr>
<tr>
<td>Performance complete):</td>
<td> $(find trade-histories -name "*-closed.history.csv.result" -exec cat {} \; | awk '{ SUM += $1} END { printf("%.2f", SUM) }')%</td>
</tr>
</table>" >>../index.html.tmp
echo '<h2>Open Trades (Invested Assets)</h2>' >>../index.html.tmp
echo "<table>" >>../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 "<tr>
<td><a href=\"botdata/asset-histories/${spot_balances[0]}${CURRENCY}.history.csv\">${spot_balances[0]}</a> <a href=\"https://www.coingecko.com/de/munze/$(egrep -i ^$(echo ${spot_balances[0]} | sed "s/${CURRENCY}$//"), COINGECKO_IDS | cut -d, -f2 )\">🔗</a></td>
<td>${spot_balances[1]}</td>
<td>${CURRENCY} ${spot_balances[2]} ( $(cat DIFF_BUY_PRICE_${spot_balances[0]}${CURRENCY})%)</td>
</tr>" >>../index.html.tmp
done
echo "</table>" >>../index.html.tmp
echo "<h2>Market Performance ( $(cat MARKET_PERFORMANCE_LATEST)%)</h2>" >>../index.html.tmp
echo -e "<pre>$(egrep ":00:" MARKET_PERFORMANCE | tail -n10)\n$(tail -n1 MARKET_PERFORMANCE)</pre>" >>../index.html.tmp
echo "<a href=\"botdata/MARKET_PERFORMANCE\">Complete list</a>" >>../index.html.tmp
echo '<h2>Latest trades</h2>' >>../index.html.tmp
echo '<h3>Open</h3>' >>../index.html.tmp
echo "<table><tr>" >>../index.html.tmp
echo "<td>Date</td>
<td>Asset</td>
<td>Action</td>
<td>${CURRENCY} Quantity</td>
<td>${CURRENCY} Price</td>
<td>Commission</td>
<td>Comment</td></tr>" >>../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 "<td>$(echo ${tradeline} | cut -d, -f1)</td>
<td><a href=\"botdata/asset-histories/${asset}.history.csv\">${asset}</a> <a href=\"https://www.coingecko.com/de/munze/$(egrep -i ^$(echo ${asset} | sed "s/${CURRENCY}$//"), COINGECKO_IDS | cut -d, -f2 )\">🔗</a></td>
<td>$(echo ${tradeline} | cut -d, -f2)</td>
<td>$(echo ${tradeline} | cut -d, -f4)</td>
<td>$(echo ${tradeline} | cut -d, -f5)</td>
<td>$(echo ${tradeline} | cut -d, -f6)</td>
<td>$(echo ${tradeline} | cut -d, -f7,8,9,10,11,12,13,14,15)</td>
</tr>" >>../index.html.tmp
done
echo "</table>" >>../index.html.tmp
echo '<h3>Closed</h3>' >>../index.html.tmp
echo "<table><tr>" >>../index.html.tmp
echo "<td>Date</td>
<td>Asset</td>
<td>Action</td>
<td>${CURRENCY} Quantity</td>
<td>${CURRENCY} Price (result)</td>
<td>Commission</td>
<td>Comment</td></tr>" >>../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 "<td>$(echo ${tradeline} | cut -d, -f1)</td>
<td><a href=\"botdata/asset-histories/${asset}.history.csv\">${asset}</a> <a href=\"https://www.coingecko.com/de/munze/$(egrep -i ^$(echo ${asset} | sed "s/${CURRENCY}$//"), COINGECKO_IDS | cut -d, -f2 )\">🔗</a></td>
<td>${f_action}</td>
<td>$(echo ${tradeline} | cut -d, -f4)</td>
<td>${f_price}</td>
<td>$(echo ${tradeline} | cut -d, -f6)</td>
<td>$(echo ${tradeline} | cut -d, -f7,8,9,10,11,12,13,14,15)</td>
</tr>" >>../index.html.tmp
done
done
echo "</table>" >>../index.html.tmp
# echo "<table><tr>" >>../index.html.tmp
# echo "<td>Date</td>
# <td>Asset</td>
# <td>Action</td>
# <td>${CURRENCY} Quantity</td>
# <td>${CURRENCY} Price (profit/loss)</td>
# <td>Commission</td>
# <td>Comment</td></tr>" >>../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 "<td>${trade[3]}</td>
# <td><a href=\"botdata/asset-histories/${trade[1]}.history.csv\">${trade[1]}</a> <a href=\"https://www.coingecko.com/de/munze/$(egrep -i ^$(echo ${trade[1]} | sed "s/${CURRENCY}$//"), COINGECKO_IDS | cut -d, -f2 )\">🔗</a></td>
# <td>${trade[4]}</td>
# <td>${trade[6]}</td>
# <td>${f_trace_price}</td>
# <td>${trade[9]} ${trade[10]}</td>
# <td>${trade[@]:11:30}</td>
# </tr>" >>../index.html.tmp
#
# done
# echo "</table>" >>../index.html.tmp
echo "<h2>Current config</h2>" >>../index.html.tmp
echo "<pre>$(cat ../../bot.conf | perl -pe 's/\</&#60;/g; s/\>/&#62;/g;')</pre>" >>../index.html.tmp
echo '<h2>Available Assets and histories</h2>' >>../index.html.tmp
echo "<table><tr>" >>../index.html.tmp
echo "<tr><td>Asset</td><td>Date</td><td>Price ${CURRENCY}</td><td>24h change (USD)</td></tr>" >>../index.html.tmp
local asset
cat ASSETS | egrep -v "${BLACKLIST}" | sort | while read asset
do
[ -s asset-histories/${asset}.history.csv ] || continue
echo "<td><a href=\"botdata/asset-histories/${asset}.history.csv\">${asset}</a> <a href=\"https://www.coingecko.com/de/munze/$(egrep -i ^$(echo ${asset} | sed "s/${CURRENCY}$//"), COINGECKO_IDS | cut -d, -f2 )\">🔗</a></td>" >>../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 "
<td>${asset[0]} ${asset[1]}</td>
<td>${CURRENCY} ${asset[2]}</td>
<td> $(grep "^$kcurrency," ASSET_PRICE_CHANGE_PERCENTAGE_24H | cut -d, -f2)%</td>
</tr>" >>../index.html.tmp
done
echo "</table>" >>../index.html.tmp
echo '<h2>Complete trading histories</h2>' >>../index.html.tmp
echo "<table>" >>../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 "<tr><td><a href=\"botdata/trade-histories/${asset}.history.csv\">${asset}</a> <a href=\"https://www.coingecko.com/de/munze/$(egrep -i ^$(echo ${asset} | sed "s/${CURRENCY}$//"), COINGECKO_IDS | cut -d, -f2 )\">🔗</a></td></tr>" >>../index.html.tmp
done
echo "</table>" >>../index.html.tmp
# color magic
cat ../index.html.tmp | perl -pe 's/ (\-[0-9]+\.[0-9]+\%)/<font color=red>$1<\/font>/g; s/ ([0-9]+\.[0-9]+\%)/<font color=green>$1<\/font>/g;' >../index.html
#mv ../index.html.tmp ../index.html
}

View File

@ -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;
}