Mizar_Library
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// Mizar Library to send JSON commands to DCA bots
// version 1.0 - May 2023
// Intellectual property © Mizar.com

// Mizar public library

//@version=5

// @description Provides general functions to use Mizar DCA bot system
library("Mizar_Library", overlay = true)

// ************************************
// **         BOT functions			***
// ************************************

// @type Bot_params
export type bot_params
    string bot_id       = "#nil"
    string api_key      = "#nil"
    string action       = "open"
    string tp_perc      = "#nil"
    string base_asset   = "#nil"
    string quote_asset  = "USDT"
    string direction    = "#nil"

// @function DCA_bot_msg
// @param _cmd 		    	::: the user-defined type [UDT] with all the info for the bot command
// @param - bot_id 			::: the BOT ID number from your Mizar bot
// @param - api_key 		::: your private (do not share!) API key from your Mizar account
// @param - action 			::: the command to perform: "open" [standard] or "close"
// @param - tp_perc 		::: the target price in percentage (1% = "0.01")
// @param - base_asset 		::: the coin you want to buy (e.g. "BTC")
// @param - quote_asset		::: the coin with which you want to pay (e.g. "USDT" [standard])
// @param - direction     	::: the direction of the position: "long" or "short"
// @returns A string with the complete JSON command for a Mizar DCA bot.
export DCA_bot_msg(bot_params _cmd) =>
    string _msg = '{ "bot_id": "' + _cmd.bot_id + '", "api_key": "' + _cmd.api_key + '", "base_asset": "' + _cmd.base_asset + '", "quote_asset": "' + _cmd.quote_asset + '", "action": "' + _cmd.action + "-position"

    if _cmd.tp_perc != "#nil"
        _msg += '", "take_profit_pct": "' + _cmd.tp_perc

    if _cmd.direction != "#nil"
        _msg += '", "side": "' + _cmd.direction

    _msg += '" }'


// ************************************
// **      Support functions		***
// ************************************

// @function rounding_to_ticks
// @param value 		::: the calculated price as float type, which should be rounded to the next real price
// @param ticks		 	::: the smallest possible price (you get via request in your script)
// @param rounding_type	::: 0 = closest real price, 1 = closest real price above, 2 = closest real price below
// @returns A float with the rounded value to the next tick.
export rounding_to_ticks(float value, float ticks, int rounding_type) =>
    float fun_return    = na
    int factor          = na

    float sym_in_ticks  = math.round(value/ticks, 0)

    if sym_in_ticks * ticks > value
        factor := 0
    else
        factor := 1
    
    if rounding_type != 1 and rounding_type != 2            // Standard rounding to closest CEX tick
        fun_return := sym_in_ticks * ticks

    if rounding_type == 1                                   // Rounding to the next CEX tick above the calculated price
        fun_return := (sym_in_ticks + factor) * ticks
    
    if rounding_type == 2                                   // Rounding to the next CEX tick below the calculated price
        fun_return := (sym_in_ticks - 1 + factor) * ticks
    
    fun_return