分享

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

 cntagu 2015-02-06

这篇算是一个科普贴,高手绕行。


================

这里插播一个东西,有些朋友在FQuantStudio公众号上给我留言,我基本都回复了。但有的朋友可能微信设置了关闭接收公众号消息还是什么原因,导致您通过FQuantStudio公众号给我留言,我给您回复时显示“对方关闭了接收消息”,所以您给我的留言,不是我不回复,是无法回复,在此说明一下。

再者建议大家通过我的邮箱(farutoliyang@foxmail.com)或者加我微信(faruto)来一起交流,FQuantStudio公众号的消息查看和回复需要登录网页(或者也能手机登陆?我没试过),我除非要发新的文章,否则不会经常登录FQuantStudio公众号。

=================

下面言归正传。


有的时候我们编写好一个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其内容为:

[code]

%%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

[StockList,StockListFull] =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

[IndexList] = 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

[SaveLog,ProbList,NewList] =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

[SaveLog,ProbList,NewList] =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;

[SaveLog,ProbList,NewList] =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;

[SaveLog,ProbList,NewList] =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);

[/code]

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


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


这里有几点需要大家注意

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

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

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

[MatlabSentMail(subject,content, TargetAddress, Attachments);]

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

fclose(fid);

exit;




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

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

[code]

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')'

[/code]


你需要稍微熟悉一下脚本文件语言,也不是很复杂。上面代码中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程序任务的解决方案>能帮助到您,如果您遇到了类似的问题。


最后,预祝朋友们春节快乐——李洋faruto




更多内容请点击“阅读原文”,本公众号由李洋(微信faruto)维护。

更多量化投资、MATLAB应用内容可以关注:

MATLAB技术论坛:

http://www./

李洋(faruto)微博、博客

http://weibo.com/faruto

http://blog.sina.com.cn/faruto


===分享给朋友===

点击右上角,在弹出菜单中选择“发送给朋友”或“分享到朋友圈”


===订阅FQuantStudio公众号===

点击右上角,在弹出菜单中选择“查看公众号”,点击“关注”。还可以微信上搜索“FQuantStudio”或扫描下面的二维码进行关注(点击下面的二维码,点击右上角,在弹出菜单中选择“识别图中二维码”,即可完成)。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多