nodes: 0, module; 1, function_definition; 2, function_name:risk_metric_period; 3, parameters; 4, block; 5, identifier:cls; 6, identifier:start_session; 7, identifier:end_session; 8, identifier:algorithm_returns; 9, identifier:benchmark_returns; 10, identifier:algorithm_leverages; 11, expression_statement; 12, expression_statement; 13, comment:# Benchmark needs to be masked to the same dates as the algo returns; 14, expression_statement; 15, expression_statement; 16, expression_statement; 17, expression_statement; 18, expression_statement; 19, comment:# The consumer currently expects a 0.0 value for sharpe in period,; 20, comment:# this differs from cumulative which was np.nan.; 21, comment:# When factoring out the sharpe_ratio, the different return types; 22, comment:# were collapsed into `np.nan`.; 23, comment:# TODO: Either fix consumer to accept `np.nan` or make the; 24, comment:# `sharpe_ratio` return type configurable.; 25, comment:# In the meantime, convert nan values to 0.0; 26, if_statement; 27, expression_statement; 28, expression_statement; 29, comment:# check if a field in rval is nan or inf, and replace it with None; 30, comment:# except period_label which is always a str; 31, return_statement; 32, comment:"""
          Creates a dictionary representing the state of the risk report.
  
          Parameters
          ----------
          start_session : pd.Timestamp
              Start of period (inclusive) to produce metrics on
          end_session : pd.Timestamp
              End of period (inclusive) to produce metrics on
          algorithm_returns : pd.Series(pd.Timestamp -> float)
              Series of algorithm returns as of the end of each session
          benchmark_returns : pd.Series(pd.Timestamp -> float)
              Series of benchmark returns as of the end of each session
          algorithm_leverages : pd.Series(pd.Timestamp -> float)
              Series of algorithm leverages as of the end of each session
  
  
          Returns
          -------
          risk_metric : dict[str, any]
              Dict of metrics that with fields like:
                  {
                      'algorithm_period_return': 0.0,
                      'benchmark_period_return': 0.0,
                      'treasury_period_return': 0,
                      'excess_return': 0.0,
                      'alpha': 0.0,
                      'beta': 0.0,
                      'sharpe': 0.0,
                      'sortino': 0.0,
                      'period_label': '1970-01',
                      'trading_days': 0,
                      'algo_volatility': 0.0,
                      'benchmark_volatility': 0.0,
                      'max_drawdown': 0.0,
                      'max_leverage': 0.0,
                  }
          """; 33, assignment; 34, assignment; 35, assignment; 36, assignment; 37, assignment; 38, assignment; 39, call; 40, block; 41, assignment; 42, assignment; 43, dictionary_comprehension; 44, identifier:algorithm_returns; 45, subscript; 46, identifier:benchmark_returns; 47, subscript; 48, identifier:benchmark_period_returns; 49, subscript; 50, identifier:algorithm_period_returns; 51, subscript; 52, pattern_list; 53, call; 54, identifier:sharpe; 55, call; 56, attribute; 57, argument_list; 58, expression_statement; 59, identifier:sortino; 60, call; 61, identifier:rval; 62, dictionary; 63, pair; 64, for_in_clause; 65, identifier:algorithm_returns; 66, binary_operator:(algorithm_returns.index >= start_session) &
              (algorithm_returns.index <= end_session); 67, identifier:benchmark_returns; 68, binary_operator:(benchmark_returns.index >= start_session) &
              (benchmark_returns.index <= algorithm_returns.index[-1]); 69, attribute; 70, unary_operator; 71, attribute; 72, unary_operator; 73, identifier:alpha; 74, identifier:beta; 75, attribute; 76, argument_list; 77, attribute; 78, argument_list; 79, identifier:pd; 80, identifier:isnull; 81, identifier:sharpe; 82, assignment; 83, attribute; 84, argument_list; 85, pair; 86, pair; 87, pair; 88, pair; 89, pair; 90, pair; 91, pair; 92, pair; 93, pair; 94, pair; 95, pair; 96, pair; 97, pair; 98, pair; 99, identifier:k; 100, parenthesized_expression; 101, pattern_list; 102, call; 103, parenthesized_expression; 104, parenthesized_expression; 105, parenthesized_expression; 106, parenthesized_expression; 107, call; 108, identifier:iloc; 109, integer:1; 110, call; 111, identifier:iloc; 112, integer:1; 113, identifier:ep; 114, identifier:alpha_beta_aligned; 115, attribute; 116, attribute; 117, identifier:ep; 118, identifier:sharpe_ratio; 119, identifier:algorithm_returns; 120, identifier:sharpe; 121, float:0.0; 122, identifier:ep; 123, identifier:sortino_ratio; 124, attribute; 125, keyword_argument; 126, string; 127, identifier:algorithm_period_returns; 128, string; 129, identifier:benchmark_period_returns; 130, string; 131, integer:0; 132, string; 133, identifier:algorithm_period_returns; 134, string; 135, identifier:alpha; 136, string; 137, identifier:beta; 138, string; 139, identifier:sharpe; 140, string; 141, identifier:sortino; 142, string; 143, call; 144, string; 145, call; 146, string; 147, call; 148, string; 149, call; 150, string; 151, call; 152, string; 153, call; 154, conditional_expression:None
                  if k != 'period_label' and not np.isfinite(v) else
                  v; 155, identifier:k; 156, identifier:v; 157, identifier:iteritems; 158, argument_list; 159, comparison_operator:algorithm_returns.index >= start_session; 160, comparison_operator:algorithm_returns.index <= end_session; 161, comparison_operator:benchmark_returns.index >= start_session; 162, comparison_operator:benchmark_returns.index <= algorithm_returns.index[-1]; 163, attribute; 164, argument_list; 165, attribute; 166, argument_list; 167, identifier:algorithm_returns; 168, identifier:values; 169, identifier:benchmark_returns; 170, identifier:values; 171, identifier:algorithm_returns; 172, identifier:values; 173, identifier:_downside_risk; 174, call; 175, string_content:algorithm_period_return; 176, string_content:benchmark_period_return; 177, string_content:treasury_period_return; 178, string_content:excess_return; 179, string_content:alpha; 180, string_content:beta; 181, string_content:sharpe; 182, string_content:sortino; 183, string_content:period_label; 184, attribute; 185, argument_list; 186, string_content:trading_days; 187, identifier:len; 188, argument_list; 189, string_content:algo_volatility; 190, attribute; 191, argument_list; 192, string_content:benchmark_volatility; 193, attribute; 194, argument_list; 195, string_content:max_drawdown; 196, attribute; 197, argument_list; 198, string_content:max_leverage; 199, attribute; 200, argument_list; 201, None; 202, boolean_operator; 203, identifier:v; 204, identifier:rval; 205, attribute; 206, identifier:start_session; 207, attribute; 208, identifier:end_session; 209, attribute; 210, identifier:start_session; 211, attribute; 212, subscript; 213, identifier:ep; 214, identifier:cum_returns; 215, identifier:benchmark_returns; 216, identifier:ep; 217, identifier:cum_returns; 218, identifier:algorithm_returns; 219, attribute; 220, argument_list; 221, identifier:end_session; 222, identifier:strftime; 223, string:"%Y-%m"; 224, identifier:benchmark_returns; 225, identifier:ep; 226, identifier:annual_volatility; 227, identifier:algorithm_returns; 228, identifier:ep; 229, identifier:annual_volatility; 230, identifier:benchmark_returns; 231, identifier:ep; 232, identifier:max_drawdown; 233, attribute; 234, identifier:algorithm_leverages; 235, identifier:max; 236, comparison_operator:k != 'period_label'; 237, not_operator; 238, identifier:algorithm_returns; 239, identifier:index; 240, identifier:algorithm_returns; 241, identifier:index; 242, identifier:benchmark_returns; 243, identifier:index; 244, identifier:benchmark_returns; 245, identifier:index; 246, attribute; 247, unary_operator; 248, identifier:ep; 249, identifier:downside_risk; 250, attribute; 251, identifier:algorithm_returns; 252, identifier:values; 253, identifier:k; 254, string; 255, call; 256, identifier:algorithm_returns; 257, identifier:index; 258, integer:1; 259, identifier:algorithm_returns; 260, identifier:values; 261, string_content:period_label; 262, attribute; 263, argument_list; 264, identifier:np; 265, identifier:isfinite; 266, identifier:v
code: def risk_metric_period(cls,
                             start_session,
                             end_session,
                             algorithm_returns,
                             benchmark_returns,
                             algorithm_leverages):
          """
          Creates a dictionary representing the state of the risk report.
  
          Parameters
          ----------
          start_session : pd.Timestamp
              Start of period (inclusive) to produce metrics on
          end_session : pd.Timestamp
              End of period (inclusive) to produce metrics on
          algorithm_returns : pd.Series(pd.Timestamp -> float)
              Series of algorithm returns as of the end of each session
          benchmark_returns : pd.Series(pd.Timestamp -> float)
              Series of benchmark returns as of the end of each session
          algorithm_leverages : pd.Series(pd.Timestamp -> float)
              Series of algorithm leverages as of the end of each session
  
  
          Returns
          -------
          risk_metric : dict[str, any]
              Dict of metrics that with fields like:
                  {
                      'algorithm_period_return': 0.0,
                      'benchmark_period_return': 0.0,
                      'treasury_period_return': 0,
                      'excess_return': 0.0,
                      'alpha': 0.0,
                      'beta': 0.0,
                      'sharpe': 0.0,
                      'sortino': 0.0,
                      'period_label': '1970-01',
                      'trading_days': 0,
                      'algo_volatility': 0.0,
                      'benchmark_volatility': 0.0,
                      'max_drawdown': 0.0,
                      'max_leverage': 0.0,
                  }
          """
  
          algorithm_returns = algorithm_returns[
              (algorithm_returns.index >= start_session) &
              (algorithm_returns.index <= end_session)
          ]
  
          # Benchmark needs to be masked to the same dates as the algo returns
          benchmark_returns = benchmark_returns[
              (benchmark_returns.index >= start_session) &
              (benchmark_returns.index <= algorithm_returns.index[-1])
          ]
  
          benchmark_period_returns = ep.cum_returns(benchmark_returns).iloc[-1]
          algorithm_period_returns = ep.cum_returns(algorithm_returns).iloc[-1]
  
          alpha, beta = ep.alpha_beta_aligned(
              algorithm_returns.values,
              benchmark_returns.values,
          )
  
          sharpe = ep.sharpe_ratio(algorithm_returns)
  
          # The consumer currently expects a 0.0 value for sharpe in period,
          # this differs from cumulative which was np.nan.
          # When factoring out the sharpe_ratio, the different return types
          # were collapsed into `np.nan`.
          # TODO: Either fix consumer to accept `np.nan` or make the
          # `sharpe_ratio` return type configurable.
          # In the meantime, convert nan values to 0.0
          if pd.isnull(sharpe):
              sharpe = 0.0
  
          sortino = ep.sortino_ratio(
              algorithm_returns.values,
              _downside_risk=ep.downside_risk(algorithm_returns.values),
          )
  
          rval = {
              'algorithm_period_return': algorithm_period_returns,
              'benchmark_period_return': benchmark_period_returns,
              'treasury_period_return': 0,
              'excess_return': algorithm_period_returns,
              'alpha': alpha,
              'beta': beta,
              'sharpe': sharpe,
              'sortino': sortino,
              'period_label': end_session.strftime("%Y-%m"),
              'trading_days': len(benchmark_returns),
              'algo_volatility': ep.annual_volatility(algorithm_returns),
              'benchmark_volatility': ep.annual_volatility(benchmark_returns),
              'max_drawdown': ep.max_drawdown(algorithm_returns.values),
              'max_leverage': algorithm_leverages.max(),
          }
  
          # check if a field in rval is nan or inf, and replace it with None
          # except period_label which is always a str
          return {
              k: (
                  None
                  if k != 'period_label' and not np.isfinite(v) else
                  v
              )
              for k, v in iteritems(rval)
          }