Создание сводной таблицы результатов обратного тестирования
создает таблицу метрик для суммирования обратного теста. Каждая строка таблицы является вычисляемой метрикой, и каждый столбец представляет стратегию. Вы должны запустить функцию сводки только после выполнения summaryTable = summary(backtester)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,:));Анализ итоговых результатов
summary функция использует результаты теста и возвращает таблицу высокоуровневых результатов теста.
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
Каждая строка выходных данных таблицы представляет собой измерение эффективности стратегии. Каждая стратегия занимает столбец. 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)

Анализ подробных результатов
После того, как вы проведете обратный тест, backtestEngine объект обновляет поля, доступные только для чтения, с подробными результатами бэктеста. Returns, Positions, Turnover, BuyCost, и SellCost каждый из свойств содержит расписание результатов. Поскольку в этом примере используются данные о дневных ценах в фоновом тестировании, эти графики содержат ежедневные результаты.
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]
Прибыль
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]);

Положения
Positions свойство содержит структуру расписаний, по одному на стратегию.
backtester.Positions
ans = struct with fields:
EqualWeighted: [231x8 timetable]
InverseVariance: [231x8 timetable]
Positions график каждой стратегии содержит позиции за шаг по каждому активу, а также Cash актив (который зарабатывает безрисковую ставку). 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

Товарооборот
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 (%)');

Стоимость покупки и стоимость SellCost
BuyCost и SellCost расписания содержат пошаговые комиссии за транзакции для каждого типа транзакций, покупок и продаж.
totalCost = sum(backtester.BuyCost{:,:}) + sum(backtester.SellCost{:,:});
bar(totalCost);
title('Total Transaction Costs');
ylabel('$')
set(gca,'xticklabel',[strategies.Name])
Создание кривой собственного капитала
Использовать equityCurve для построения кривой собственного капитала для стратегий равной взвешенной и обратной дисперсии.
equityCurve(backtester)

Функции ребалансировки
В этом разделе описывается реализация функций перебалансировки стратегии. Дополнительные сведения о создании стратегий и записи функций ребалансировки см. в разделе 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
backtester - Двигатель обратного тестированияbacktestEngine объектМеханизм обратного тестирования, указанный как backtestEngine объект. Использовать backtestEngine для создания механизма обратного тестирования и последующего использования runBacktest чтобы выполнить обратный тест.
Типы данных: object
summaryTable - Показатели, суммирующие обратное тестированиеМетрики, суммирующие обратный тест, возвращаются в виде таблицы, где каждая строка таблицы является расчетной метрикой, а каждый столбец представляет стратегию. Ниже представлены следующие метрики:
TotalReturn - Общая отдача стратегии за весь бэктест
SharpeRatio - Коэффициент Шарпа для каждой стратегии
Volatility - Волатильность каждой стратегии в фоновом режиме
AverageTurnover - Средний оборот за шаг времени в десятичном проценте
MaxTurnover - Максимальный оборот за один временной шаг
AverageReturn - Средняя доходность за шаг
MaxDrawdown - Максимальное сокращение портфеля в десятичном проценте
AverageBuyCost - Средние затраты на транзакцию за шаг для покупки основных средств
AverageSellCost - Средние затраты на транзакцию за шаг для продажи основных средств
backtestEngine | backtestStrategy | equityCurve | runBacktest
Имеется измененная версия этого примера. Открыть этот пример с помощью изменений?
1. Если смысл перевода понятен, то лучше оставьте как есть и не придирайтесь к словам, синонимам и тому подобному. О вкусах не спорим.
2. Не дополняйте перевод комментариями “от себя”. В исправлении не должно появляться дополнительных смыслов и комментариев, отсутствующих в оригинале. Такие правки не получится интегрировать в алгоритме автоматического перевода.
3. Сохраняйте структуру оригинального текста - например, не разбивайте одно предложение на два.
4. Не имеет смысла однотипное исправление перевода какого-то термина во всех предложениях. Исправляйте только в одном месте. Когда Вашу правку одобрят, это исправление будет алгоритмически распространено и на другие части документации.
5. По иным вопросам, например если надо исправить заблокированное для перевода слово, обратитесь к редакторам через форму технической поддержки.