classdef app_tesis < matlab.apps.AppBase

    % Properties that correspond to app components
    properties (Access = public)
        BacktestingOptimizacindeportafoliosUIFigure  matlab.ui.Figure
        GridLayout                  matlab.ui.container.GridLayout
        LeftPanel                   matlab.ui.container.Panel
        SeleccioneLoscostosdeTransaccinButtonGroup  matlab.ui.container.ButtonGroup
        VariablesButton             matlab.ui.control.RadioButton
        Fijos20pbsButton            matlab.ui.control.RadioButton
        SincostosButton             matlab.ui.control.RadioButton
        SeleccioneelfactordeAversinalRiesgoEditField  matlab.ui.control.NumericEditField
        SeleccioneelfactordeAversinalRiesgoLabel  matlab.ui.control.Label
        SeleccioneFechaButtonGroup  matlab.ui.container.ButtonGroup
        Button_6                    matlab.ui.control.RadioButton
        Button_5                    matlab.ui.control.RadioButton
        Button_4                    matlab.ui.control.RadioButton
        Button_3                    matlab.ui.control.RadioButton
        Button_2                    matlab.ui.control.RadioButton
        AccionesseleccionadasLabel  matlab.ui.control.Label
        UITable                     matlab.ui.control.Table
        CargueelarchivoquecontieneladataLabel  matlab.ui.control.Label
        Button                      matlab.ui.control.Button
        RightPanel                  matlab.ui.container.Panel
        GuardarResumenButton        matlab.ui.control.Button
        ResumendeBacktestingMercadoCOLLabel  matlab.ui.control.Label
        UITable2_2                  matlab.ui.control.Table
        ResumendeBacktestingMercadoUSLabel  matlab.ui.control.Label
        UITable2                    matlab.ui.control.Table
        Archivo                     matlab.ui.container.Menu
        SalirMenu                   matlab.ui.container.Menu
        ContextMenu                 matlab.ui.container.ContextMenu
        CopiarMenu                  matlab.ui.container.Menu
    end

    % Properties that correspond to apps with auto-reflow
    properties (Access = private)
        onePanelWidth = 576;
    end


    properties (Access = private)
        DialogAPP % Description
        Nombre_Archivo
        file
        indice_fecha
        indice_transaccion
        contador
        lambda_m
        resumen_metricas
        resumen_metricas_col
        annualRiskFreeRate
    end

    methods (Access = public)


    end


    % Callbacks that handle component events
    methods (Access = private)

        % Code that executes after component creation
        function startupFcn(app)
            delete(gcp('nocreate'));
            app.UITable.Visible='off';
            app.UITable2.Visible = 'off';
            app.UITable2_2.Visible='off';
            app.indice_fecha = 1;
            app.indice_transaccion = 1;
            app.contador=0;
            annualRiskFreeRate = 0;
            app.lambda_m = 0.01;
        end

        % Changes arrangement of the app based on UIFigure width
        function updateAppLayout(app, event)
            currentFigureWidth = app.BacktestingOptimizacindeportafoliosUIFigure.Position(3);
            if(currentFigureWidth <= app.onePanelWidth)
                % Change to a 2x1 grid
                app.GridLayout.RowHeight = {550, 550};
                app.GridLayout.ColumnWidth = {'1x'};
                app.RightPanel.Layout.Row = 2;
                app.RightPanel.Layout.Column = 1;
            else
                % Change to a 1x2 grid
                app.GridLayout.RowHeight = {'1x'};
                app.GridLayout.ColumnWidth = {545, '1x'};
                app.RightPanel.Layout.Row = 1;
                app.RightPanel.Layout.Column = 2;
            end
        end

        % Menu selected function: SalirMenu
        function SalirMenuSelected(app, event)
            YN = uiconfirm(app.BacktestingOptimizacindeportafoliosUIFigure,'Desea cerrar la aplicación?', 'Cerrar');
            if strcmpi(YN,'OK')
                delete(app)
            end
        end

        % Close request function: 
        % BacktestingOptimizacindeportafoliosUIFigure
        function BacktestingOptimizacindeportafoliosUIFigureCloseRequest(app, event)
            YN = uiconfirm(app.BacktestingOptimizacindeportafoliosUIFigure,'Desea cerrar la aplicación?', 'Cerrar');
            if strcmpi(YN,'OK')
                delete(app)
            end

        end

        % Button pushed function: Button
        function ButtonPushed(app, event)
            %variable contador que sirve para habilitar las figuras

            delete(gcp('nocreate'));

            % Selecciona el archivo de excel con los precios de cierre
            [file,path] = uigetfile({'*.xlsx'},...
                'Seleccione Archivo');
            %Asigna a la variable Nombre_Archivo el valor de file

            if isnumeric(file) || isnumeric(path)
                errordlg('Debe Seleccionar un Archivo.','Error');
            else
                app.lambda_m= app.SeleccioneelfactordeAversinalRiesgoEditField.Value; 
                
                app.contador=app.contador+1
                app.Nombre_Archivo=file;
                % lee el arcihivo y lo almacena como una tabla
                Tabla_usa = readtable(app.Nombre_Archivo,'Sheet','US');
                benchmark_usa = readtable(app.Nombre_Archivo,'Sheet','S&P 500 index');
                Tabla_col = readtable(app.Nombre_Archivo,'Sheet','COL');
                benchmark_col = readtable(app.Nombre_Archivo,'Sheet','Colcap index');
                %% Guarda los tickers de la tabla ignorando la columna fecha
                assetSymbols = Tabla_usa.Properties.VariableNames(2:length(Tabla_usa.Properties.VariableNames));
                assetSymbols_col = Tabla_col.Properties.VariableNames(2:length(Tabla_col.Properties.VariableNames));
                %benchmark_usa_Symbol = ["GSPC"];
                benchmark_usa_Symbol = benchmark_usa.Properties.VariableNames(2);
                benchmark_col_Symbol = benchmark_col.Properties.VariableNames(2);
               
                % define la columna de fecha como Date
                timeColumn = Tabla_usa.Properties.VariableNames(1);

                Tabla_usa = Tabla_usa(:,[timeColumn assetSymbols]);
                Tabla_col = Tabla_col(:,[timeColumn assetSymbols_col]);


                benchmark_usa = benchmark_usa(:,[timeColumn benchmark_usa_Symbol]);
                benchmark_col = benchmark_col(:,[timeColumn benchmark_col_Symbol]);

                columnas = ["Date",assetSymbols, assetSymbols_col];
                % Para el uso del motor de backtesting la tabla se coniverte a
                % tabla de tiempo
                pricesTT = table2timetable(Tabla_usa,'RowTimes','Date');
                
                pricesTT_col = table2timetable(Tabla_col,'RowTimes','Date');
                benchmarkTT_col = table2timetable(benchmark_col,'RowTimes','Date');
                benchmarkTT_usa = table2timetable(benchmark_usa,'RowTimes','Date');
                % Hace visible la tabla con las acciones seleccionadas de
                % acuerdo al arcivo
                if app.contador==1
                    app.UITable.Visible='on';
                end
                %% Crea el label para las columnas de la tabla
                app.UITable.ColumnName = columnas;

                % ciclo que define el rango de fechas, el titulo que lleva el
                % mapa de calor, la tasa libre de riesgo y el periodo inicial
                % para la construcción de los portafolios de acuerdo al rango
                % seleccionado en el boton selección
                if app.indice_fecha==1
                    pricesTT = pricesTT(timerange("01-Jan-2013","01-Jan-2023"),:);
                    benchmarkTT_usa = benchmarkTT_usa(timerange("01-Jan-2013","01-Jan-2023"),:);
                    pricesTT_col = pricesTT_col(timerange("01-Jan-2013","01-Jan-2023"),:);
                    benchmarkTT_col = benchmarkTT_col(timerange("01-Jan-2013","01-Jan-2023"),:);
                    titulo_mapa_calor='Distribución inicial de activos 01/01/2013-31/12/2022';
                    app.annualRiskFreeRate = 0.0212;
                    warmupPeriod=252;
                elseif app.indice_fecha==2
                    pricesTT = pricesTT(timerange("01-Jan-2013","01-Jul-2015"),:);
                    benchmarkTT_usa = benchmarkTT_usa(timerange("01-Jan-2013","01-Jul-2015"),:);
                    pricesTT_col = pricesTT_col(timerange("01-Jan-2013","01-Jul-2015"),:);
                    benchmarkTT_col = benchmarkTT_col(timerange("01-Jan-2013","01-Jul-2015"),:);
                    titulo_mapa_calor='Distribución inicial de activos 01/01/2013-30/06/2015';
                    app.annualRiskFreeRate = 0.0233;
                    warmupPeriod=21*3;
                elseif app.indice_fecha==3
                    pricesTT = pricesTT(timerange("01-Jul-2015","01-Jan-2018"),:);
                    benchmarkTT_usa = benchmarkTT_usa(timerange("01-Jul-2015","01-Jan-2018"),:);
                    pricesTT_col = pricesTT_col(timerange("01-Jul-2015","01-Jan-2018"),:);
                    benchmarkTT_col = benchmarkTT_col(timerange("01-Jul-2015","01-Jan-2018"),:);
                    titulo_mapa_calor='Distribución inicial de activos 01/07/2015-31/12/2027';
                    app.annualRiskFreeRate = 0.0208;
                    warmupPeriod=21*3;
                elseif app.indice_fecha==4
                    pricesTT = pricesTT(timerange("01-Jan-2018","01-Jul-2020"),:);
                    benchmarkTT_usa = benchmarkTT_usa(timerange("01-Jan-2018","01-Jul-2020"),:);
                    pricesTT_col = pricesTT_col(timerange("01-Jan-2018","01-Jul-2020"),:);
                    benchmarkTT_col = benchmarkTT_col(timerange("01-Jan-2018","01-Jul-2020"),:);
                    titulo_mapa_calor='Distribución inicial de activos 01/01/2018-30/06/2020';
                    app.annualRiskFreeRate = 0.0220;
                    warmupPeriod=21*3;
                elseif app.indice_fecha==5
                    pricesTT = pricesTT(timerange("01-Jul-2020","01-Jan-2023"),:);
                    benchmarkTT_usa = benchmarkTT_usa(timerange("01-Jul-2020","01-Jan-2023"),:);
                    pricesTT_col = pricesTT_col(timerange("01-Jul-2020","01-Jan-2023"),:);
                    benchmarkTT_col = benchmarkTT_col(timerange("01-Jul-2020","01-Jan-2023"),:);
                    titulo_mapa_calor='Distribución inicial de activos 01/07/2020-31/12/2022';
                    app.annualRiskFreeRate = 0.0188;
                    warmupPeriod=21*3;
                end
                % añade la data seleccionada de acuerdo al periodo de tiempo a
                % la tabla que se visualiza
                precios = [pricesTT,pricesTT_col];
                app.UITable.Data=timetable2table(precios);
                % numSample = cantidad de datos a analizar
                numSample = size(pricesTT.Variables, 1);
                % numAssets = numero de activos
                numAssets = size(pricesTT.Variables, 2);
                numAssets_bench_usa= size(benchmarkTT_usa.Variables,2);
                numAssets_col = size(pricesTT_col.Variables,2);
                numAssets_bench_col = size(benchmarkTT_col.Variables,2);
                table(numSample, numAssets);




                %crea los pesos iniciales de los actrivos para que sean cero
                current_weights = zeros(1,numAssets);
                current_weight_benchmark_usa =zeros(1,numAssets_bench_usa);
                current_weights_col = zeros (1,numAssets_col);
                current_weights_benchmark_col = zeros(1,numAssets_bench_col);
                % define la variable warmupTT de la tabla de tiempo desde el
                % primer dato hasta el periodo inical
                warmupTT = pricesTT(1:warmupPeriod,:);
                warmupTT_bench_usa = benchmarkTT_usa(1:warmupPeriod,:);
                warmupTT_col= pricesTT_col(1:warmupPeriod,:);
                warmupTT_bench_col = benchmarkTT_col(1:warmupPeriod,:);


                %Crea los portafolios iniciales de acuerdo a cada función
                benchmark_usa_initial   = benchmarkFcn(current_weight_benchmark_usa,warmupTT_bench_usa);
                benchmark_col_inital    = benchmarkFcn(current_weights_benchmark_col, warmupTT_bench_col);
                equalWeight_initial     = equalWeightFcn(current_weights,warmupTT);
                maxSharpeRatio_initial  = maxSharpeRatioFcn(current_weights,warmupTT);

                markowitz_initial       = markowitzFcn(current_weights,warmupTT);

                equalWeight_initial_col = equalWeightFcn(current_weights_col,warmupTT_col);
                maxSharpeRatio_initial_col  = maxSharpeRatioFcn(current_weights_col,warmupTT_col);

                markowitz_initial_col       = markowitzFcn(current_weights_col,warmupTT_col); 
                
                %% Inicia proceamiento en computación paralela
                parpool;
               
                ga_initial = geneticMaxSharpePortfolio(current_weights,warmupTT);
                ga_initial_col = geneticMaxSharpePortfolio(current_weights_col,warmupTT_col);
                delete(gcp('nocreate'));
                
                %Crea un arreglo con los nombres de las estrategias a evaluar

                
                strategyNames = {'Pesos iguales', 'Max Ratio de Sharpe','Markowitz', 'Algoritmo Genetico'};
                % para el uso se toman de nuevo los simbolos de los activos
                assetSymbols = pricesTT.Properties.VariableNames;
                assetSymbols_col = pricesTT_col.Properties.VariableNames;
                % Se crea una tabla con los pesos iniciales de las estrategias
                initialWeights = [equalWeight_initial(:), maxSharpeRatio_initial(:),markowitz_initial(:),ga_initial(:)];
                initalWeights_col = [equalWeight_initial_col(:), maxSharpeRatio_initial_col(:), markowitz_initial_col(:),ga_initial_col(:)];
                % hace visible la grafica del mapa de calor

                % se crea el mapa de calor de acuerdo a los pesos iniciales de
                % los activos
                figure('Name','Mapa de Calor Estrategias','NumberTitle','off');
                subplot(2,1,1) 
                heatmap(strategyNames, assetSymbols, initialWeights, 'title',titulo_mapa_calor,'Colormap', parula);
                %variable para definir el rebalanceo del portafolio (21 días o
                %aproximadamente 1 mes)
                %figure('Name','Mapa de Calor Estrategias Mercado COL','NumberTitle','off');
                subplot(2,1,2) 
                heatmap(strategyNames, assetSymbols_col, initalWeights_col, 'title',titulo_mapa_calor,'Colormap', parula);
                
                rebalFreq = 21;

                % se define la variable para ver en retrospectiva para que sea
                % de al menos 40 dias y maximo 126
                lookback  = [40 126];

                % Se define el costo de transacción para que sea fijo en 0 o en 2%
                if app.indice_transaccion == 1
                    transactionsFixed = 0;
                elseif app.indice_transaccion ==2
                    transactionsFixed = 0.002;
                end

                %% costos de transacción variables
                transactionsVariable = @variableTransactionCosts;

                %Se definen las estrategias de acuerdo a su función, rebalanceo
                %del portafolio si es necesario, la retrospectiva, los costos
                %de transacción y los pesos iniciales
                if app.indice_transaccion == 1 || app.indice_transaccion == 2
                strat1 = backtestStrategy('Pesos Iguales', @equalWeightFcn, ...
                    'RebalanceFrequency', rebalFreq, ...
                    'LookbackWindow', 0, ...
                    'TransactionCosts', transactionsFixed, ...
                    'InitialWeights', equalWeight_initial);

                strat2 = backtestStrategy('Max Ratio de Sharpe', @maxSharpeRatioFcn, ...
                    'RebalanceFrequency', rebalFreq, ...
                    'LookbackWindow', lookback, ...
                    'TransactionCosts', transactionsFixed, ...
                    'InitialWeights', maxSharpeRatio_initial);


                strat3 = backtestStrategy('Markowitz', @markowitzFcn, ...
                    'RebalanceFrequency', rebalFreq, ...
                    'LookbackWindow', lookback, ...
                    'TransactionCosts', transactionsFixed, ...
                    'InitialWeights', markowitz_initial);
                strat4 = backtestStrategy('Algoritmo Genetico', @geneticMaxSharpePortfolio, ...
                    'RebalanceFrequency', rebalFreq, ...
                    'LookbackWindow', lookback, ...
                    'TransactionCosts', transactionsFixed, ...
                    'InitialWeights', ga_initial);

                strat5 = backtestStrategy('benchmark', @benchmarkFcn, ...
                    'RebalanceFrequency', rebalFreq, ...
                    'LookbackWindow', lookback, ...
                    'TransactionCosts', 0, ...
                    'InitialWeights', benchmark_usa_initial);
                
                strat6 = backtestStrategy('Pesos Iguales', @equalWeightFcn, ...
                    'RebalanceFrequency', rebalFreq, ...
                    'LookbackWindow', 0, ...
                    'TransactionCosts', transactionsFixed, ...
                    'InitialWeights', equalWeight_initial_col);

                strat7 = backtestStrategy('Max Ratio de Sharpe', @maxSharpeRatioFcn, ...
                    'RebalanceFrequency', rebalFreq, ...
                    'LookbackWindow', lookback, ...
                    'TransactionCosts', transactionsFixed, ...
                    'InitialWeights', maxSharpeRatio_initial_col);


                strat8 = backtestStrategy('Markowitz', @markowitzFcn, ...
                    'RebalanceFrequency', rebalFreq, ...
                    'LookbackWindow', lookback, ...
                    'TransactionCosts', transactionsFixed, ...
                    'InitialWeights', markowitz_initial_col);
                
                strat9 = backtestStrategy('Algoritmo Genetico', @geneticMaxSharpePortfolio, ...
                    'RebalanceFrequency', rebalFreq, ...
                    'LookbackWindow', lookback, ...
                    'TransactionCosts', transactionsFixed, ...
                    'InitialWeights', ga_initial_col);

                
                strat10 = backtestStrategy('benchmark', @benchmarkFcn, ...
                    'RebalanceFrequency', rebalFreq, ...
                    'LookbackWindow', lookback, ...
                    'TransactionCosts', 0, ...
                    'InitialWeights', benchmark_col_inital);
                elseif app.indice_transaccion==3
                
                strat1 = backtestStrategy('Pesos Iguales', @equalWeightFcn, ...
                    'RebalanceFrequency', rebalFreq, ...
                    'LookbackWindow', 0, ...
                    'TransactionCosts', @variableTransactionCosts, ...
                    'InitialWeights', equalWeight_initial);

                strat2 = backtestStrategy('Max Ratio de Sharpe', @maxSharpeRatioFcn, ...
                    'RebalanceFrequency', rebalFreq, ...
                    'LookbackWindow', lookback, ...
                    'TransactionCosts', @variableTransactionCosts, ...
                    'InitialWeights', maxSharpeRatio_initial);


                strat3 = backtestStrategy('Markowitz', @markowitzFcn, ...
                    'RebalanceFrequency', rebalFreq, ...
                    'LookbackWindow', lookback, ...
                    'TransactionCosts', @variableTransactionCosts, ...
                    'InitialWeights', markowitz_initial);
                strat4 = backtestStrategy('Algoritmo Genetico', @geneticMaxSharpePortfolio, ...
                    'RebalanceFrequency', rebalFreq, ...
                    'LookbackWindow', lookback, ...
                    'TransactionCosts', @variableTransactionCosts, ...
                    'InitialWeights', ga_initial);

                strat5 = backtestStrategy('benchmark', @benchmarkFcn, ...
                    'RebalanceFrequency', rebalFreq, ...
                    'LookbackWindow', lookback, ...
                    'TransactionCosts', 0, ...
                    'InitialWeights', benchmark_usa_initial);
                
                strat6 = backtestStrategy('Pesos Iguales', @equalWeightFcn, ...
                    'RebalanceFrequency', rebalFreq, ...
                    'LookbackWindow', 0, ...
                    'TransactionCosts', @variableTransactionCosts, ...
                    'InitialWeights', equalWeight_initial_col);

                strat7 = backtestStrategy('Max Ratio de Sharpe', @maxSharpeRatioFcn, ...
                    'RebalanceFrequency', rebalFreq, ...
                    'LookbackWindow', lookback, ...
                    'TransactionCosts', @variableTransactionCosts, ...
                    'InitialWeights', maxSharpeRatio_initial_col);


                strat8 = backtestStrategy('Markowitz', @markowitzFcn, ...
                    'RebalanceFrequency', rebalFreq, ...
                    'LookbackWindow', lookback, ...
                    'TransactionCosts', @variableTransactionCosts, ...
                    'InitialWeights', markowitz_initial_col);
                
                strat9 = backtestStrategy('Algoritmo Genetico', @geneticMaxSharpePortfolio, ...
                    'RebalanceFrequency', rebalFreq, ...
                    'LookbackWindow', lookback, ...
                    'TransactionCosts', @variableTransactionCosts, ...
                    'InitialWeights', ga_initial_col);

                
                strat10 = backtestStrategy('benchmark', @benchmarkFcn, ...
                    'RebalanceFrequency', rebalFreq, ...
                    'LookbackWindow', lookback, ...
                    'TransactionCosts', 0, ...
                    'InitialWeights', benchmark_col_inital);                
                end

                % Se define un arreglo con los objetos strategia creados
                % anteriormente
                strategies = [strat1, strat2, strat3, strat4];
                estrategia_bench_usa = [strat5];
                strategies_col = [strat6, strat7, strat8, strat9];
                estrategia_bench_col = [strat10];



                % Se crea el objeto para el motor de backtesting definiendo las
                % siguientes condiciones: la tasa libre de riesgo (se toma anual), la
                % conversion de las tasas (anualizadas) y el valor inicial del
                % portafolio
                backtester = backtestEngine(strategies, 'RiskFreeRate', app.annualRiskFreeRate, 'RatesConvention','Annualized','InitialPortfolioValue',10000);
                backtester2 = backtestEngine(estrategia_bench_usa, 'RiskFreeRate', app.annualRiskFreeRate, 'RatesConvention','Annualized','InitialPortfolioValue',10000);
                backtester3 = backtestEngine(strategies_col, 'RiskFreeRate', app.annualRiskFreeRate, 'RatesConvention','Annualized','InitialPortfolioValue',10000);
                backtester4= backtestEngine(estrategia_bench_col, 'RiskFreeRate', app.annualRiskFreeRate, 'RatesConvention','Annualized','InitialPortfolioValue',10000);
                %Se corre el backtesting con procesamiento en paralelo
                parpool;
                
                backtester = runBacktest(backtester, pricesTT, 'Start', warmupPeriod);
                backtester2 = runBacktest(backtester2, benchmarkTT_usa, 'Start', warmupPeriod);
                backtester3 = runBacktest(backtester3,pricesTT_col,'Start',warmupPeriod);
                backtester4 = runBacktest(backtester4,benchmarkTT_col,'Start',warmupPeriod);
                delete(gcp('nocreate'));
                
                summaryByStrategies = summary(backtester);
                resumen_bench_usa= summary(backtester2);
                summaryByStrategies_col = summary(backtester3);
                resumen_bench_col = summary(backtester4);

                %Resumen de las estrategias utilizando la propiedad summary


                % Se crea la grafica equity curve que es uan propiedad del
                % motor de backtester donde se mustran los retornos de todas
                % las estrategias
                figure('Name','Valor portafolios Según Estrategia','NumberTitle','off');

                periodo=backtester.Positions.Pesos_Iguales.Time;
                subplot(2,1,1)
                equityCurve(backtester)
                xlabel('Fecha');
                datetick('x','mm/dd/yyyy','keepticks');
                xlim([periodo(1) periodo(end)])
                ylabel('Valor Portafolio U.S')
                hold on
                equityCurve(backtester2)
                hold off

                periodo=backtester3.Positions.Pesos_Iguales.Time;
                subplot(2,1,2)
                equityCurve(backtester3)
                xlabel('Fecha');
                datetick('x','mm/dd/yyyy','keepticks');
                xlim([periodo(1) periodo(end)])
                ylabel('Valor Portafolio COL')
                hold on
                equityCurve(backtester4)
                hold off            

                % esta sección se encarga de en la tabla del panel derecho
                % mostrar en la tabla el resumen de las estrategias segun cada
                % una de las metricas señaladas como summaryByMetrics.Properties.VariableNames{i}
                summaryByMetrics = rows2vars(summaryByStrategies);
                summaryByMetrics.Properties.VariableNames{1} = 'Estrategia';
                summaryByMetrics.AverageReturn = summaryByMetrics.AverageReturn * 252;
                summaryByMetrics.Volatility = summaryByMetrics.Volatility * (252^(1/2));
                summaryByMetrics.SharpeRatio = (summaryByMetrics.AverageReturn-app.annualRiskFreeRate)./summaryByMetrics.Volatility;
                summaryByMetrics_bench_usa=rows2vars(resumen_bench_usa);
                summaryByMetrics_bench_usa.AverageReturn = (summaryByMetrics_bench_usa.AverageReturn * 252);
                summaryByMetrics_bench_usa.Volatility = summaryByMetrics_bench_usa.Volatility * (252^(1/2));
                summaryByMetrics_bench_usa.SharpeRatio = (summaryByMetrics_bench_usa.AverageReturn-app.annualRiskFreeRate)./summaryByMetrics_bench_usa.Volatility;
                summaryByMetrics_bench_usa.Properties.VariableNames{1} = 'Estrategia';
                app.resumen_metricas = [summaryByMetrics;summaryByMetrics_bench_usa];
                summaryByMetrics_col = rows2vars(summaryByStrategies_col);
                summaryByMetrics_col.AverageReturn = summaryByMetrics_col.AverageReturn * 252;
                summaryByMetrics_col.Volatility = summaryByMetrics_col.Volatility * (252^(1/2));
                summaryByMetrics_col.SharpeRatio = (summaryByMetrics_col.AverageReturn-app.annualRiskFreeRate)./summaryByMetrics_col.Volatility;
                summaryByMetrics_col.Properties.VariableNames{1}= 'Estrategia';
                summaryByMetrics_bench_col=rows2vars(resumen_bench_col);
                summaryByMetrics_bench_col.AverageReturn = summaryByMetrics_bench_col.AverageReturn * 252;
                summaryByMetrics_bench_col.Volatility = summaryByMetrics_bench_col.Volatility * (252^(1/2));
                summaryByMetrics_bench_col.SharpeRatio = (summaryByMetrics_bench_col.AverageReturn-app.annualRiskFreeRate)./summaryByMetrics_bench_col.Volatility;
                summaryByMetrics_bench_col.Properties.VariableNames{1} = 'Estrategia';
                app.resumen_metricas_col = [summaryByMetrics_col; summaryByMetrics_bench_col];
                
                app.UITable2.Data = app.resumen_metricas(:,app.resumen_metricas.Properties.VariableNames(1:4));

                app.resumen_metricas.Properties.VariableNames{1} = 'Estrategia';
                app.resumen_metricas.Properties.VariableNames{2} = 'Retorno Total';
                app.resumen_metricas.Properties.VariableNames{3} = 'Ratio de Sharpe Anual';
                app.resumen_metricas.Properties.VariableNames{4} = 'Volatilidad Anual';
                
                app.UITable2_2.Data = app.resumen_metricas_col(:,app.resumen_metricas_col.Properties.VariableNames(1:4));
                
                app.resumen_metricas_col.Properties.VariableNames{1} = 'Estrategia';
                app.resumen_metricas_col.Properties.VariableNames{2} = 'Retorno Total';
                app.resumen_metricas_col.Properties.VariableNames{3} = 'Ratio de Sharpe Anual';
                app.resumen_metricas_col.Properties.VariableNames{4} = 'Volatilidad Anual';
                
                if app.contador==1
                    app.UITable2.Visible='on';
                    app.UITable2_2.Visible ='on';
                end

                app.UITable2.ColumnName= app.resumen_metricas.Properties.VariableNames(1:4);
                app.UITable2_2.ColumnName= app.resumen_metricas_col.Properties.VariableNames(1:4);

                posiciones_estrategia_usa(backtester,'Pesos_Iguales');
                posiciones_estrategia_usa(backtester,'Markowitz');
                posiciones_estrategia_usa(backtester,'Max_Ratio_de_Sharpe');
                posiciones_estrategia_usa(backtester,'Algoritmo_Genetico');
                posiciones_estrategia_col(backtester3,'Pesos_Iguales');
                posiciones_estrategia_col(backtester3,'Markowitz');
                posiciones_estrategia_col(backtester3,'Max_Ratio_de_Sharpe');
                posiciones_estrategia_col(backtester3,'Algoritmo_Genetico');

                figure('Name','Grafica de Area Activos','NumberTitle','off');
                subplot(2,1,1)
                assetAreaPlot(backtester,'Pesos_Iguales');
                subplot(2,1,2)
                assetAreaPlot(backtester3,'Pesos_Iguales');
                
                figure('Name','Grafica de Area Activos','NumberTitle','off');
                subplot(2,1,1)
                assetAreaPlot(backtester,'Max_Ratio_de_Sharpe');
                subplot(2,1,2)
                assetAreaPlot(backtester3,'Max_Ratio_de_Sharpe');
                
                figure('Name','Grafica de Area Activos','NumberTitle','off');
                subplot(2,1,1)
                assetAreaPlot(backtester,'Markowitz');
                subplot(2,1,2)
                assetAreaPlot(backtester3,'Markowitz');
                
                figure('Name','Grafica de Area Activos','NumberTitle','off');
                subplot(2,1,1)
                assetAreaPlot(backtester,'Algoritmo_Genetico');
                subplot(2,1,2)
                assetAreaPlot(backtester3,'Algoritmo_Genetico');
                
                
                


            end

        function new_weights = benchmarkFcn(current_weight_benchmark, benchmarkTT)
            % Equal-weighted portfolio allocation

            nAssets = size(benchmarkTT, 2);
            new_weights = ones(1,nAssets);
            new_weights = new_weights / sum(new_weights);
            new_weights = round(new_weights,4);

        end


        function new_weights = equalWeightFcn(current_weights, pricesTT)
            % Equal-weighted portfolio allocation

            nAssets = size(pricesTT, 2);
            new_weights = ones(1,nAssets);
            new_weights = new_weights / sum(new_weights);
            %
            new_weights = round(new_weights,4);
        end

        function new_weights = maxSharpeRatioFcn(current_weights, pricesTT)
            

            nAssets = size(pricesTT, 2);
            assetReturns = tick2ret(pricesTT,'Method','Continuous');
            
            p = Portfolio('NumAssets',nAssets,...
                'LowerBound',0,'UpperBound',1,...
                'LowerBudget',1,'UpperBudget',1);


            p = estimateAssetMoments(p, assetReturns{:,:});

            new_weights = estimateMaxSharpeRatio(p,"Method","iterative");
            %
            new_weights = round(new_weights,4);
        end

        function new_weights = inverseVarianceFcn(current_weights, pricesTT)
            % Inverse-variance portfolio allocation

            assetReturns = tick2ret(pricesTT);
            assetCov = cov(assetReturns{:,:});
            new_weights = 1 ./ diag(assetCov);
            new_weights = new_weights / sum(new_weights);

        end

        function new_weights = robustOptimFcn(current_weights, pricesTT)
            % Robust portfolio allocation

            nAssets = size(pricesTT, 2);
            assetReturns = tick2ret(pricesTT,'Method','Continuous');

            Q = cov(table2array(assetReturns));
            SIGMAx = diag(diag(Q));

            % Robust aversion coefficient
            k = 1.1;

            % Robust aversion coefficient
            lambda = 0.05;

            rPortfolio = mean(table2array(assetReturns))';

            % Create the optimization problem
            pRobust = optimproblem('Description','Robust Portfolio');

            % Define the variables
            %xRobust - x  allocation vector
            xRobust = optimvar('x',nAssets,1,'Type','continuous','LowerBound',0.0,'UpperBound',0.25);
            zRobust = optimvar('z','LowerBound',0);

            % Define the budget constraint
            pRobust.Constraints.budget = sum(xRobust) == 1;

            % Define the robust constraint
            pRobust.Constraints.robust = xRobust'*SIGMAx*xRobust - zRobust*zRobust <=0;
            pRobust.Objective = -rPortfolio'*xRobust + k*zRobust + lambda*xRobust'*Q*xRobust;
            x0.x = zeros(nAssets,1);
            x0.z = 0;
            opt = optimoptions('fmincon','Display','off');
            [solRobust,~,~] = solve(pRobust,x0,'Options',opt);
            new_weights = solRobust.x;

        end

        function new_weights = markowitzFcn(current_weights, pricesTT)
            

            nAssets = size(pricesTT, 2);
            assetReturns = tick2ret(pricesTT,'Method','Continuous');

            Q = cov(table2array(assetReturns));

            % Risk aversion coefficient
            %lambda = 0.05;
             lambda = app.lambda_m;
            rPortfolio = mean(table2array(assetReturns))';

            % Create the optimization problem
            pMrkwtz = optimproblem('Description','Markowitz Mean Variance Portfolio ');

            % Define the variables
            % xRobust - x  allocation vector
            xMrkwtz = optimvar('x',nAssets,1,'Type','continuous','LowerBound',0.0,'UpperBound',1);

            % Define the budget constraint
            pMrkwtz.Constraints.budget = sum(xMrkwtz) == 1;

            % Define the Markowitz objective
            pMrkwtz.Objective = -rPortfolio'*xMrkwtz + lambda*xMrkwtz'*Q*xMrkwtz;
            x0.x = zeros(nAssets,1);

            opt = optimoptions('quadprog','Display','off');
            [solMrkwtz,~,~] = solve(pMrkwtz,x0,'Options',opt);
            new_weights = solMrkwtz.x;
            new_weights = round(new_weights,4);
        end

