# from investing_algorithm_framework.core.models import PerformanceMetric, \
#     TimeFrame
# from investing_algorithm_framework.core.performance import \
#     SnapshotAssetPriceCollection
#
#
# class PerformanceService:
#
#     @staticmethod
#     def of_metric(portfolio, metric: PerformanceMetric, time_frame: TimeFrame):
#         # Create SnapshotAssetPriceCollection object for iteration
#         snapshot_asset_price_collection = SnapshotAssetPriceCollection(
#             portfolio=portfolio,
#             time_frame=time_frame,
#         )
#
#         if PerformanceMetric.OVERALL_PERFORMANCE.equals(metric):
#             return PerformanceService().generate_overall_performance(
#                 snapshot_asset_price_collection
#             )
#         elif PerformanceMetric.DELTA.equals(metric):
#             return PerformanceService().generate_delta(
#                 snapshot_asset_price_collection
#             )
#
#         raise NotImplementedError("Performance metric not supported")
#
#     def generate_delta(self, snapshot_asset_price_collection):
#         """
#             Performance calculation with Time Weighted Return
#             TWR = [(1 + HP_1) * (1 + HP_2) * ... * (1 + HP_n)] - 1
#
#             Where
#                 TWR = Time weighted return
#                 n = Number of sub-periods
#                 HP = (Total Value - (Previous Total Value + Cash Flow))
#                         / (Previous Total Value + Cash Flow)
#                 HP_n = Return for sub-period n
#         """
#         points = []
#         previous_snapshot = None
#         previous_asset_prices = None
#         previous_point = 1.0
#         delta = 1
#
#         points.append(previous_point)
#
#         for date, snapshot, asset_prices in snapshot_asset_price_collection:
#             points.append(1 + self.get_hp(
#                 snapshot,
#                 previous_snapshot,
#                 asset_prices,
#                 previous_asset_prices
#             ))
#
#             previous_asset_prices = asset_prices
#             previous_snapshot = snapshot
#
#         for point in points:
#             delta = delta * point
#
#         return delta - 1
#
#     def generate_overall_performance(self, snapshot_asset_price_collection):
#         """
#             Performance calculation with Time Weighted Return
#             TWR = [(1 + HP_1) * (1 + HP_2) * ... * (1 + HP_n)] - 1
#
#             Where
#                 TWR = Time weighted return
#                 n = Number of sub-periods
#                 HP = (Total Value - (Previous Total Value + Cash Flow))
#                         / (Previous Total Value + Cash Flow)
#                 HP_n = Return for sub-period n
#         """
#         points = []
#         previous_snapshot = None
#         previous_asset_prices = None
#         previous_point = 1.0
#
#         for date, snapshot, asset_prices in snapshot_asset_price_collection:
#             hp_value = 1 + self.get_hp(
#                 snapshot,
#                 previous_snapshot,
#                 asset_prices,
#                 previous_asset_prices
#             )
#
#             points.append(
#                 {
#                     "datetime": date,
#                     "value": (previous_point * hp_value) - 1
#                 }
#             )
#
#             previous_asset_prices = asset_prices
#             previous_snapshot = snapshot
#             previous_point = (previous_point * hp_value)
#
#         return points
#
#     def get_hp(
#         self,
#         snapshot,
#         previous_snapshot,
#         current_asset_prices,
#         previous_asset_prices
#     ):
#         if snapshot is not None and previous_snapshot is not None:
#             return (
#                 snapshot.get_total_value(current_asset_prices) -
#                 (previous_snapshot.get_total_value(previous_asset_prices)
#                  + snapshot.cash_flow)) \
#                / (previous_snapshot.get_total_value(previous_asset_prices)
#                   + snapshot.cash_flow)
#
#         return 0

