<commit_before>module Homma
  class Portfolio

    attr_accessor :current_positions, :current_holdings,
      :cash, :commission, :total

    DIRECTION_MAPPING = {
      buy: 1,
      sell: -1
    }

    def initialize context
      @context = context
      @commission_per_trade = @context.commission_per_trade

      @current_positions = context.symbols.inject({}) do |h, symbol|
        h.merge(symbol => 0)
      end

      @current_holdings = context.symbols.inject({}) do |h, symbol|
        h.merge(symbol => 0.0)
      end

      @cash = @context.starting_capital
      @commission = 0.0
      @total = 0.0
    end

    def on_bar bar
      bar.each do |symbol, data|
        if !data.nil? && data.has_key?(:adj_close)
          @current_holdings[symbol] = @current_positions[symbol] * data[:adj_close]
        end
      end
      @total = @cash + @current_holdings.inject(0) { |sum, (symbol, value)| sum + value }
    end

    def on_fill symbol, direction, quantity
      fill_cost = @context.feeder.market_data[symbol].last[:adj_close]

      # update positions
      fill_direction = DIRECTION_MAPPING[direction].to_i
      @current_positions[symbol] += (fill_direction * quantity)

      order_fill_cost = @current_positions[symbol] * fill_cost
      order_commission = @commission_per_trade # assuming flat commission per trade
      order_total_cost = order_fill_cost + order_commission

      # update holdings
      @current_holdings[symbol] += order_fill_cost
      @commission += order_commission
      @cash -= order_total_cost
      @total = @cash + @commission + @current_holdings[symbol]
    end

    def place_order symbol, direction
      # max out order quantity with all cash we have
      order_quantity = ( (@cash - @commission_per_trade) / @context.feeder.market_data[symbol].last[:adj_close]).floor
      current_quantity = @current_positions[symbol]
      direction, quantity = if direction == :long && current_quantity == 0
                         [:buy, order_quantity]
                       elsif direction == :short && current_quantity == 0
                         [:sell, order_quantity]
                       elsif direction == :exit && currrent_quantity > 0
                         [:sell, current_quantity.to_i.abs]
                       elsif direction == :exit && current_quantity < 0
                         [:buy, current_quantity.to_i.abs]
                       end
      @context.events.push Event.new(:order, symbol: symbol, direction: direction, quantity: quantity)
    end

  end
end
<commit_msg>calculate returns<commit_after>module Homma
  class Portfolio

    attr_accessor :current_positions, :current_holdings,
      :cash, :commission, :total

    DIRECTION_MAPPING = {
      buy: 1,
      sell: -1
    }

    def initialize context
      @context = context
      @commission_per_trade = @context.commission_per_trade

      @current_positions = context.symbols.inject({}) do |h, symbol|
        h.merge(symbol => 0)
      end

      @current_holdings = context.symbols.inject({}) do |h, symbol|
        h.merge(symbol => 0.0)
      end

      @cash = @context.starting_capital
      @commission = 0.0
      @total = @context.starting_capital
      @returns = {}
    end

    def on_bar bar
      bar.each do |symbol, data|
        if !data.nil? && data.has_key?(:adj_close)
          @current_holdings[symbol] = @current_positions[symbol] * data[:adj_close]
        end
      end
      new_total = @cash + @current_holdings.inject(0) { |sum, (symbol, value)| sum + value }
      @returns[@context.current_date.strftime('%Y-%m-%d')] = new_total / @total
      @total = new_total
    end

    def on_fill symbol, direction, quantity
      fill_cost = @context.feeder.market_data[symbol].last[:adj_close]

      # update positions
      fill_direction = DIRECTION_MAPPING[direction].to_i
      @current_positions[symbol] += (fill_direction * quantity)

      order_fill_cost = @current_positions[symbol] * fill_cost
      order_commission = @commission_per_trade # assuming flat commission per trade
      order_total_cost = order_fill_cost + order_commission

      # update holdings
      @current_holdings[symbol] += order_fill_cost
      @commission += order_commission
      @cash -= order_total_cost
      @total = @cash + @current_holdings[symbol]
    end

    def place_order symbol, direction
      # max out order quantity with all cash we have
      order_quantity = ( (@cash - @commission_per_trade) / @context.feeder.market_data[symbol].last[:adj_close]).floor
      current_quantity = @current_positions[symbol]
      direction, quantity = if direction == :long && current_quantity == 0
                         [:buy, order_quantity]
                       elsif direction == :short && current_quantity == 0
                         [:sell, order_quantity]
                       elsif direction == :exit && currrent_quantity > 0
                         [:sell, current_quantity.to_i.abs]
                       elsif direction == :exit && current_quantity < 0
                         [:buy, current_quantity.to_i.abs]
                       end
      @context.events.push Event.new(:order, symbol: symbol, direction: direction, quantity: quantity)
    end

  end
end

{'fraction_non_alphanumeric': 0.10026686999618757, 'fraction_numerical': 0.004956157072054899, 'mean_word_length': 2.429411764705882, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3673241', 'n_tokens_mistral': 1622, 'n_tokens_neox': 1491, 'n_words': 346}