Untitled
unknown
plain_text
a year ago
28 kB
12
Indexable
//@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)Editor is loading...
Leave a Comment