happy 发表于 2015-10-16 09:05

定时运行MATLAB程序任务的解决方案

有的时候我们编写好一个MATLAB程序后,可能需要每天某一时间定时运行这个程序,比如某个量化模型每天的回测结果和报告,需要在收盘后运行或需要在第二天开盘前看到回测结果,比如某些本地的数据库需要定时更新(比如FQuantToolBox本地数据每日全市场数据更新)等等这些需要每天(或每隔某一固定时间区间)定时跑一个MATLAB程序,当然我们可以每天在某一时间打开MATLAB运行相应的程序,但这样一则显得不够pro,二则当你需要定时运行程序增多的时候,这种方式根本不现实,尤其当你由于其他事情(比如开会或者出差时)不在电脑前时。所以需要一个定时运行MATLAB程序任务的解决方案,故有此篇。

定时运行MATLAB程序任务的解决方案我能想到的大体有两种方法,第一种方法是使用timer函数来实现,关于timer的东西这里不做过多展开;第二种方法是本篇重点讲解的。

大体的解决方法就是

编写好待运行的MATLAB程序(比如叫做Main_AutoRunMatlabProgram.m)——>
编写一个脚本文件可以启动MATLAB运行上述M文件
(比如叫做Main_AutoRunMatlabProgram.bat)——>
设置电脑定时任务,定时启动上述脚本文件。
当然这个定时运行MATLAB程序任务的解决方案有一个要求就是你的电脑常开或者是把相关文件提交到服务器上运行。

下面以FQuantToolBox本地数据每日全市场数据更新为例,来看下具体的操作。

1.首先编写好一个待运行的MATLAB程序

比如叫做Main_AutoRunMatlabProgramNum1.m其内容为:


%%Main_AutoRunMatlabProgramNum1

%by LiYang_faruto

%Email:farutoliyang@foxmail.com

%2015/01/01


%%A Little Clean Work

tic;

%clear;

%clc;

%close all;

formatcompact;

%%目录调整


FileStr= ['E:\###数据库-Faruto的数据库\FQuantToolBox']

cd(FileStr);

%%日志文件


fid= fopen('Dlog.txt','at+');

TitleStr= ['日期时间:',datestr(now),'操作记录日志by李洋faruto'];

fprintf(fid,'%s\n',TitleStr);

%%获取股票代码列表

run= 1;

if1 == run

ticID = tic;

try

=GetStockList_Web;

save('StockList','StockList');


TitleStr = ['日期时间:',datestr(now),'更新股票代码列表成功'];

fprintf(fid,'%s\n',TitleStr);


elapsedTime = toc(ticID);

TimeStr = [ '共耗时',num2str(elapsedTime), ' seconds(',num2str(elapsedTime/60), ' minutes)', ...

'(',num2str(elapsedTime/60/60), 'hours)'];

fprintf(fid,'%s\n',TimeStr);


subject = TitleStr;

content = TimeStr;

TargetAddress = '516667408@qq.com';

Attachments = 'Dlog.txt';

MatlabSentMail(subject, content,TargetAddress, Attachments);


catch err

TitleStr = ['日期时间:',datestr(now),'更新股票代码列表失败:',err.message];

fprintf(fid,'%s\n',TitleStr);

for i = 1:size(err.stack,1)

StrTemp = ['FunName:',err.stack(i).name,'Line:',num2str(err.stack(i).line)];

fprintf(fid,'%s\n',StrTemp);

end

subject = TitleStr;

content = [];

TargetAddress = '516667408@qq.com';

Attachments = 'Dlog.txt';

MatlabSentMail(subject, content,TargetAddress, Attachments);

end

else

load StockList;

end


%%获取指数代码列表

run= 1;

if1 == run


ticID = tic;

try

= GetIndexList_Web;

save('IndexList','IndexList');


TitleStr = ['日期时间:',datestr(now),'更新指数代码列表成功'];

fprintf(fid,'%s\n',TitleStr);


elapsedTime = toc(ticID);

TimeStr = [ '共耗时',num2str(elapsedTime), ' seconds(',num2str(elapsedTime/60), ' minutes)', ...

'(',num2str(elapsedTime/60/60), 'hours)'];

fprintf(fid,'%s\n',TimeStr);


subject = TitleStr;

content = TimeStr;

TargetAddress = '516667408@qq.com';

Attachments = 'Dlog.txt';

MatlabSentMail(subject, content,TargetAddress, Attachments);


catch err

TitleStr = ['日期时间:',datestr(now),'更新指数代码列表失败:',err.message];

fprintf(fid,'%s\n',TitleStr);

for i = 1:size(err.stack,1)

StrTemp = ['FunName:',err.stack(i).name,'Line:',num2str(err.stack(i).line)];

fprintf(fid,'%s\n',StrTemp);

end

subject = TitleStr;

content = [];

TargetAddress = '516667408@qq.com';

Attachments = 'Dlog.txt';

MatlabSentMail(subject, content,TargetAddress, Attachments);

end

else

load IndexList;

end

