% Skript zum Test der Momentum Strategie
% Input Definieren:
%   iRankingPeriod:   integer,   ranking-Zeitraum - Perioden
%   iGapPeriod:       integer,   Zeitraum zw. Ranking & Holding - Perioden
%   iHoldingPeriod:   integer,   Holding-Zeitraum - Perioden
%   iNumPortfolio:    integer,   Anzahl der zu bildenen Portfolio (gemäß
%                                Ranking-Zeitraum)
%   iUsedPortfolio:   integer,   betrachtetes Portfolio, für Strategie zu
%                                 verwendetes Portfolio
%    mReturns:        N X M - Matrix, Matrix der Renditen, älteste Beobachtung oben, jünste
%                     Beobachtung unten, Assets in den Spalten

% (Kleine Matrix auf die Große matrix rübergestüllpt und geguckt wieviel
% mal sie rüberläuft)
% outputs
%   mResults.Detail    N x M - Matrix
%       column 1 :     number of ranking periods
%       column 2 :     number of gap periods
%       column 3 :     number of holding periods
%       column 4 :     ranking from period
%       column 5 :     ranking to period
%       column 6 :     holding from peroiod
%       column 7 :     holding to period
%       column 8 :     used portfolio
%       column 9 :     average performance of portfolio in window per
%                      period
%       column 10-end: used asset numbers in used portfolio (column8)

% Test-Setting:

clear;
clc;

%mErgebniss= [];

%--------------------------------------------------------------------
%mKurse=xlsread('Assets.xlsx', 'Tabelle1', 'B3:AE4698');
%mKurse1=  xlsread('Assets.xls', 'Tabelle1', 'B3:IQ10561');
%mKurse2=  xlsread('Assets.xls', 'Tabelle2', 'B3:IQ10561');
%mKurse3=  xlsread('Assets.xls', 'Tabelle3', 'B3:IQ10561');
%mKurse4=  xlsread('Assets.xls', 'Tabelle4', 'B3:IQ10561');
%mKurse5=  xlsread('Assets.xls', 'Tabelle5', 'B3:IQ10561');
%mKurse6=  xlsread('Assets.xls', 'Tabelle6', 'B3:IQ10561');
%mKurse7=  xlsread('Assets.xls', 'Tabelle7', 'B3:IQ10561');
%mKurse8=  xlsread('Assets.xls', 'Tabelle8', 'B3:IQ10561');
%mKurse9=  xlsread('Assets.xls', 'Tabelle9', 'B3:DZ10561');

%mKurse=[mKurse1 mKurse2 mKurse3 mKurse4]; %mKurse5 mKurse6 mKurse7 mKurse8
%mKurse9];

%--------------------------------------------------------------------------
% Zeile 57-61 Parameter
mReturns= xlsread('Assets.xls','Tabelle1','B9517:AE10561');    %kurse einleiten d.h. wenns 2000 sind muss man 2000 schreibn

% for r=[60 120 180 240];
% for h=[60 120 180 240];
iRankingPeriod=  60;
iHoldingPeriod=  60;
iGapPeriod=       1;
iNumPortfolios=  5;    %anzahl portfolios
iUsingPortfolio= 5;   %welches portfolio soll verwendet werden
                        %Niedrigste Zahl = schlechtestes Portfolio; höchste
                        %Zahl = bestes Portfolio



%routine
% Zeile        Spalte    = Dimensionserkennung von mReturns (Matrix von iNumPeriods & iNumAssets)
[iNumPeriods iNumAssets] = size (mReturns); %Zeilen und Spalten von mKurse:Perioden und Anzahl Aktien werden ermittelt
iNumAssetsPerPortfolio = floor(iNumAssets/iNumPortfolios)+1;
                        


% Stetige Renditen ausrechnen
mRendite = log(mReturns(2:end,:))-log(mReturns(1:end-1,:));  



mResults = [];
vColsPortfolio=[];

%Überlappende Holding Periods - test momentum Strategy
% iWindowLength = iRankingPeriod + iGapPeriod + iHoldingPeriod;
% iNumIteration = (iNumPeriods - iWindowLength +1);

