nodes: 0, module; 1, function_definition; 2, function_name:sortino_ratio; 3, parameters; 4, block; 5, identifier:returns; 6, default_parameter; 7, default_parameter; 8, default_parameter; 9, default_parameter; 10, default_parameter; 11, expression_statement; 12, expression_statement; 13, if_statement; 14, expression_statement; 15, if_statement; 16, expression_statement; 17, expression_statement; 18, expression_statement; 19, expression_statement; 20, expression_statement; 21, if_statement; 22, return_statement; 23, identifier:required_return; 24, integer:0; 25, identifier:period; 26, identifier:DAILY; 27, identifier:annualization; 28, None; 29, identifier:out; 30, None; 31, identifier:_downside_risk; 32, None; 33, comment:"""
      Determines the Sortino ratio of a strategy.
  
      Parameters
      ----------
      returns : pd.Series or np.ndarray or pd.DataFrame
          Daily returns of the strategy, noncumulative.
          - See full explanation in :func:`~empyrical.stats.cum_returns`.
      required_return: float / series
          minimum acceptable return
      period : str, optional
          Defines the periodicity of the 'returns' data for purposes of
          annualizing. Value ignored if `annualization` parameter is specified.
          Defaults are::
  
              'monthly':12
              'weekly': 52
              'daily': 252
  
      annualization : int, optional
          Used to suppress default values available in `period` to convert
          returns into annual returns. Value should be the annual frequency of
          `returns`.
      _downside_risk : float, optional
          The downside risk of the given inputs, if known. Will be calculated if
          not provided.
      out : array-like, optional
          Array to use as output buffer.
          If not passed, a new array will be created.
  
      Returns
      -------
      sortino_ratio : float or pd.Series
  
          depends on input type
          series ==> float
          DataFrame ==> pd.Series
  
      Note
      -----
      See `<https://www.sunrisecapital.com/wp-content/uploads/2014/06/Futures_
      Mag_Sortino_0213.pdf>`__ for more details.
  
      """; 34, assignment; 35, identifier:allocated_output; 36, block; 37, assignment; 38, comparison_operator:len(returns) < 2; 39, block; 40, assignment; 41, assignment; 42, assignment; 43, assignment; 44, call; 45, identifier:return_1d; 46, block; 47, elif_clause; 48, identifier:out; 49, identifier:allocated_output; 50, comparison_operator:out is None; 51, expression_statement; 52, identifier:return_1d; 53, comparison_operator:returns.ndim == 1; 54, call; 55, integer:2; 56, expression_statement; 57, if_statement; 58, return_statement; 59, identifier:adj_returns; 60, call; 61, identifier:ann_factor; 62, call; 63, identifier:average_annual_return; 64, binary_operator:nanmean(adj_returns, axis=0) * ann_factor; 65, identifier:annualized_downside_risk; 66, parenthesized_expression; 67, attribute; 68, argument_list; 69, expression_statement; 70, call; 71, block; 72, identifier:out; 73, None; 74, assignment; 75, attribute; 76, integer:1; 77, identifier:len; 78, argument_list; 79, assignment; 80, identifier:return_1d; 81, block; 82, identifier:out; 83, attribute; 84, argument_list; 85, identifier:annualization_factor; 86, argument_list; 87, call; 88, identifier:ann_factor; 89, conditional_expression:_downside_risk
          if _downside_risk is not None else
          downside_risk(returns, required_return, period, annualization); 90, identifier:np; 91, identifier:divide; 92, identifier:average_annual_return; 93, identifier:annualized_downside_risk; 94, keyword_argument; 95, assignment; 96, identifier:isinstance; 97, argument_list; 98, expression_statement; 99, identifier:out; 100, call; 101, identifier:returns; 102, identifier:ndim; 103, identifier:returns; 104, subscript; 105, attribute; 106, expression_statement; 107, identifier:np; 108, identifier:asanyarray; 109, call; 110, identifier:period; 111, identifier:annualization; 112, identifier:nanmean; 113, argument_list; 114, identifier:_downside_risk; 115, comparison_operator:_downside_risk is not None; 116, call; 117, identifier:out; 118, identifier:out; 119, identifier:out; 120, call; 121, identifier:returns; 122, attribute; 123, assignment; 124, attribute; 125, argument_list; 126, identifier:out; 127, tuple; 128, identifier:np; 129, identifier:nan; 130, assignment; 131, identifier:_adjust_returns; 132, argument_list; 133, identifier:adj_returns; 134, keyword_argument; 135, identifier:_downside_risk; 136, None; 137, identifier:downside_risk; 138, argument_list; 139, attribute; 140, argument_list; 141, identifier:pd; 142, identifier:DataFrame; 143, identifier:out; 144, call; 145, identifier:np; 146, identifier:empty; 147, subscript; 148, identifier:out; 149, call; 150, identifier:returns; 151, identifier:required_return; 152, identifier:axis; 153, integer:0; 154, identifier:returns; 155, identifier:required_return; 156, identifier:period; 157, identifier:annualization; 158, identifier:out; 159, identifier:item; 160, attribute; 161, argument_list; 162, attribute; 163, slice; 164, attribute; 165, argument_list; 166, identifier:pd; 167, identifier:Series; 168, identifier:out; 169, identifier:returns; 170, identifier:shape; 171, integer:1; 172, identifier:out; 173, identifier:item
code: def sortino_ratio(returns,
                    required_return=0,
                    period=DAILY,
                    annualization=None,
                    out=None,
                    _downside_risk=None):
      """
      Determines the Sortino ratio of a strategy.
  
      Parameters
      ----------
      returns : pd.Series or np.ndarray or pd.DataFrame
          Daily returns of the strategy, noncumulative.
          - See full explanation in :func:`~empyrical.stats.cum_returns`.
      required_return: float / series
          minimum acceptable return
      period : str, optional
          Defines the periodicity of the 'returns' data for purposes of
          annualizing. Value ignored if `annualization` parameter is specified.
          Defaults are::
  
              'monthly':12
              'weekly': 52
              'daily': 252
  
      annualization : int, optional
          Used to suppress default values available in `period` to convert
          returns into annual returns. Value should be the annual frequency of
          `returns`.
      _downside_risk : float, optional
          The downside risk of the given inputs, if known. Will be calculated if
          not provided.
      out : array-like, optional
          Array to use as output buffer.
          If not passed, a new array will be created.
  
      Returns
      -------
      sortino_ratio : float or pd.Series
  
          depends on input type
          series ==> float
          DataFrame ==> pd.Series
  
      Note
      -----
      See `<https://www.sunrisecapital.com/wp-content/uploads/2014/06/Futures_
      Mag_Sortino_0213.pdf>`__ for more details.
  
      """
      allocated_output = out is None
      if allocated_output:
          out = np.empty(returns.shape[1:])
  
      return_1d = returns.ndim == 1
  
      if len(returns) < 2:
          out[()] = np.nan
          if return_1d:
              out = out.item()
          return out
  
      adj_returns = np.asanyarray(_adjust_returns(returns, required_return))
  
      ann_factor = annualization_factor(period, annualization)
  
      average_annual_return = nanmean(adj_returns, axis=0) * ann_factor
      annualized_downside_risk = (
          _downside_risk
          if _downside_risk is not None else
          downside_risk(returns, required_return, period, annualization)
      )
      np.divide(average_annual_return, annualized_downside_risk, out=out)
      if return_1d:
          out = out.item()
      elif isinstance(returns, pd.DataFrame):
          out = pd.Series(out)
  
      return out