summary

Сгенерируйте сводную таблицу результатов бэктеста

Описание

пример

summaryTable = summary(backtester) генерирует таблицу метрик для суммирования бэктеста. Каждая строка таблицы является вычисленной метрикой, и каждый столбец представляет стратегию. Вы должны запустить функцию summary только после запуска runBacktest функция.

Примеры

свернуть все

Механизм обратного тестирования MATLAB ® запускает бэктесты инвестиционных стратегий портфеля на временных рядах данных о ценах активов. Можно использовать summary сравнение нескольких стратегий по одному и тому же рыночному сценарию. В этом примере показано, как изучить результаты бэктеста с двумя стратегиями.

Загрузка данных

Загрузка данных о ценах на акции за один год. Для читаемости в этом примере используется подмножество запасов DJIA.

% Read table of daily adjusted close prices for 2006 DJIA stocks
T = readtable('dowPortfolio.xlsx');

% Prune the table to include only the dates and selected stocks
timeColumn = "Dates";
assetSymbols = ["BA", "CAT", "DIS", "GE", "IBM", "MCD", "MSFT"];
T = T(:,[timeColumn assetSymbols]);

% Convert to timetable
pricesTT = table2timetable(T,'RowTimes','Dates');

% View the final asset price timetable
head(pricesTT)
ans=8×7 timetable
       Dates        BA       CAT      DIS      GE       IBM      MCD     MSFT 
    ___________    _____    _____    _____    _____    _____    _____    _____

    03-Jan-2006    68.63    55.86    24.18     33.6    80.13    32.72    26.19
    04-Jan-2006    69.34    57.29    23.77    33.56    80.03    33.01    26.32
    05-Jan-2006    68.53    57.29    24.19    33.47    80.56    33.05    26.34
    06-Jan-2006    67.57    58.43    24.52     33.7    82.96    33.25    26.26
    09-Jan-2006    67.01    59.49    24.78    33.61    81.76    33.88    26.21
    10-Jan-2006    67.33    59.25    25.09    33.43     82.1    33.91    26.35
    11-Jan-2006     68.3    59.28    25.33    33.66    82.19     34.5    26.63
    12-Jan-2006     67.9    60.13    25.41    33.25    81.61    33.96    26.48

Стратегия обратного отклонения требует инициализации некоторой истории цен, поэтому можно выделить фрагмент данных для установки начальных весов. Делая это, можно «нагреть» бэктест.

warmupRange = 1:20;
testRange = 21:height(pricesTT);

Создание стратегий

Определите инвестиционную стратегию при помощи backtestStrategy функция. Этот пример строит две стратегии:

  • Равный взвешенный

  • Обратное отклонение

Этот пример не содержит подробных сведений о том, как создать стратегии. Для получения дополнительной информации о создании стратегий смотрите backtestStrategy. Функции ребаланса стратегии реализованы в разделе Функции ребаланса.

% Create the strategies
ewInitialWeights = equalWeightFcn([],pricesTT(warmupRange,:));
ewStrategy = backtestStrategy("EqualWeighted",@equalWeightFcn,...
    'RebalanceFrequency',20,...
    'TransactionCosts',[0.0025 0.005],...
    'LookbackWindow',0,...
    'InitialWeights',ewInitialWeights);

ivInitialWeights = inverseVarianceFcn([],pricesTT(warmupRange,:));
ivStrategy = backtestStrategy("InverseVariance",@inverseVarianceFcn,...
    'RebalanceFrequency',20,...
    'TransactionCosts',[0.0025 0.005],...
    'InitialWeights',ivInitialWeights);

% Aggregate the strategies into an array
strategies = [ewStrategy ivStrategy];

Запуск бэктеста

Создайте механизм обратного тестирования и запустите бэктест за год хранения данных. Для получения дополнительной информации о создании узлов обратного тестирования смотрите backtestEngine. Программа инициализирует несколько свойств backtestEngine объект пуст. Эти свойства только для чтения заполняются модулем после запуска бэктеста.

