nodes: 0, module; 1, function_definition; 2, function_name:downside_risk; 3, parameters; 4, block; 5, identifier:returns; 6, default_parameter; 7, default_parameter; 8, default_parameter; 9, default_parameter; 10, expression_statement; 11, expression_statement; 12, if_statement; 13, expression_statement; 14, if_statement; 15, expression_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, comment:"""
      Determines the downside deviation below a threshold
  
      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`.
      out : array-like, optional
          Array to use as output buffer.
          If not passed, a new array will be created.
  
      Returns
      -------
      downside_deviation : 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, specifically why using the
      standard deviation of the negative returns is not correct.
      """; 32, assignment; 33, identifier:allocated_output; 34, block; 35, assignment; 36, comparison_operator:len(returns) < 1; 37, block; 38, assignment; 39, assignment; 40, call; 41, call; 42, call; 43, call; 44, identifier:returns_1d; 45, block; 46, elif_clause; 47, identifier:out; 48, identifier:allocated_output; 49, comparison_operator:out is None; 50, expression_statement; 51, identifier:returns_1d; 52, comparison_operator:returns.ndim == 1; 53, call; 54, integer:1; 55, expression_statement; 56, if_statement; 57, return_statement; 58, identifier:ann_factor; 59, call; 60, identifier:downside_diff; 61, call; 62, attribute; 63, argument_list; 64, identifier:nanmean; 65, argument_list; 66, attribute; 67, argument_list; 68, attribute; 69, argument_list; 70, expression_statement; 71, call; 72, block; 73, identifier:out; 74, None; 75, assignment; 76, attribute; 77, integer:1; 78, identifier:len; 79, argument_list; 80, assignment; 81, identifier:returns_1d; 82, block; 83, identifier:out; 84, identifier:annualization_factor; 85, argument_list; 86, attribute; 87, argument_list; 88, identifier:np; 89, identifier:square; 90, identifier:downside_diff; 91, keyword_argument; 92, identifier:downside_diff; 93, keyword_argument; 94, keyword_argument; 95, identifier:np; 96, identifier:sqrt; 97, identifier:out; 98, keyword_argument; 99, identifier:np; 100, identifier:multiply; 101, identifier:out; 102, call; 103, keyword_argument; 104, assignment; 105, identifier:isinstance; 106, argument_list; 107, expression_statement; 108, identifier:out; 109, call; 110, identifier:returns; 111, identifier:ndim; 112, identifier:returns; 113, subscript; 114, attribute; 115, expression_statement; 116, identifier:period; 117, identifier:annualization; 118, identifier:np; 119, identifier:clip; 120, call; 121, attribute; 122, integer:0; 123, identifier:out; 124, identifier:downside_diff; 125, identifier:axis; 126, integer:0; 127, identifier:out; 128, identifier:out; 129, identifier:out; 130, identifier:out; 131, attribute; 132, argument_list; 133, identifier:out; 134, identifier:out; 135, identifier:out; 136, call; 137, identifier:returns; 138, attribute; 139, assignment; 140, attribute; 141, argument_list; 142, identifier:out; 143, tuple; 144, identifier:np; 145, identifier:nan; 146, assignment; 147, identifier:_adjust_returns; 148, argument_list; 149, identifier:np; 150, identifier:NINF; 151, identifier:np; 152, identifier:sqrt; 153, identifier:ann_factor; 154, attribute; 155, argument_list; 156, identifier:pd; 157, identifier:DataFrame; 158, identifier:out; 159, call; 160, identifier:np; 161, identifier:empty; 162, subscript; 163, identifier:out; 164, call; 165, call; 166, call; 167, identifier:out; 168, identifier:item; 169, attribute; 170, argument_list; 171, attribute; 172, slice; 173, attribute; 174, argument_list; 175, attribute; 176, argument_list; 177, attribute; 178, argument_list; 179, identifier:pd; 180, identifier:Series; 181, identifier:out; 182, keyword_argument; 183, identifier:returns; 184, identifier:shape; 185, integer:1; 186, identifier:out; 187, identifier:item; 188, identifier:np; 189, identifier:asanyarray; 190, identifier:returns; 191, identifier:np; 192, identifier:asanyarray; 193, identifier:required_return; 194, identifier:index; 195, attribute; 196, identifier:returns; 197, identifier:columns
code: def downside_risk(returns,
                    required_return=0,
                    period=DAILY,
                    annualization=None,
                    out=None):
      """
      Determines the downside deviation below a threshold
  
      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`.
      out : array-like, optional
          Array to use as output buffer.
          If not passed, a new array will be created.
  
      Returns
      -------
      downside_deviation : 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, specifically why using the
      standard deviation of the negative returns is not correct.
      """
      allocated_output = out is None
      if allocated_output:
          out = np.empty(returns.shape[1:])
  
      returns_1d = returns.ndim == 1
  
      if len(returns) < 1:
          out[()] = np.nan
          if returns_1d:
              out = out.item()
          return out
  
      ann_factor = annualization_factor(period, annualization)
  
      downside_diff = np.clip(
          _adjust_returns(
              np.asanyarray(returns),
              np.asanyarray(required_return),
          ),
          np.NINF,
          0,
      )
  
      np.square(downside_diff, out=downside_diff)
      nanmean(downside_diff, axis=0, out=out)
      np.sqrt(out, out=out)
      np.multiply(out, np.sqrt(ann_factor), out=out)
  
      if returns_1d:
          out = out.item()
      elif isinstance(returns, pd.DataFrame):
          out = pd.Series(out, index=returns.columns)
      return out