function ratio = sharpeRatio(current_weights, pricesTT,libre_riesgo)
    % Calcula el índice de Sharpe basado en los pesos y datos de precios
    % libre_riesgo es la tasa libre de riesgo y los retornos son
    % logartimicos

    assetReturns = tick2ret(pricesTT,'Method','Continuous');
    assetReturns = table2array(assetReturns);
    portfolioReturns = assetReturns * current_weights';
    
    % Calcula la volatilidad del portafolio
    portfolioVolatility = std(portfolioReturns);
    
    % Calcula el rendimiento del portafolio
    portfolioMeanReturn = mean(portfolioReturns);
    
    % Calcula el índice de Sharpe
    ratio = (portfolioMeanReturn -(libre_riesgo/252) ) / portfolioVolatility;
end

function maxSharpeWeights = geneticMaxSharpePortfolio(current_weights,pricesTT)
    % Parámetros del algoritmo genético
    rng default; %para reproducibilidad
    populationSize = 50;
    generations = 30;
    mutationRate = 0.01;
    crossover_rate = 0.01;
    stallGenLimit = 5;
    libre_riesgo = app.annualRiskFreeRate;
    % Tamaño del portafolio y número de activos
    nAssets = size(pricesTT, 2);
    % Función de aptitud para el algoritmo genético (maximizar Sharpe)
    fitnessFunction = @(weights) -sharpeRatio(weights, pricesTT, libre_riesgo);
    % Espacio de búsqueda: pesos entre 0 y 1 para cada activo
    lb = zeros(1, nAssets);
    ub = ones(1, nAssets);
    % Restricción: la suma de los pesos debe ser igual a 1
    A = [];
    b = [];
    Aeq = ones(1, nAssets);
    beq = 1;
    % Inicializar población aleatoria
    initialPopulation = rand(populationSize, nAssets);
    % Ejecutar el algoritmo genético con restricción de suma
    options = optimoptions('ga', 'MaxGenerations', generations,...
        'MutationFcn', {@mutationadaptfeasible, mutationRate},...
        'CrossoverFcn',{@crossoverintermediate,crossover_rate},...
        'SelectionFcn',{@selectiontournament,4},...
        'StallGenLimit',stallGenLimit);
    
    [maxSharpeWeights, ~, ~, ~] = ga(fitnessFunction, nAssets,...
                                    A, b, Aeq, beq, lb, ub, [], options);
    