% Create the backtesting engine using the default settings
backtester = backtestEngine(strategies)
backtester = 
  backtestEngine with properties:

               Strategies: [1x2 backtestStrategy]
             RiskFreeRate: 0
           CashBorrowRate: 0
          RatesConvention: "Annualized"
                    Basis: 0
    InitialPortfolioValue: 10000
                NumAssets: []
                  Returns: []
                Positions: []
                 Turnover: []
                  BuyCost: []
                 SellCost: []

Запуск бэктеста с помощью runBacktest.

% Run the backtest
backtester = runBacktest(backtester,pricesTT(testRange,:));

Исследуйте итоговые результаты

The summary функция использует результаты backtest и возвращает таблицу результатов высокого уровня из backtest.

s1 = summary(backtester)
s1=9×2 table
                       EqualWeighted    InverseVariance
                       _____________    _______________

    TotalReturn            0.17567           0.17155   
    SharpeRatio           0.097946           0.10213   
    Volatility           0.0074876         0.0069961   
    AverageTurnover      0.0007014         0.0024246   
    MaxTurnover           0.021107          0.097472   
    AverageReturn       0.00073178        0.00071296   
    MaxDrawdown           0.097647          0.096299   
    AverageBuyCost        0.018532          0.061913   
    AverageSellCost       0.037064           0.12383   

Каждая строка выходного документа таблицы является измерением эффективности стратегии. Каждая стратегия занимает столбец. The summary отчеты функции по следующим метрикам:

  • TotalReturn - неаннулированный общий возврат стратегии, включая гонорары, в течение самого полного периода.

  • SharpeRatio - Неаннуализованное соотношение Шарпа каждой стратегии на обратном тесте. Для получения дополнительной информации смотрите sharpe.

  • Volatility - Неаннуализованное стандартное отклонение возвратов стратегии в относительных временных шагах.

  • AverageTurnover - Средний оборот портфеля за шаг времени, выраженный в десятичном проценте.

  • MaxTurnover - максимальный оборот портфеля в одном ребалансе, выраженный в десятичном проценте.

  • AverageReturn - арифметика доходности портфеля за временной шаг.

  • MaxDrawdown - Максимальная просадка портфеля, выраженная в десятичном проценте. Для получения дополнительной информации смотрите maxdrawdown.

  • AverageBuyCost - средние затраты на транзакцию в относительных временных шагах, связанные с портфелем покупок активов.

  • AverageSellCost - Средние затраты по транзакции в относительных временных шагах, связанные с портфелем продаж активов.

Иногда полезно транспонировать summary таблица при построении графиков метрик различных стратегий.

s2 = rows2vars(s1);
s2.Properties.VariableNames{1} = 'StrategyName'
s2=2×10 table
       StrategyName        TotalReturn    SharpeRatio    Volatility    AverageTurnover    MaxTurnover    AverageReturn    MaxDrawdown    AverageBuyCost    AverageSellCost
    ___________________    ___________    ___________    __________    _______________    ___________    _____________    ___________    ______________    _______________

    {'EqualWeighted'  }      0.17567       0.097946      0.0074876        0.0007014        0.021107       0.00073178       0.097647         0.018532          0.037064    
    {'InverseVariance'}      0.17155        0.10213      0.0069961        0.0024246        0.097472       0.00071296       0.096299         0.061913           0.12383    

bar(s2.AverageTurnover)
title('Average Turnover')
ylabel('Average Turnover (%)')
set(gca,'xticklabel',s2.StrategyName)

Figure contains an axes. The axes with title Average Turnover contains an object of type bar.

Исследуйте подробные результаты

После запуска backtest, backtestEngine объект обновляет поля только для чтения с подробными результатами бэктеста. The Returns, Positions, Turnover, BuyCost, и SellCost каждый из свойств содержит расписание результатов. Поскольку в этом примере используются данные дневной цены в backtest, эти расписания содержат ежедневные результаты.