# from investing_algorithm_framework.core.models import PerformanceMetric, \
#     TimeFrame
# from investing_algorithm_framework.core.performance import \
#     SnapshotAssetPriceCollection
#
#
# class PerformanceService:
#
#     @staticmethod
#     def of_metric(portfolio, metric: PerformanceMetric, time_frame: TimeFrame):
#         # Create SnapshotAssetPriceCollection object for iteration
#         snapshot_asset_price_collection = SnapshotAssetPriceCollection(
#             portfolio=portfolio,
#             time_frame=time_frame,
#         )
#
#         if PerformanceMetric.OVERALL_PERFORMANCE.equals(metric):
#             return PerformanceService().generate_overall_performance(
#                 snapshot_asset_price_collection
#             )
#         elif PerformanceMetric.DELTA.equals(metric):
#             return PerformanceService().generate_delta(
#                 snapshot_asset_price_collection
#             )
#
#         raise NotImplementedError("Performance metric not supported")
#
#     def generate_delta(self, snapshot_asset_price_collection):
#         """
#             Performance calculation with Time Weighted Return
#             TWR = [(1 + HP_1) * (1 + HP_2) * ... * (1 + HP_n)] - 1
#
#             Where
#                 TWR = Time weighted return
#                 n = Number of sub-periods
#                 HP = (Total Value - (Previous Total Value + Cash Flow))
#                         / (Previous Total Value + Cash Flow)
#                 HP_n = Return for sub-period n
#         """
#         points = []
#         previous_snapshot = None
#         previous_asset_prices = None
#         previous_point = 1.0
#         delta = 1
#
#         points.append(previous_point)
#
#         for date, snapshot, asset_prices in snapshot_asset_price_collection:
#             points.append(1 + self.get_hp(
#                 snapshot,
#                 previous_snapshot,
#                 asset_prices,
#                 previous_asset_prices
#             ))
#
#             previous_asset_prices = asset_prices
#             previous_snapshot = snapshot
#
#         for point in points:
#             delta = delta * point
#
#         return delta - 1
#
#     def generate_overall_performance(self, snapshot_asset_price_collection):
#         """
#             Performance calculation with Time Weighted Return
#             TWR = [(1 + HP_1) * (1 + HP_2) * ... * (1 + HP_n)] - 1
#
#             Where
#                 TWR = Time weighted return
#                 n = Number of sub-periods
#                 HP = (Total Value - (Previous Total Value + Cash Flow))
#                         / (Previous Total Value + Cash Flow)
#                 HP_n = Return for sub-period n
#         """
#         points = []
#         previous_snapshot = None
#         previous_asset_prices = None
#         previous_point = 1.0
#
#         for date, snapshot, asset_prices in snapshot_asset_price_collection:
#             hp_value = 1 + self.get_hp(
#                 snapshot,
#                 previous_snapshot,
#                 asset_prices,
#                 previous_asset_prices
#             )
#
#             points.append(
#                 {
#                     "datetime": date,
#                     "value": (previous_point * hp_value) - 1
#                 }
#             )
#
#             previous_asset_prices = asset_prices
#             previous_snapshot = snapshot
#             previous_point = (previous_point * hp_value)
#
#         return points
#
#     def get_hp(
#         self,
#         snapshot,
#         previous_snapshot,
#         current_asset_prices,
#         previous_asset_prices
#     ):
#         if snapshot is not None and previous_snapshot is not None:
#             return (
#                 snapshot.get_total_value(current_asset_prices) -
#                 (previous_snapshot.get_total_value(previous_asset_prices)
#                  + snapshot.cash_flow)) \
#                / (previous_snapshot.get_total_value(previous_asset_prices)
#                   + snapshot.cash_flow)
#
#         return 0

# from investing_algorithm_framework.core.models import PerformanceMetric, \ #     TimeFrame # from investing_algorithm_framework.core.performance import \ #     SnapshotAssetPriceCollection # # # class PerformanceService: # #     @staticmethod #     def of_metric(portfolio, metric: PerformanceMetric, time_frame: TimeFrame): #         # Create SnapshotAssetPriceCollection object for iteration #         snapshot_asset_price_collection = SnapshotAssetPriceCollection( #             portfolio=portfolio, #             time_frame=time_frame, #         ) # #         if PerformanceMetric.OVERALL_PERFORMANCE.equals(metric): #             return PerformanceService().generate_overall_performance( #                 snapshot_asset_price_collection #             ) #         elif PerformanceMetric.DELTA.equals(metric): #             return PerformanceService().generate_delta( #                 snapshot_asset_price_collection #             ) # #         raise NotImplementedError("Performance metric not supported") # #     def generate_delta(self, snapshot_asset_price_collection): #         """ #             Performance calculation with Time Weighted Return #             TWR = [(1 + HP_1) * (1 + HP_2) * ... * (1 + HP_n)] - 1 # #             Where #                 TWR = Time weighted return #                 n = Number of sub-periods #                 HP = (Total Value - (Previous Total Value + Cash Flow)) #                         / (Previous Total Value + Cash Flow) #                 HP_n = Return for sub-period n #         """ #         points = [] #         previous_snapshot = None #         previous_asset_prices = None #         previous_point = 1.0 #         delta = 1 # #         points.append(previous_point) # #         for date, snapshot, asset_prices in snapshot_asset_price_collection: #             points.append(1 + self.get_hp( #                 snapshot, #                 previous_snapshot, #                 asset_prices, #                 previous_asset_prices #             )) # #             previous_asset_prices = asset_prices #             previous_snapshot = snapshot # #         for point in points: #             delta = delta * point # #         return delta - 1 # #     def generate_overall_performance(self, snapshot_asset_price_collection): #         """ #             Performance calculation with Time Weighted Return #             TWR = [(1 + HP_1) * (1 + HP_2) * ... * (1 + HP_n)] - 1 # #             Where #                 TWR = Time weighted return #                 n = Number of sub-periods #                 HP = (Total Value - (Previous Total Value + Cash Flow)) #                         / (Previous Total Value + Cash Flow) #                 HP_n = Return for sub-period n #         """ #         points = [] #         previous_snapshot = None #         previous_asset_prices = None #         previous_point = 1.0 # #         for date, snapshot, asset_prices in snapshot_asset_price_collection: #             hp_value = 1 + self.get_hp( #                 snapshot, #                 previous_snapshot, #                 asset_prices, #                 previous_asset_prices #             ) # #             points.append( #                 { #                     "datetime": date, #                     "value": (previous_point * hp_value) - 1 #                 } #             ) # #             previous_asset_prices = asset_prices #             previous_snapshot = snapshot #             previous_point = (previous_point * hp_value) # #         return points # #     def get_hp( #         self, #         snapshot, #         previous_snapshot, #         current_asset_prices, #         previous_asset_prices #     ): #         if snapshot is not None and previous_snapshot is not None: #             return ( #                 snapshot.get_total_value(current_asset_prices) - #                 (previous_snapshot.get_total_value(previous_asset_prices) #                  + snapshot.cash_flow)) \ #                / (previous_snapshot.get_total_value(previous_asset_prices) #                   + snapshot.cash_flow) # #         return 0