第一步 python获取实时股票数据
这一步在网上查资料查来查去,三个小时才完成。
python之前没有安yfinance工具包,虽然应该是超级简单的pip install,但是莫名报错
一下是panda库的问题,一下是numpy版本不兼容,panda库的报错内容在csdn查了一下,
这篇文章基本解决了第一个问题:
http://t.csdn.cn/XhDe2http://t.csdn.cn/XhDe2反复尝试fix_yahoo_finance 无果,又查来查去发现是yfinance
这个是系统自动提示的好像,有Anacoda,在命令窗口输入这个就好
conda install -c ranaroussi yfinance
之后用这个代码就可以在python使用yfinance 并且获得股票数据了
import pandas as pd
import pandas_datareader.data as web
import datetime
import yfinance as fix
import numpy
fix.pdr_override()
start=datetime.datetime(2020, 10, 1)
end=datetime.datetime(2023, 1, 1)
web.get_data_yahoo('AAPL',start,end)
data=fix.download('AAPL','2020-08-31','2023-4-1')
python可以正常使用之后去matlab尝试 发现报错
py.importlib.import_module('pandas');
ModuleNotFoundError: No module named 'yfinance'
这里又是因为matlab调用python的路径在C盘,而这里的找不到yfinance包(之前下载的python在C盘,anaconda版在D盘)
于是设定路径 (这里是GPT教的)
pyversion('E:\Anaconda\envs\myenv\python.exe')
matlab又报错numpy找不到 又回馈给GPT
事情越来越复杂 最后没有办法,直接从python导出数据到matlab算了
data.to_csv("AAPL_stock.csv")
这里的csv文件直接存储在当前文件夹下,在matlab中可以直接按键式导入 自动生成脚本:
%% 设置导入选项并导入数据
opts = delimitedTextImportOptions("NumVariables", 7);
% 指定范围和分隔符
opts.DataLines = [2, Inf];
opts.Delimiter = ",";
% 指定列名称和类型
opts.VariableNames = ["Date", "Open", "High", "Low", "Close", "AdjClose", "Volume"];
opts.VariableTypes = ["double", "double", "double", "double", "double", "double", "double"];
% 指定文件级属性
opts.ExtraColumnsRule = "ignore";
opts.EmptyLineRule = "read";
% 指定变量属性
opts = setvaropts(opts, "Date", "TrimNonNumeric", true);
opts = setvaropts(opts, "Date", "ThousandsSeparator", ",");
% 导入数据
AAPLstock = readtable("C:\Users\lenovo\AAPL_stock.csv", opts);
%% 转换为输出类型
AAPLstock = table2array(AAPLstock);
%% 清除临时变量
clear opts
第二步 在MATLAB 中发出多空头指令
第一列时间导进来换成日历型数据,之后可能要找日期
%先导入数据
% 第一列时间数据类型
AAPLstock(:,1)=x2mdate(AAPLstock(:,1));
calendar=datestr(AAPLstock(:,1));
第一步 多空头指令(这段代码完全是曹志广老师在他的教材《金融编程与计算》里留下的课后作业答案,稍作改动找到金叉死叉)
function [s,ma,tdeadcross1,tgoldcross1]=truly_ma(p,N)
% INPUT
% p: T*K,股票时间序列矩阵
% N:integer, 均线期数
% OUTPUT
% s: T*K,每期多空指令
% ma:T*K, 每期均线
[m,k]=size(p);
s=zeros(m,k);
ma=s;
ma(1:N-1,:)=p(1:N-1,:);
for i=N:m
A=p(i:-1:i-N+1,:);
ma(i,:)=mean(A);
end
s(p>ma)=1;
t=diff(s);
%tgoldcross1: 股票A出现金叉的当天
%tdeadcross1: 股票A出现死叉的当天
tgoldcross1=find(t(:,1)>0)+1;
tdeadcross1=find(t(:,1)<0)+1;
设置7天为一期,创造均线并画图
%多空头和金死叉my_ma 期数选7天
% s: T*K,每期多空指令
% ma:T*K, 每期均线
p=AAPLstock(:,6);
N=7;
[s,ma,tdeadcross1,tgoldcross1]=truly_ma(p,N);
figure(1);
subplot(2,1,1);
plot([AAPLstock(:,6),ma(:,1)]);
hold on;
又是曹老师的课后题答案 这里依据之前的多空头方案具体进行操作
为了简化,我把交易成本删掉了
function [num,ret_trade,prob_win]=my_performance_evaluation(p,s)
% INPUT
% p: N*1, price vector
% s: N*1, position vector
% OUTPUT
% num: integer, trading times
% ret_trade: N*1, profit/share
% prob_win: scalar, probability of winning
N=length(p);
s(N)=0; % clear at the end 最后结算清仓
A=[s(1);diff(s)]; % A:仓位变化 (留住第一期 之后做差分)
B=A.*s; % A:仓位变化, s:当前仓位, B~=0说明仓位有变化(不在空仓0)且当前没有平仓
open_id=(A~=0&B~=0); % 仓位有变化且当前仓位不是0,说明已开仓 1是开仓点
close_id=((A~=0&B==0)|abs(A)==2); % 要么仓位有变化且当前仓位归0,要么仓位变化是+2或-2,说明已在单方向先平仓
% 对于仓位变化绝对值为2的情况(103:105),104期既平仓掉空头头寸,又开仓多头头寸
ret_bh=[0;diff(p)]; %%return
gross_ret=[0;ret_bh(2:end).*s(1:N-1)]; % 仓位s在每天交易日开始或头一天晚上就订好 %%交易成本 A表示有交易 有可能为2
ret=gross_ret;
cum_ret=cumsum(ret);
ret_trade=cum_ret(close_id)-cum_ret(open_id); %321次交易的收益
final=cumsum(ret_trade(:,1));
num=length(ret_trade);
prob_win=sum(ret_trade>0)/num;
[num,ret_trade,prob_win]=my_performance_evaluation(p,s);
完工 虽然胜率不高,到头也只赚了4.13
有更好的策略可以分享给我哦~