Untitled
unknown
plain_text
a month ago
28 kB
4
Indexable
Never
//@version=5 strategy("CBA Grid Backtester", overlay=true, max_lines_count=500, initial_capital=1000) int version = 1 // Input parameters upper_limit = input.price(title="Upper Limit", defval=100.0) lower_limit = input.price(title="Lower Limit", defval=60.0) num_grids = input.int(title="Number of Grids", defval=20, minval=5, maxval=100) START_DATE = input.time(timestamp("2019-01-01"), title="Start Date", group="Date Range", tooltip="Configure this date to the present day when enabling automation to receive the most recent alerts.") ENABLE_TAKE_PROFIT = input.bool(false, "Take Profit", tooltip = "Configure Take profit option to close the bot when the price moves in the market direction and reaches the specified price. If the price is reached, the bot sells all the Quote currency used and stops further operations.") TAKE_PROFIT_PRICE = input.price(1000, " Take Profit Price") ENABLE_TAKE_PROFIT_PERC = input.bool(false, "Take Profit Percentage", tooltip = "Configure Take profit option to close the bot when the price moves in the market direction and reaches the specified profit percentage. If the price is reached, the bot sells all the Quote currency used and stops further operations.") TAKE_PROFIT_PERC = input.float(5, title=" Take Profit Percentage") ENABLE_STOP_LOSS = input.bool(false, "Stop Loss", tooltip = "Configure Stop Loss options to close the bot when the price moves against the chosen direction. If the price reaches a specified Stop Loss level, the bot sells all the Quote currency used and stops further operations.") STOP_LOSS_PRICE = input.price(500, " Stop Loss Price") ENABLE_STOP_LOSS_PERC = input.bool(false, "Stop Loss Percentage", tooltip = "Configure Stop Loss options to close the bot when the price moves against the chosen direction. If the price reaches a specified Stop Loss level, the bot sells all the Quote currency used and stops further operations.") STOP_LOSS_PERC = input.float(5, title=" Stop Loss Percentage") ENABLE_TRAINLING_UP = input.bool(false, "Trailing Up", tooltip = "If enabled, the bot will move the Take Profit price up as the price increases. This option only works when the Take Profit option is enabled.") ENABLE_TRAINLING_DOWN = input.bool(false, "Trailing Down", tooltip = "If enabled, the bot will move the Stop Loss price down as the price decreases. This option only works when the Stop Loss option is enabled.") // Exchange fee (adjust as needed) exchange_fee_pct = 0.001 // Assuming 0.1% fee f_calculate_grid_step_perc(upper_limit, lower_limit, num_grids) => base_step = math.pow(upper_limit / lower_limit, 1 / num_grids) - 1 adjusted_step = base_step * (1 - 2 * exchange_fee_pct) // Adjusting by 2 * exchange_fee_pct adjusted_step * 100 // Convert to percentage // Calculate grid levels and sizes grid_step_perc = f_calculate_grid_step_perc(upper_limit, lower_limit, num_grids) var float grid_investment = na // will calculate later strategy.initial_capital / num_grids // Define a custom type for grid levels type GridLevel float price line level_line string static_order_id string dynamic_order_id // Define a custom type for grid state type GridState float no_fee_zone_upper_level float no_fee_zone_lower_level int dynamic_order_counter float upper_limit float lower_limit // Initialize the GridState var GridState grid_state = GridState.new(na, na, 0, upper_limit, lower_limit) // Initialize variables var GridLevel[] buy_levels = array.new<GridLevel>() var GridLevel[] sell_levels = array.new<GridLevel>() var bool is_initialized = false var bool initial_buy_executed = false var bool bot_ended = false var int end_time = na // Function to generate lines for take profit and stop loss f_generate_tp_sl_lines() => if ENABLE_TAKE_PROFIT tp_line = line.new(bar_index, TAKE_PROFIT_PRICE, bar_index + 1, TAKE_PROFIT_PRICE, extend=extend.both, color=color.green, width = 2) if ENABLE_STOP_LOSS sl_line = line.new(bar_index, STOP_LOSS_PRICE, bar_index + 1, STOP_LOSS_PRICE, extend=extend.both, color=color.red, width = 2) f_calculate_grid_levels() => if grid_step_perc <= 0.1 runtime.error("Unable to setup grid: Use less grid lines or increase the grid span.") current_price = close no_fee_zone_lower = current_price * (1 - exchange_fee_pct) no_fee_zone_upper = current_price * (1 + exchange_fee_pct + grid_step_perc / 100) //label.new(bar_index, high, "grid_step_perc: " + str.tostring(grid_step_perc, "#.##") + "%") local_buy_levels = array.new<GridLevel>() local_sell_levels = array.new<GridLevel>() current_level = lower_limit lower_grid_placed = false for i = 0 to num_grids - 1 if current_level > no_fee_zone_lower and current_level < no_fee_zone_upper and lower_grid_placed current_level := current_level * (1 + grid_step_perc / 100) continue level_line = line.new(bar_index, current_level, bar_index+1, current_level, extend=extend.both, color=current_level < close ? color.green : color.red) new_level = GridLevel.new(current_level, level_line) if close <= current_level local_sell_levels.push(new_level) else local_buy_levels.unshift(new_level) if current_level <= current_price lower_grid_placed := true current_level := math.min(upper_limit, current_level * (1 + grid_step_perc / 100)) total_levels = local_buy_levels.size() + local_sell_levels.size() my_grid_investment = strategy.initial_capital / total_levels // here set up the order int j = 0 while j < local_buy_levels.size() level = local_buy_levels.get(j) level.static_order_id := "Initial Grid Buy " + str.tostring(j) strategy.order(level.static_order_id, strategy.long, qty=my_grid_investment / level.price, limit=level.price) j += 1 j := 0 while j < local_sell_levels.size() level = local_sell_levels.get(j) level.static_order_id := "Initial Grid Sell " + str.tostring(j) strategy.order(level.static_order_id, strategy.short, qty=my_grid_investment / level.price, limit=level.price) j += 1 if local_buy_levels.size() == 0 and local_sell_levels.size() == 0 runtime.error("Unable to setup grid: Use less grid lines or increase the grid span.") local_no_fee_zone_lower_level = local_buy_levels.size() > 0 ? local_buy_levels.get(0).price : na local_no_fee_zone_upper_level = local_sell_levels.size() > 0 ? local_sell_levels.get(0).price : na [local_buy_levels, local_sell_levels, local_no_fee_zone_lower_level, local_no_fee_zone_upper_level, my_grid_investment] if time >= START_DATE and not is_initialized [new_buy_levels, new_sell_levels, new_no_fee_zone_lower, new_no_fee_zone_upper, my_grid_investment] = f_calculate_grid_levels() buy_levels := new_buy_levels sell_levels := new_sell_levels grid_state.no_fee_zone_lower_level := new_no_fee_zone_lower grid_state.no_fee_zone_upper_level := new_no_fee_zone_upper grid_investment := my_grid_investment f_generate_tp_sl_lines() is_initialized := true // Initial buy order if is_initialized and not initial_buy_executed and not na(grid_state.no_fee_zone_lower_level) and not na(grid_state.no_fee_zone_upper_level) sell_levels_count = sell_levels.size() initial_buy_amount = grid_investment * sell_levels_count entry_amount = initial_buy_amount / close strategy.entry("Initial Buy", strategy.long, qty=entry_amount) initial_buy_executed := true f_is_outside_no_fee_zone(price1, price2, current_price) => no_fee_zone_lower = current_price * (1 - exchange_fee_pct) no_fee_zone_upper = current_price * (1 + exchange_fee_pct + grid_step_perc / 100) price_diff = math.abs(price1 - price2) no_fee_zone_size = no_fee_zone_upper - no_fee_zone_lower price_diff >= no_fee_zone_size f_remove_grid_level(GridLevel level) => level.level_line.delete() if not na(level.static_order_id) strategy.cancel(level.static_order_id) if not na(level.dynamic_order_id) strategy.cancel(level.dynamic_order_id) // Dynamic orders (moving with exchange fee zone) f_update_dynamic_orders_high(GridState state) => bool changed = false if high >= state.no_fee_zone_upper_level and sell_levels.size() > 0 changed := true current_price = state.no_fee_zone_upper_level f_remove_grid_level(sell_levels.get(0)) sell_levels.remove(0) if sell_levels.size() > 0 state.no_fee_zone_upper_level := sell_levels.get(0).price else state.no_fee_zone_upper_level := na state.no_fee_zone_lower_level := state.no_fee_zone_lower_level * (1 + grid_step_perc / 100) if f_is_outside_no_fee_zone(na(state.no_fee_zone_upper_level) ? state.upper_limit : state.no_fee_zone_upper_level, na(state.no_fee_zone_lower_level) ? state.lower_limit : state.no_fee_zone_lower_level, current_price) state.no_fee_zone_lower_level := na(state.no_fee_zone_lower_level) ? state.lower_limit : state.no_fee_zone_lower_level GridLevel new_buy_level = GridLevel.new(state.no_fee_zone_lower_level, line.new(bar_index, state.no_fee_zone_lower_level, bar_index+1, state.no_fee_zone_lower_level, extend=extend.both, color=color.green)) new_buy_level.dynamic_order_id := "Dynamic Buy " + str.tostring(state.dynamic_order_counter) buy_levels.unshift(new_buy_level) strategy.order(new_buy_level.dynamic_order_id, strategy.long, qty=grid_investment / state.no_fee_zone_lower_level, limit=state.no_fee_zone_lower_level) //label.new(bar_index, high, "Dynamic Buy " + str.tostring(state.dynamic_order_counter) + " @ " + str.tostring(state.no_fee_zone_lower_level) + "\n\n\n\n") state.dynamic_order_counter += 1 else if na(state.no_fee_zone_upper_level) if buy_levels.get(0).price < state.upper_limit next_buy_level = buy_levels.get(0).price * (1 + grid_step_perc / 100) new_buy_level = GridLevel.new(next_buy_level, line.new(bar_index, next_buy_level, bar_index+1, next_buy_level, extend=extend.both, color=color.green)) new_buy_level.dynamic_order_id := "Dynamic Buy " + str.tostring(state.dynamic_order_counter) buy_levels.unshift(new_buy_level) strategy.order(new_buy_level.dynamic_order_id, strategy.long, qty=grid_investment / next_buy_level, limit=next_buy_level) state.dynamic_order_counter += 1 // else // no_fee_zone_lower = current_price * (1 - exchange_fee_pct) // no_fee_zone_upper = current_price * (1 + exchange_fee_pct + grid_step_perc / 100) // no_fee_zone_size = no_fee_zone_upper - no_fee_zone_lower // up_prc = na(state.no_fee_zone_upper_level) ? upper_limit : state.no_fee_zone_upper_level // dn_prc = na(state.no_fee_zone_lower_level) ? state.lower_limit : state.no_fee_zone_lower_level // label.new(bar_index, high, "price_diff: " + str.tostring(up_prc - dn_prc) + // "\n no_fee_zone_size: " + str.tostring(no_fee_zone_size) + "\n\n\n\n") changed // Function to handle low price updates f_update_dynamic_orders_low(GridState state) => bool changed = false if low <= state.no_fee_zone_lower_level and buy_levels.size() > 0 changed := true current_price = state.no_fee_zone_lower_level f_remove_grid_level(buy_levels.get(0)) buy_levels.remove(0) if buy_levels.size() > 0 state.no_fee_zone_lower_level := buy_levels.get(0).price else state.no_fee_zone_lower_level := na state.no_fee_zone_upper_level := state.no_fee_zone_upper_level * (1 - grid_step_perc / 100) if f_is_outside_no_fee_zone(na(state.no_fee_zone_upper_level) ? state.upper_limit : state.no_fee_zone_upper_level, na(state.no_fee_zone_lower_level) ? state.lower_limit : state.no_fee_zone_lower_level, current_price) state.no_fee_zone_upper_level := na(state.no_fee_zone_upper_level) ? state.upper_limit : state.no_fee_zone_upper_level GridLevel new_sell_level = GridLevel.new(state.no_fee_zone_upper_level, line.new(bar_index, state.no_fee_zone_upper_level, bar_index+1, state.no_fee_zone_upper_level, extend=extend.both, color=color.red)) new_sell_level.dynamic_order_id := "Dynamic Sell " + str.tostring(state.dynamic_order_counter) sell_levels.unshift(new_sell_level) strategy.order(new_sell_level.dynamic_order_id, strategy.short, qty=grid_investment/state.no_fee_zone_upper_level, limit=state.no_fee_zone_upper_level) state.dynamic_order_counter += 1 //label.new(bar_index, high, "outside range") else if na(state.no_fee_zone_lower_level) if sell_levels.get(0).price > state.lower_limit next_sell_level = sell_levels.get(0).price * (1 - grid_step_perc / 100) new_sell_level = GridLevel.new(next_sell_level, line.new(bar_index, next_sell_level, bar_index+1, next_sell_level, extend=extend.both, color=color.red)) new_sell_level.dynamic_order_id := "Dynamic Sell " + str.tostring(state.dynamic_order_counter) sell_levels.unshift(new_sell_level) strategy.order(new_sell_level.dynamic_order_id, strategy.short, qty=grid_investment / next_sell_level, limit=next_sell_level) state.dynamic_order_counter += 1 //label.new(bar_index, high, "fill up") // else // no_fee_zone_lower = current_price * (1 - exchange_fee_pct) // no_fee_zone_upper = current_price * (1 + exchange_fee_pct + grid_step_perc / 100) // no_fee_zone_size = no_fee_zone_upper - no_fee_zone_lower // up_prc = na(state.no_fee_zone_upper_level) ? upper_limit : state.no_fee_zone_upper_level // dn_prc = na(state.no_fee_zone_lower_level) ? lower_limit : state.no_fee_zone_lower_level // label.new(bar_index, high, "price_diff: " + str.tostring(up_prc - dn_prc) + // "\n no_fee_zone_size: " + str.tostring(no_fee_zone_size) + "\n\n\n\n") changed f_trailing_up(GridState state) => if ENABLE_TRAINLING_UP and sell_levels.size() <= 1 and buy_levels.size() > 0 float next_sell_level = na if sell_levels.size() > 0 next_sell_level := sell_levels.get(0).price * (1 + grid_step_perc / 100) else next_sell_level := buy_levels.get(0).price * (1 + 2 * exchange_fee_pct + 2 * grid_step_perc / 100) new_sell_level = GridLevel.new(next_sell_level, line.new(bar_index, next_sell_level, bar_index+1, next_sell_level, extend=extend.both, color=color.red)) new_sell_level.dynamic_order_id := "Dynamic Sell " + str.tostring(state.dynamic_order_counter) sell_levels.push(new_sell_level) strategy.order(new_sell_level.dynamic_order_id, strategy.short, qty=grid_investment / next_sell_level, limit=next_sell_level) state.dynamic_order_counter += 1 last_elem = buy_levels.pop() f_remove_grid_level(last_elem) strategy.order("Trailing Up Buy " + str.tostring(state.dynamic_order_counter), strategy.long, qty=grid_investment / close) state.dynamic_order_counter += 1 state.upper_limit := next_sell_level state.lower_limit := last_elem.price state.no_fee_zone_upper_level := next_sell_level true else false f_trailing_down(GridState state) => if ENABLE_TRAINLING_DOWN and buy_levels.size() <= 1 and sell_levels.size() > 0 float next_buy_level = na if buy_levels.size() > 0 next_buy_level := buy_levels.get(0).price * (1 - grid_step_perc / 100) else next_buy_level := sell_levels.get(0).price * (1 - 2 * exchange_fee_pct - 2 * grid_step_perc / 100) new_buy_level = GridLevel.new(next_buy_level, line.new(bar_index, next_buy_level, bar_index+1, next_buy_level, extend=extend.both, color=color.green)) new_buy_level.dynamic_order_id := "Dynamic Buy " + str.tostring(state.dynamic_order_counter) buy_levels.unshift(new_buy_level) strategy.order(new_buy_level.dynamic_order_id, strategy.long, qty=grid_investment / next_buy_level, limit=next_buy_level) state.dynamic_order_counter += 1 last_elem = sell_levels.pop() f_remove_grid_level(last_elem) strategy.order("Trailing Down Sell " + str.tostring(state.dynamic_order_counter), strategy.short, qty=grid_investment / close) state.dynamic_order_counter += 1 state.upper_limit := last_elem.price state.lower_limit := next_buy_level state.no_fee_zone_lower_level := next_buy_level true else false // DEBUGGING // int bar_dir = 0 // int before_highs = 0 // int after_highs = 0 // int before_lows = 0 // int after_lows = 0 // int after_trailing_up = 0 // int after_trailing_down = 0 // Update dynamic orders on each bar if is_initialized and not bot_ended if close < open // bar_dir := -1 // before_highs := grid_state.dynamic_order_counter for i = 1 to 10 changed = f_update_dynamic_orders_high(grid_state) if not changed break // after_highs := grid_state.dynamic_order_counter for i = 1 to 10 changed = f_update_dynamic_orders_low(grid_state) if not changed break // after_lows := grid_state.dynamic_order_counter f_trailing_up(grid_state) // after_trailing_up := grid_state.dynamic_order_counter f_trailing_down(grid_state) // after_trailing_down := grid_state.dynamic_order_counter else // bar_dir := 1 // before_lows := grid_state.dynamic_order_counter for i = 1 to 10 changed = f_update_dynamic_orders_low(grid_state) if not changed break // after_lows := grid_state.dynamic_order_counter for i = 1 to 10 changed = f_update_dynamic_orders_high(grid_state) if not changed break // after_highs := grid_state.dynamic_order_counter f_trailing_up(grid_state) // after_trailing_up := grid_state.dynamic_order_counter f_trailing_down(grid_state) // after_trailing_down := grid_state.dynamic_order_counter // Add this function to check for Take Profit and Stop Loss conditions f_check_tp_sl() => if ENABLE_TAKE_PROFIT and high >= TAKE_PROFIT_PRICE strategy.cancel_all() strategy.close_all("Take Profit") true else if ENABLE_STOP_LOSS and low <= STOP_LOSS_PRICE strategy.cancel_all() strategy.close_all("Stop Loss") true else false // Modify your main strategy logic to include the Take Profit and Stop Loss check if is_initialized and initial_buy_executed and not bot_ended if f_check_tp_sl() bot_ended := true end_time := time else if ENABLE_TAKE_PROFIT_PERC and strategy.openprofit_percent >= TAKE_PROFIT_PERC strategy.cancel_all() strategy.close_all("Take Profit Perc") bot_ended := true end_time := time else if ENABLE_STOP_LOSS_PERC and strategy.netprofit_percent <= (STOP_LOSS_PERC * -1) strategy.cancel_all() strategy.close_all("Stop Loss Perc") bot_ended := true end_time := time // DEBUG // plot(grid_state.no_fee_zone_upper_level, title = "no_fee_zone_upper_level", color=color.new(color = color.blue , transp = 0), display=display.data_window) // plot(grid_state.no_fee_zone_lower_level, title = "no_fee_zone_lower_level", color=color.new(color = color.blue , transp = 0), display=display.data_window) // plot(buy_levels.size(), title = "buy_levels.size()", color=color.new(color = color.blue , transp = 0), display=display.data_window) // plot(sell_levels.size(), title = "sell_levels.size()", color=color.new(color = color.blue , transp = 0), display=display.data_window) // plot(upper_limit, title = "upper_limit", color=color.new(color = color.blue , transp = 0), display=display.data_window) // plot(lower_limit, title = "lower_limit", color=color.new(color = color.blue , transp = 0), display=display.data_window) // plot(grid_step_perc, title = "grid_step_perc", color=color.new(color = color.blue , transp = 0), display=display.data_window) // plot(bot_ended? 1 : 0, title = "bot_ended", color=color.new(color = color.blue , transp = 0), display=display.data_window) // plot(strategy.position_avg_price, title = "strategy.position_avg_price", color=color.new(color = color.blue , transp = 0), display=display.data_window) // plot(grid_state.dynamic_order_counter, title = "dynamic_order_counter", color=color.new(color = color.red , transp = 0), display=display.data_window) // plot(bar_dir, title = "bar_dir", color=color.new(color = color.red , transp = 0), display=display.data_window) // plot(before_highs, title = "before_highs", color=color.new(color = color.red , transp = 0), display=display.data_window) // plot(after_highs, title = "after_highs", color=color.new(color = color.red , transp = 0), display=display.data_window) // plot(before_lows, title = "before_lows", color=color.new(color = color.red , transp = 0), display=display.data_window) // plot(after_lows, title = "after_lows", color=color.new(color = color.red , transp = 0), display=display.data_window) // plot(after_trailing_up, title = "after_trailing_up", color=color.new(color = color.green , transp = 0), display=display.data_window) // plot(after_trailing_down, title = "after_trailing_down", color=color.new(color = color.green , transp = 0), display=display.data_window) if barstate.islastconfirmedhistory transparent = color.new(#131722, transp = 0) color1 = color.white quote = syminfo.currency var table tab1 = table.new(position = position.top_right, columns = 15, rows = 15, bgcolor=transparent, frame_color = transparent,frame_width = 0,border_color = transparent,border_width = 0) table.cell(tab1, 0, 1, 'CBA Grid Backtester' , text_halign = text.align_left, text_size= size.normal, text_color=color1) table.cell(tab1, 1, 1, str.tostring(version, '#.0') , text_halign = text.align_right, text_size= size.normal, text_color=color1) table.cell(tab1, 0, 2, "Grid Step %", text_halign = text.align_left, text_size= size.normal, text_color=color1) table.cell(tab1, 1, 2, str.tostring(grid_step_perc, "#.##") + "%", text_halign = text.align_right, text_size= size.normal, text_color=color1) grid_range = ((upper_limit - lower_limit) / upper_limit) * 100 table.cell(tab1, 0, 3, "Grid Range", text_halign = text.align_left, text_size= size.normal, text_color=color1) table.cell(tab1, 1, 3, str.tostring(grid_range, "#.##") + "%", text_halign = text.align_right, text_size= size.normal, text_color=color1) current_value = strategy.equity table.cell(tab1, 0, 4, "Current Value", text_halign = text.align_left, text_size= size.normal, text_color=color1) table.cell(tab1, 1, 4, str.tostring(current_value, "#,###.##") + " " + quote, text_halign = text.align_right, text_size= size.normal, text_color=color1) total_pnl = strategy.netprofit table.cell(tab1, 0, 5, "Total PNL", text_halign = text.align_left, text_size= size.normal, text_color=color1) table.cell(tab1, 1, 5, str.tostring(total_pnl, "#,###.##") + " " + quote, text_halign = text.align_right, text_size= size.normal, text_color=color1) portfolio_profit_pct = (current_value / strategy.initial_capital - 1) * 100 table.cell(tab1, 0, 6, "Total PNL %", text_halign = text.align_left, text_size= size.normal, text_color=color1) table.cell(tab1, 1, 6, str.tostring(portfolio_profit_pct, "#.##") + "%", text_halign = text.align_right, text_size= size.normal, text_color=color1) // bot_profit = strategy.grossprofit // table.cell(tab1, 0, 7, "Bot Profit", text_halign = text.align_left, text_size= size.normal, text_color=color1) // table.cell(tab1, 1, 7, str.tostring(bot_profit, "#,###.##") + " " + quote, text_halign = text.align_right, text_size= size.normal, text_color=color1) // bot_profit := strategy.grossprofit_percent // table.cell(tab1, 0, 8, "Bot Profit %", text_halign = text.align_left, text_size= size.normal, text_color=color1) // table.cell(tab1, 1, 8, str.tostring(bot_profit, "#,###.##") + " " + quote, text_halign = text.align_right, text_size= size.normal, text_color=color1) days_elapsed = ((na(end_time) ? time : end_time) - START_DATE) / (1000 * 60 * 60 * 24) avg_daily_profit = total_pnl / days_elapsed table.cell(tab1, 0, 9, "Avg. Daily", text_halign = text.align_left, text_size= size.normal, text_color=color1) table.cell(tab1, 1, 9, str.tostring(avg_daily_profit, "#,###.##") + " " + quote, text_halign = text.align_right, text_size= size.normal, text_color=color1) avg_daily_percent = (math.pow(1 + portfolio_profit_pct / 100, 1 / days_elapsed) - 1) * 100 table.cell(tab1, 0, 10, "Avg. Daily %", text_halign = text.align_left, text_size= size.normal, text_color=color1) table.cell(tab1, 1, 10, str.tostring(avg_daily_percent, "#.##") + "%", text_halign = text.align_right, text_size= size.normal, text_color=color1) table.cell(tab1, 0, 11, "Total Days Traded", text_halign = text.align_left, text_size= size.normal, text_color=color1) table.cell(tab1, 1, 11, str.tostring(days_elapsed, "#"), text_halign = text.align_right, text_size= size.normal, text_color=color1) // Additional statistics // total_trades = strategy.closedtrades // table.cell(tab1, 0, 10, "Total Trades", text_halign = text.align_left, text_size= size.normal, text_color=color1) // table.cell(tab1, 1, 10, str.tostring(total_trades), text_halign = text.align_right, text_size= size.normal, text_color=color1) // win_rate = strategy.wintrades / total_trades * 100 // table.cell(tab1, 0, 11, "Win Rate", text_halign = text.align_left, text_size= size.normal, text_color=color1) // table.cell(tab1, 1, 11, str.tostring(win_rate, "#.##") + "%", text_halign = text.align_right, text_size= size.normal, text_color=color1) // profit_factor = strategy.grossprofit / math.abs(strategy.grossloss) // table.cell(tab1, 0, 12, "Profit Factor", text_halign = text.align_left, text_size= size.normal, text_color=color1) // table.cell(tab1, 1, 12, str.tostring(profit_factor, "#.##"), text_halign = text.align_right, text_size= size.normal, text_color=color1) // max_drawdown = strategy.max_drawdown // table.cell(tab1, 0, 13, "Max Drawdown", text_halign = text.align_left, text_size= size.normal, text_color=color1) // table.cell(tab1, 1, 13, str.tostring(max_drawdown, "#,###.##") + " " + quote, text_halign = text.align_right, text_size= size.normal, text_color=color1)
Leave a Comment