backtester
backtester = 
  backtestEngine with properties:

               Strategies: [1x2 backtestStrategy]
             RiskFreeRate: 0
           CashBorrowRate: 0
          RatesConvention: "Annualized"
                    Basis: 0
    InitialPortfolioValue: 10000
                NumAssets: 7
                  Returns: [230x2 timetable]
                Positions: [1x1 struct]
                 Turnover: [230x2 timetable]
                  BuyCost: [230x2 timetable]
                 SellCost: [230x2 timetable]

Возвраты

The Returns свойство содержит расписание стратегических (простых) возвратов для каждого временного шага. Эти возвраты включают все комиссии за транзакции.

head(backtester.Returns)
ans=8×2 timetable
       Time        EqualWeighted    InverseVariance
    ___________    _____________    _______________

    02-Feb-2006      -0.007553        -0.0070957   
    03-Feb-2006     -0.0037771         -0.003327   
    06-Feb-2006     -0.0010094        -0.0014312   
    07-Feb-2006      0.0053284         0.0020578   
    08-Feb-2006      0.0099755         0.0095781   
    09-Feb-2006     -0.0026871        -0.0014999   
    10-Feb-2006      0.0048374         0.0059589   
    13-Feb-2006     -0.0056868        -0.0051232   

binedges = -0.025:0.0025:0.025;
h1 = histogram(backtester.Returns.EqualWeighted,'BinEdges',binedges);
hold on
histogram(backtester.Returns.InverseVariance,'BinEdges',binedges);
hold off
title('Distribution of Daily Returns')
legend([strategies.Name]);

Figure contains an axes. The axes with title Distribution of Daily Returns contains 2 objects of type histogram. These objects represent EqualWeighted, InverseVariance.

Положения

The Positions свойство содержит структуру расписаний, по одному на стратегию.

backtester.Positions
ans = struct with fields:
      EqualWeighted: [231x8 timetable]
    InverseVariance: [231x8 timetable]

The Positions расписание каждой стратегии содержит позиции в относительных шагах для каждого актива, а также Cash актив (который зарабатывает безрисковую ставку). The Positions расписания содержат на одну строку больше, чем другие расписания результатов, потому что Positions расписания включают начальные позиции стратегии в качестве их первой строки. Можно рассматривать начальные положения как Time = 0 портфельные позиции. В этом примере Positions расписания начинаются с 1 февраля, а остальные - со 2 февраля.

head(backtester.Positions.InverseVariance)
ans=8×8 timetable
       Time           Cash          BA       CAT       DIS        GE       IBM       MCD       MSFT 
    ___________    ___________    ______    ______    ______    ______    ______    ______    ______

    01-Feb-2006              0    1401.2    682.17    795.14    2186.8    1900.1    1874.9    1159.8
    02-Feb-2006              0    1402.8    673.74    789.74    2170.8    1883.5    1863.6      1145
    03-Feb-2006     1.0987e-12    1386.5     671.2     787.2    2167.3    1854.3    1890.5      1139
    06-Feb-2006     2.1942e-12    1391.9    676.78    785.62    2161.1    1843.6    1899.1    1123.8
    07-Feb-2006     1.0994e-12      1400    661.66    840.23    2131.9    1851.6    1902.3    1114.5
    08-Feb-2006    -2.2198e-12    1409.8     677.9    846.58    2160.4    1878.2      1911    1113.2
    09-Feb-2006              0    1414.8    674.35    840.87    2172.2      1869    1908.3    1102.6
    10-Feb-2006     1.1148e-12    1425.1    677.29     839.6    2195.8    1890.6    1909.3    1103.9

% Plot the change of asset allocation over time
t = backtester.Positions.InverseVariance.Time;
positions = backtester.Positions.InverseVariance.Variables;
h = area(t,positions);
title('Inverse Variance Positions');
xlabel('Date');
ylabel('Asset Positions');
datetick('x','mm/dd','keepticks');
ylim([0 12000])
xlim([t(1) t(end)])
cm = parula(numel(h));
for i = 1:numel(h)
    set(h(i),'FaceColor',cm(i,:));
end

Figure contains an axes. The axes with title Inverse Variance Positions contains 8 objects of type area.

