基于matlab进行程序化交易设计

Discussion in 'Julia / MATLAB / SAS' started by jemnbo, Jan 2, 2010.

  1. 使用matlab的好处在于其数据处理量能够很大,矩阵运算非常快,且编程时也能简单明了,tools也提供了相当程度的便捷函数。
    我这里不想贴出我是如何用matlab程序方法做出一个程序化交易策略的,这在我的个人blog上大家可以看到,http://hexun.com/jemnbo/default.html
    我这里想跟大家交流的是,如何利用数据和工具。
    首先,工具必须可得可靠,matlab是为数不多提供原代码学习的工具,且其解析式的编程让你对推导过程非常明了。
    其次,数据的可得可靠性。例如,你得到了中国的CPI,可信吗?这就要率先斟酌一下。
    再次,所需数据类别,这取决于你策略的持有周期,如果你是高频交易,你没有必要了解现在处于经济周期的什么位置,如果你是长线投资,你也没有必要管现在盘口价差是多少。
    再次,数据分析方法,取决于你的策略是单品种还是组合投资,是趋势跟踪还是均值回复或保值,不同目标,数学方法也不同。
    最后,无论多精深的数序模型还是紧密的系统,都不可能完全解决掉系统性风险,人为干预并非不可取,但这需要情形分析和清醒的头脑,如果你是完全独立的策略执行人,你要了解你的策略假设基础,如果你是下属,你要让你的领导知道这一点,切记!提前让他知道!
     
  2. 提供一个简单的程序,以供初学者参考。
    %% Introduction:

    % This M-file is an integrated file of several programs designed to analyze the local empirical distributions by using resample fashion,
    % and to present the simulated trade results based on the distributions.
    %
    % The main functions include:
    %
    % 1) Extract data from SQL server;
    % 2) Data trimming;
    % 3) Construct local empirical distributions of the trimmed mean of spread/ratio by using resample method;
    % 4) Construct bootstrap confidence intervals of the trimmed mean of spread/ratio;
    % 5) Construct simulated trade results based on historical data and resample methods;
    % 6) Present simulated trade results;

    %% 1.
    % clear
    clc
    tic
    % delete v.mat;

    %% 2. Load Data from SQL Datebase.

    % sqldatabase;

    pause(3);

    %% 3. Choose the routine you want to run.

    kk = 'Yes';
    while strcmp(kk,'Yes') == 1,

    k = menu('Please choose one of the routines blow you want to ran: ', 'Construct empirical distributions at each time. ',...
    'Simulate trades based on empirical local distribution.', 'None.' );

    switch k

    %% 4. Function 1: Local Empirical Distribution.

    case 1

    % Parameters Settings.
    prompt = {'Please enter the two-sided percentage you would like to trim for constructing trimmed means: ',...
    'Please enter your setting of resample times for bootstrap procedure: ',...
    'Please enter the first date you would like start bootstrap resampling: '};

    name = 'Specify the tables and date: ';
    numlines = 1;
    options.Resize = 'on';
    options.WindowStyle = 'normal';
    options.Interpreter = 'tex';

    defaultanswer = {'10','500','100'};

    answer = inputdlg(prompt,name,numlines,defaultanswer,options); %inputdlg(prompt,dlg_title,num_lines,defAns,options)

    % Convert inputs into matrix structure.
    Parameter = zeros(3,1);

    for i = 1:3
    Parameter(i) = str2double(answer{i});
    end

    % Execute the main program for constructing local empirical distributions.
    localempiricaldist(Parameter);

    kk = questdlg('Do you want to continue your analysis procedure? ');

    %% 5. Function 2: Spread/Ratio Arbitrage Trades.

    case 2

    % Parameters settings - specify bootstrap details.
    prompt = {'Please enter the two-sided percentage you would like to trim for constructing trimmed mean: ',...
    'Please enter your setting of resample times for bootstrap procedure: ',...
    'Please enter the first date you would like start bootstrap resampling: '};

    name = 'Specify the bootstrap details: ';
    numlines = 1;
    options.Resize = 'on';
    options.WindowStyle = 'normal';
    options.Interpreter = 'tex';

    defaultanswer = {'10','1000','30'};

    answer = inputdlg(prompt,name,numlines,defaultanswer,options);

    % Convert inputs into matrix structure.
    Parameter_Boot = zeros(3,1);

    for i = 1:3
    Parameter_Boot(i) = str2double(answer{i});
    end

    % -------------------------------------------------------------------------
    % Parameters settings - specify trade details(P-value).
    prompt = {'Please enter the P_value you prefer for your openning strategies :',...
    'Please enter the P_value you prefer for your closing strategies :',...
    };

    name = 'Specify the trade details: ';
    numlines = 1;
    options.Resize = 'on';
    options.WindowStyle = 'normal';
    options.Interpreter = 'tex';

    defaultanswer = {'0.05','0.3'};

    answer = inputdlg(prompt,name,numlines,defaultanswer,options);

    % Convert inputs into matrix structure.
    Parameter_Trade = zeros(3,1);

    for i = 1:2
    Parameter_Trade(i) = str2double(answer{i});
    end

    % Execute the main program for constructing simulated trades.
    table = simutrade(Parameter_Boot, Parameter_Trade);
    [profit_statistics] = outputsummary(table);

    kk = questdlg('Do you want to continue your analysis procedure? ');

    %% 6. Function 3: None.
    case 3
    kk = 'No';
    end
    end
    toc



    %% Program Part 1: Extract data from SQL DB.

    %% 1.
    clear
    clc

    %% 2. Choose Data Source.

    sourceName = 'TaiwanData';
    Timeout = logintimeout(10); % Set or get time allowed to establish database connection
    conn = database(sourceName,'sa','123456'); % Connect to database , conn = database('datasourcename','username','password')
    ping(conn) % Get status information about database connection

    %% 3. Select specific tables you would like to exploit.

    uiwait(warndlg('First select the tables and specify the timeslot you want to exploit. Please be noted that in this version, you can at most choose two different tables and select only one specific day: '));
    % Block execution and wait for resume
    prompt = {'Enter the main table you want to exploit: ','Enter the control table you want to exploit: ',...
    'Enter the date on which you want to carry out the analysis : '};

    name = 'Specify the tables and date: ';
    numlines = 1;
    options.Resize = 'on';
    options.WindowStyle = 'normal';
    options.Interpreter = 'tex';

    defaultanswer = {'twi','wtx','2009-10-27'};

    answer = inputdlg(prompt,name,numlines,defaultanswer,options);

    %% 4. Extract data from SQL Server.

    for i = 1:2,

    sql{i} = ['select * from ',answer{i},' where datepart=','''', answer{3}, ''''];
    curs{i} = exec(conn,sql{i}); % curs = exec(conn, 'sqlquery'),
    % executes the SQL statement sqlquery for the database connection conn, and opens a cursor.
    setdbprefs('DataReturnFormat','cellarray'); % returns current values for database preferences
    curs{i} = fetch(curs{i}); % cursor.fetch or database.fetch
    numrows(i) = rows(curs{i});% Return number of rows in fetched data set
    numcols(i) = cols(curs{i}); % Retrieve number of columns in fetched data set

    % Display table information sets.

    disp('--------------------------------------------------------------');
    fprintf(' Information of Table %s . ',answer{i});

    disp('--------------------------------------------------------------');
    fprintf( ' number of rows = %d, number of columns = %d ',numrows(i),numcols(i));
    disp('--------------------------------------------------------------');
    disp(' FieldName typeName typeValue columnWidth nullable');

    for k = 1:numcols

    attributes=attr(curs{i},k); % Retrieve attributes of columns in fetched data set

    tableinfo{k,1}=attributes.fieldName; %获取字段名称
    tableinfo{k,2}=attributes.typeName; %获取字段类型名
    tableinfo{k,3}=attributes.typeValue; %获取字段类型代码
    tableinfo{k,4}=attributes.columnWidth; %获取字段的宽度
    tableinfo{k,5}=attributes.nullable; %获取字段是否可空
    end
    disp(tableinfo); %显示数据表的结构信息


    disp('-------------------------------------------------------------');
    fprintf(' Data of Table %s . ',answer{i});
    disp('--------------------------------------------------------------');

    for j3=1:numcols
    fprintf(' %s',tableinfo{j3,1});
    end
    fprintf(' ');

    tabledata{i} = curs{i}.data; %获取结果集对象的数据

    table{i} = tabledata{i}:),2:8); %时间 开 高 低 收 日期 交易时间 量

    table{i}:),5:6) = [];

    B = datevec(table{i}:),5));% Convert date and time to vector of components
    b = 100*B:),4)+B:),5);

    tablenew{i} = cell2mat(table{i}:),1:4)); % Convert cell array of matrices to single matrix
    tablenew{i}:),5) = b;
    end

    %% 5. Collect close prices.

    v = zeros(max(numrows(1),numrows(2)),4);

    if numrows(2) - numrows(1) > 0,
    adj_Num = numrows(2) - numrows(1);
    tablenew{1} = [tablenew{1};NaN*zeros(adj_Num,5)];
    elseif numrows(2) - numrows(1) < 0,
    adj_Num = numrows(1) - numrows(2);
    tablenew{2} = [tablenew{2};NaN*zeros(adj_Num,5)];
    end

    v:),1) = tablenew{1}:),5);
    v:),2) = tablenew{1}:),4);
    v:),3) = tablenew{2}:),5);
    v:),4) = tablenew{2}:),4);

    save v.mat v;
    %% 6.
    clear
     
  3. function [table] = simutrade(Parameter_Boot, Parameter_Trade)
    %% Introduction:

    % This program is designed to construct simultate trades based on historical data and on the empirical distributions we obtain by use of resampling methods.
    %
    % The input is the same as in localempiricaldist.m file.
    %
    % The program first constructs the bootstrap confidence intervals based on the resample procedure and the BCa methods. Then, based on these intervals, one
    % could obtain the mareket strategies with entering and exit signals.
    %
    % The output is the matrix consists of all details regarding the simulated trades.


    %%

    load v.mat;

    %% 1. Parameters settings, read parameter settings from the main program.

    alpha = Parameter_Boot(1); % Trim value for trimmed mean.
    n = Parameter_Boot(2); % Bootstrap repeat times.
    ST = Parameter_Boot(3); % Starting point of bootstrap.

    alpha_s = Parameter_Trade(1); % Percentile parameters of spreads.
    alpha_s1 = Parameter_Trade(2); % Closing area of spreads.

    alpha_r = Parameter_Trade(1); % Percentile parameters of returns.
    alpha_r1 = Parameter_Trade(2); % Closing area of returns.



    %% 2. Data timming,to match each data record to the corresponding timepoints.

    a = size(v,1)-sum(isnan(v:),1)));
    b=size(v,2);
    new = zeros(a,b);
    new:),1:2)=v(1:a,1:2);

    for i=1:a,
    j= v:),3)==new(i,1);
    new(i,3:4)=v(j,3:4);
    end

    % Obtain table of the form as "time-priceA-priceB".
    table=new(1:a,:);
    table:),3)=[];

    %% 3. Resample procedure.

    k = menu('please choose which variable you want to analyze: ', 'Spreads', 'Returns','None');
    switch k;

    %% 3.1. Spreads.

    case 1
    disp('Analyzing spreads, please be waiting...')

    % Calculate spreads.
    s = table:),3) - table:),2);
    length_s = length(s);

    % Bootstrap empirical critical value.
    for j = 1:length_s-ST+1
    cb_s(j,:) = bootci(n,{@(x)trimmean(x,alpha),s(j:j+ST-1)},'alpha',alpha_s);
    cb_s1(j,:) = bootci(n,{@(x)trimmean(x,alpha),s(j:j+ST-1)},'alpha',alpha_s1);
    end

    % Modify empirical critical value to get openning areas ajusted to transaction fees.
    barrar_s = cb_s + ones(length_s-ST+1,1)*[-1 1];
    close_s = cb_s1 + ones(length_s-ST+1,1)*[-1 1];

    %% 3.1.1. Transcation.

    table = [table s];
    table(1:ST-1,5:6) = str2double('NaN')*ones(1:ST-1,1:2);
    table(ST:end,5:6) = barrar_s;

    % Generate transaction signals.
    for j1 = 1:a
    if table(j1,4) < table(j1,5),
    table(j1,7) = 1;
    elseif table(j1,4) > table(j1,6),
    table(j1,7) = -1;
    else
    table(j1,7) = 0;
    end
    end

    % Generate closing areas.
    table(ST:end,8:9) = close_s;

    % Construct transaction details.
    table:),10:11) = zeros(270,2);

    for j2 = ST:a,
    if table(j2,7) == 1 && table(j2-1,7)*table(j2,7) <= 0,
    kk = find(table(j2+1:end,4) > table(j2+1:end,8) ,1,'first');
    table(kk+j2,10) = table(kk+j2,3) - table(j2,3);
    table(kk+j2,11) = table(kk+j2,10)*200 - 180 - (table(j2,3)+table(kk+j2,3))*0.00004;
    elseif table(j2,7) == -1 && table(j2-1,7)*table(j2,7) <= 0,
    kk = find(table(j2+1:end,4) < table(j2+1:end,9),1,'first');
    table(kk+j2,10) = table(j2,3) - table(kk+j2,3);
    table(kk+j2,11) = table(kk+j2,10)*200 - 180 - (table(j2,3)+table(kk+j2,3))*0.00004;
    else
    end
    end

    %% 3.2. Returns
    case 2
    disp('Analyzing returns, please be waiting...')

    % Calculate returns.
    r = (table:),3) - table:),2))./table:),3);
    length_r = length(r);

    % Bootstrap empirical critical value.
    for j = 1:length_r-ST+1
    cb_r(j,:) = bootci(n,{@(x)trimmean(x,alpha),r(j:j+ST-1)},'alpha',alpha_r);
    cb_r1(j,:) = bootci(n,{@(x)trimmean(x,alpha),r(j:j+ST-1)},'alpha',alpha_r1);
    end

    % Modify empirical critical value to get openning areas ajusted to transaction fees.
    barrar_r = cb_r + ones(length_r-ST+1,1)*[0 0];
    close_r = cb_r1 + ones(length_r-ST+1,1)*[0 0];

    %% 3.2.1. Transcation.

    table = [table r];
    table(1:ST-1,5:6) = str2double('NaN')*ones(1:ST-1,1:2);
    table(ST:end,5:6) = barrar_r;

    % Generate transaction signals.
    for j1 = 1:a
    if table(j1,4) < table(j1,5),
    table(j1,7) = 1;
    elseif table(j1,4) > table(j1,6),
    table(j1,7) = -1;
    else
    table(j1,7) = 0;
    end
    end

    % Generate closing areas.
    table(ST:end,8:9) = close_r;


    % Construct transaction details.
    table:),10:11) = zeros(270,2);

    for j2 = ST:a,
    if table(j2,7) == 1 && table(j2-1,7)*table(j2,7) <= 0,
    kk = find(table(j2+1:end,4) > table(j2+1:end,8) ,1,'first');
    table(kk+j2,10) = table(kk+j2,3) - table(j2,3);
    table(kk+j2,11) = table(kk+j2,10)*200 - 180 - (table(j2,3)+table(kk+j2,3))*0.00004;
    elseif table(j2,7) == -1 && table(j2-1,7)*table(j2,7) <= 0,
    kk = find(table(j2+1:end,4) < table(j2+1:end,9),1,'first');
    table(kk+j2,10) = table(j2,3) - table(kk+j2,3);
    table(kk+j2,11) = table(kk+j2,10)*200 - 180 - (table(j2,3)+table(kk+j2,3))*0.00004;
    else
    end
    end

    %% 3.3. None
    case 3
    msgbox('No simulated trades were analyzed, please try again. Good luck!')
    end



    function [profit_statistics] = outputsummary(table)
    %% Introduction.

    % Summarize all the trade details and present them on screen.

    %% Figures.

    figure(1)
    subplot(2,1,1),plot(table:),11))
    axis auto
    grid on
    title('Path of Profit fluctuation ','fontname','bf');

    subplot(2,1,2),hist(table:),11));
    grid on
    title('Distribution of Profit ','fontname','bf');

    figure(2)
    subplot(2,1,1),plot(table:),2),'-k');
    hold on
    plot(table:),3),'-r');
    grid on
    h = legend('stock index', 'stock index future','BestOutside');
    title('Path of Price Fluctuations ','fontname','bf');
    hold off

    subplot(2,1,2),plot(table:),4));
    grid on
    title('Path of Spreads/Returns Fluctuations ','fontname','bf');

    %% Descriptive statistics.

    total_profit = sum(table:),11));
    Out1 = table:),11);
    Out1(isinf(1./Out1)) = [];

    num_profit = nnz(table:),11)); %Number of nonzero matrix elements
    avg_profit = mean(Out1);
    std_profit = std(Out1);
    max_profit = table(table:),11) == max(table:),11)),1:11);
    min_profit = table(table:),11) == min(table:),11)),1:11);


    A = zeros(1,6);
    A(1) = num_profit;
    A(2) = total_profit;
    A(3) = avg_profit;
    A(4) = std_profit;
    A(5) = max_profit(11);
    A(6) = min_profit(11);

    profit_statistics = A;



    disp('--------------------------------------------------------------------');
    disp(' Descriptive Statistics of Profit Results. ');

    fprintf('Number of transactions: %d\r\n ', num_profit);
    fprintf('Total Profit: %s\r\n ', total_profit);
    fprintf('Average of Profit Results: %s\r\n ', avg_profit);
    fprintf('Standard Deviation of Profit Results: %s\r\n ', std_profit);
    fprintf('Maxium Profit: %d , Timepoint: %d\r\n',max_profit(11), max_profit(1));
    fprintf('Maxium Loss: %d , Timepoint: %d\r\n',min_profit(11), min_profit(1));
     
  4. 粘贴长度受限,到我个人主页上看吧
     
  5. 顶一下~