197 lines
6.2 KiB
Bash
197 lines
6.2 KiB
Bash
#!/bin/bash
|
|
|
|
# Copyright (c) 2022-2024 olli
|
|
#
|
|
# This file is part of dabo (crypto bot).
|
|
#
|
|
# dabo is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# dabo is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with dabo. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
function order {
|
|
# Info for log
|
|
g_echo_note "RUNNING FUNCTION ${FUNCNAME} $@"
|
|
|
|
# needed vars
|
|
local f_symbol=$1
|
|
local f_amount=$2 # amount in $CURRENCY / if crypto_amount:XXX then amount in crypto
|
|
local f_side=$3 # buy/sell long/short
|
|
local f_price=$4 # price for limit order - if "0" do market order - "stoploss" for pure StopLoss Order and "takeprofit" for pure TakeProfit Order
|
|
local f_stoploss=$5
|
|
local f_takeprofit=$6
|
|
local f_params="params={"
|
|
local f_type f_side_opposite
|
|
|
|
### validity checks ###
|
|
|
|
# check symbol XXX/$CURRENCY[:$CURRENCY]
|
|
[[ $f_symbol =~ /$CURRENCY ]] || return 1
|
|
|
|
# check side
|
|
if [ "$f_side" = "long" ] || [ "$f_side" = "buy" ]
|
|
then
|
|
f_side="buy"
|
|
f_pos_side="Long"
|
|
f_side_opposide="sell"
|
|
fi
|
|
if [ "$f_side" = "short" ] || [ "$f_side" = "sell" ]
|
|
then
|
|
f_side="sell"
|
|
f_pos_side="Short"
|
|
f_side_opposide="buy"
|
|
fi
|
|
[[ $f_side =~ ^buy$|^sell$ ]] || return 1
|
|
|
|
# check order type limit/market
|
|
if [[ $f_price = 0 ]]
|
|
then
|
|
f_type="market"
|
|
#elif [[ $f_price = stoploss ]] || [[ $f_price = takeprofit ]]
|
|
#then
|
|
# f_price="None"
|
|
else
|
|
f_type="limit"
|
|
fi
|
|
|
|
### validity checks end ###
|
|
|
|
|
|
# check for swap/margin trades
|
|
if [ -n "$LEVERAGE" ]
|
|
then
|
|
# do some margin things
|
|
|
|
# check for CCXT swap symbol :$CURRENCY
|
|
[[ $f_symbol =~ : ]] || f_symbol="$f_symbol:$CURRENCY"
|
|
|
|
# set position mode
|
|
f_ccxt "$STOCK_EXCHANGE.setPositionMode(hedged=False, symbol='$f_symbol')" || return 1
|
|
|
|
# set leverage
|
|
f_ccxt "$STOCK_EXCHANGE.setLeverage($LEVERAGE, '$f_symbol')" || return 1
|
|
|
|
# define margin mode isolated/cross
|
|
#[[ $f_type =~ limit|market ]] &&
|
|
f_params="${f_params}'marginMode': '$MARGIN_MODE', "
|
|
|
|
# calculate amount with leverage
|
|
g_calc "${f_amount}*${LEVERAGE}"
|
|
f_amount=$g_calc_result
|
|
else
|
|
# short/sell not possible in spot market
|
|
[[ $f_side =~ ^sell$ ]] || return 1
|
|
fi
|
|
|
|
|
|
# get amount in crypto asset
|
|
if [[ $f_amount =~ ^crypto_amount: ]]
|
|
then
|
|
# if given in crypto
|
|
f_amount=${f_amount//crypto_amount:}
|
|
else
|
|
# on market order use current price
|
|
if [[ $f_type = market ]]
|
|
then
|
|
# if given in $CURRENCY
|
|
local f_asset=${f_symbol///*}
|
|
currency_converter $f_amount $CURRENCY $f_asset || return 1
|
|
f_amount=$f_currency_converter_result
|
|
# on limit order use limit price
|
|
elif [[ $f_type = limit ]]
|
|
then
|
|
g_calc "1/${f_price}*${f_amount}"
|
|
f_amount=$g_calc_result
|
|
fi
|
|
fi
|
|
|
|
|
|
# Add stoploss and take profit if available
|
|
if [ -n "$f_stoploss" ]
|
|
then
|
|
if [[ $f_type = limit ]]
|
|
then
|
|
# check for long
|
|
if [[ $f_side = buy ]] && g_num_is_higher_equal $f_stoploss $f_price
|
|
then
|
|
g_echo_warn "Long Order not possible: Stoploss ($f_stoploss) higher then buy price ($f_price)"
|
|
return 1
|
|
fi
|
|
# check for short
|
|
if [[ $f_side = sell ]] && g_num_is_lower_equal $f_stoploss $f_price
|
|
then
|
|
g_echo_warn "Short Order not possible: Stoploss ($f_stoploss) lower then buy price ($f_price)"
|
|
return 1
|
|
fi
|
|
fi
|
|
f_ccxt "print($STOCK_EXCHANGE.priceToPrecision('${f_symbol}', ${f_stoploss}))"
|
|
f_stoploss=$f_ccxt_result
|
|
# market or limit order with stoploss
|
|
if [[ $f_type =~ limit|market ]]
|
|
then
|
|
f_params="${f_params}'stopLoss': { 'triggerPrice': $f_stoploss, 'type': 'market' }, "
|
|
# stoploss (change) for open position
|
|
elif [[ $f_price = "stoploss" ]]
|
|
then
|
|
f_params="${f_params}'reduceOnly': True, 'triggerPrice': $f_stoploss, 'triggerDirection': 'down', 'type': 'market, '"
|
|
fi
|
|
fi
|
|
if [ -n "$f_takeprofit" ]
|
|
then
|
|
# check for long
|
|
if [[ $f_type = limit ]]
|
|
then
|
|
if [[ $f_side = buy ]] && g_num_is_lower_equal $f_takeprofit $f_price
|
|
then
|
|
g_echo_warn "Long Order not possible:TakeProfit ($f_takeprofit) lower then buy price ($f_price)"
|
|
return 1
|
|
fi
|
|
# check for short
|
|
if [[ $f_side = sell ]] && g_num_is_higher_equal $f_takeprofit $f_price
|
|
then
|
|
g_echo_warn "Short Order not possible:TakeProfit ($f_takeprofit) higher then buy price ($f_price)"
|
|
return 1
|
|
fi
|
|
fi
|
|
f_ccxt "print($STOCK_EXCHANGE.priceToPrecision('${f_symbol}', ${f_takeprofit}))"
|
|
f_takeprofit=$f_ccxt_result
|
|
[[ $f_type =~ limit|market ]] && f_params="${f_params}'takeProfit': { 'triggerPrice': $f_takeprofit, 'type': 'limit', 'price': $f_takeprofit, }, "
|
|
[[ $f_price = "takeprofit" ]] && f_params="${f_params}'stopPx': '$f_takeprofit', "
|
|
fi
|
|
|
|
# end up params syntax with "}"
|
|
f_params="${f_params}}"
|
|
|
|
# calculate price amount precision
|
|
f_ccxt "print($STOCK_EXCHANGE.amountToPrecision('${f_symbol}', ${f_amount}))"
|
|
f_amount=$f_ccxt_result
|
|
if [[ $f_type = limit ]]
|
|
then
|
|
f_ccxt "print($STOCK_EXCHANGE.priceToPrecision('${f_symbol}', ${f_price}))"
|
|
f_price=$f_ccxt_result
|
|
fi
|
|
|
|
# do the order
|
|
[[ $f_type = limit ]] && local f_order="symbol='${f_symbol}', type='$f_type', price=$f_price, amount=${f_amount}, side='${f_side}', ${f_params}"
|
|
[[ $f_type = market ]] && local f_order="symbol='${f_symbol}', type='$f_type', amount=${f_amount}, side='${f_side}', ${f_params}"
|
|
[[ $f_type = Stop ]] && local f_order="symbol='${f_symbol}', type='$f_type', amount='0', side='${f_side_opposide}', price='None', ${f_params}"
|
|
echo "$f_order" | notify.sh -s "ORDER"
|
|
f_ccxt "print($STOCK_EXCHANGE.createOrder(${f_order}))" || return 1
|
|
|
|
# refresh orders and positions
|
|
get_orders "$f_symbol"
|
|
get_positions
|
|
get_position_array
|
|
get_orders_array
|
|
}
|
|
|