% Nicht-Überlappende Holding Periods -Index Tracking
iWindowLength = iRankingPeriod + iHoldingPeriod + iGapPeriod ;
iNumIteration= (iNumPeriods - iRankingPeriod - iGapPeriod)/ iHoldingPeriod;
for i = 1:iNumIteration
    mWindow = mReturns (i*iHoldingPeriod-iHoldingPeriod+1:i*iHoldingPeriod-iHoldingPeriod+iWindowLength,:);
   
    mWindow = [1:iNumAssets; mWindow]; %spalten werden nummeriert, damit man nachher die felder ohne einträge rausschmeißen kann
    % remove assets with NaN's
    for a = 1:iNumAssets
        if any (isnan(mWindow(2:iRankingPeriod+iGapPeriod+1,a)))
        %if any(isnan (mWindow(2:end,j)))
            vLogic(1,a) = 0;
        else 
            vLogic (1,a) = 1;
        end
    end
    %durchschnittliche Tagesrendite
    mWindowNoNan = mWindow(:,logical(vLogic)); %alte matrix, alte zeilen, aber nur die spalten, in denen auch eine 1 im logischen vektor steht,werden übernommen
    vRanking = mean (mWindowNoNan(2:iRankingPeriod+1,:),1); %die 1 hinten stellt sicher, dass matlab jeweils die spalten mittelt!
    dQuantileStepSize = 1/iNumPortfolios;    %anzahl portfolios..
    vQuantile = 0:dQuantileStepSize:1;
    vQuantileVAL = quantile(vRanking,vQuantile);
    vQuantileVAL(1,1)= vQuantileVAL(1,1) - 0.00001;
    % Prüfung der schlechtesten Rankings, ob der Quantilswert
    for j = 1:size(vRanking,2)
        if ((vRanking(j) > vQuantileVAL (iUsingPortfolio)) && (vRanking(j) <= vQuantileVAL(iUsingPortfolio+1)));
            vColsPortfolio = [vColsPortfolio mWindowNoNan(1,j)];
        end
    end
    mHolding = mWindow(1+iRankingPeriod+iGapPeriod+1:end,[vColsPortfolio]);
    vResults = NaN(1,9+iNumAssetsPerPortfolio);
    vResults(1,1) = iRankingPeriod; % number of ranking periods
    vResults(1,2) = iGapPeriod;     % number of gap periods
    vResults(1,3) = iHoldingPeriod; % number of holding periods
    vResults(1,4) = i*iHoldingPeriod-iHoldingPeriod+1;  %Ranking FROM Period
    vResults(1,5) = i*iHoldingPeriod-iHoldingPeriod+iRankingPeriod; % Ranking TO Period
    vResults(1,6) = i*iHoldingPeriod-2*iHoldingPeriod+iWindowLength+1; % Holding FROM Period
    vResults(1,7) = i*iHoldingPeriod-iHoldingPeriod+iWindowLength;  % Holding TO Period
    vResults(1,8) = iUsingPortfolio;    % used portfolio
    vResults(1,9)= mean (mean(mHolding)); % average performance of portfolio in window per period
    [rows cols] = size (vColsPortfolio);
    vResults (1,10:9+cols)= vColsPortfolio;
    mResults = [mResults; vResults];
        vColsPortfolio =[];
end      
 %--------------------------------------------------------------------------     
 %  PROBE     ANFANG

 % Daten zerlegen
mAssetRet = mReturns(:,1:end-1);
vIndexRet = mReturns(:,end);   

% Unter- und Obergrenzen setzen
vLB = 0.05 * ones(8,1);
vUB = 0.4 * ones(8,1);
% 
% Bonus-Return setzen
% Wenn dBonus = [], dann wird ohne Bonus Return optimiert
dBonus = 0.008;  

[vWeights, dEstTE2, iRetCode] = fIndTrackMar(vIndexRet, mAssetRet, dBonus, vLB, vUB);


