//@version=5
strategy('[VV] Parameter Optimization Bot', overlay=true)

tim = input.timeframe('375')

// Parameter ranges for optimization
lengths = array.new_int(3, 0)
array.set(lengths, 0, 50)
array.set(lengths, 1, 81)
array.set(lengths, 2, 100)

band1_values = array.new_float(3, 0.0)
array.set(band1_values, 0, 1.0)
array.set(band1_values, 1, 1.5)
array.set(band1_values, 2, 2.0)

band2_values = array.new_float(3, 0.0)
array.set(band2_values, 0, 2.0)
array.set(band2_values, 1, 2.5)
array.set(band2_values, 2, 3.0)

takeProfit_values = array.new_float(3, 0.0)
array.set(takeProfit_values, 0, 1.0)
array.set(takeProfit_values, 1, 1.5)
array.set(takeProfit_values, 2, 2.0)

stopLoss_values = array.new_float(3, 0.0)
array.set(stopLoss_values, 0, 0.5)
array.set(stopLoss_values, 1, 1.0)
array.set(stopLoss_values, 2, 1.5)

// Function to calculate bands
f_calculateBands(src, length, bandFactor) =>
    basis = ta.sma(src, length)
    dev = bandFactor * ta.stdev(src, length)
    [basis, basis + dev, basis - dev]

// Variables to store performance metrics
var float bestProfit = na
var int bestLength = na
var float bestBand1 = na
var float bestBand2 = na
var float bestTakeProfit = na
var float bestStopLoss = na

// Variable to accumulate gains
var float totalProfit = 0.0
var float lastProfit = 0.0

// Loop through combinations of parameters
for i = 0 to array.size(lengths) - 1
    for j = 0 to array.size(band1_values) - 1
        for k = 0 to array.size(band2_values) - 1
            for m = 0 to array.size(takeProfit_values) - 1
                for n = 0 to array.size(stopLoss_values) - 1
                    length = array.get(lengths, i)
                    Band1 = array.get(band1_values, j)
                    Band2 = array.get(band2_values, k)
                    takeProfit = array.get(takeProfit_values, m)
                    stopLoss = array.get(stopLoss_values, n)

                    // Calculate bands
                    [basis, upperBand1, lowerBand1] = f_calculateBands(close, length, Band1)

                    longCondition = ta.crossover(close, open) and close < upperBand1
                    shortCondition = ta.crossunder(close, open) and close > lowerBand1

                    // Long entry and exit
                    if longCondition
                        strategy.entry('long', strategy.long)
                        strategy.exit('TP/SL Long', from_entry='long', limit=close * (1 + takeProfit / 100), stop=close * (1 - stopLoss / 100))

                    // Short entry and exit
                    if shortCondition
                        strategy.entry('short', strategy.short)
                        strategy.exit('TP/SL Short', from_entry='short', limit=close * (1 - takeProfit / 100), stop=close * (1 + stopLoss / 100))
                    
                    // Calculate total profit and store last profit
                    if strategy.closedtrades > 0
                        lastProfit := strategy.closedtrades.profit(strategy.closedtrades - 1) // Get the profit of the last closed trade
                        totalProfit := totalProfit + lastProfit

// Update best parameters based on total profit
if not na(totalProfit) and (na(bestProfit) or totalProfit > bestProfit)
    bestProfit := totalProfit
    bestLength := length
    bestBand1 := Band1
    bestBand2 := Band2
    bestTakeProfit := takeProfit
    bestStopLoss := stopLoss

// Display the best parameters on the chart
label.new(bar_index, high, text="Best Length: " + str.tostring(bestLength) + 
    "\nBest Band1: " + str.tostring(bestBand1) + 
    "\nBest Band2: " + str.tostring(bestBand2) + 
    "\nBest TP: " + str.tostring(bestTakeProfit) + 
    "\nBest SL: " + str.tostring(bestStopLoss), 
    color=color.new(color.green, 90))