Code covered by the BSD License  

Highlights from
FinMetrics

  • fm(varargin) This source file is subject to version 3 of the GPL license,
  • AssetThis source file is subject to version 3 of the GPL license,
  • AssetUniverseThis source file is subject to version 3 of the GPL license,
  • AxlThis source file is subject to version 3 of the GPL license,
  • CashPositionThis source file is subject to version 3 of the GPL license,
  • CashTransactionThis source file is subject to version 3 of the GPL license,
  • Config This source file is subject to version 3 of the GPL license,
  • ConsoleMenuThis source file is subject to version 3 of the GPL license,
  • ConsoleMenuItemThis source file is subject to version 3 of the GPL license,
  • CurrencyAssetThis source file is subject to version 3 of the GPL license,
  • ExchangeTradedAssetThis source file is subject to version 3 of the GPL license,
  • FinMetricsThis source file is subject to version 3 of the GPL license,
  • PortfolioThis source file is subject to version 3 of the GPL license,
  • PositionThis source file is subject to version 3 of the GPL license,
  • StatisticsThis source file is subject to version 3 of the GPL license,
  • StockPositionThis source file is subject to version 3 of the GPL license,
  • StockTransactionThis source file is subject to version 3 of the GPL license,
  • TextUIThis source file is subject to version 3 of the GPL license,
  • TextUILocaleThis source file is subject to version 3 of the GPL license,
  • TextUIQuestionThis source file is subject to version 3 of the GPL license,
  • TextUIQuestionnaireThis source file is subject to version 3 of the GPL license,
  • TransactionThis source file is subject to version 3 of the GPL license,
  • View all files

FinMetrics

by

 

Open source/open architecture quantitative portfolio management environment.