% % [vWts, fval, exitflag] = fMarIndexOpt(vR, mV, dBonus, vLB, vUB)
% % % Markowitz Optimierung zur Bestimmung eines Tracking Portfolios
% % %
% % % INPUT:
% % %   vR:     1x(N+1) Zeilenvektor der erwarteten Renditen (N Assets + 1 Index)
% % %   mV:     (N+1)x(N+1) Kovarianzmatrix
% % %   dBonus: geforderter Bonus-Retunr, wenn dBonus = [], dann wird der
% % %           Bonus-Return nicht berücksichtigt
% % %   vLB:    Nx1 Vektor der Bestandsuntergrenzen
% % %   vUB:    Nx1 Vektor der Bestandsobergrenzen
% % % OUTPUT:
% % %   vWts:   Nx1 Gewichtevektor
% % %   fval:   Zielfunktionswert, hier: quadrierter Tracking Error
% % %   exitflag: Return-Code der quadratischen Optimierung
% % 
% % % Aufsetzen des Optimierungsproblems für Toolbox-Routine
% % iNumAssets = size(vR,2);
% % f = zeros(iNumAssets,1);
% % H = 2 * mV;
% % A = [];
% % b = [];
% % Aeq = [ones(1,iNumAssets); [zeros(1,iNumAssets-1) 1]];
% % beq = [0; -1];
% % if ~isempty(dBonus)
% %     Aeq = [Aeq; vR];
% %     beq = [beq; dBonus];
% % end
% %     
% % % Optionen für den Optimierungsalgorithmus setzen
% % options = optimset('Display', 'off', 'LargeScale', 'off');
% % 
% % % Startpunkt ist naive Portfolio
% % vW0 = [1/(iNumAssets-1) * ones(iNumAssets-1,1); -1];
% % 
% % % Toolbox-Routine: Quadratische Optimierung
% % [vWts, fval, exitflag] = quadprog(H, f, A, b, Aeq, beq, vLB, vUB, vW0, options);
% % 
% % % Ergebnis der Optimierung prüfen und Gewichte zurückgeben
% % if exitflag ~= 1
% %     vWts = zeros(iNumAssets-1,1);
% % else
% %     vWts = vWts(1:end-1,:);
% % end


%xlswrite('Assets.xls', vWeights, 'Tabelle10', 'B2');
%xlswrite('Assets.xls', dEstTE2, 'Tabelle10', 'B8');
   

% PROBE   ENDE


%mErgebnisse= [mErgebnisse; Ranking Holding mean(mResults(:,9))];
% end 
% end



     %-----------------------------------------------------------------------------      
        %-----------------------------------------------
%     %% Hier IndexTracking anwenden
%     % Beispieldaten einlesen
%mReturnData = xlsread('IndexTrackingMarkowitz.xls', 'Markowitz Ansatz', 'L12:T120');
%mReturnData = mHolding;            %muss das nicht iwie die rankingperiod sein??

% % Daten zerlegen
% mAssetRet = mReturnData(:,1:end-1);
% vIndexRet = mReturnData(:,end);
% 
% Unter- und Obergrenzen setzen
% vLB = 0.05 * ones(8,1);
% vUB = 0.4 * ones(8,1);
% 
% Bonus-Return setzen
% Wenn dBonus = [], dann wird ohne Bonus Return optimiert
% dBonus = 0.008;
%dBonus = [];
% % 
% % Tracking Portfolio ausrechnen
% [vWeights, dEstTE2, iRetCode] = fIndTrackMar(vIndexRet, mAssetRet, dBonus, vLB, vUB);

% % Daten nach Excel schreiben
% %xlswrite('IndexTrackingMarkowitz.xls', vWeights, 'Markowitz Ansatz', 'X44');
% %xlswrite('IndexTrackingMarkowitz.xls', dEstTE2, 'Markowitz Ansatz', 'X52');
% 
% xlswrite('indextracking.xls', vWeights, 'Tabelle1', 'A1');
% xlswrite('indextracking.xls', dEstTE2, 'Tabelle1', 'B1');    
%     
%     
    
%end
  

%1.Performance des Portfolios bezieht sich hier auf die gesamte Halteperiode.
% Für das Index-Tracking ist aber die Performance des Portfolios zu jedem
% Zeitpunkt notwendig.
%2. Hier: Momentum-Strategie mit aufeinander folgenden Halteperioden (->
%für Index Bildung). Für Test der Momentum-Strategie notwendig:
%überlappende Halteperioden.
%3. Schleifen für Inputparameter verwenden
%4. Achtung: Vorzeichen der UsedPortfolios (Winner/Loser)