end





        function [buy, sell] = variableTransactionCosts(deltaPositions)
            buy  = zeros(1,numel(deltaPositions));
            sell = zeros(1,numel(deltaPositions));

            % Buys
            idx = 0 < deltaPositions & deltaPositions < 1e4;
            buy(idx) = 0.002 * deltaPositions(idx); % 20 puntos basicos
            idx = 1e4 <= deltaPositions;
            buy(idx) = 0.0015 * deltaPositions(idx); % 15 puntos basicos
            buy = sum(buy);

            % Sells
            idx = -1e3 < deltaPositions & deltaPositions < 0;
            sell(idx) = 0.002 * -deltaPositions(idx); % 20 puntos basicos
            idx = deltaPositions <= -1e3;
            sell(idx) = 0.0015 * -deltaPositions(idx); % 15 basis points
            sell = sum(sell);

        end

        function assetAreaPlot(backtester,strategyName)
            % Plot the asset allocation as an area plot.

            t = backtester.Positions.(strategyName).Time;
            positions = backtester.Positions.(strategyName).Variables;
            h=area(t,positions);

            title(sprintf('%s Posiciones',strrep(strategyName,'_',' ')));
            xlabel('Date');
            ylabel('Posiciones de los activos');


            datetick('x','mm/dd/yyyy','keepticks');
            xlim([t(1) t(end)])
            oldylim = ylim;
            ylim([0 oldylim(2)]);
            cm = parula(numel(h));
            for i = 1:numel(h)
                set(h(i),'FaceColor',cm(i,:));
            end
            legend(backtester.Positions.(strategyName).Properties.VariableNames)

        end

        function posiciones_estrategia_usa(backtester,strategyName)
            fechas = backtester.Positions.(strategyName).Time;
            posiciones = backtester.Positions.(strategyName).Variables;
            posiciones = round(posiciones,4);
            posiciones = array2table(posiciones,'VariableNames',backtester.Positions.(strategyName).Properties.VariableNames);

            resumen_posiciones = table2timetable(posiciones,'RowTimes',fechas);
            texto_fecha= app.SeleccioneFechaButtonGroup.SelectedObject.Text;
            texto_fecha=strrep(texto_fecha,'/','_');
            mkdir ResumenUS
            archivo_salida = append(path,'ResumenUS','\Resumen_posiciones_',(strategyName),'_',texto_fecha,'.xlsx');
            writetimetable(resumen_posiciones,archivo_salida);
        end

