Whitelist portfolio simulation

In [70]:
from simple_back_test import *
import warnings
warnings.filterwarnings('ignore')
import pickle
from plotnine import *
from dfply import *
In [48]:
ff = "../../data/portfolio_simulations_many.pickle"
br_runs = pickle.load(open(ff, 'rb'))
In [58]:
runs = all_runs_to_df(br_runs)
In [102]:
runs = runs >> arrange('annualised_ret', ascending=False)
In [95]:
def table_and_chart(df, gg):
    df[gg] = df[gg].astype('category')
    summarised = (df >> 
                  group_by(gg) >> 
                  summarise(
                            max_ann_ret = colmax(X.annualised_ret),
                            mean_ann_ret = mean(X.annualised_ret), 
                            min_ann_ret = colmin(X.annualised_ret),
                            mean_sharpe = mean(X.sharpe), 
                            mean_total_tracks=mean(X.total_number_tracks)))
   
    display(summarised)
    print(ggplot(df, aes('annualised_ret')) + geom_density(aes(color = gg), alpha = 0.5))
    return summarised
    

Compare difference max prices

In [68]:
max_price_diffs = runs >> mask(X.execution_slippage == 0.1, X.clip_individual_returns == 3, X.new_streams_per_date == 1/7)
In [96]:
a = table_and_chart(max_price_diffs, 'max_price')
max_price max_ann_ret mean_ann_ret min_ann_ret mean_sharpe mean_total_tracks
0 10000.0 0.557796 0.314418 0.135382 2.316898 52.00
1 20000.0 0.747912 0.388193 0.175065 2.073243 51.96
2 50000.0 1.110146 0.683299 0.189538 2.237604 50.66
<ggplot: (8775619826103)>

Compare differences for how many tracks we can sign

In [100]:
signed_deals_diff = runs >> mask(X.execution_slippage == 0.1, X.clip_individual_returns == 3, X.max_price == 50000)
a = table_and_chart(signed_deals_diff, 'new_streams_per_date')
new_streams_per_date max_ann_ret mean_ann_ret min_ann_ret mean_sharpe mean_total_tracks
0 0.142857 1.110146 0.683299 0.189538 2.237604 50.66
1 0.285714 1.532392 0.996685 0.351331 2.731044 87.11
2 0.428571 1.754954 1.186065 0.716061 2.988296 108.60
<ggplot: (-9223363261234876044)>

Compare clipping

In [105]:
df = runs >> mask(X.execution_slippage == 0.1, X.new_streams_per_date == 3/7, X.max_price == 50000)
a = table_and_chart(df, 'clip_individual_returns')
clip_individual_returns max_ann_ret mean_ann_ret min_ann_ret mean_sharpe mean_total_tracks
0 3 1.754954 1.186065 0.716061 2.988296 108.60
1 5 2.981609 1.885412 0.937845 2.895200 118.92
<ggplot: (-9223363261234725467)>

Compare execution slippage

In [106]:
df = runs >> mask(X.clip_individual_returns == 3, X.new_streams_per_date == 3/7, X.max_price == 50000)
a = table_and_chart(df, 'execution_slippage')
execution_slippage max_ann_ret mean_ann_ret min_ann_ret mean_sharpe mean_total_tracks
0 0.05 1.817067 1.258926 0.681593 3.084556 109.61
1 0.10 1.754954 1.186065 0.716061 2.988296 108.60
<ggplot: (-9223363261234987804)>

Best portolio

In [109]:
runs.iloc[0]
Out[109]:
artist_advance_fraction          0.800000
capital                     250000.000000
clip_individual_returns          5.000000
duration_days                  365.000000
execution_slippage               0.100000
max_price                    50000.000000
min_price                     5000.000000
new_streams_per_date             0.428571
payment_per_stream               0.005000
pop_5_slippage                   0.150000
average_positions               25.382932
average_position_size       389819.712787
average_portfolio_return         0.006188
portfolio_std                    0.042138
cumulative_return               11.251843
total_number_tracks            116.000000
max_drawdown                    -0.047787
sharpe                           2.331084
annualised_ret                   2.981609
annual_volatility                0.668921
sortino                         42.560849
downside_risk                    0.036637
tail_risk                       45.771678
Name: 3549, dtype: float64

Actual opportunities

In [174]:
actual_stream_counts
Out[174]:
Number of tracks Min streams Mean streams Median streams Max Streams
Artist_Advance
<2k 1248 10 1.082879e+05 37760.5 581970
5k 171 588900 9.344912e+05 882289.0 1466000
10k 93 1487000 2.117939e+06 2039966.0 2897000
20k 65 2949000 4.042791e+06 3997000.0 5767000
30k 40 6022000 8.885636e+06 8481000.0 14650000
>50k 64 14884400 7.826420e+07 29884500.0 740764000