examples

trailing stop loss

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
for index, frame in tqdm(df.groupby('date'), 'Backtesting'):
   days_count = frame.index[0]
     frame.set_index('ticker', inplace=True)

   # Sell if stop loss is hit
   for ticker, info in portfolio.holding():
      if frame.loc[ticker, 'low'] <= info['cut_loss']:
          portfolio.sell(ticker, Reason.EXIT, index, info['cut_loss'], days_count)

   # Trailing stop loss
   for ticker, info in portfolio.holding():
      stop_percentage = 0.25
      trailing_stop_price = frame.loc[ticker, 'high'] * (1 - stop_percentage)  # Trail stop 25% below current high
      if trailing_stop_price > info['cut_loss']:
          portfolio.set_cut_loss_price(ticker, trailing_stop_price)

take profit

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# take profit can be set when initializing portfolio
portfolio = Portfolio(df, EquityModel.CORE_EQUITY, PositionSizing.EQUAL_UNIT, initial_capital=100000, size=10, take_profit=0.34, cut_loss=0.1)

for index, frame in tqdm(df.groupby('date'), "Backtesting"):
   days_count = frame.index[0]
   frame.set_index('ticker', inplace=True)

   for ticker, info in portfolio.holding():
      if frame.loc[ticker, 'low'] <= info['cut_loss']:
          portfolio.sell(ticker, Reason.CL, index, info['cut_loss'], days_count)

      elif frame.loc[ticker, 'sell_signal'] == 1:
          portfolio.sell(ticker, Reason.EXIT, index, frame.loc[ticker, 'open'], days_count)

      elif info['take_profit'] is not None: # examples for take profit
          if frame.loc[ticker, 'high'] >= info['take_profit']:
              portfolio.sell(ticker, Reason.TP, index, info['take_profit'], days_count)

# take profit can be overrode by calling portfolio.buy(..., tp_price= ?)

time stop

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
df['sell_signal'] = np.where((df['buy_signal'].shift(10) > 0) & (df['ticker'] == df['ticker'].shift(10)),
                          df['date'].shift(10).dt.date, pd.to_datetime('2000-01-01'))

for index, frame in tqdm(df.groupby('date'), "Backtesting"):  # loop dataframe by date
    days_count = frame.index[0]  # date
    frame.set_index('ticker', inplace=True)  # set ticker as index

    # Check portfolio and sell if stop loss is hit
    for ticker, info in portfolio.holding():
        if frame.loc[ticker, 'sell_signal'] == info['open_date']:  # 10 days sell signal
            portfolio.sell(ticker, Reason.EXIT, index, frame.loc[ticker, 'open'], days_count)

consider commissions and set brokerage fee in portfolio

1
2
portfolio = Portfolio(df, EquityModel.CORE_EQUITY, PositionSizing.EQUAL_UNIT, initial_capital=100000, size=10,
                      take_profit=None, cut_loss=0.1, commission=True, brokerage_fee=0.08)

sell based on yesterday’s condition

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
yesterday_frame = pd.DataFrame()

for index, frame in tqdm(df.groupby('date'), "Backtesting"):
    days_count = frame.index[0]
    frame.set_index('ticker', inplace=True)

    for ticker, info in portfolio.holding():
        # Sell at market open if previous bar close below SL
        if yesterday_frame.loc[ticker, 'close'] <= info['cut_loss']:
            portfolio.sell(ticker, Reason.EXIT, index, frame.loc[ticker, 'open'], days_count)

    yesterday_frame = frame.copy()  # Update yesterday frame

view all performances of strategy

1
2
3
4
5
6
7
8
performance = Performance(portfolio, show=True)
performance.objective_function()
performance.performance_metric()
performance.transactions_to_csv()
performance.objective_to_csv('strategy 1', 'objective_function.csv')
performance.performance_to_csv('performance 1', 'performance_metric.csv')
performance.generate_all_files(strategy_name='strategy_name', code_path='file_name.py', version='v1',
                               plot_image=True)

dataframe list for multi period backtesting

1
2
3
4
5
6
7
date1 = pd.to_datetime('2019-01-01')
date2 = pd.to_datetime('2020-01-01')
date3 = pd.to_datetime('2021-01-01')
df_list = universe.df_multi_period(date1, date2, date3)

for df in df_list:
# do backtesting

stocks to buy tomorrow at market open

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# Init df_today
today = datetime.today().strftime('%Y-%m-%d')
today = pd.to_datetime(today)
mask = df.index.date == today
df_today = df[mask]
df_today.set_index('ticker', inplace=True)

# Stocks to buy tomorrow
buy = []
df_today['buy_signal_today'] = np.where((df_today['turnover'] >= 1000000), df['turnover'].values, 0)
df_today = df_today.loc[
               (df_today['buy_signal_today'].values != 0) & (~df_today.index.isin(portfolio.list()))].sort_values(
    'buy_signal_today', ascending=False)[:portfolio.free()]
for item in df_today.index.to_list():
    portfolio.buy(item, today, df_today.loc[item, 'close'], today)
    buy.append(item)
print(f'Buy tomorrow at market open: {buy}')

backtest on different parameters

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
def backtest(param1, param2):
    # do backtesting

    # record performance into csv
    performance = Performance(portfolio, show=False)
    performance.objective_function(need_print=False)
    performance.performance_metric(need_print=False)
    performance.objective_to_csv(f'{param1}_{param2}', 'objective_function.csv')
    performance.performance_to_csv(f'{param1}_{param2}', 'performance_metric.csv')


if __name__ == '__main__':
    # Init indicator and signal

    # Backtest
    for i in param1_list:  # row
        for j in param2_list:  # col
            backtest(i, j)

plot heatmap for specific metric

1
2
3
universe.plot_heatmap('objective_function.csv', 'Maximum Daily Drawdown %', param_row.tolist(),
                      param_col.tolist(), 'Param col', 'Param row', 15, 10, True,
                      'Drawdown Heatmap.png')

generate tick data

1
2
3
4
from optimus.backtesting.tick_data import TickData
tick_data = TickData()
df = tick_data.df
print(df)

resample a timeframe from tick data

1
2
from optimus.backtesting.tick_data import TickData
tick_data.resample('15min')

get dataframe of a timeframe

1
2
3
from optimus.backtesting.tick_data import TickData
timeframe_df = tick_data.get_timeframe('15min', '2021-07-12')
print(timeframe_df)

get technical analysis of a timeframe

1
2
3
4
5
6
from optimus.backtesting.tick_data import TickData
indicator = Indicator()
indicator.sma([50])
indicator.parabolic_sar()
ta_df = tick_data.get_TA('5min', indicator)
print(ta_df)