Товарооборот

The Turnover расписание содержит оборот портфеля за временной шаг.

head(backtester.Turnover)
ans=8×2 timetable
       Time        EqualWeighted    InverseVariance
    ___________    _____________    _______________

    02-Feb-2006          0                 0       
    03-Feb-2006          0                 0       
    06-Feb-2006          0                 0       
    07-Feb-2006          0                 0       
    08-Feb-2006          0                 0       
    09-Feb-2006          0                 0       
    10-Feb-2006          0                 0       
    13-Feb-2006          0                 0       

В зависимости от частоты ребаланса, Turnover таблица может содержать в основном нули. Удаление этих нулей при визуализации оборота портфеля полезно.

nonZeroIdx = sum(backtester.Turnover.Variables,2) > 0;
to = backtester.Turnover(nonZeroIdx,:);
plot(to.Time,to.EqualWeighted,'-o',to.Time,to.InverseVariance,'-x',...
    'LineWidth',2,'MarkerSize',5);
legend([strategies.Name]);
title('Portfolio Turnover');
ylabel('Turnover (%)');

Figure contains an axes. The axes with title Portfolio Turnover contains 2 objects of type line. These objects represent EqualWeighted, InverseVariance.

BuyCost и SellCost

The BuyCost и SellCost В расписаниях указаны комиссии за транзакции для каждого типа транзакции, покупок и продаж.

totalCost = sum(backtester.BuyCost{:,:}) + sum(backtester.SellCost{:,:});
bar(totalCost);
title('Total Transaction Costs');
ylabel('$')
set(gca,'xticklabel',[strategies.Name])

Figure contains an axes. The axes with title Total Transaction Costs contains an object of type bar.

Сгенерируйте кривую собственного капитала

Использование equityCurve для построения графика кривой собственного капитала для стратегий равной взвешенного и обратного отклонения.

equityCurve(backtester)

Figure contains an axes. The axes with title Equity Curve contains 2 objects of type line. These objects represent EqualWeighted, InverseVariance.

Функции ребаланса

В этом разделе описывается реализация функций ребаланса стратегии. Для получения дополнительной информации о создании стратегий и записи функций ребаланса смотрите backtestStrategy.

function new_weights = equalWeightFcn(current_weights, pricesTT) %#ok<INUSL> 
% Equal weighted portfolio allocation

nAssets = size(pricesTT, 2);
new_weights = ones(1,nAssets);
new_weights = new_weights / sum(new_weights);

end
function new_weights = inverseVarianceFcn(current_weights, pricesTT) %#ok<INUSL> 
% Inverse-variance portfolio allocation

assetReturns = tick2ret(pricesTT);
assetCov = cov(assetReturns{:,:});
new_weights = 1 ./ diag(assetCov);
new_weights = new_weights / sum(new_weights);

end

Входные параметры

свернуть все

Механизм обратного тестирования, заданный как backtestEngine объект. Использование backtestEngine чтобы создать механизм обратного тестирования и затем использовать runBacktest чтобы запустить бэктест.

Типы данных: object

Выходные аргументы

свернуть все

Метрики, суммирующие бэктест, возвращаются как таблица, где каждая строка таблицы является вычисленной метрикой, и каждый столбец представляет стратегию. Представленные метрики следующие:

  • TotalReturn - Полный возврат стратегии по всему backtest

  • SharpeRatio - Коэффициент Шарпа для каждой стратегии

  • Volatility - Волатильность каждой стратегии по сравнению с backtest

  • AverageTurnover - Средний оборот за временной шаг в виде десятичного процента

  • MaxTurnover - Максимальный оборот за один временной шаг

  • AverageReturn - Среднее значение возврата за шаг времени

  • MaxDrawdown - Максимальная просадка портфеля в десятичных процентах

  • AverageBuyCost - Средние затраты по транзакциям для покупок активов в относительные сроки

  • AverageSellCost - Средние затраты по транзакциям для продаж основных средств в относительные сроки

Введенный в R2020b