Exemple #1
0
 def showProgressBar(self, flag=True):
     if flag and self.progress == None:
         self.progress = ProgBar()
     elif self.progress != None and not flag:
         if self.progress.isActive():
             self.progress.halt()
         self.progress = None
Exemple #2
0
def optimap(f_xy, X_params, Y_params, heat=True, symm=False):

    Stats = ["Trades", "Mean", "R | Sharpe", "R | Sterling"
             ]  ## Around which statistical metrics are we going to optimize.
    arrays = (list, tuple, dict, range, numpy.ndarray, pandas.Series
              )  ## Indexable arrays for "X" & "Y" parameter arguments.
    assert isinstance(X_params, arrays) and isinstance(
        Y_params, arrays), "{TYPE} 'X' & 'Y' params must be indexable arrays."
    X_labels, Y_labels = X_params, Y_params  ## "Grid" df's index/column labels may tentatively be the parameters themselves.
    ## However, if "X"/"Y" params' array is a dict, keys will be column labels in Grid. Values will be arguments for "f_xy".
    if isinstance(X_params, dict):
        X_params, X_labels = list(X_params.values()), list(X_params.keys())
    if isinstance(Y_params, dict):
        Y_params, Y_labels = list(Y_params.values()), list(Y_params.keys())
    Grid = pandas.DataFrame(
        index=X_labels,
        columns=pandas.MultiIndex.from_product(iterables=(Stats, Y_labels)))
    Combs = list(itertools.product(range(len(X_params)), range(
        len(Y_params))))  ## Indexes of all possible "X" & "Y" pairs.
    ## In cases where "X" & "Y" share exact same indicator nature (e.g.: both SMA), omit repeated/swapped cases. Example:
    if symm:
        Combs = [(nx, ny) for nx, ny in Combs if (X_params[nx] <= Y_params[ny])
                 ]  ## "(p1, p2) = (p2, p1)". Keep just one.
    Prog = ProgBar.ProgBar(steps=len(
        list(Combs)))  ## Create a progress bar made with characters.
    ## For given parameters "x" and "y", we will run the exercise, find its stats and create a 2D grid.
    for nx, ny in Combs:  ## For every combination of parameters.
        x_param, y_param, x_label, y_label = X_params[nx], Y_params[
            ny], X_labels[nx], Y_labels[ny]
        try:  ## Run the exercise with a function as specified.
            S = f_xy(x_param, y_param).Stats[symbol][
                "Return"]  ## From the backtest results, keep only the returns' ".Stats".
            for stat in Stats:
                Grid.loc[x_label, (stat, y_label)] = S[stat]
        except:
            1  ## When it's impossible to calculate stats (e.g.: no signals/trades), forget about errors.
        Prog.up()  ## Increase progress bar.
    Figure, Axes = matplotlib.pyplot.subplots(ncols=len(Stats))
    ## Heatmaps will display the most optimal spots in red.
    Grid.replace(to_replace=[-numpy.inf, numpy.inf],
                 value=numpy.nan,
                 inplace=True)
    for n, stat in enumerate(Stats):  ## Infs ⇧ when denominator is 0.
        lim = max(abs(Grid[stat].min().min()), abs(
            Grid[stat].max().max())) * 1.25  ## Y-axes' max span for lines.
        if heat:
            Axes[n].contourf(*numpy.meshgrid(X_params, Y_params),
                             Grid[stat].values.T)
            # Heatmap, 2D.
        else:
            Grid[stat].plot(
                ylim=[-lim * (Grid[stat] < 0).any().any(),
                      lim],  ## When no negative numbers found...
                ax=Axes[n],
                legend=False,
                linewidth=2.5)
            ## ...lowest y-axis point can be 0.
        Axes[n].set_title(stat, fontweight="bold")
    if not (heat):
        Axes[0].legend(fontsize=13)  ## Add legend just to the first line plot.
    matplotlib.pyplot.pause(
        1e-13)  ## This line avoids a (quite loooong) Tkinter warning print.
    return Figure, Grid