TextUI
classdef TextUI < handle
% This source file is subject to version 3 of the GPL license, 
% that is bundled with this package in the file LICENSE, and is 
% available online at http://www.gnu.org/licenses/gpl.txt
%
% This source file can be linked to GPL-incompatible facilities, 
% produced or made available by MathWorks, Inc.

    properties (GetAccess = public, SetAccess = private)
        Menu = {};
        AppData = {};
        Locale;
    end
    
    methods
        function TUIobj = TextUI(FinMetrics)
            TUIobj.AppData = FinMetrics;
            TUIobj.Locale = FM.TextUILocale('en_US');
            TUIobj.createMenus;                                     
        end
        
        function ret = Init(TUIobj)
            ret = TUIobj.Menu.Pick;
        end
    end
    
    methods (Access = private)
        function createMenus(TUIobj)
            % Create menus
            TUIobj.Menu = FM.ConsoleMenu(TUIobj.Locale.MENU_MAIN_TITLE, TUIobj.AppData, {'PreSelectCallback', @TUIobj.showStatus });
            projectMenu = FM.ConsoleMenu(TUIobj.Locale.MENU_PROJECT_TITLE, TUIobj.AppData, {'Parent', TUIobj.Menu, 'PreSelectCallback', @TUIobj.showStatus});
            auMenu = FM.ConsoleMenu(TUIobj.Locale.MENU_AU_TITLE, TUIobj.AppData, {'Parent', TUIobj.Menu, 'PreSelectCallback', @TUIobj.showStatus});
            portfolioMenu = FM.ConsoleMenu(TUIobj.Locale.MENU_PORTFOLIO_TITLE, TUIobj.AppData, {'Parent', TUIobj.Menu, 'PreSelectCallback', @TUIobj.showStatus});
            
            TUIobj.Menu.InsertItem(FM.ConsoleMenuItem(TUIobj.Locale.MENU_MAIN_PROJECT, {'Tag', 'mainmenuProject', 'Callback', projectMenu, 'Enabled', true}), 'END');                       
            TUIobj.Menu.InsertItem(FM.ConsoleMenuItem(TUIobj.Locale.MENU_MAIN_AU, {'Tag', 'mainmenuAssetUniverse', 'Callback', auMenu, 'Enabled', true}), 'END');                       
            TUIobj.Menu.InsertItem(FM.ConsoleMenuItem(TUIobj.Locale.MENU_MAIN_PORTFOLIO, { 'Tag', 'mainmenuPortfolio', 'Callback', portfolioMenu, 'Enabled', true}), 'END');            

            projectMenu.InsertItem(FM.ConsoleMenuItem(TUIobj.Locale.MENU_PROJECT_NEW, {'Tag', 'projectMenuNew', 'Callback', @TUIobj.newProject, 'Enabled', true}), 'END');
            projectMenu.InsertItem(FM.ConsoleMenuItem(TUIobj.Locale.MENU_PROJECT_AU_NEW, {'Tag', 'projectMenuNewAssetUniverse', 'Callback', @TUIobj.newAssetUniverse, 'Enabled', true}), 'END');            
            projectMenu.InsertItem(FM.ConsoleMenuItem(TUIobj.Locale.MENU_PROJECT_PORTFOLIO_NEW, {'Tag', 'projectMenuPortfolioNew', 'Callback', @TUIobj.newPortfolio, 'Enabled', false}), 'END');            
            projectMenu.InsertItem(FM.ConsoleMenuItem(TUIobj.Locale.MENU_PROJECT_NEW_SCRIPT_TEMPLATE, {'Tag', 'projectMenuNewScriptTemplate', 'Callback', @TUIobj.newScriptTemplate, 'Enabled', false}), 'END');            
            projectMenu.InsertItem(FM.ConsoleMenuItem(TUIobj.Locale.MENU_PROJECT_OPEN, {'Tag', 'projectMenuOpen', 'Callback', @TUIobj.openProject, 'Enabled', true}), 'END'); 
            projectMenu.InsertItem(FM.ConsoleMenuItem(TUIobj.Locale.MENU_PROJECT_AU_OPEN, {'Tag', 'projectMenuOpenAssetUniverse', 'Callback', @TUIobj.openAssetUniverse, 'Enabled', true}), 'END'); 
            projectMenu.InsertItem(FM.ConsoleMenuItem(TUIobj.Locale.MENU_PROJECT_SAVE, {'Tag', 'projectMenuSave', 'Callback', @TUIobj.saveProject, 'Enabled', true, 'Separator', true}), 'END');           
            projectMenu.InsertItem(FM.ConsoleMenuItem(TUIobj.Locale.MENU_PROJECT_AU_SAVE, {'Tag', 'projectMenuSaveAssetUniverse', 'Callback', @TUIobj.saveAssetUniverse}), 'END');                                    
            projectMenu.InsertItem(FM.ConsoleMenuItem(TUIobj.Locale.MENU_PROJECT_PORTFOLIO_IMPORT, {'Tag', 'projectMenuImportPortfolio', 'Callback', @TUIobj.importPortfolio, 'Separator', true}), 'END');                                    
            
            auMenu.InsertItem(FM.ConsoleMenuItem(TUIobj.Locale.MENU_AU_ASSET_ADD, {'Tag', 'auMenuAddAsset', 'Callback', @TUIobj.addAsset, 'Enabled', false}), 'END');
            auMenu.InsertItem(FM.ConsoleMenuItem(TUIobj.Locale.MENU_AU_ASSET_LIST_IMPORT, {'Tag', 'auMenuAssetImportList', 'Callback', @TUIobj.assetImportList, 'Enabled', false}), 'END');
            auMenu.InsertItem(FM.ConsoleMenuItem(TUIobj.Locale.MENU_AU_ASSET_BROWSE, {'Tag', 'auMenuBrowseAssets', 'Callback', @TUIobj.browseAssets, 'Hotkey', 'ba'}), 'END');                                    
            auMenu.InsertItem(FM.ConsoleMenuItem(TUIobj.Locale.MENU_AU_ASSET_DELETE, {'Tag', 'auMenuDeleteAsset', 'Callback', @TUIobj.deleteAsset}), 'END');
            auMenu.InsertItem(FM.ConsoleMenuItem(TUIobj.Locale.MENU_AU_ASSET_UPDATE, {'Tag', 'auMenuUpdateAsset', 'Callback', @TUIobj.updateAssetPrices}), 'END');                                                                            
            
            portfolioMenu.InsertItem(FM.ConsoleMenuItem(TUIobj.Locale.MENU_PORTFOLIO_ACTIVE, {'Tag', 'portfolioMenuActivePortfolio', 'Callback', @TUIobj.activePortfolio, 'Enabled', false, 'Hotkey', 'ap'}), 'END');
            portfolioMenu.InsertItem(FM.ConsoleMenuItem(TUIobj.Locale.MENU_PORTFOLIO_NEW_TRANS, {'Tag', 'portfolioMenuNewTransaction', 'Callback', @TUIobj.portfolioNewTransaction, 'Enabled', false, 'Separator', true}), 'END');
            portfolioMenu.InsertItem(FM.ConsoleMenuItem(TUIobj.Locale.MENU_PORTFOLIO_LIST_TRANS, {'Tag', 'portfolioMenuListTransaction', 'Callback', @TUIobj.portfolioListTransaction, 'Enabled', false, 'Hotkey', 'lt'}), 'END');
            portfolioMenu.InsertItem(FM.ConsoleMenuItem(TUIobj.Locale.MENU_PORTFOLIO_COMM_TRANS, {'Tag', 'portfolioMenuCommTransaction', 'Callback', @TUIobj.portfolioCommitTransactions, 'Enabled', false}), 'END');
            portfolioMenu.InsertItem(FM.ConsoleMenuItem(TUIobj.Locale.MENU_PORTFOLIO_UNCOMM_TRANS, {'Tag', 'portfolioMenuUncommTransaction', 'Callback', @TUIobj.portfolioUncommitTransactions, 'Enabled', false}), 'END');
            portfolioMenu.InsertItem(FM.ConsoleMenuItem(TUIobj.Locale.MENU_PORTFOLIO_LIST_POS, {'Tag', 'portfolioMenuListPositions', 'Callback', @TUIobj.portfolioListPositions, 'Enabled', false, 'Separator', true}), 'END');
            
            TUIobj.AppData.addlistener('FinMetrics_AssetUniverse_loaded', @FinMetrics_AssetUniverse_loaded_callback);                                
            TUIobj.AppData.addlistener('FinMetrics_Portfolios_modified', @FinMetrics_Portfolio_loaded_callback);
            
            % If asset universe have been before menus were created, enable
            % appropriate menu items.
            if isa(TUIobj.AppData.AssetUniverse, 'FM.AssetUniverse')
                FinMetrics_AssetUniverse_loaded_callback();
            end
            
            % If at least one portfolio exists, enable Portfolio menu items
            
            if (size(TUIobj.AppData.Portfolios,1) >0)
                FinMetrics_Portfolio_loaded_callback();
            end
            
            function FinMetrics_AssetUniverse_loaded_callback(eventSrc, eventData)
                 projectMenu.SetItemProperty('projectMenuSaveAssetUniverse', 'Enabled', 'true');
                 projectMenu.SetItemProperty('projectMenuPortfolioNew', 'Enabled', 'true');
                 projectMenu.SetItemProperty('projectMenuImportPortfolio', 'Enabled', 'true');
                 projectMenu.SetItemProperty('projectMenuNewScriptTemplate', 'Enabled', 'true');                 
                 auMenu.SetItemProperty('auMenuAssetImportList', 'Enabled', 'true');
                 auMenu.SetItemProperty('auMenuBrowseAssets', 'Enabled', 'true');
                 auMenu.SetItemProperty('auMenuAddAsset', 'Enabled', 'true');
                 auMenu.SetItemProperty('auMenuUpdateAsset', 'Enabled', 'true');                 
            end

            function FinMetrics_Portfolio_loaded_callback(eventSrc, eventData)
                portfolioMenu.SetItemProperty('portfolioMenuActivePortfolio', 'Enabled', 'true');
                portfolioMenu.SetItemProperty('portfolioMenuNewTransaction', 'Enabled', 'true');
                portfolioMenu.SetItemProperty('portfolioMenuListTransaction', 'Enabled', 'true');
                portfolioMenu.SetItemProperty('portfolioMenuCommTransaction', 'Enabled', 'true');
                portfolioMenu.SetItemProperty('portfolioMenuUncommTransaction', 'Enabled', 'true');
                portfolioMenu.SetItemProperty('portfolioMenuListPositions', 'Enabled', 'true');
            end
        
        end        
        
        function ret = newProject(TUIobj, selection)
            ret = -1;
        end
        
        function ret = openProject(TUIobj, selection)
            ret = -2;
        end
        
        function ret = saveProject(TUIobj, selection)
            ret = 0;
            spTQ = FM.TextUIQuestionnaire(TUIobj.Locale.Q_NEW_PROJECT_TITLE);
                                    
            spTQ.InsertItem(FM.TextUIQuestion(TUIobj.Locale.Q_NEW_PROJECT_NAME, 'askProjectName', {'DefaultAnswer', TUIobj.AppData.Project}), 'END');
            spTQ.InsertItem(FM.TextUIQuestion(TUIobj.Locale.Q_NEW_PROJECT_LOCATION, 'askProjectLocation', {'ValidateCallback', @askProjectLocationCallback, 'EmptyAnswer', true, 'DefaultAnswer', TUIobj.AppData.Directory}), 'END');            
            spTQ.InsertItem(FM.TextUIQuestion(TUIobj.Locale.Q_NEW_PROJECT_LOCATION_CHG, 'changeProjectNameLocation', {'Details', 'WARNING: The file with the specified path and name already exists.', 'List', true, 'ListItems', { TUIobj.Locale.COREWORD_YES; TUIobj.Locale.COREWORD_NO; }, 'DefaultAnswer', {TUIobj.Locale.COREWORD_YES},  'DisplayInReview', false, 'ValidateCallback', @changeProjectNameLocationCallback} ), 'END');        
            
            if (spTQ.Ask == 1)
                if (isempty(spTQ.GetItemByTag('askProjectLocation').DefaultAnswer))
                    location = pwd();
                else
                    location = spTQ.GetItemByTag('askProjectLocation').DefaultAnswer;
                end
                TUIobj.AppData.SaveProject(spTQ.GetItemByTag('askProjectName').DefaultAnswer, location);
            end

            function ret = askProjectLocationCallback(answer)
                ret = 'Complete';
                projectName = spTQ.GetItemByTag('askProjectName').DefaultAnswer;
                
                projectFile = sprintf ('%s/%s.mat', answer, projectName);
                
                if (exist(projectFile, 'file'))
                    ret = 1;
                end
            end
            
            function ret = changeProjectNameLocationCallback(answer)
                ret = 0;
                if (strcmpi(spTQ.GetItemByTag('changeProjectNameLocation').ListItems{1}, answer))                    
                    return;
                elseif (strcmpi(spTQ.GetItemByTag('changeProjectNameLocation').ListItems{2}, answer))
                    ret = 1;
                end
            end    
        end
        
        function ret = newAssetUniverse(TUIobj, selection)
            ret = 0;
            nauTQ = FM.TextUIQuestionnaire(TUIobj.Locale.MENU_AU_NEW_QUEST_TITLE);
                                    
            nauTQ.InsertItem(FM.TextUIQuestion(TUIobj.Locale.MENU_AU_NEW_QUEST_NAME, 'askAuName'), 'END');
            nauTQ.InsertItem(FM.TextUIQuestion(TUIobj.Locale.MENU_AU_NEW_QUEST_LOCATION, 'askAuLocation', {'ValidateCallback', @askAuLocationCallback, }), 'END');            
            nauTQ.InsertItem(FM.TextUIQuestion(TUIobj.Locale.MENU_AU_NEW_QUEST_LOCATION_CHG, 'changeAUNameLocation', {'Details', 'WARNING: The specified file already exists.', 'List', true, 'ListItems', { TUIobj.Locale.COREWORD_YES; TUIobj.Locale.COREWORD_NO; }, 'DefaultAnswer', {TUIobj.Locale.COREWORD_YES}, 'HelpMessage', 'This is my help message.', 'DisplayInReview', false, 'ValidateCallback', @changeAUNameLocationCallback} ), 'END');
                        
            if (nauTQ.Ask == 1)
                TUIobj.AppData.CreateAssetUniverse(nauTQ.GetItemByTag('askAuName').DefaultAnswer, nauTQ.GetItemByTag('askAuLocation').DefaultAnswer);
            end
            
            function ret = askAuLocationCallback(answer)
                ret = 'Complete';
                
                if (exist(answer, 'file'))
                    ret = 1;
                end
            end
            
            function ret = changeAUNameLocationCallback(answer)
                ret = 0;
                if (strcmpi(nauTQ.GetItemByTag('changeAUNameLocation').ListItems{1}, answer))                    
                    return;
                elseif (strcmpi(nauTQ.GetItemByTag('changeAUNameLocation').ListItems{2}, answer))
                    ret = 1;
                end
            end                        
            
        end
        
        function ret = importPortfolio(TUIobj, selection)
            ret = 0;
            ipTQ = FM.TextUIQuestionnaire(TUIobj.Locale.Q_PORTFOLIO_IMPORT_TITLE);
                                                
            ipTQ.InsertItem(FM.TextUIQuestion(TUIobj.Locale.Q_PORTFOLIO_IMPORT_LOCATION, 'askPortfolioLocation', {'ValidateCallback', @askPortfolioLocationCallback, }), 'END');            
            ipTQ.InsertItem(FM.TextUIQuestion(TUIobj.Locale.Q_PORTFOLIO_IMPORT_LOCATION_CHG, 'changePortfolioFileName', {'Details', 'WARNING: The specified file does not exist.', 'List', true, 'ListItems', { TUIobj.Locale.COREWORD_YES; TUIobj.Locale.COREWORD_NO; }, 'DefaultAnswer', {TUIobj.Locale.COREWORD_YES}, 'DisplayInReview', false, 'ValidateCallback', @changePortfolioFileNameCallback} ), 'END');
                        
            if (ipTQ.Ask == 1)                
                pi = TUIobj.AppData.ImportPortfolio(ipTQ.GetItemByTag('askPortfolioLocation').DefaultAnswer);
                
                if (pi == 2)
                    msg = sprintf('\n%s\n%s', TUIobj.Locale.Q_PORTFOLIO_IMPORT_NAME_CONFL, TUIobj.Locale.GEN_PRESS_ENTER_CONT);
                    input(msg);
                end
            end
            
            function ret = askPortfolioLocationCallback(answer)
                ret = 'Complete';
                if (~exist(answer, 'file'))
                    fprintf ('%s: %s\n', TUIobj.Locale.ERR_GEN_FILE_NOT_FOUND, answer)
                    ret = 0;                
                end
            end
            
            function ret = changePortfolioFileNameCallback(answer)
                ret = 0;
                if (strcmpi(ipTQ.GetItemByTag('changePortfolioFileName').ListItems{1}, answer))                    
                    ret = 'askPortfolioLocation';
                elseif (strcmpi(ipTQ.GetItemByTag('changePortfolioFileName').ListItems{2}, answer))
                    ret = 1;
                end
            end                                    
        end

        
        function ret = newPortfolio(TUIobj, selection)
            ret = 0;
            npTQ = FM.TextUIQuestionnaire(TUIobj.Locale.Q_PORTFOLIO_NEW_TITLE);
                                    
            npTQ.InsertItem(FM.TextUIQuestion(TUIobj.Locale.Q_PORTFOLIO_NEW_NAME, 'askPortfolioName'), 'END');
            npTQ.InsertItem(FM.TextUIQuestion(TUIobj.Locale.Q_PORTFOLIO_NEW_LOCATION, 'askPortfolioLocation', {'ValidateCallback', @askPortfolioLocationCallback, }), 'END');            
            npTQ.InsertItem(FM.TextUIQuestion(TUIobj.Locale.Q_PORTFOLIO_NEW_LOCATION_CHG, 'changePortfolioFileName', {'Details', 'WARNING: The specified file already exists.', 'List', true, 'ListItems', { TUIobj.Locale.COREWORD_YES; TUIobj.Locale.COREWORD_NO; }, 'DefaultAnswer', {TUIobj.Locale.COREWORD_YES}, 'DisplayInReview', false, 'ValidateCallback', @changePortfolioFileNameCallback} ), 'END');
                        
            if (npTQ.Ask == 1)
                TUIobj.AppData.CreateNewPortfolio(npTQ.GetItemByTag('askPortfolioName').DefaultAnswer, npTQ.GetItemByTag('askPortfolioLocation').DefaultAnswer);
                pi = TUIobj.AppData.ImportPortfolio(npTQ.GetItemByTag('askPortfolioLocation').DefaultAnswer);
                
                if (pi == 2)
                    msg = sprintf('\n%s\n%s', TUIobj.Locale.Q_PORTFOLIO_NEW_NAME_CONFL, TUIobj.Locale.GEN_PRESS_ENTER_CONT);
                    input(msg);
                end
            end
            
            function ret = askPortfolioLocationCallback(answer)
                ret = 'Complete';
                
                if (exist(answer, 'file'))
                    ret = 1;
                end
            end
            
            function ret = changePortfolioFileNameCallback(answer)
                ret = 0;
                if (strcmpi(npTQ.GetItemByTag('changePortfolioFileName').ListItems{1}, answer))                    
                    ret = 'askPortfolioLocation';
                elseif (strcmpi(npTQ.GetItemByTag('changePortfolioFileName').ListItems{2}, answer))
                    ret = 1;
                end
            end                                    
        end
        
        function ret = openAssetUniverse(TUIobj, selection)
            ret = 0;
            oauTQ = FM.TextUIQuestionnaire(TUIobj.Locale.Q_AU_OPEN_TITLE);
                                                
            oauTQ.InsertItem(FM.TextUIQuestion(TUIobj.Locale.Q_AU_OPEN_ASK_FILE, 'askAuFile', {'ValidateCallback', @askAuFileCallback, }), 'END');                        
                        
            if (oauTQ.Ask == 1)
                TUIobj.AppData.OpenAssetUniverse(oauTQ.GetItemByTag('askAuFile').DefaultAnswer);                
            end            
            
            function ret = askAuFileCallback(answer)
                if (exist(answer, 'file') ~= 2)
                    fprintf ('%s: %s\n', TUIobj.Locale.ERR_GEN_FILE_NOT_FOUND, answer)
                    ret = 0;
                else
                    ret = 1;
                end
            end

        end
        
        function ret = saveAssetUniverse(TUIobj, selection)
            ret = 0;
            TUIobj.AppData.AssetUniverse_Save();
        end

        function ret = updateAssetPrices(TUIobj, selection)
            ret = 0;
            TUIobj.AppData.AssetUniverse_UpdateAssetPrices();
        end
        
        function ret = assetImportList(TUIobj, selection)
            ret = 0;
            ailTQ = FM.TextUIQuestionnaire(TUIobj.Locale.Q_ASSET_IMPORT_LIST);
            
            ailTQ.InsertItem(FM.TextUIQuestion(TUIobj.Locale.Q_ASSET_IMPORT_LIST_FILEPATH, 'askImportListFilepath', { 'ValidateCallback', @askImportListFilepathCallback } ), 'END');
            
            if (ailTQ.Ask == 1)
                ret = TUIobj.AppData.AssetUniverse_ImportAssetList(ailTQ.GetItemByTag('askImportListFilepath').DefaultAnswer);               
                msg = sprintf('\n(%d) %s.\n%s', ret, TUIobj.Locale.Q_ASSET_IMPORT_LIST_IMPORTED, TUIobj.Locale.GEN_PRESS_ENTER_CONT);
                    
                input(msg);
            end
            
            function ret = askImportListFilepathCallback(answer)
                if (exist(answer, 'file') ~= 2)
                    fprintf ('%s: %s\n', TUIobj.Locale.ERR_GEN_FILE_NOT_FOUND, answer)
                    ret = 0;
                else
                    ret = 1;
                end
            end
        end
                
        function ret = newScriptTemplate(TUIobj, selection)
            ret = 0;
            nstTQ = FM.TextUIQuestionnaire(TUIobj.Locale.Q_NEW_SCRIPT_TEMPLATE_TITLE);
            
            nstTQ.InsertItem(FM.TextUIQuestion(TUIobj.Locale.Q_NEW_SCRIPT_TEMPLATE_FILEPATH, 'askScriptTemplateFilepath', { 'ValidateCallback', @askScriptTemplateFilepathCallback } ), 'END');
            nstTQ.InsertItem(FM.TextUIQuestion(TUIobj.Locale.Q_NEW_SCRIPT_TEMPLATE_FILEPATH_CHG, 'changeScriptTemplateFile', {'Details', 'WARNING: A file with a specified name already exists.', 'List', true, 'ListItems', { TUIobj.Locale.COREWORD_YES; TUIobj.Locale.COREWORD_NO; }, 'DefaultAnswer', {TUIobj.Locale.COREWORD_YES}, 'DisplayInReview', false, 'ValidateCallback', @changeScriptTemplateFileCallback} ), 'END');
            
            if (nstTQ.Ask == 1)
                ret = TUIobj.AppData.NewScriptTemplate(nstTQ.GetItemByTag('askScriptTemplateFilepath').DefaultAnswer);               
            end
            
            function ret = askScriptTemplateFilepathCallback(answer)
                if (exist(answer, 'file') == 2)                    
                    ret = 'changeScriptTemplateFile';
                else
                    ret = 'Complete';
                end
            end
            
            function ret = changeScriptTemplateFileCallback(answer)
                ret = 0;
                if (strcmpi(nstTQ.GetItemByTag('changeScriptTemplateFile').ListItems{1}, answer))                    
                    ret = 'askScriptTemplateFilepath';
                elseif (strcmpi(nstTQ.GetItemByTag('changeScriptTemplateFile').ListItems{2}, answer))
                    ret = 1;
                end
            end                                    

        end
        
        function ret = addAsset(TUIobj, selection)
            ret = 0;
            aanTQ = FM.TextUIQuestionnaire(TUIobj.Locale.Q_ASSET_ADD_TITLE);
                                    
            aanTQ.InsertItem(FM.TextUIQuestion(TUIobj.Locale.Q_ASSET_ADD_TYPE, 'askAssetType', {'List', 'true', 'ListItems', {'ExchangeTraded'; 'Currency'}, 'ValidateCallback', @askAssetTypeCallback } ), 'END');                       
            aanTQ.InsertItem(FM.TextUIQuestion(TUIobj.Locale.Q_ASSET_ADD_SYMBOL, 'askAssetSymbol', {'ValidateCallback', @askAssetSymbolCallback, 'DisplayInReview', false } ), 'END');
            aanTQ.InsertItem(FM.TextUIQuestion(TUIobj.Locale.Q_ASSET_ADD_EXCHANGE, 'askAssetExchnage', {'List', 'true', 'ListItems', {'NYSE'; 'NASDAQ'; 'AMEX'}, 'DefaultAnswer', 'NYSE', 'ValidateCallback', @askAssetExchangeCallback, 'DisplayInReview', false } ), 'END');
            aanTQ.InsertItem(FM.TextUIQuestion(TUIobj.Locale.Q_ASSET_ADD_CLASS, 'askAssetClass', {'List', 'true', 'ListItems', {'Equity'}, 'ValidateCallback', @askAssetClassCallback, 'DefaultAnswer', 'Equity', 'DisplayInReview', false } ), 'END');                       
            aanTQ.InsertItem(FM.TextUIQuestion(TUIobj.Locale.Q_ASSET_ADD_CATEGORY, 'askAssetCategory', {'List', 'true', 'ListItems', {'Stock'; 'ETF' }, 'ValidateCallback', @askAssetCategoryCallback, 'DefaultAnswer', 'Stock', 'DisplayInReview', false } ), 'END');                       
            aanTQ.InsertItem(FM.TextUIQuestion(TUIobj.Locale.Q_ASSET_ADD_CURRENCY, 'askAssetCurrency', {'ValidateCallback', @askAssetCurrencyCallback, 'DisplayInReview', false } ), 'END');            
            aanTQ.InsertItem(FM.TextUIQuestion(TUIobj.Locale.Q_ASSET_ADD_CLASS, 'askAssetClassOther', {'List', 'true', 'ListItems', {'Cash'}, 'ValidateCallback', @askAssetClassOtherCallback, 'DefaultAnswer', 'Cash', 'DisplayInReview', false } ), 'END');                       
            aanTQ.InsertItem(FM.TextUIQuestion(TUIobj.Locale.Q_ASSET_ADD_CATEGORY, 'askAssetCategoryOther', {'List', 'true', 'ListItems', {'Currency'; }, 'ValidateCallback', @askAssetCategoryOtherCallback, 'DefaultAnswer', 'Currency', 'DisplayInReview', false } ), 'END');                       

            if (aanTQ.Ask == 1)
                switch upper(aanTQ.GetItemByTag('askAssetType').DefaultAnswer)
                    case upper(aanTQ.GetItemByTag('askAssetType').ListItems{1})
                        TUIobj.AppData.AssetUniverse_AddETAsset(aanTQ.GetItemByTag('askAssetSymbol').DefaultAnswer, aanTQ.GetItemByTag('askAssetExchnage').DefaultAnswer, aanTQ.GetItemByTag('askAssetClass').DefaultAnswer, aanTQ.GetItemByTag('askAssetCategory').DefaultAnswer);
                    case upper(aanTQ.GetItemByTag('askAssetType').ListItems{2})
                        TUIobj.AppData.AssetUniverse_AddCurrencyAsset(aanTQ.GetItemByTag('askAssetCurrency').DefaultAnswer, aanTQ.GetItemByTag('askAssetClassOther').DefaultAnswer, aanTQ.GetItemByTag('askAssetCategoryOther').DefaultAnswer);
                end
            end
            
            function ret = askAssetTypeCallback(answer)
                switch upper(answer)
                    case upper(aanTQ.GetItemByTag('askAssetType').ListItems{1})
                        aanTQ.SetItemProperty('askAssetSymbol', 'DisplayInReview', true);
                        aanTQ.SetItemProperty('askAssetExchnage', 'DisplayInReview', true);
                        aanTQ.SetItemProperty('askAssetClass', 'DisplayInReview', true);
                        aanTQ.SetItemProperty('askAssetCategory', 'DisplayInReview', true);
                        ret = 1;
                    case upper(aanTQ.GetItemByTag('askAssetType').ListItems{2})
                        aanTQ.SetItemProperty('askAssetCurrency', 'DisplayInReview', true);
                        aanTQ.SetItemProperty('askAssetClassOther', 'DisplayInReview', true);
                        aanTQ.SetItemProperty('askAssetCategoryOther', 'DisplayInReview', true);
                        ret = 'askAssetCurrency';
                end
            end
            
            function ret = askAssetSymbolCallback(answer)
                ret = 1;
            end

            function ret = askAssetExchangeCallback(answer)
                ret = 1;
            end

            function ret = askAssetClassCallback(answer)
                ret = 1;
            end

            function ret = askAssetCategoryCallback(answer)
                ret = 'Complete';
            end

            function ret = askAssetCurrencyCallback(answer)
                ret = 1;
            end

            function ret = askAssetClassOtherCallback(answer)
                ret = 1;
            end
            
            function ret = askAssetCategoryOtherCallback(answer)
                ret = 1;
            end
            
        end

        function ret = browseAssets(TUIobj, selection)
            ret = 0;
            baMenu = FM.ConsoleMenu(TUIobj.Locale.MENU_BA_TITLE, TUIobj.AppData, {'PostSelectCallback', @browseAssetDetails, 'Parent', TUIobj.Menu.GetItemByTag('mainmenuAssetUniverse').Callback});
            
            if (size(TUIobj.AppData.AssetUniverse.Assets) ~= 0)
                for i=1:size(TUIobj.AppData.AssetUniverse.Assets,1),
                    baMenu.InsertItem(FM.ConsoleMenuItem(TUIobj.AppData.AssetUniverse.Assets{i}.Ident(), { 'Tag', TUIobj.AppData.AssetUniverse.Assets{i}.Ident(), 'Enabled', true} ), 'END');                    
                end                
                baMenu.Pick();
            end
            
            function browseAssetDetails(selection)
                asset = TUIobj.AppData.AssetUniverse.Assets{str2num(selection)};
                fprintf('\nDetails for %s\n', asset.Ident);
                fprintf('\n%s\n', asset.Detail);
                asset.Plot();
                
                msg = sprintf('\n%s',  TUIobj.Locale.GEN_PRESS_ENTER_CONT);
                input(msg);                
            end            
        end               
        
        function ret = portfolioNewTransaction(TUIobj, selection)
            ret = 0;
            ntTQ = FM.TextUIQuestionnaire(TUIobj.Locale.Q_PORTFOLIO_NEW_TRANSACTION);
            ntTQ.InsertItem(FM.TextUIQuestion(TUIobj.Locale.Q_PORTFOLIO_NEW_TRANSACTION_SELECT_ASSET, 'selectUnderlyingAsset', {'ValidateCallback', @selectUnderlyingAsset, 'AnswerOverrideCallback', @selectUnderlyingAssetOverride, 'DisplayInReview', true, 'Details', TUIobj.Locale.Q_PORTFOLIO_NEW_TRANSACTION_SELECT_ASSET_DETAILS } ), 'END');
            
            ntTQ.InsertItem(FM.TextUIQuestion(TUIobj.Locale.Q_PORTFOLIO_TR_ACTION, 'askStockTransactionAction', {'List', 'true', 'ListItems', {'Buy'; 'Sell'; 'Sell Short'; 'Buy to Cover' }, 'ValidateCallback', @askStockTransactionActionCallback } ), 'END');
            ntTQ.InsertItem(FM.TextUIQuestion(TUIobj.Locale.Q_PORTFOLIO_TR_ACTION, 'askCashTransactionAction', {'List', 'true', 'ListItems', {'Deposit'; 'Withdrawal'; 'Credit'; 'Debit' }, 'ValidateCallback', @askCashTransactionActionCallback } ), 'END');            
            ntTQ.InsertItem(FM.TextUIQuestion(TUIobj.Locale.Q_PORTFOLIO_TR_QUANTITY, 'askTransactionQuantity', {'ValidateCallback', @askTransactionQuantityCallback} ), 'END');
                        
            if (ntTQ.Ask == 1)
                if isa(ntTQ.GetItemByTag('selectUnderlyingAsset').Data, 'FM.ExchangeTradedAsset')
                    nTR = struct('Action', ntTQ.GetItemByTag('askStockTransactionAction').DefaultAnswer, 'Asset', ntTQ.GetItemByTag('selectUnderlyingAsset').Data, 'Quantity', str2double(ntTQ.GetItemByTag('askTransactionQuantity').DefaultAnswer));
                    trID = TUIobj.AppData.Portfolio_StockTransaction(TUIobj.AppData.Portfolios{TUIobj.AppData.ActivePortfolio}, nTR);                    
                elseif isa(ntTQ.GetItemByTag('selectUnderlyingAsset').Data, 'FM.CurrencyAsset')
                    nTR = struct('Action', ntTQ.GetItemByTag('askCashTransactionAction').DefaultAnswer, 'Asset', ntTQ.GetItemByTag('selectUnderlyingAsset').Data, 'Quantity', str2double(ntTQ.GetItemByTag('askTransactionQuantity').DefaultAnswer));
                    trID = TUIobj.AppData.Portfolio_CashTransaction(TUIobj.AppData.Portfolios{TUIobj.AppData.ActivePortfolio}, nTR);
                end 
                
                if (trID ~= false)
                    msg = sprintf('\n%s\n%s', TUIobj.Locale.Q_PORTFOLIO_TR_ADDED, TUIobj.Locale.GEN_PRESS_ENTER_CONT);
                    input(msg);
                else
                    msg = sprintf('\n%s\n%s', TUIobj.Locale.Q_PORTFOLIO_TR_FAILED_ADD, TUIobj.Locale.GEN_PRESS_ENTER_CONT);
                    input(msg);
                end
                
            end

            function ret = askStockTransactionActionCallback(answer)
                ret = 0;
                % Check if answer has a supported 'Action'
                for i=1:size(ntTQ.GetItemByTag('askStockTransactionAction').ListItems,1)
                    if (strcmpi(answer, ntTQ.GetItemByTag('askStockTransactionAction').ListItems{i}))
                        ntTQ.SetItemProperty('askStockTransactionAction', 'DisplayInReview', true);
                        ntTQ.SetItemProperty('askCashTransactionAction', 'DisplayInReview', false);
                        ret = 'askTransactionQuantity';
                    end
                end
                
            end

            function ret = askCashTransactionActionCallback(answer)
                ret = 0;
                % Check if answer has a supported 'Action'
                for i=1:size(ntTQ.GetItemByTag('askCashTransactionAction').ListItems,1)
                    if (strcmpi(answer, ntTQ.GetItemByTag('askCashTransactionAction').ListItems{i}))
                        ntTQ.SetItemProperty('askStockTransactionAction', 'DisplayInReview', false);
                        ntTQ.SetItemProperty('askCashTransactionAction', 'DisplayInReview', true);
                        ret = 'askTransactionQuantity';
                    end
                end                
            end
            
            function ret = askTransactionQuantityCallback(answer)
                ret = 0;
                
                if (isnan(str2double(answer)))
                    return;
                else
                    ret = 'Complete';
                end
            end
                        
            function ret = selectUnderlyingAssetOverride(answer)
                    ret = ntTQ.GetItemByTag('selectUnderlyingAsset').Data.Ident();
            end
           
            function ret = selectUnderlyingAsset(answer)
                ret = 0;
                
                switch upper(answer)
                    case 'L'
                        uaMenu = FM.ConsoleMenu(TUIobj.Locale.Q_PORTFOLIO_NEW_TRANSACTION_UNDERLYING_ASSET_TITLE, TUIobj.AppData, {});

                        if (size(TUIobj.AppData.AssetUniverse.Assets) ~= 0)
                            for i=1:size(TUIobj.AppData.AssetUniverse.Assets,1),
                                uaMenu.InsertItem(FM.ConsoleMenuItem(TUIobj.AppData.AssetUniverse.Assets{i}.Ident(), { 'Tag', TUIobj.AppData.AssetUniverse.Assets{i}.Ident(), 'Enabled', true, 'Callback', @lookupUnderlyingAsset} ), 'END');                    
                            end                
                            underlyingAsset = uaMenu.Pick();                

                            if ~isa(underlyingAsset, 'FM.Asset')
                                return;                    
                            else
                                ntTQ.GetItemByTag('selectUnderlyingAsset').Data = underlyingAsset;
                                ret = 1;
                            end            
                        end
                    otherwise
                        if ~isempty(ntTQ.GetItemByTag('selectUnderlyingAsset').Data)
                            if strcmp(answer, ntTQ.GetItemByTag('selectUnderlyingAsset').Data.Ident())
                                ret = 1;
                            end
                        end
                        
                        if ~isnan((str2double(answer)))
                            answer = str2double(answer);
                            if (answer >0 && (answer <= size(TUIobj.AppData.AssetUniverse.Assets,1)) )
                                ntTQ.GetItemByTag('selectUnderlyingAsset').Data = TUIobj.AppData.AssetUniverse.Assets{answer};
                                ret = 1;               
                            else
                                return
                            end
                        end
                end
                
                if ((ret == 1) && isa(ntTQ.GetItemByTag('selectUnderlyingAsset').Data, 'FM.ExchangeTradedAsset'))
                    ret = 'askStockTransactionAction';
                elseif ((ret == 1) && isa(ntTQ.GetItemByTag('selectUnderlyingAsset').Data, 'FM.CurrencyAsset'))
                    ret = 'askCashTransactionAction';
                end

            end
            
            
            function ret = lookupUnderlyingAsset(answer)
                ret = TUIobj.AppData.AssetUniverse.Assets{answer};
            end                                   
        end
        
        function ret = portfolioListTransaction(TUIobj, selection)
            ret = 0;
            
            pltMenu = FM.ConsoleMenu(TUIobj.Locale.MENU_PORTFOLIO_LT_TITLE, TUIobj.AppData, {'PostSelectCallback', @browseTransactionDetails, 'Parent', TUIobj.Menu.GetItemByTag('mainmenuPortfolio').Callback});
            
            activePortfolio = TUIobj.AppData.ActivePortfolio;
            if (size(TUIobj.AppData.Portfolios{activePortfolio}.Transactions) ~= 0)
                for i=1:size(TUIobj.AppData.Portfolios{activePortfolio}.Transactions,1),
                    pltMenu.InsertItem(FM.ConsoleMenuItem(TUIobj.AppData.Portfolios{activePortfolio}.Transactions{i}.Summary(), { 'Tag', sprintf('%s-%d', TUIobj.AppData.Portfolios{activePortfolio}.Name, i), 'Enabled', false} ), 'END');                    
                end                
                pltMenu.Pick();
            end            
            
            function ret = browseTransactionDetails(selection)
                ret = NaN;
            end
        end

        function ret = portfolioListPositions(TUIobj, selection)
            ret = 0;
            
            plpMenu = FM.ConsoleMenu(TUIobj.Locale.MENU_PORTFOLIO_LP_TITLE, TUIobj.AppData, {'PostSelectCallback', @browsePositionDetails, 'Parent', TUIobj.Menu.GetItemByTag('mainmenuPortfolio').Callback});
            
            activePortfolio = TUIobj.AppData.ActivePortfolio;
            if (size(TUIobj.AppData.Portfolios{activePortfolio}.Positions) ~= 0)
                for i=1:size(TUIobj.AppData.Portfolios{activePortfolio}.Positions,1),
                    plpMenu.InsertItem(FM.ConsoleMenuItem(TUIobj.AppData.Portfolios{activePortfolio}.Positions{i}.Summary(), { 'Tag', sprintf('%s-%d', TUIobj.AppData.Portfolios{activePortfolio}.Name, i), 'Enabled', true} ), 'END');                    
                end                
                plpMenu.Pick();
            end            
            
            function ret = browsePositionDetails(selection)
                ret = TUIobj.AppData.Portfolios{activePortfolio}.ListPositionTransactions(str2double(selection));                
                
                msg = sprintf('\n%s',  TUIobj.Locale.GEN_PRESS_ENTER_CONT);
                input(msg);                
            end
