class_docstr: Applies some basic trade analysis for a trading strategy (as defined by TradingModel). Use PyFolio to create some
  basic trading statistics. Also allows you test multiple parameters for a specific strategy (like TC).
class_docstr_tok: ["Applies","some","basic","trade","analysis","for","a","trading","strategy","(","as","defined","by","TradingModel",")",".","Use","PyFolio","to","create","some","basic","trading","statistics",".","Also","allows","you","test","multiple","parameters","for","a","specific","strategy","(","like","TC",")","."]
code: def run_arbitrary_sensitivity(
      self,
      trading_model,
      parameter_list=None,
      pretty_portfolio_names=None,
      parameter_type=None,
      run_in_parallel=False,
      reload_market_data=True,
      plot=True,
  ):
      if not (reload_market_data):
          (
              asset_df,
              spot_df,
              spot_df2,
              basket_dict,
              contract_value_df,
          ) = self._load_assets(trading_model)
  
      port_list = []
      ret_stats_list = []
  
      if (
          market_constants.backtest_thread_no[
              market_constants.generic_plat
          ]
          > 1
          and run_in_parallel
      ):
          swim_pool = SwimPool(
              multiprocessing_library=market_constants.multiprocessing_library
          )
  
          pool = swim_pool.create_pool(
              thread_technique=market_constants.backtest_thread_technique,
              thread_no=market_constants.backtest_thread_no[
                  market_constants.generic_plat
              ],
          )
  
          mult_results = []
  
          for i in range(0, len(parameter_list)):
              # br = copy.copy(trading_model.load_parameters())
              # reset all parameters
              br = copy.copy(trading_model.load_parameters())
  
              current_parameter = parameter_list[i]
  
              # for calculating P&L, change the assets
              for k in current_parameter.keys():
                  setattr(br, k, current_parameter[k])
                  setattr(br.tech_params, k, current_parameter[k])
  
              # should specify reloading the data, if our parameters impact which assets we are fetching
              if reload_market_data:
                  (
                      asset_df,
                      spot_df,
                      spot_df2,
                      basket_dict,
                      contract_value_df,
                  ) = self._load_assets(trading_model, br=br)
  
              mult_results.append(
                  pool.apply_async(
                      self._run_strategy,
                      args=(
                          trading_model,
                          asset_df,
                          spot_df,
                          spot_df2,
                          br,
                          contract_value_df,
                          pretty_portfolio_names[i],
                      ),
                  )
              )
  
          for p in mult_results:
              port, ret_stats = p.get()
  
              port_list.append(port)
              ret_stats_list.append(ret_stats)
  
          try:
              swim_pool.close_pool(pool)
          except:
              pass
  
      else:
          for i in range(0, len(parameter_list)):
              # reset all parameters
              br = copy.copy(trading_model.load_parameters())
  
              current_parameter = parameter_list[i]
  
              # for calculating P&L
              for k in current_parameter.keys():
                  setattr(br, k, current_parameter[k])
                  setattr(br.tech_params, k, current_parameter[k])
  
              # should specify reloading the data, if our parameters impact which assets we are fetching
              if reload_market_data:
                  (
                      asset_df,
                      spot_df,
                      spot_df2,
                      basket_dict,
                      contract_value_df,
                  ) = self._load_assets(trading_model, br=br)
  
              # br = copy.copy(trading_model.br)
  
              port, ret_stats = self._run_strategy(
                  trading_model,
                  asset_df,
                  spot_df,
                  spot_df2,
                  br,
                  contract_value_df,
                  pretty_portfolio_names[i],
              )
  
              port_list.append(port)
              ret_stats_list.append(ret_stats)
  
      port_list = Calculations().join(port_list, how="outer")
  
      # reset the parameters of the strategy
      trading_model.br = trading_model.load_parameters()
  
      style = Style()
  
      ir = [t.inforatio()[0] for t in ret_stats_list]
      rets = [t.ann_returns()[0] for t in ret_stats_list]
  
      # if we have too many combinations remove legend and use scaled shaded colour
      # if len(port_list) > 10:
      # style.color = 'Blues'
      # style.display_legend = False
  
      # careful with plotting labels, may need to convert to strings
      pretty_portfolio_names = [str(p) for p in pretty_portfolio_names]
  
      # plot all the variations
      style.resample = "B"
      style.file_output = (
          self.DUMP_PATH
          + trading_model.FINAL_STRATEGY
          + " "
          + parameter_type
          + ".png"
      )
      style.html_file_output = (
          self.DUMP_PATH
          + trading_model.FINAL_STRATEGY
          + " "
          + parameter_type
          + ".html"
      )
      style.scale_factor = trading_model.SCALE_FACTOR
      style.title = trading_model.FINAL_STRATEGY + " " + parameter_type
  
      if plot:
          self.chart.plot(port_list, chart_type="line", style=style)
  
      # plot all the IR in a bar chart form (can be easier to read!)
      style = Style()
      style.file_output = (
          self.DUMP_PATH
          + trading_model.FINAL_STRATEGY
          + " "
          + parameter_type
          + " IR.png"
      )
      style.html_file_output = (
          self.DUMP_PATH
          + trading_model.FINAL_STRATEGY
          + " "
          + parameter_type
          + " IR.html"
      )
      style.scale_factor = trading_model.SCALE_FACTOR
      style.title = trading_model.FINAL_STRATEGY + " " + parameter_type
      summary_ir = pandas.DataFrame(
          index=pretty_portfolio_names, data=ir, columns=["IR"]
      )
  
      if plot:
          self.chart.plot(summary_ir, chart_type="bar", style=style)
  
      # plot all the rets
      style.file_output = (
          self.DUMP_PATH
          + trading_model.FINAL_STRATEGY
          + " "
          + parameter_type
          + " Rets.png"
      )
      style.html_file_output = (
          self.DUMP_PATH
          + trading_model.FINAL_STRATEGY
          + " "
          + parameter_type
          + " Rets.html"
      )
  
      summary_rets = (
          pandas.DataFrame(
              index=pretty_portfolio_names,
              data=rets,
              columns=["Rets (%)"],
          )
          * 100
      )
  
      if plot:
          self.chart.plot(summary_rets, chart_type="bar", style=style)
  
      return port_list, summary_ir, summary_rets
  
imports: import datetime
  import pandas
  import copy
  from chartpy import Chart, Style, ChartConstants
  from findatapy.timeseries import Calculations, Timezone
  from findatapy.util.loggermanager import LoggerManager
  from finmarketpy.backtest import Backtest
  from finmarketpy.util.marketconstants import MarketConstants
  from findatapy.util.swimpool import SwimPool
label_desc: Use image node_id 6 for calling the TradeAnalysis obj's underlying member method code with example usage: obj.run_arbitrary_sensitivity(trading_model, parameter_list, pretty_portfolio_names, parameter_type, run_in_parallel, reload_market_data, plot) and returns: port_list,  summary_ir,  summary_rets