// Version: 0.64 // Updated: July 12, 2023 // This source code is subject to the terms of th GNU General Public License v3.0 at https://choosealicense.com/licenses/gpl-3.0/ // © pAulseperformance // ==================================================================================================D~ // _ __ // /\ | | / _| // _ __ / \ _ _| |___ ___ _ __ ___ _ __| |_ ___ _ __ _ __ ___ __ _ _ __ ___ ___ // | '_ \ / /\ \| | | | / __|/ _ \ '_ \ / _ \ '__| _/ _ \| '__| '_ ` _ \ / _` | '_ \ / __/ _ \ // | |_) / ____ \ |_| | \__ \ __/ |_) | __/ | | || (_) | | | | | | | | (_| | | | | (_| __/ // | .__/_/ \_\__,_|_|___/\___| .__/ \___|_| |_| \___/|_| |_| |_| |_|\__,_|_| |_|\___\___| // | | | | // |_| |_| // ==================================================================================================D~ // ## How Do I Use This Tool? // In order for this tool to work, you will need to add two scripts to your chart. // 1. This indicator // 2. The script you want to test which contains a signal plot (More info on this below) // You will feed the output of the script you want to test into the input of the Strategy Optimizer. // ### Step One: Get Set Up On TradingView // 1. Login to your TradingView account, if you don't have one, you can sign up for free. // 2. Open the chart for the asset you want to run the tool on. // ### Step Two: Add The Strategy Optimizer To Your Chart // 1. Open the "Pine Editor", by clicking the tab on the bottom left. // 2. Remove the existing boiler plate code and copy and paste the Strategy Optimizer code into the editor. // 3. Save the script, give it a name and then click "Add to chart" // Now your strategy tester is ready to go! But you still need an indicator to test. // ### Step Three: Add Another Script To Your Chart // 1. Open a new script and add this example indicator. // 2. Save the script, give it a unique name, and then click "Add to chart" // Now that you have the indicator and the tool on your chart you are almost ready! // ### Step Four: Combine Your Script With The Strategy Optimizer // 1. Go to the settings of the backtesting tool and click the "source" dropdown and select the output from the otherindicator // You can now use the script to analyze the chart and make trading decisions. // The script will automatically update with the latest data as you move the chart, // so you can see how your analysis changes over time. // ### Important Notes // In order for the Strategy Optimizer to properly register the other scripts signals, // you need to make sure the other script is plotting the correct signals which can be used by the Strategy Optimizer. // This process is impossible to automate. //@version=5 strategy('[pAulseperformance] Free Strategy Optimizer', overlay=true, precision=2, default_qty_type=strategy.percent_of_equity, default_qty_value=2, initial_capital=100000, currency='USD', slippage=3, commission_type=strategy.commission.percent, commission_value=0.1, process_orders_on_close=true, calc_on_order_fills=false ) // Strategy{ i_externalSource = input(close, title='External Source', group="Signal Detection", inline="Signal Detection") i_reverseSignal = input(false, title='Reverse Signal', group="Signal Detection", inline="Signal Detection", tooltip = "Will not affect exit signal. Only entry signals will be reversed.") // Useful if you want to see how the strategy might perform when using the oppsite logic to enter and exit trades //Integer Signals i_longSignal = input(1, 'Buy', inline="Signal", group="Signal Detection") i_shortSignal = input(-1, 'Sell',inline="Signal", group="Signal Detection") i_exitSignal = input(0, 'Exit',inline="Signal", group="Signal Detection", tooltip = 'Buy Signal | Sell Signal | Exit Signal\nMatch these numbers to your external indicators signal output that you want to test.') // Date Filter i_useStartTime = input.bool(false, '', group="Date Filter", inline='Start Time') i_useEndTime = input.bool(false, '', group="Date Filter", inline='End Time') i_startTime = input.time(defval=timestamp('01 Jan 2020 00:00 +0000'), title='Start Time', group="Date Filter", inline='Start Time') i_endTime = input.time(defval=timestamp('27 Nov 2020 00:00 +0000'), title='End Time', group="Date Filter", inline='End Time') inDateRange = (i_useStartTime ? time >= i_startTime : true) and (i_useEndTime ? time <= i_endTime : true) // Strategy i_direction = input.string('all', title='Trade Direction', options=['all', 'long', 'short'], group="Strategy") i_oppositeSigRvrse = input.string('On', 'Opposite Signals Reverse Position', ['On', 'Off'], group = "Strategy", tooltip = 'Replicates Traditional TV Strategies "Never Flat"' ) strategy.risk.allow_entry_in(i_direction) stratLong = (i_externalSource == (i_reverseSignal ? i_shortSignal : i_longSignal) and inDateRange) stratShort = (i_externalSource == (i_reverseSignal ? i_longSignal : i_shortSignal) and inDateRange) stratExit = (i_externalSource == i_exitSignal and inDateRange) i_riskRewardRatio = input.float(1.5, "Risk Reward Ratio") // } // TP/Stop Management { // Set stop Loss i_stopLoss = input.string('ATR', '', ['ATR', 'Pivot Point', 'Chand Kroll', 'None'], group="Stop Loss",inline='Stop Loss') i_SLLB = input.int(3, "Lookback", group="Stop Loss", inline='Stop Loss') // to Most Recent Swing Lo/hi pivot_high = fixnan(ta.pivothigh(high, i_SLLB, 0)) pivot_low = fixnan(ta.pivotlow(low, i_SLLB, 0)) f_pivotSwingExit(bool isLong) => _SL = isLong ? pivot_low : pivot_high // ATR STOP _atr = ta.atr(i_SLLB) f_atrStop(bool isLong) => _SL = isLong ? close - _atr : _atr + close // Chand Kroll Stop x = 1 q = 9 first_high_stop = ta.highest(high, i_SLLB) - x * ta.atr(i_SLLB) first_low_stop = ta.lowest(low, i_SLLB) + x * ta.atr(i_SLLB) stop_short = ta.highest(first_high_stop, i_SLLB) stop_long = ta.lowest(first_low_stop, i_SLLB) f_chandKrollStop(bool isLong) => _SL = isLong ? stop_long : stop_short // Get STOP LOSS f_getSL(bool isLong=true) => switch i_stopLoss 'Pivot Point' => f_pivotSwingExit(isLong) 'ATR' => f_atrStop(isLong) 'Chand Kroll' => f_chandKrollStop(isLong) => float(na) // } var float TP = na var float SL = na var int entryTime = time var int entryIndex = bar_index var float entryPrice = close if stratLong and strategy.position_size == 0 or (stratLong and i_oppositeSigRvrse == 'On') _tradeuid = 'long' strategy.entry(_tradeuid, strategy.long) entryPrice := close entryTime := time entryIndex := bar_index SL := f_getSL(true) _stopGap = entryPrice - SL TP := entryPrice + (_stopGap*i_riskRewardRatio) strategy.exit('Exit', _tradeuid, limit = TP, stop = SL) if stratShort and strategy.position_size == 0 or (stratShort and i_oppositeSigRvrse == 'On') _tradeuid = 'short' strategy.entry(_tradeuid, strategy.short) entryPrice := close entryTime := time entryIndex := bar_index SL := f_getSL(false) _stopGap = SL - entryPrice TP := entryPrice - (_stopGap*i_riskRewardRatio) strategy.exit('Exit', _tradeuid, limit = TP, stop = SL) if stratExit strategy.close_all() strategy.cancel_all() // Plot TP-SL-Entry P_TP = plot(strategy.opentrades ? TP : na, 'TP', color.green,1, plot.style_linebr, display = display.data_window + display.status_line) P_SL = plot(strategy.opentrades ? SL : na, 'SL', color.red,1, plot.style_linebr, display = display.data_window + display.status_line) P_EP = plot(strategy.opentrades ? entryPrice: na, 'Entry', color.gray,1, plot.style_linebr, display = display.data_window + display.status_line) fill(P_EP, P_TP, color.rgb(76, 175, 79, 75)) fill(P_EP, P_SL, color.rgb(255, 82, 82, 75)) // DATA WINDOW var T_dataWindow = table.new(position.top_right, 2, 13, color.rgb(255, 255, 255, 55), border_width = 1) if barstate.islast or barstate.islastconfirmedhistory table.cell(T_dataWindow, 0, 0, 'Info', text_size = size.auto, text_color = color.white, bgcolor = color.gray, text_halign = text.align_left) table.cell(T_dataWindow, 0, 1, 'Initial Capital', text_size = size.auto, text_color = color.white, bgcolor = color.black, text_halign = text.align_left) table.cell(T_dataWindow, 0, 2, 'Equity', text_size = size.auto, text_color = color.white, bgcolor = color.black, text_halign = text.align_left) table.cell(T_dataWindow, 0, 3, 'Net Profit', text_size = size.auto, text_color = color.white, bgcolor = color.black, text_halign = text.align_left) table.cell(T_dataWindow, 0, 4, 'Open Profit', text_size = size.auto, text_color = color.white, bgcolor = color.black, text_halign = text.align_left) table.cell(T_dataWindow, 0, 5, 'Gross Profit', text_size = size.auto, text_color = color.white, bgcolor = color.black, text_halign = text.align_left) table.cell(T_dataWindow, 0, 6, 'Gross Loss', text_size = size.auto, text_color = color.white, bgcolor = color.black, text_halign = text.align_left) table.cell(T_dataWindow, 0, 7, 'Open Trades', text_size = size.auto, text_color = color.white, bgcolor = color.black, text_halign = text.align_left) table.cell(T_dataWindow, 0, 8, 'Closed Trades', text_size = size.auto, text_color = color.white, bgcolor = color.black, text_halign = text.align_left) table.cell(T_dataWindow, 0, 9, 'Winning Trades', text_size = size.auto, text_color = color.white, bgcolor = color.black, text_halign = text.align_left) table.cell(T_dataWindow, 0, 10, 'Losing Trades', text_size = size.auto, text_color = color.white, bgcolor = color.black, text_halign = text.align_left) table.cell(T_dataWindow, 0, 11, 'Break Even Trades', text_size = size.auto, text_color = color.white, bgcolor = color.black, text_halign = text.align_left) table.cell(T_dataWindow, 1, 0, 'Value', text_size = size.auto, text_color = color.white, bgcolor = color.gray, text_halign = text.align_left) table.cell(T_dataWindow, 1, 1, str.tostring(strategy.initial_capital, '#.##'), text_size = size.auto, text_color = color.white, bgcolor = color.black, text_halign = text.align_left) table.cell(T_dataWindow, 1, 2, str.tostring(strategy.equity, '#.##'), text_size = size.auto, text_color = color.white, bgcolor = color.black, text_halign = text.align_left) table.cell(T_dataWindow, 1, 3, str.tostring(strategy.netprofit, '#.##'), text_size = size.auto, text_color = color.white, bgcolor = color.black, text_halign = text.align_left) table.cell(T_dataWindow, 1, 4, str.tostring(strategy.openprofit, '#.##'), text_size = size.auto, text_color = color.white, bgcolor = color.black, text_halign = text.align_left) table.cell(T_dataWindow, 1, 5, str.tostring(strategy.grossprofit, '#.##'), text_size = size.auto, text_color = color.white, bgcolor = color.black, text_halign = text.align_left) table.cell(T_dataWindow, 1, 6, str.tostring(strategy.grossloss, '#.##'), text_size = size.auto, text_color = color.white, bgcolor = color.black, text_halign = text.align_left) table.cell(T_dataWindow, 1, 7, str.tostring(strategy.opentrades), text_size = size.auto, text_color = color.white, bgcolor = color.black, text_halign = text.align_left) table.cell(T_dataWindow, 1, 8, str.tostring(strategy.closedtrades), text_size = size.auto, text_color = color.white, bgcolor = color.black, text_halign = text.align_left) table.cell(T_dataWindow, 1, 9, str.tostring(strategy.wintrades), text_size = size.auto, text_color = color.white, bgcolor = color.black, text_halign = text.align_left) table.cell(T_dataWindow, 1, 10, str.tostring(strategy.losstrades), text_size = size.auto, text_color = color.white, bgcolor = color.black, text_halign = text.align_left) table.cell(T_dataWindow, 1, 11, str.tostring(strategy.eventrades), text_size = size.auto, text_color = color.white, bgcolor = color.black, text_halign = text.align_left)