%%获取股票基本信息以及所属行业板块(证监会行业分类)和所属概念板块(新浪财经定义)

run= 1;

if1 == run


ticID = tic;

try

=SaveStockInfo(StockList);


TitleStr = ['日期时间:',datestr(now),'更新股票基本信息成功'];

fprintf(fid,'%s\n',TitleStr);


elapsedTime = toc(ticID);

TimeStr = [ '共耗时',num2str(elapsedTime), ' seconds(',num2str(elapsedTime/60), ' minutes)', ...

'(',num2str(elapsedTime/60/60), 'hours)'];

fprintf(fid,'%s\n',TimeStr);


subject = TitleStr;

content = TimeStr;

TargetAddress = '516667408@qq.com';

Attachments = 'Dlog.txt';

MatlabSentMail(subject, content,TargetAddress, Attachments);


catch err

TitleStr = ['日期时间:',datestr(now),'更新股票基本信息失败:',err.message];

fprintf(fid,'%s\n',TitleStr);

for i = 1:size(err.stack,1)

StrTemp = ['FunName:',err.stack(i).name,'Line:',num2str(err.stack(i).line)];

fprintf(fid,'%s\n',StrTemp);

end

subject = TitleStr;

content = [];

TargetAddress = '516667408@qq.com';

Attachments = 'Dlog.txt';

MatlabSentMail(subject, content,TargetAddress, Attachments);

end

end

%%更新指数数据

run= 1;

if1 == run


ticID = tic;

try

=SaveIndexTSDay(IndexList);


TitleStr = ['日期时间:',datestr(now),'更新指数日线数据成功'];

fprintf(fid,'%s\n',TitleStr);


elapsedTime = toc(ticID);

TimeStr = [ '共耗时',num2str(elapsedTime), ' seconds(',num2str(elapsedTime/60), ' minutes)', ...

'(',num2str(elapsedTime/60/60), 'hours)'];

fprintf(fid,'%s\n',TimeStr);


subject = TitleStr;

content = TimeStr;

TargetAddress = '516667408@qq.com';

Attachments = 'Dlog.txt';

MatlabSentMail(subject, content,TargetAddress, Attachments);


catch err

TitleStr = ['日期时间:',datestr(now),'更新指数日线数据失败:',err.message];

fprintf(fid,'%s\n',TitleStr);

for i = 1:size(err.stack,1)

StrTemp = ['FunName:',err.stack(i).name,'Line:',num2str(err.stack(i).line)];

fprintf(fid,'%s\n',StrTemp);

end

subject = TitleStr;

content = [];

TargetAddress = '516667408@qq.com';

Attachments = 'Dlog.txt';

MatlabSentMail(subject, content,TargetAddress, Attachments);

end

end

%%股票日线数据更新-除权除息数据-无并行操作

run= 1;

if1 == run

ticID = tic;

try

AdjFlag = 0;

XRDFlag = 0;

=SaveStockTSDay(StockList,AdjFlag,XRDFlag);


TitleStr = ['日期时间:',datestr(now),'股票日线数据更新-除权除息数据成功!'];

fprintf(fid,'%s\n',TitleStr);


elapsedTime = toc(ticID);

TimeStr = [ '共耗时',num2str(elapsedTime), ' seconds(',num2str(elapsedTime/60), ' minutes)', ...

'(',num2str(elapsedTime/60/60), 'hours)'];

fprintf(fid,'%s\n',TimeStr);


subject = TitleStr;

content = TimeStr;

TargetAddress = '516667408@qq.com';

Attachments = 'Dlog.txt';

MatlabSentMail(subject, content,TargetAddress, Attachments);


catch err

TitleStr = ['日期时间:',datestr(now),'股票日线数据更新-除权除息数据失败!:',err.message];

fprintf(fid,'%s\n',TitleStr);

for i = 1:size(err.stack,1)

StrTemp = ['FunName:',err.stack(i).name,'Line:',num2str(err.stack(i).line)];

fprintf(fid,'%s\n',StrTemp);

end

subject = TitleStr;

content = [];

TargetAddress = '516667408@qq.com';

Attachments = 'Dlog.txt';

MatlabSentMail(subject, content,TargetAddress, Attachments);

end

end


%%股票数据更新-前复权

run= 1;

if1 == run

ticID = tic;

try

AdjFlag = 1;

XRDFlag = 0;

=SaveStockTSDay(StockList,AdjFlag,XRDFlag);

TitleStr = ['日期时间:',datestr(now),'股票数据更新-前复权成功!'];

fprintf(fid,'%s\n',TitleStr);


elapsedTime = toc(ticID);

TimeStr = [ '共耗时',num2str(elapsedTime), ' seconds(',num2str(elapsedTime/60), ' minutes)', ...

'(',num2str(elapsedTime/60/60), 'hours)'];

fprintf(fid,'%s\n',TimeStr);


subject = TitleStr;

content = TimeStr;

TargetAddress = '516667408@qq.com';

Attachments = 'Dlog.txt';

