TradingHook
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © dokang

//@version=5

// @description This library is a client script for making a webhook signal formatted string to TradingHook webhook server.
library("TradingHook", overlay = true)

 
check_exchange(string exchange) =>
    var supported_exchanges = array.from("UPBIT", "BINANCE", "BITGET")
    if not array.includes(supported_exchanges, exchange)
        runtime.error(exchange+"is not supported.")

check_exchange_support_amount_order(string exchange) =>
    var supported_exchanges = array.from("BINANCE")
    if not array.includes(supported_exchanges, exchange)
        runtime.error(exchange+"is not supported.")
        
check_exchange_support_cost_order(string exchange) =>
    var supported_exchanges = array.from("UPBIT")
    if not array.includes(supported_exchanges, exchange)
        runtime.error(exchange+"is not supported.")
check_futures(string ticker) =>
    if not str.endswith(ticker, "PERP")
	    runtime.error("Function entry_message() is only supported in Futures ticker")

is_futures(string ticker) =>
    if str.endswith(ticker, "PERP")
	    true
	else
	    false

// @function            Make a buy Message for TradingHook. 
// @param password      (string) [Required] password that you set in .env file.
// @param amount        (float)  [Optional] amount. If not set, your strategy qty will be sent.
// @param order_name    (string)  [Optional] order_name. The default name is "Order".
// @returns             (string) A string containing the formatted webhook message.
export buy_message(string password, float amount = na, string order_name="Order") =>
    prefix = syminfo.prefix
	check_exchange(prefix)
	order_amount = float(na)
	str_amount = string(na)
	
	if amount
	    order_amount := amount
	    str_amount := str.tostring(amount)
	else
	    str_amount := "{{strategy.order.contracts}}" 
	    order_amount := str.tonumber(str_amount)
	    
	cost = order_amount * close
	str_cost = str.tostring(cost)
	str_price = str.tostring(close) 
    json =  '{'
             + str.format(
             ' 
                 "password":"{0}",
                 "amount":"{1}",
                 "price":"{2}",
                 "cost":"{3}",
                 "side":"{4}",
                 "exchange":"{5}",
                 "base":"{6}",
                 "quote":"{7}",
                 "order_name":"{8}"
                 
             ', password, str_amount, str_price, str_cost, "BUY", syminfo.prefix, syminfo.basecurrency, syminfo.currency, order_name) 
             +'}'
    json

// @function            Make a sell message for TradingHook. 
// @param password      (string) [Required] password that you set in .env file.
// @param percent       (string)  [Required] what percentage of your quantity you want to sell.
// @param order_name    (string) [Optional] order_name. The default name is "Order".
// @returns             (string) A string containing the formatted webhook message.
export sell_message(string password, string percent, string order_name="Order") =>
    check_exchange(syminfo.prefix)
    pos = str.pos(percent,"%")
    if not pos
        runtime.error("Function sell_message() param 'percent' must include '%'")
    sell_percent = str.substring(percent, 0, pos)
	str_price = str.tostring(close)
    json =  '{'
             + str.format(
             ' 
                 "password":"{0}",
                 "amount":"{1}",
                 "price":"{2}",
                 "sell_percent":"{3}",
                 "side":"{4}",
                 "exchange":"{5}",
                 "base":"{6}",
                 "quote":"{7}",
                 "order_name":"{8}"
                 
             ', password, "0",str_price, sell_percent,"SELL", syminfo.prefix, syminfo.basecurrency, syminfo.currency, order_name) 
             +'}'
    json
    
// @function            Make a Entry Message for TradingHook. 
// @param password      (string) [Required] password that you set in .env file.
// @param amount        (float)  [Optional] amount. If not set, your strategy qty will be sent.
// @param leverage      (int)    [Optional] leverage. If not set, your leverage doesn't change.
// @param order_name    (string) [Optional] order_name. The default name is "Order".
// @returns             (string) A string containing the formatted webhook message.
export entry_message(string password, float amount = na, int leverage = 0,string order_name="Order") =>
    prefix = syminfo.prefix
	check_exchange(prefix)
	if not is_futures(syminfo.ticker)
	    runtime.error("Function entry_message() is only supported in Futures ticker")
	order_amount = float(na)
	str_amount = string(na)
	action = "{{strategy.order.action}}"
	if amount
	    order_amount := amount
	    str_amount := str.tostring(amount)
	else
	    str_amount := "{{strategy.order.contracts}}" 
	    order_amount := str.tonumber(str_amount)

	cost = order_amount * close
	str_cost = str.tostring(cost)
	str_price = str.tostring(close)
	str_leverage = str.tostring(leverage)
    json =  '{'
             + str.format(
             ' 
                 "password":"{0}",
                 "amount":"{1}",
                 "price":"{2}",
                 "cost":"{3}",
                 "side":"{4}",
                 "exchange":"{5}",
                 "base":"{6}",
                 "quote":"{7}",
                 "leverage": "{8}",
                 "order_name":"{9}"
                 
             ', password, str_amount, str_price, str_cost, "entry/"+action, syminfo.prefix, syminfo.basecurrency, syminfo.currency+"PERP", str_leverage, order_name) 
             +'}'
    json

// @function            Make a close message for TradingHook. 
// @param password      (string) [Required]             password that you set in .env file.
// @param percent       (string) [Required/Optional]    what percentage of your quantity you want to close.
// @param amount        (float)  [Required/Optional]    quantity you want to close.
// @param order_name    (string) [Optional]             order_name. The default name is "Order".
// @returns             (string) A string containing the formatted webhook message.
export close_message(string password, string percent = na, float amount = na, string order_name="Order") =>
    check_exchange(syminfo.prefix)
    check_futures(syminfo.ticker)
    action = "{{strategy.order.action}}"
    str_price = str.tostring(close)
    json = string(na)
    
    // for percent
    pos = int(na)
    close_percent = string(na)
    
    // for amount
    order_amount = float(na)
	str_amount = string(na)
    
    if na(percent) and na(amount)
        runtime.error("You have to set percent or amount param")
    else if not na(percent) and not na(amount)
        runtime.error("You have to set only percent or amount param. You can't set both percent and amount ")
    else if not na(percent)
        pos := str.pos(percent,"%")
        if not pos
            runtime.error("Function close_message() param 'percent' must include '%'")
    
        close_percent := str.substring(percent, 0, pos)
        json :=  '{'
             + str.format(
             ' 
                 "password":"{0}",
                 "amount":"{1}",
                 "price":"{2}",
                 "close_percent":"{3}",
                 "side":"{4}",
                 "exchange":"{5}",
                 "base":"{6}",
                 "quote":"{7}",
                 "order_name":"{8}"
                 
             ', password, "0",str_price, close_percent, "close/"+action, syminfo.prefix, syminfo.basecurrency, syminfo.currency+"PERP", order_name) 
             +'}'
    else if not na(amount)
	    order_amount := amount
	    str_amount := str.tostring(amount)
	    json :=  '{'
             + str.format(
             ' 
                 "password":"{0}",
                 "amount":"{1}",
                 "price":"{2}",
                 "close_percent":"{3}",
                 "side":"{4}",
                 "exchange":"{5}",
                 "base":"{6}",
                 "quote":"{7}",
                 "order_name":"{8}"
                 
             ', password, str_amount, str_price, "0", "close/"+action, syminfo.prefix, syminfo.basecurrency, syminfo.currency+"PERP", order_name) 
             +'}'
    json