def test_value_update_long_position(self):
        """Tests if the values are correctly updated when holding a long
        position."""
        start_value = 1000
        sim = StockMarketStrategySim("test", datetime.date(2015,1,1),
                                     start_value, BuyAndHoldStrategy())
        sim.run()

        # The difference in points in the test csv is the following, assuming
        # buy on day 1 (at halfway point between open and close) and no sell:
        buy_val = (1005 + 1010) / 2.0
        proc_diff = (1010 - buy_val) / buy_val
        # Calculate end value. Private method in sim used here for test purposes
        # only:
        start_value_stock = start_value - sim._get_transaction_cost(start_value)
        end_value = start_value_stock * (1+proc_diff)

        # Using inequality check because of rounding differences and/or
        # inaccuracies due to using floats precision.

        assert abs(end_value - sim.get_current_value()) < .01, \
            "End value {0} expected, got {1}".format(end_value,
                                                     sim.get_current_value())
def grid_search(strategy_class, param_grid):
    """Performs a grid search of all possible combinations or parameters
    in param_grid.
    Prints the best combination to screen when done.

    Input:
    - strategy: concrete subclass of AbstractStrategy (not instantiated)
    - param_grid: a lists of dicts in form: [{'kwarg': [options]}]
                  e.g. [{'rsi_days': [7, 14, 21], {'rsi_buy_threshold': [30]}]
    The current maximum is 4 keyword args.
    """
    highest = None
    highest_params = {}

    param_combinations, mapping = parse_grid_params(param_grid)

    num_runs = len(param_combinations)
    print("{} unique combinations of parameters found. Starting...".format(num_runs))

    run_number = 1
    for comb in param_combinations:
        strategy_kwargs = {}
        for indexer, arg_name in mapping.iteritems():
            strategy_kwargs[arg_name] = comb[indexer]

        strategy = strategy_class(**strategy_kwargs)

        start_date = datetime.date(2014, 7, 1)
        sim = StockMarketStrategySim("^GSPC", start_date, 10000, strategy).set_silent()
        sim.run()

        value = sim.get_current_value()

        print("Run {}/{} completed, value at end: {:5.2f}".format(run_number, num_runs, value))

        if value > highest:
            highest = value
            highest_params = strategy_kwargs

        run_number += 1

    print("Done! Best value: {}, best params: {}".format(highest, highest_params))