MatlabSentMail(subject, content,TargetAddress, Attachments);

catch err

TitleStr = ['日期时间:',datestr(now),'股票数据更新-前复权失败!:',err.message];

fprintf(fid,'%s\n',TitleStr);

for i = 1:size(err.stack,1)

StrTemp = ['FunName:',err.stack(i).name,'Line:',num2str(err.stack(i).line)];

fprintf(fid,'%s\n',StrTemp);

end

subject = TitleStr;

content = [];

TargetAddress = '516667408@qq.com';

Attachments = 'Dlog.txt';

MatlabSentMail(subject, content,TargetAddress, Attachments);

end

end


%… …

%由于代码过程没有粘贴全部代码

%%Exit


fclose(fid);

exit;


%%Record Time

toc;

displayEndOfDemoMessage(mfilename);

由于代码过长没有粘贴全部代码

Main_AutoRunMatlabProgramNum1.m中的代码内容基本就是运行FQuantToolBox中的相关函数,进行本地数据更新。(更新股票代码列表,更新指数代码列表,更新个股信息数据,更新本地指数数据,更新本地股票数据等等等等)

这里有几点需要大家注意

(1)try catch的使用,一则可以防止某一块cell模块的运行出现问题,导致整个程序停止;二则若果真出现问题可以捕获相应的报错写入log文件(Dlog.txt)。

(2)设置log文件,将所有的操作记录和运行情况记录在日志里面,一则方便事后查看(程序运行时间、是否有报错、报错内容、报错位置);二则可以将日志以附件的形式给自己发送邮件,移动办公查看程序运行情况,很是方便。

(3)程序运行情况给自己发送邮件推送通知,包括数据是否更新成功、运行时间、是否有异常报错等等。



(4)别忘了日志文件的句柄关闭,在程序尾端关闭相关日志文件并退出MATLAB

fclose(fid);

exit;


转自:http://www.360doc.com/content/15/0206/13/14222116_446668320.shtml

happy 发表于 2015-10-16 09:11

2.编写一个脚本文件可以启动MATLAB运行上述M文件

比如叫做Main_AutoRunMatlabProgram.bat,其内容为:



rem注释内容

remMATLAB AutoRun

remby LiYang_faruto

rem2015.03.01

rem-nojvm 禁用JAVA虚拟机
rem-nosplash 启动闪屏(splash windows)禁用

start D:\'ProgramFiles'\MATLAB_R2014b\bin\matlab.exe -nosplash -r 'run('E:\###数据库-Faruto的数据库\AutoRunProgram\Main_AutoRunMatlabProgramNum1.m')'



你需要稍微熟悉一下脚本文件语言,也不是很复杂。上面代码中rem就想相当于MATLAB中的%是注释的作用可以忽略,重点看下面这段代码

start D:\'Program Files'\MATLAB_R2014b\bin\matlab.exe-nosplash -r 'run('E:\###数据库-Faruto的数据库\AutoRunProgram\Main_AutoRunMatlabProgramNum1.m')'

作用就是启动以无闪屏模式(-nosplash)启动MATLAB并运行指定位置的m文件。i.e.你若双击Main_AutoRunMatlabProgram.bat这个文件,就会启动MATLAB然后运行Main_AutoRunMatlabProgramNum1.m文件。


3.设置电脑定时任务,定时启动上述脚本文件

通过设置电脑定时任务,就可以定时运行相关程序了。

Windows平台下,打开“任务计划程序”(控制面板-管理工具-任务计划程序),点击“创建基本任务程序”:

然后一步一步按照创建基本任务向导操作即可,目的是让电脑能自动运行
Main_AutoRunMatlabProgram.bat文件(意味着可以自动运行里面的MATLAB程序)。







最后可以看到设置好的定时任务

4.整体运行情况
至此,定时运行MATLAB程序任务都设置完毕,看下每天运行的情况,不外乎每天会在凌晨1点定时运行,然后可以收到邮件,在手机上查看运行情况,收到的邮件为:

邮件内容:

通过查看附件Dlog.txt可以查看全部的运行日志。

4.总结
这样的话就可以省时省心的定时运行MATLAB程序,然后查看邮件即可。这篇内容还仅仅是数据更新,但大体框架是类似的,比如您可以定时运行相关量化模型的回测结果,然后生成pdf或者doc报告文件(都可以用MATLAB自动生成),然后推送给自己的邮箱,第一时间查看相关择时模型、选股模型或者相关CTA模型的信号、股票列表和结果。

哦。对了,上面用到了使用MATLAB收发邮件,实现方式也很多。具体可以去MATLAB技术论坛找相关的实现函数,核心用到了MATLAB中的sendmail函数,涉及到国内具体的邮箱域名,需要再封装调整一下,也不复杂。

希望这篇<定时运行MATLAB程序任务的解决方案>能帮助到您,如果您遇到了类似的问题。

sizhiyuan2006 发表于 2017-10-9 10:04

感谢楼主分享
页: [1]
查看完整版本: 定时运行MATLAB程序任务的解决方案