'Main generator work loop.'

def transform(self):

    algo = self.algo
    perf_tracker = algo.perf_tracker
    emission_rate = perf_tracker.emission_rate
    def every_bar(dt_to_use, current_data=self.current_data, handle_data=algo.event_manager.handle_data):
        algo.on_dt_changed(dt_to_use)
        for capital_change in calculate_minute_capital_changes(dt_to_use):
            (yield capital_change)
        self.simulation_dt = dt_to_use
        blotter = algo.blotter
        (new_transactions, new_commissions, closed_orders) = blotter.get_transactions(current_data)
        blotter.prune_orders(closed_orders)
        for transaction in new_transactions:
            perf_tracker.process_transaction(transaction)
            order = blotter.orders[transaction.order_id]
            perf_tracker.process_order(order)
        if new_commissions:
            for commission in new_commissions:
                perf_tracker.process_commission(commission)
        handle_data(algo, current_data, dt_to_use)
        new_orders = blotter.new_orders
        blotter.new_orders = []
        if new_orders:
            for new_order in new_orders:
                perf_tracker.process_order(new_order)
        algo.portfolio_needs_update = True
        algo.account_needs_update = True
        algo.performance_needs_update = True
    def once_a_day(midnight_dt, current_data=self.current_data, data_portal=self.data_portal):
        self.simulation_dt = midnight_dt
        algo.on_dt_changed(midnight_dt)
        for capital_change in algo.calculate_capital_changes(midnight_dt, emission_rate=emission_rate, is_interday=True):
            (yield capital_change)
        assets_we_care_about = (viewkeys(perf_tracker.position_tracker.positions) | viewkeys(algo.blotter.open_orders))
        if assets_we_care_about:
            splits = data_portal.get_splits(assets_we_care_about, midnight_dt)
            if splits:
                algo.blotter.process_splits(splits)
                perf_tracker.position_tracker.handle_splits(splits)
    def handle_benchmark(date, benchmark_source=self.benchmark_source):
        perf_tracker.all_benchmark_returns[date] = benchmark_source.get_value(date)
    def on_exit():
        self.algo = None
        self.benchmark_source = self.current_data = self.data_portal = None
    with ExitStack() as stack:
        stack.callback(on_exit)
        stack.enter_context(self.processor)
        stack.enter_context(ZiplineAPI(self.algo))
        if (algo.data_frequency == 'minute'):
            def execute_order_cancellation_policy():
                algo.blotter.execute_cancel_policy(SESSION_END)
            def calculate_minute_capital_changes(dt):
                return algo.calculate_capital_changes(dt, emission_rate=emission_rate, is_interday=False)
        else:
            def execute_order_cancellation_policy():
                pass
            def calculate_minute_capital_changes(dt):
                return []
        for (dt, action) in self.clock:
            if (action == BAR):
                for capital_change_packet in every_bar(dt):
                    (yield capital_change_packet)
            elif (action == SESSION_START):
                for capital_change_packet in once_a_day(dt):
                    (yield capital_change_packet)
            elif (action == SESSION_END):
                positions = perf_tracker.position_tracker.positions
                position_assets = algo.asset_finder.retrieve_all(positions)
                self._cleanup_expired_assets(dt, position_assets)
                if (emission_rate == 'daily'):
                    handle_benchmark(normalize_date(dt))
                else:
                    perf_tracker.update_performance()
                execute_order_cancellation_policy()
                algo.validate_account_controls()
                (yield self._get_daily_message(dt, algo, perf_tracker))
            elif (action == BEFORE_TRADING_START_BAR):
                self.simulation_dt = dt
                algo.on_dt_changed(dt)
                algo.before_trading_start(self.current_data)
            elif (action == MINUTE_END):
                handle_benchmark(dt)
                minute_msg = self._get_minute_message(dt, algo, perf_tracker)
                (yield minute_msg)
    risk_message = perf_tracker.handle_simulation_end()
    (yield risk_message)