end
        
        function ret = portfolioCommitTransactionsExec(TUIobj, params)
            ret = 0;                
                
                for i=1:size(params.TransVector,2),
                    Action = '';
                    commStatus = false;                    
                
                    if (TUIobj.AppData.Portfolios{TUIobj.AppData.ActivePortfolio}.LastCommitedTransaction == 0)
                        lastComm = datenum(FM.Config.BackfillStartDate); 
                    else
                        lastComm = TUIobj.AppData.Portfolios{TUIobj.AppData.ActivePortfolio}.Transactions{TUIobj.AppData.Portfolios{TUIobj.AppData.ActivePortfolio}.LastCommitedTransaction}.CommittedOn;
                    end

                    allowedTimeRange = sprintf('%s-%s', datestr(lastComm, 2), datestr(now, 2));
                    trans = TUIobj.AppData.Portfolios{TUIobj.AppData.ActivePortfolio}.Transactions{params.TransVector(i)};
                    cTQ = FM.TextUIQuestionnaire(TUIobj.Locale.Q_PORTFOLIO_CTRANS);                         
                    
                    if (isempty(trans.PreviouslyCommittedOn))
                        Action = 'Commit';
                    elseif (floor(trans.PreviouslyCommittedOn) >= floor(lastComm))
                        cTQ.InsertItem(FM.TextUIQuestion(TUIobj.Locale.Q_PORTFOLIO_CTRANS_RECOMMIT, 'portfolioCTransRecommit', {'List', true, 'ListItems', { TUIobj.Locale.COREWORD_YES; TUIobj.Locale.COREWORD_NO; }, 'DefaultAnswer', TUIobj.Locale.COREWORD_YES,  'DisplayInReview', true, 'ValidateCallback', @portfolioCTransRecommit, 'Details', trans.Summary()} ), 'END');
                        Action = 'Recommit';
                    else
                        Action = 'Commit';
                    end                    

                    cTQ.InsertItem(FM.TextUIQuestion(TUIobj.Locale.Q_PORTFOLIO_CTRANS_TIME, 'portfolioCTransTime', { 'DisplayInReview', false, 'ValidateCallback', @portfolioCTransTimeCallback, 'Details', sprintf('Commit %s, allowed commit time frame %s', trans.Summary(), allowedTimeRange)} ), 'END');                            
                    cTQ.InsertItem(FM.TextUIQuestion(TUIobj.Locale.Q_PORTFOLIO_CTRANS_PRICE, 'portfolioCTransPrice', { 'DisplayInReview', false,  'List', true, 'ListItems', { 'Close'; 'Open'; 'Low'; 'High'; '###.##' }, 'DefaultAnswer', 'Close', 'ValidateCallback', @portfolioCTransPriceCallback} ), 'END');                                                    
                    
                    if ~isempty(Action) 

                        if (cTQ.Ask())
                            if (strcmp(Action, 'Commit') || strcmpi(cTQ.GetItemByTag('portfolioCTransRecommit').DefaultAnswer, TUIobj.Locale.COREWORD_NO))
                                if isa(trans, 'FM.CashTransaction')                        
                                    paramsCT = struct('TrID', params.TransVector(i), 'Action', 'Commit', 'Time', datenum(cTQ.GetItemByTag('portfolioCTransTime').DefaultAnswer));
                                    commStatus = TUIobj.AppData.Portfolio_CashTransaction(TUIobj.AppData.Portfolios{TUIobj.AppData.ActivePortfolio}, paramsCT);
                                elseif isa(trans, 'FM.StockTransaction')
                                    paramsCT = struct('TrID', params.TransVector(i), 'Action', 'Commit', 'Price', str2double(cTQ.GetItemByTag('portfolioCTransPrice').DefaultAnswer), 'Time', datenum(cTQ.GetItemByTag('portfolioCTransTime').DefaultAnswer));
                                    commStatus = TUIobj.AppData.Portfolio_StockTransaction(TUIobj.AppData.Portfolios{TUIobj.AppData.ActivePortfolio}, paramsCT);
                                end 
                            else
                                if isa(trans, 'FM.CashTransaction')                        
                                    paramsCT = struct('TrID', params.TransVector(i), 'Action', 'Recommit');
                                    commStatus = TUIobj.AppData.Portfolio_CashTransaction(TUIobj.AppData.Portfolios{TUIobj.AppData.ActivePortfolio}, paramsCT);
                                elseif isa(trans, 'FM.StockTransaction')
                                    paramsCT = struct('TrID', params.TransVector(i), 'Action', 'Recommit');
                                    commStatus = TUIobj.AppData.Portfolio_StockTransaction(TUIobj.AppData.Portfolios{TUIobj.AppData.ActivePortfolio}, paramsCT);
                                end 
                            end
                            
                            if ((params.StopOnErr) && ~commStatus)
                                msg = sprintf('\n%s\n%s', TUIobj.Locale.ERR_PORTFOLIO_CT_FAILED, TUIobj.Locale.GEN_PRESS_ENTER_CONT);
                                input(msg);                                
                                break;
                            end
                        end
                    end
                end
           return;
           
            function ret = portfolioCTransRecommit(answer)
                    ret = 0;
                    
                    if (strcmpi(answer, TUIobj.Locale.COREWORD_YES))
                        ret = 'Complete';
                    elseif strcmpi(answer, TUIobj.Locale.COREWORD_NO) 
                        ret = 'portfolioCTransTime';
                    end                                    
            end
            
            function ret = portfolioCTransTimeCallback(answer)
                try
                    cdate = datenum(answer);                
                catch ME1
                    ret = 0;
                    return;
                end
                
                if ((cdate > floor(now)) || (cdate < floor(lastComm)))
                    ret = 0;
                elseif isa(trans, 'FM.CashTransaction')                    
                    cTQ.SetItemProperty('portfolioCTransTime', 'DisplayInReview', true);
                    ret = 'Complete';
                else
                    cTQ.SetItemProperty('portfolioCTransTime', 'DisplayInReview', true);
                    cTQ.SetItemProperty('portfolioCTransPrice', 'DisplayInReview', true);
                    ret = 1;
                end                                
            end
            
            function ret = portfolioCTransPriceCallback(answer)
                
                if (strcmpi(answer, 'OPEN') || strcmpi(answer, 'HIGH') || strcmpi(answer, 'LOW') || strcmpi(answer, 'CLOSE') || ~isnan(str2double(answer))) 
                    ret = 1;                
                else
                    ret = 0;
                end
            end
        end

        function ret = portfolioCommitTransactions(TUIobj, selection)
            ret = 0;
            
            pctMenu = FM.ConsoleMenu(TUIobj.Locale.MENU_PORTFOLIO_CT_TITLE, TUIobj.AppData, {'Parent', TUIobj.Menu.GetItemByTag('mainmenuPortfolio').Callback});
            
            activePortfolio = TUIobj.AppData.ActivePortfolio;
            if (size(TUIobj.AppData.Portfolios{activePortfolio}.Transactions) ~= 0)
                for i=1:size(TUIobj.AppData.Portfolios{activePortfolio}.Transactions,1),
                    if (i > TUIobj.AppData.Portfolios{activePortfolio}.LastCommitedTransaction)
                        pctMenu.InsertItem(FM.ConsoleMenuItem(TUIobj.AppData.Portfolios{activePortfolio}.Transactions{i}.Summary(), { 'Tag', sprintf('%s-%d', TUIobj.AppData.Portfolios{activePortfolio}.Name, i), 'Enabled', true, 'Callback',  @commitPortfolioTransactionsCallback} ), 'END');                    
                    else
                        pctMenu.InsertItem(FM.ConsoleMenuItem(TUIobj.AppData.Portfolios{activePortfolio}.Transactions{i}.Summary(), { 'Tag', sprintf('%s-%d', TUIobj.AppData.Portfolios{activePortfolio}.Name, i), 'Enabled', false} ), 'END');                    
                    end
                end                
                pctMenu.Pick();
            end            
            
            function ret = commitPortfolioTransactionsCallback(selection)
                ctTQ = FM.TextUIQuestionnaire(TUIobj.Locale.Q_PORTFOLIO_CT);
                
                if ((selection - TUIobj.AppData.Portfolios{activePortfolio}.LastCommitedTransaction) >1)
                    ctTQ.InsertItem(FM.TextUIQuestion(TUIobj.Locale.Q_PORTFOLIO_CT_RANGE, 'portfolioCTRange', {'List', true, 'ListItems', { TUIobj.Locale.Q_PORTFOLIO_CT_ALL; TUIobj.Locale.Q_PORTFOLIO_CT_SEL; }, 'DefaultAnswer', TUIobj.Locale.Q_PORTFOLIO_CT_SEL,  'DisplayInReview', true, 'ValidateCallback', @portfolioCTRangeCallback} ), 'END');                            
                    ctTQ.InsertItem(FM.TextUIQuestion(TUIobj.Locale.Q_PORTFOLIO_CT_STOP, 'portfolioCTStop', {'ValidateCallback', @portfolioCTStopCallback,  'List', true, 'ListItems', { TUIobj.Locale.COREWORD_YES; TUIobj.Locale.COREWORD_NO; }, 'DefaultAnswer', TUIobj.Locale.COREWORD_YES, 'DisplayInReview', false} ), 'END');                
                
                    if (ctTQ.Ask == 1)
                        ret = 1;
                    else
                        ret = 0;
                        return;
                    end
                else
                    ret = 1;
                end
                
                % Establish a vector of transactions to commit
                if (~isempty(ctTQ.GetItemByTag('portfolioCTRange')))
                    if (strcmpi(ctTQ.GetItemByTag('portfolioCTRange').DefaultAnswer, TUIobj.Locale.Q_PORTFOLIO_CT_ALL))
                        firstTrans = TUIobj.AppData.Portfolios{activePortfolio}.LastCommitedTransaction + 1;
                        lastTrans = selection;
                    else
                            firstTrans = selection;
                            lastTrans = selection;                                            
                    end                    
                else
                        firstTrans = selection;
                        lastTrans = selection;                    
                end
                stopOnErr = false;
                
                if (~isempty(ctTQ.GetItemByTag('portfolioCTStop')))
                    if (strcmpi(ctTQ.GetItemByTag('portfolioCTStop').DefaultAnswer, TUIobj.Locale.COREWORD_YES))
                        stopOnErr = true;
                    end                    
                end
                
                transVector = [firstTrans:lastTrans];
                
                TUIobj.portfolioCommitTransactionsExec(struct('TransVector', transVector, 'StopOnErr', stopOnErr))
                
                function ret = portfolioCTRangeCallback(answer)
                    ret = 0;
                    
                    if (strcmpi(answer, TUIobj.Locale.Q_PORTFOLIO_CT_ALL))
                        ctTQ.SetItemProperty('portfolioCTStop', 'DisplayInReview', true);
                        ret = 1;
                    elseif (strcmpi(answer, TUIobj.Locale.Q_PORTFOLIO_CT_SEL))
                        ctTQ.SetItemProperty('portfolioCTStop', 'DisplayInReview', false);
                        ret = 'Complete';
                    end
                end
                
                function ret = portfolioCTStopCallback(answer)
                    ret = 0;
                    
                    if (strcmpi(answer, TUIobj.Locale.COREWORD_YES) || strcmpi(answer, TUIobj.Locale.COREWORD_NO) )
                        ret = 'Complete';
                    end                    
                end                                
            end
        end
        
        function ret = portfolioUncommitTransactions(TUIobj, selection)
            ret = 0;
            
            uctMenu = FM.ConsoleMenu(TUIobj.Locale.MENU_PORTFOLIO_UT_TITLE, TUIobj.AppData, {'Parent', TUIobj.Menu.GetItemByTag('mainmenuPortfolio').Callback});
            
            activePortfolio = TUIobj.AppData.ActivePortfolio;
            if (size(TUIobj.AppData.Portfolios{activePortfolio}.Transactions) ~= 0)
                for i=1:size(TUIobj.AppData.Portfolios{activePortfolio}.Transactions,1),
                    if ((i <= TUIobj.AppData.Portfolios{activePortfolio}.LastCommitedTransaction) && ~isempty(TUIobj.AppData.Portfolios{activePortfolio}.Transactions{i}.CommittedOn))
                        uctMenu.InsertItem(FM.ConsoleMenuItem(TUIobj.AppData.Portfolios{activePortfolio}.Transactions{i}.Summary(), { 'Tag', sprintf('%s-%d', TUIobj.AppData.Portfolios{activePortfolio}.Name, i), 'Enabled', true, 'Callback',  @uncommitPortfolioTransactionsCallback} ), 'END');                    
                    else
                        uctMenu.InsertItem(FM.ConsoleMenuItem(TUIobj.AppData.Portfolios{activePortfolio}.Transactions{i}.Summary(), { 'Tag', sprintf('%s-%d', TUIobj.AppData.Portfolios{activePortfolio}.Name, i), 'Enabled', false} ), 'END');                    
                    end
                end                
                uctMenu.Pick();
            end
            
            function ret = uncommitPortfolioTransactionsCallback(selection)                
                firstTrans = selection;
                lastTrans = TUIobj.AppData.Portfolios{activePortfolio}.LastCommitedTransaction;                
                transVector = [firstTrans:lastTrans];
                
                if (size(transVector,2) > 1)
                    range = sprintf('%d-%d', firstTrans, lastTrans);
                else
                    range = sprintf('%d', transVector);
                end

                utTQ = FM.TextUIQuestionnaire(TUIobj.Locale.Q_PORTFOLIO_UT);                
                utTQ.InsertItem(FM.TextUIQuestion(TUIobj.Locale.Q_PORTFOLIO_UT_RANGE, 'portfolioUTRange', {'List', true, 'ListItems', { TUIobj.Locale.COREWORD_YES; TUIobj.Locale.COREWORD_NO; }, 'DefaultAnswer', TUIobj.Locale.COREWORD_YES, 'DisplayInReview', true, 'ValidateCallback', @portfolioUTRangeCallback, 'Details', sprintf('%s: %s', TUIobj.Locale.Q_PORTFOLIO_UT, range)} ), 'END');                            

                if (utTQ.Ask == 1)
                    TUIobj.portfolioUncommitTransactionsExec(transVector);
                    ret = true;
                else
                    ret = false;
                end

                    function ret = portfolioUTRangeCallback(answer)
                            ret = 0;

                            if (strcmpi(answer, TUIobj.Locale.COREWORD_YES))
                                ret = 'Complete';
                            elseif strcmpi(answer, TUIobj.Locale.COREWORD_NO) 
                                ret = 2;
                            end                                    
                    end                                
            end
        end

        function unCommStatus = portfolioUncommitTransactionsExec(TUIobj, transVector)

                transVector = fliplr(transVector);                
                for i=1:size(transVector,2),
                    trans = TUIobj.AppData.Portfolios{TUIobj.AppData.ActivePortfolio}.Transactions{transVector(i)};
                    if isa(trans, 'FM.CashTransaction')                        
                       paramsUT = struct('TrID', transVector(i), 'Action', 'Uncommit');
                       unCommStatus = TUIobj.AppData.Portfolio_CashTransaction(TUIobj.AppData.Portfolios{TUIobj.AppData.ActivePortfolio}, paramsUT);
                    elseif isa(trans, 'FM.StockTransaction')
                       paramsUT = struct('TrID', transVector(i), 'Action', 'Uncommit');
                       unCommStatus = TUIobj.AppData.Portfolio_StockTransaction(TUIobj.AppData.Portfolios{TUIobj.AppData.ActivePortfolio}, paramsUT);
                    end                     
                end
        end
        
        function ret = activePortfolio(TUIobj, selection)
            ret = 0;
            apMenu = FM.ConsoleMenu(TUIobj.Locale.MENU_PORTFOLIO_ACTIVE_TITLE, TUIobj.AppData, {'PostSelectCallback', @switchActivePortfolio, 'Parent', TUIobj.Menu.GetItemByTag('mainmenuPortfolio').Callback});
            
            if (size(TUIobj.AppData.Portfolios,1) ~= 0)
                for i=1:size(TUIobj.AppData.Portfolios,1),
                    if (TUIobj.AppData.ActivePortfolio ==i)
                        apMenu.InsertItem(FM.ConsoleMenuItem(TUIobj.AppData.Portfolios{i}.Name, { 'Tag', TUIobj.AppData.Portfolios{i}.Name, 'Enabled', true, 'Checked', true} ), 'END');                                            
                    else
                        apMenu.InsertItem(FM.ConsoleMenuItem(TUIobj.AppData.Portfolios{i}.Name, { 'Tag', TUIobj.AppData.Portfolios{i}.Name, 'Enabled', true} ), 'END');                    
                    end
                end                
                apMenu.Pick();
            end
            
            function ret = switchActivePortfolio(selection)
                ret = false;
                selection = str2double(selection);
                if ((selection < 1) || (selection > size(TUIobj.AppData.Portfolios,1)) || isnan(selection))
                    return;
                end
                
                if (isempty(TUIobj.AppData.ActivePortfolio)) 
                    TUIobj.AppData.SetActivePortfolio(selection);
                    apMenu.SetItemProperty(TUIobj.AppData.Portfolios{selection}.Name, 'Checked', true);
                else                    
                    apMenu.SetItemProperty(TUIobj.AppData.Portfolios{TUIobj.AppData.ActivePortfolio}.Name, 'Checked', false);
                    TUIobj.AppData.SetActivePortfolio(selection);
                    apMenu.SetItemProperty(TUIobj.AppData.Portfolios{selection}.Name, 'Checked', true);
                end
                                                
            end            
        end               

        
        function showStatus(TUIobj)
            if ~isa(TUIobj.AppData.AssetUniverse, 'FM.AssetUniverse')
                auName = 'N/A';
            else
                auName = TUIobj.AppData.AssetUniverse.Name;
            end
            
            if (TUIobj.AppData.ProjectSaved == false)
                projectState = '*';
            else
                projectState = '';
            end
            
            if (TUIobj.AppData.AssetUniverseSaved == false)
                auState = '*';
            else
                auState = '';
            end

            if (TUIobj.AppData.PortfoliosSaved == false)
                portfoliosState = '*';
            else
                portfoliosState = '';
            end
            
            
            numPort = size(TUIobj.AppData.Portfolios,1);
            
            fprintf('Project: "%s%s", Asset Universe: "%s%s", Portfolios: %s%d\n', projectState, TUIobj.AppData.Project, auState,auName, portfoliosState,numPort);            
        end                                    
    end        
end

Contact us