function posiciones_estrategia_col(backtester,strategyName)
            fechas = backtester.Positions.(strategyName).Time;
            posiciones = backtester.Positions.(strategyName).Variables;
            posiciones = round(posiciones,4);
            posiciones = array2table(posiciones,'VariableNames',backtester.Positions.(strategyName).Properties.VariableNames);

            resumen_posiciones = table2timetable(posiciones,'RowTimes',fechas);
            texto_fecha= app.SeleccioneFechaButtonGroup.SelectedObject.Text;
            texto_fecha=strrep(texto_fecha,'/','_');
            mkdir ResumenCOL
            archivo_salida = append(path,'ResumenCOL','\Resumen_posiciones_',(strategyName),'_',texto_fecha,'.xlsx');
            writetimetable(resumen_posiciones,archivo_salida);
        end


        end

        % Callback function
        function ProcesarButtonPushed(app, event)


        end

        % Selection changed function: SeleccioneFechaButtonGroup
        function SeleccioneFechaButtonGroupSelectionChanged(app, event)
            selectedButton = app.SeleccioneFechaButtonGroup.SelectedObject;

            if selectedButton == app.Button_2
                app.indice_fecha = 1;

            elseif selectedButton== app.Button_3
                app.indice_fecha = 2;
            elseif selectedButton== app.Button_4
                app.indice_fecha = 3;
            elseif selectedButton== app.Button_5
                app.indice_fecha = 4;
            elseif selectedButton==app.Button_6
                app.indice_fecha = 5;
            end

        end

        % Callback function
        function Button_7Pushed(app, event)

        end

        % Callback function
        function SeleccioneMercadoButtonGroupSelectionChanged(app, event)
            selectedButton = app.SeleccioneMercadoButtonGroup.SelectedObject;


        end

        % Cell selection callback: UITable2
        function UITable2CellSelection(app, event)
            indices = event.Indices;
            
        end

        % Menu selected function: CopiarMenu
        function CopiarMenuSelected(app, event)
            
        end

        % Button pushed function: GuardarResumenButton
        function GuardarResumenButtonPushed(app, event)
           writetable(app.resumen_metricas(:,app.resumen_metricas.Properties.VariableNames(1:4)),'Resumen_estrategias.xlsx','WriteMode','append','Sheet','Mercado US');
           writetable(app.resumen_metricas_col(:,app.resumen_metricas_col.Properties.VariableNames(1:4)),'Resumen_estrategias.xlsx','WriteMode','append','Sheet','Mercado COL');
        end

        % Selection changed function: 
        % SeleccioneLoscostosdeTransaccinButtonGroup
        function SeleccioneLoscostosdeTransaccinButtonGroupSelectionChanged(app, event)
            selectedButton = app.SeleccioneLoscostosdeTransaccinButtonGroup.SelectedObject;
            if selectedButton == app.SincostosButton
                app.indice_transaccion=1;
            elseif selectedButton == app.Fijos20pbsButton
                    app.indice_transaccion=2;
            elseif selectedButton == app.VariablesButton
                    app.indice_transaccion=3;
            end
            
            
        end
    end

    % Component initialization
    methods (Access = private)

        % Create UIFigure and components
        function createComponents(app)

            % Create BacktestingOptimizacindeportafoliosUIFigure and hide until all components are created
            app.BacktestingOptimizacindeportafoliosUIFigure = uifigure('Visible', 'off');
            app.BacktestingOptimizacindeportafoliosUIFigure.AutoResizeChildren = 'off';
            app.BacktestingOptimizacindeportafoliosUIFigure.Position = [0 0 1000 550];
            app.BacktestingOptimizacindeportafoliosUIFigure.Name = 'Backtesting Optimización de portafolios';
            app.BacktestingOptimizacindeportafoliosUIFigure.Icon = 'eafit-logo.png';
            app.BacktestingOptimizacindeportafoliosUIFigure.CloseRequestFcn = createCallbackFcn(app, @BacktestingOptimizacindeportafoliosUIFigureCloseRequest, true);
            app.BacktestingOptimizacindeportafoliosUIFigure.SizeChangedFcn = createCallbackFcn(app, @updateAppLayout, true);

            % Create GridLayout
            app.GridLayout = uigridlayout(app.BacktestingOptimizacindeportafoliosUIFigure);
            app.GridLayout.ColumnWidth = {545, '1x'};
            app.GridLayout.RowHeight = {'1x'};
            app.GridLayout.ColumnSpacing = 0;
            app.GridLayout.RowSpacing = 0;
            app.GridLayout.Padding = [0 0 0 0];
            app.GridLayout.Scrollable = 'on';

            % Create LeftPanel
            app.LeftPanel = uipanel(app.GridLayout);
            app.LeftPanel.Layout.Row = 1;
            app.LeftPanel.Layout.Column = 1;

            % Create Button
            app.Button = uibutton(app.LeftPanel, 'push');
            app.Button.ButtonPushedFcn = createCallbackFcn(app, @ButtonPushed, true);
            app.Button.Position = [277 310 100 22];
            app.Button.Text = '...';

            % Create CargueelarchivoquecontieneladataLabel
            app.CargueelarchivoquecontieneladataLabel = uilabel(app.LeftPanel);
            app.CargueelarchivoquecontieneladataLabel.Position = [26 310 227 22];
            app.CargueelarchivoquecontieneladataLabel.Text = '4) Cargue el archivo que contiene la data';

            % Create UITable
            app.UITable = uitable(app.LeftPanel);
            app.UITable.ColumnName = {'Column 1'; 'Column 2'; 'Column 3'; 'Column 4'; 'Colum 5'};
            app.UITable.RowName = {};
            app.UITable.Position = [20 33 457 229];

            % Create AccionesseleccionadasLabel
            app.AccionesseleccionadasLabel = uilabel(app.LeftPanel);
            app.AccionesseleccionadasLabel.Position = [20 273 134 22];
            app.AccionesseleccionadasLabel.Text = 'Acciones seleccionadas';

            % Create SeleccioneFechaButtonGroup
            app.SeleccioneFechaButtonGroup = uibuttongroup(app.LeftPanel);
            app.SeleccioneFechaButtonGroup.SelectionChangedFcn = createCallbackFcn(app, @SeleccioneFechaButtonGroupSelectionChanged, true);
            app.SeleccioneFechaButtonGroup.Title = '1) Seleccione Fecha';
            app.SeleccioneFechaButtonGroup.Position = [20 383 176 137];

            % Create Button_2
            app.Button_2 = uiradiobutton(app.SeleccioneFechaButtonGroup);
            app.Button_2.Text = '01/01/2013-31/12/2022';
            app.Button_2.Position = [10 91 146 22];
            app.Button_2.Value = true;

            % Create Button_3
            app.Button_3 = uiradiobutton(app.SeleccioneFechaButtonGroup);
            app.Button_3.Text = '01/01/2013-30/06/2015';
            app.Button_3.Position = [10 69 146 22];

            % Create Button_4
            app.Button_4 = uiradiobutton(app.SeleccioneFechaButtonGroup);
            app.Button_4.Text = '01/07/2015-31/12/2017';
            app.Button_4.Position = [10 47 146 22];

            % Create Button_5
            app.Button_5 = uiradiobutton(app.SeleccioneFechaButtonGroup);
            app.Button_5.Text = '01/01/2018-30/06/2020';
            app.Button_5.Position = [11 25 146 22];

            % Create Button_6
            app.Button_6 = uiradiobutton(app.SeleccioneFechaButtonGroup);
            app.Button_6.Text = '01/07/2020-31/12/2022';
            app.Button_6.Position = [10 3 146 22];

            % Create SeleccioneelfactordeAversinalRiesgoLabel
            app.SeleccioneelfactordeAversinalRiesgoLabel = uilabel(app.LeftPanel);
            app.SeleccioneelfactordeAversinalRiesgoLabel.HorizontalAlignment = 'right';
            app.SeleccioneelfactordeAversinalRiesgoLabel.Position = [17 350 245 22];
            app.SeleccioneelfactordeAversinalRiesgoLabel.Text = '3) Seleccione el factor de Aversión al Riesgo';

            % Create SeleccioneelfactordeAversinalRiesgoEditField
            app.SeleccioneelfactordeAversinalRiesgoEditField = uieditfield(app.LeftPanel, 'numeric');
            app.SeleccioneelfactordeAversinalRiesgoEditField.Limits = [0.01 10];
            app.SeleccioneelfactordeAversinalRiesgoEditField.Position = [277 350 100 22];
            app.SeleccioneelfactordeAversinalRiesgoEditField.Value = 3;

            % Create SeleccioneLoscostosdeTransaccinButtonGroup
            app.SeleccioneLoscostosdeTransaccinButtonGroup = uibuttongroup(app.LeftPanel);
            app.SeleccioneLoscostosdeTransaccinButtonGroup.SelectionChangedFcn = createCallbackFcn(app, @SeleccioneLoscostosdeTransaccinButtonGroupSelectionChanged, true);
            app.SeleccioneLoscostosdeTransaccinButtonGroup.Title = '2) Seleccione Los costos de Transacción';
            app.SeleccioneLoscostosdeTransaccinButtonGroup.Position = [246 414 231 106];

            % Create SincostosButton
            app.SincostosButton = uiradiobutton(app.SeleccioneLoscostosdeTransaccinButtonGroup);
            app.SincostosButton.Text = 'Sin costos';
            app.SincostosButton.Position = [11 60 78 22];
            app.SincostosButton.Value = true;

            % Create Fijos20pbsButton
            app.Fijos20pbsButton = uiradiobutton(app.SeleccioneLoscostosdeTransaccinButtonGroup);
            app.Fijos20pbsButton.Text = 'Fijos 20 pbs';
            app.Fijos20pbsButton.Position = [11 38 87 22];

            % Create VariablesButton
            app.VariablesButton = uiradiobutton(app.SeleccioneLoscostosdeTransaccinButtonGroup);
            app.VariablesButton.Text = 'Variables';
            app.VariablesButton.Position = [11 16 71 22];

            % Create RightPanel
            app.RightPanel = uipanel(app.GridLayout);
            app.RightPanel.Layout.Row = 1;
            app.RightPanel.Layout.Column = 2;

            % Create UITable2
            app.UITable2 = uitable(app.RightPanel);
            app.UITable2.ColumnName = {'Column 1'; 'Column 2'; 'Column 3'; 'Column 4'};
            app.UITable2.RowName = {};
            app.UITable2.CellSelectionCallback = createCallbackFcn(app, @UITable2CellSelection, true);
            app.UITable2.Position = [21 330 415 144];

            % Create ResumendeBacktestingMercadoUSLabel
            app.ResumendeBacktestingMercadoUSLabel = uilabel(app.RightPanel);
            app.ResumendeBacktestingMercadoUSLabel.Position = [21 498 296 22];
            app.ResumendeBacktestingMercadoUSLabel.Text = 'Resumen de Backtesting Mercado U.S';

            % Create UITable2_2
            app.UITable2_2 = uitable(app.RightPanel);
            app.UITable2_2.ColumnName = {'Column 1'; 'Column 2'; 'Column 3'; 'Column 4'};
            app.UITable2_2.RowName = {};
            app.UITable2_2.Position = [22 118 414 144];

            % Create ResumendeBacktestingMercadoCOLLabel
            app.ResumendeBacktestingMercadoCOLLabel = uilabel(app.RightPanel);
            app.ResumendeBacktestingMercadoCOLLabel.Position = [21 283 296 22];
            app.ResumendeBacktestingMercadoCOLLabel.Text = 'Resumen de Backtesting Mercado COL';

            % Create GuardarResumenButton
            app.GuardarResumenButton = uibutton(app.RightPanel, 'push');
            app.GuardarResumenButton.ButtonPushedFcn = createCallbackFcn(app, @GuardarResumenButtonPushed, true);
            app.GuardarResumenButton.Position = [210 33 114 22];
            app.GuardarResumenButton.Text = 'Guardar Resumen';

            % Create Archivo
            app.Archivo = uimenu(app.BacktestingOptimizacindeportafoliosUIFigure);
            app.Archivo.Text = '&Archivo';

            % Create SalirMenu
            app.SalirMenu = uimenu(app.Archivo);
            app.SalirMenu.MenuSelectedFcn = createCallbackFcn(app, @SalirMenuSelected, true);
            app.SalirMenu.Text = 'Salir';

            % Create ContextMenu
            app.ContextMenu = uicontextmenu(app.BacktestingOptimizacindeportafoliosUIFigure);

            % Create CopiarMenu
            app.CopiarMenu = uimenu(app.ContextMenu);
            app.CopiarMenu.MenuSelectedFcn = createCallbackFcn(app, @CopiarMenuSelected, true);
            app.CopiarMenu.Text = 'Copiar';

            % Show the figure after all components are created
            app.BacktestingOptimizacindeportafoliosUIFigure.Visible = 'on';
        end
    end

    % App creation and deletion
    methods (Access = public)

        % Construct app
        function app = app_tesis

            % Create UIFigure and components
            createComponents(app)

            % Register the app with App Designer
            registerApp(app, app.BacktestingOptimizacindeportafoliosUIFigure)

            % Execute the startup function
            runStartupFcn(app, @startupFcn)

            if nargout == 0
                clear app
            end
        end

        % Code that executes before app deletion
        function delete(app)

            % Delete UIFigure when app is deleted
            delete(app.BacktestingOptimizacindeportafoliosUIFigure)
        end
    end
end