PageRenderTime 29ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/Classes/LocalDatabase.m

http://stock-shock-source.googlecode.com/
MATLAB | 964 lines | 811 code | 32 blank | 121 comment | 62 complexity | d26a484af02cd3e560c9334fefcc5229 MD5 | raw file
  1. classdef LocalDatabase < handle
  2. %Example 1: Sync Database
  3. %
  4. %Written by: Bryan Taylor
  5. %Date Created: 2nd Feb 2009
  6. %Date Modified: 13th Sep 2009
  7. %
  8. %Rev 0.01 Rev number property added.
  9. % Work offline prompt add on first failed connection.
  10. %Rev 0.02 Today replaced with floor(now)
  11. %Rev 0.03 Offline mode added through arg ins.
  12. %Rev 0.04 AutoRetry added.
  13. % Change to handle class.
  14. properties
  15. Symbol = '2ENT.ST';
  16. Location = 'C:\HmSourceSafe\Stocks & Shares\Programs\Stock Quote Sync\Data';
  17. DatabaseName = 'Database'; %OneYear
  18. DataStore
  19. LastPrice
  20. LastPriceDate
  21. ExternalCommObj = 'yahoo-fetch'; %yahoo-fetch or sqq or offline
  22. DataStoreColumnNames = {'Date', 'Close', 'Open', 'Low', 'High', 'Volume'};
  23. SymbolsList
  24. DownloadStatus
  25. StartDate
  26. EndDate
  27. ReqUpdateStatus
  28. DebugReport = 'off';
  29. NR_NoiseThreshold = 0.01;
  30. NR_SoftSwitch = 0;
  31. NR_Report = false;
  32. NR_Plot = false;
  33. conn
  34. Rev = 0.04
  35. ProgramName = 'Local Database';
  36. AutoRetry = true;
  37. end
  38. methods (Hidden = false)
  39. function [DataStore] = LoadData(obj)
  40. SaveDataPath = [obj.Location,'\',obj.DatabaseName];
  41. path = [SaveDataPath,'\Download_Mat\Data\'];
  42. try
  43. load([path,strrep(obj.Symbol,'.','_'),'.mat']);
  44. catch
  45. DataStore = [];
  46. obj.DataStore = [];
  47. return
  48. end
  49. if not(exist('DataStore')) %Load function didn't return datastore
  50. uiwait(msgbox('Data did not load'));
  51. end
  52. try
  53. obj.LastPrice = DataStore.LastPrice;
  54. obj.LastPriceDate = DataStore.LastPriceDate;
  55. end
  56. %Extract Data from structre.
  57. if isstruct(DataStore)
  58. try
  59. Data = DataStore.Data;
  60. if isstruct(Data)
  61. Data = Data.Data;
  62. end
  63. end
  64. try
  65. Data = DataStore.DataStore;
  66. end
  67. else
  68. Data = DataStore;
  69. end
  70. try
  71. obj.DataStoreColumnNames = DataStore.ColumnNames;
  72. end
  73. DataStore = Data;
  74. obj.DataStore = Data;
  75. try
  76. [x1] = size(DataStore.Data,2);
  77. [x2] = size(DataStore.ColumnNames,2);
  78. if x2 > x1
  79. warning('Column names do not match the DATA table. Removing column names')
  80. DataStore.ColumnNames = DataStore.ColumnNames(:,1:x1);
  81. end
  82. end
  83. end
  84. function [StartDate,EndDate] = DateRange(obj)
  85. %Quick: [startdate,enddate] = StockDateRangeMat(symbol,DataStore);
  86. %Slow: [startdate,enddate] = StockDateRangeMat(symbol);
  87. if isempty(obj.DataStore);
  88. disp({ 'Data not already loaded for this symbol.'; ...
  89. 'Please use LoadData method.'; ...
  90. 'For now, data is loaded automactically'; ...
  91. })
  92. obj = obj.LoadData();
  93. end
  94. try
  95. Datenum = obj.DataStore.Data(:,1);
  96. catch
  97. Datenum = obj.DataStore(:,1);
  98. end
  99. if isstruct(Datenum)
  100. Datenum = Datenum.Data(:,1);
  101. end
  102. try
  103. obj.EndDate = max(Datenum);
  104. catch
  105. x=1;
  106. end
  107. obj.StartDate = min(Datenum);
  108. EndDate = obj.EndDate;
  109. StartDate = obj.StartDate;
  110. end
  111. function [SymbolsList] = GetDownloadedSymbolList(obj)
  112. logdir = pwd;
  113. SaveDataPath = [obj.Location,obj.DatabaseName];
  114. path = [SaveDataPath,'\Download_Mat\Data\'];
  115. cd(path);
  116. array = rot90(struct2cell(dir)); %struct to cell then rotate
  117. SymbolsList = array(1:end-2,1); %crop names
  118. SymbolsList = strrep(SymbolsList,'.mat',''); %remove extention
  119. SymbolsList = strrep(SymbolsList,'_','.'); %remove extention
  120. cd(logdir);
  121. obj.SymbolsList = SymbolsList;
  122. end
  123. function [Info] = Sync(obj)
  124. if strcmpi(obj.DebugReport,'on')
  125. disp(['Syncronising symbol: ',obj.Symbol]);
  126. disp('==================================');
  127. end
  128. [LocalStatus] = obj.DetermineDownloadState();
  129. if LocalStatus == 1 %%UPDATE
  130. if strcmpi(obj.DebugReport,'on')
  131. disp(['Updating (Updating or FullDownload): ',obj.Symbol])
  132. disp(' ')
  133. end
  134. [Status] = obj.RequireSync();
  135. startdate = obj.StartDate;
  136. enddate = obj.EndDate;
  137. if strcmpi(Status,'OutOfDate')
  138. DataStore = obj.DataStore;
  139. [NewDataStore,timedout,Info] = obj.DownloadData([obj.EndDate+1,floor(now)]);
  140. if not(isempty(NewDataStore)) %Download ok
  141. [DataStore] = obj.CombineArray(DataStore,NewDataStore);
  142. obj.DataStore = DataStore;
  143. obj.SaveData();
  144. Info.Start_Date = datestr(startdate);
  145. [Info.Status] = obj.Update2Date(datenum(Info.End_Date));
  146. else % Download fail
  147. Info.Start_Date = datestr(startdate);
  148. Info.NoOfEntriesAdded = 'N/A';
  149. Info.End_Date = datestr(enddate);
  150. Info.Status = 'ErrorDownloading';
  151. end
  152. else %UpToDate.
  153. Info.NoOfEntriesAdded = 'N/A';
  154. Info.End_Date = datestr(enddate);
  155. Info.Start_Date = datestr(startdate);
  156. Info.Status =obj.Update2Date(datenum(Info.End_Date));
  157. end
  158. else %% FULL DOWNLOAD
  159. if strcmpi(obj.DebugReport,'on')
  160. disp(['FullDownload (Updating or FullDownload): ',obj.Symbol])
  161. disp(' ')
  162. end
  163. [DataStore,timedout,Info] = obj.DownloadData('all');
  164. if isempty(DataStore) == 0 %Download good, save data and update date range
  165. %Save Data
  166. obj.SaveData();
  167. [Info.Status] = obj.Update2Date(datenum(Info.End_Date));
  168. else %Download not good.
  169. Info.NoOfEntriesAdded = 'N/A';
  170. Info.End_Date = 'N/A';
  171. Info.Start_Date = 'N/A';
  172. Info.Status = 'ErrorDownloading';
  173. end
  174. end
  175. if strcmpi(obj.DebugReport,'on')
  176. disp(' ')
  177. end
  178. end
  179. function SaveData(obj)
  180. SaveDataPath = [obj.Location,obj.DatabaseName];
  181. path = [SaveDataPath,'\Download_Mat\Data\'];
  182. Data = obj.DataStore;
  183. DataStore.Data = Data;
  184. DataStore.ColumnNames = obj.DataStoreColumnNames;
  185. obj.GetLastPrice;
  186. DataStore.LastPrice = obj.LastPrice;
  187. DataStore.LastPriceDate = obj.LastPriceDate;
  188. save([path,strrep(obj.Symbol,'.','_'),'.mat'],'DataStore');
  189. end
  190. function [newsymbolset] = StockQuoteMatQuery(symbolset,date);
  191. if isempty(symbolset)
  192. error('Input symbol set is empty');
  193. end
  194. [x] = size(symbolset,1);
  195. path = 'C:\SourceSafe\Stocks & Shares\Programs\Trade Guide\SaveData\Download_Mat\Database\';
  196. for i = 1:x
  197. load([path,symbolset{i},'.mat']);
  198. try
  199. Datenum = DataStore.Data(:,1);
  200. n = find(Datenum <= date);
  201. n = n(size(n,1));
  202. newrow = [symbolset(i),num2cell((DataStore.Data(n,:)))];
  203. empty = false;
  204. catch
  205. empty = true;
  206. end
  207. if empty == false
  208. if i == 1
  209. newsymbolset = newrow;
  210. else
  211. newsymbolset = [newsymbolset;newrow];
  212. end
  213. else
  214. %do append to new symbol array.
  215. end
  216. end
  217. end
  218. function [Data] = GetColumn(obj,Name)
  219. if isempty(obj.DataStore)
  220. error('Data has not been loaded. Pleas use LoadData method')
  221. end
  222. n = find(strcmpi(Name,obj.DataStoreColumnNames));
  223. try
  224. Data = obj.DataStore.Data(:,n);
  225. catch
  226. Data = obj.DataStore(:,n);
  227. end
  228. end
  229. function [Data] = GetData(obj,Name,DateRange)
  230. if isempty(obj.DataStore)
  231. error('Data has not been loaded. Please use LoadData method')
  232. end
  233. n = find(strcmpi(Name,obj.DataStoreColumnNames));
  234. try
  235. Data = obj.DataStore(:,n);
  236. catch
  237. Data = obj.DataStore.Data(:,n);
  238. end
  239. if isstruct(Data)
  240. Data = Data.Data(:,n);
  241. end
  242. if isstruct(Data)
  243. Data = Data.Data(:,n);
  244. end
  245. Date = obj.GetColumn('Date');
  246. n = find(Date>DateRange(2));
  247. try
  248. Data = Data(n);
  249. Date = Date(n);
  250. catch
  251. x = 1;
  252. end
  253. n = find(Date<DateRange(1));
  254. Data = Data(n);
  255. Date = Date(n);
  256. end
  257. function [Data] = GetRange(obj,Name,Period)
  258. switch lower(Period)
  259. case '1w'
  260. [Data] = GetData(obj,Name,[floor(now),floor(now)-7]);
  261. case '2w'
  262. [Data] = GetData(obj,Name,[floor(now),floor(now)-14]);
  263. case '1m'
  264. [Data] = GetData(obj,Name,[floor(now),floor(now)-30]);
  265. case '3m'
  266. [Data] = GetData(obj,Name,[floor(now),floor(now)-120]);
  267. case '6m'
  268. [Data] = GetData(obj,Name,[floor(now),floor(now)-6*30]);
  269. case '1y'
  270. [Data] = GetData(obj,Name,[floor(now),floor(now)-365]);
  271. otherwise
  272. end
  273. end
  274. function GetLastPrice(obj);
  275. try
  276. [Data] = fetch(obj.conn,obj.Symbol,{'Last';'Date'});
  277. catch
  278. pause(5)
  279. obj.Connect2yahoo;
  280. [Data] = fetch(obj.conn,obj.Symbol,{'Last';'Date'});
  281. end
  282. obj.LastPrice = Data.Last;
  283. obj.LastPriceDate = Data.Date;
  284. end
  285. end
  286. methods (Hidden = false) % Calculations
  287. function [LastValue,Date] = LastDayClose(obj)
  288. if isempty(obj.DataStore);
  289. obj.LoadData();
  290. end
  291. if isempty(obj.DataStore)
  292. LastValue = NaN;
  293. Date = NaN;
  294. else
  295. Close = obj.DataStore(:,2);
  296. Date = obj.DataStore(:,1);
  297. Date = Date(end);
  298. LastValue = Close(end);
  299. end
  300. end
  301. function [Status] = CalcChange(obj)
  302. %This function assumes data is correctly loaded into Datastore
  303. %Example:
  304. %obj.Symbol = 'IBM';
  305. %obj = obj.LoadData();
  306. %obj = obj.CalcDayGrowth();
  307. if isempty(obj.DataStore);
  308. obj.LoadData();
  309. end
  310. [Status] = obj.CalcStatus('Change_Pence');
  311. [Status] = obj.CalcStatus('Change_Percentage');
  312. if strcmpi(Status,'RequireUpdate')
  313. Close = obj.GetColumn('Close');
  314. Open = obj.GetColumn('Open');
  315. Change_Pence = Close - Open;
  316. Change_Percentage = Change_Pence./Open*100;
  317. obj.DataStoreColumnNames = [obj.DataStoreColumnNames,{'Change_Pence','Change_Percentage'}];
  318. try
  319. obj.DataStore.Data = [obj.DataStore.Data,Change_Pence,Change_Percentage];
  320. catch
  321. obj.DataStore.Data = [obj.DataStore,Change_Pence,Change_Percentage];
  322. end
  323. end
  324. end
  325. function [Status] = CalcPriceMean(obj) %Verfied
  326. if isempty(obj.DataStore);
  327. obj.LoadData();
  328. end
  329. [Status] = obj.CalcStatus('PriceMean');
  330. if strcmpi(Status,'RequireUpdate')
  331. Date = obj.GetColumn('Date');
  332. Close = obj.GetColumn('Close');
  333. Open = obj.GetColumn('Open');
  334. Low = obj.GetColumn('Low');
  335. High = obj.GetColumn('High');
  336. PriceMean = mean([Close,Open,High,Low],2);
  337. obj.DataStoreColumnNames = [obj.DataStoreColumnNames,{'PriceMean'}];
  338. obj.DataStore.Data = [obj.DataStore.Data,PriceMean];
  339. end
  340. end
  341. function [Status] = CalcMovAvg(obj,NumberOfDays)
  342. if isempty(obj.DataStore);
  343. obj.LoadData();
  344. end
  345. [Status] = obj.CalcStatus(['MovAvg_',num2str(NumberOfDays)]);
  346. if strcmpi(Status,'RequireUpdate')
  347. PriceMean = obj.GetColumn('PriceMean');
  348. [x] = size(PriceMean,1);
  349. if x>NumberOfDays
  350. [MovingAv,LONG] = movavg(PriceMean,NumberOfDays,NumberOfDays,0);
  351. obj.DataStoreColumnNames = [obj.DataStoreColumnNames,{['MovAvg_',num2str(NumberOfDays)]}];
  352. obj.DataStore.Data = [obj.DataStore.Data,MovingAv];
  353. end
  354. end
  355. end
  356. function [Status] = CalcFiveDayHigh(obj)
  357. if isempty(obj.DataStore);
  358. obj.LoadData();
  359. end
  360. [Status] = obj.CalcStatus('FiveDayHigh');
  361. if strcmpi(Status,'RequireUpdate')
  362. n = find(strcmpi(obj.DataStoreColumnNames,'PriceMean'));
  363. PriceMean = obj.DataStore.Data(:,n);
  364. n = find(strcmpi(obj.DataStoreColumnNames,'Date'));
  365. Date = obj.DataStore.Data(:,n);
  366. %Five Day High
  367. [x] = size(PriceMean,1);
  368. if x>5
  369. for i = 1:x-4
  370. Window = PriceMean(i:i+4);
  371. MaxVal = max(Window);
  372. FiveDayHigh(i+4,1) = MaxVal;
  373. n = find(MaxVal == Window);
  374. if not(isempty(n))
  375. DateOfFiveDayHigh(i+4,1) = Date(i+n(end)-1);
  376. NumberOfDaysSinceFiveDayHigh(i+4,1) = 5- n(end);
  377. end
  378. end
  379. obj.DataStoreColumnNames = [obj.DataStoreColumnNames,{'FiveDayHigh','DateOfFiveDayHigh','NumberOfDaysSinceFiveDayHigh'}];
  380. obj.DataStore.Data = [obj.DataStore.Data,FiveDayHigh,DateOfFiveDayHigh,NumberOfDaysSinceFiveDayHigh];
  381. end
  382. end
  383. end
  384. function [Status] = CalcDayDiff(obj)
  385. if isempty(obj.DataStore);
  386. obj.LoadData();
  387. end
  388. [Status] = obj.CalcStatus('DayDiff');
  389. if strcmpi(Status,'RequireUpdate')
  390. PriceMean = obj.GetColumn('PriceMean');
  391. DayDiff = [0;diff(PriceMean)];
  392. obj.DataStoreColumnNames = [obj.DataStoreColumnNames,{'DayDiff'}];
  393. obj.DataStore.Data = [obj.DataStore.Data,DayDiff];
  394. end
  395. end
  396. function [Status] = PercentageChange(obj)
  397. if isempty(obj.DataStore);
  398. obj.LoadData();
  399. end
  400. [Status] = obj.CalcStatus('PercentageChange');
  401. if strcmpi(Status,'RequireUpdate')
  402. PriceMean = obj.GetColumn('PriceMean');
  403. DayDiff = obj.GetColumn('DayDiff');
  404. PercentageChange = DayDiff./PriceMean; %percent change
  405. obj.DataStoreColumnNames = [obj.DataStoreColumnNames,{'PercentageChange'}];
  406. obj.DataStore.Data = [obj.DataStore.Data,PercentageChange];
  407. end
  408. end
  409. function [Status] = VolumeDiff(obj)
  410. if isempty(obj.DataStore);
  411. obj.LoadData();
  412. end
  413. [Status] = obj.CalcStatus('VolumeDiff');
  414. if strcmpi(Status,'RequireUpdate')
  415. Volume = obj.GetColumn('Volume');
  416. VolumeDiff = [0;diff(Volume)];
  417. obj.DataStoreColumnNames = [obj.DataStoreColumnNames,{'VolumeDiff'}];
  418. obj.DataStore.Data = [obj.DataStore.Data,VolumeDiff];
  419. end
  420. end
  421. function [Status] = PriceMean_DeNoise(obj)
  422. if isempty(obj.DataStore);
  423. obj.LoadData();
  424. end
  425. [Status] = obj.CalcStatus('PriceMean_DeNoise');
  426. if strcmpi(Status,'RequireUpdate')
  427. PriceMean = obj.GetColumn('PriceMean');
  428. [PriceMean_DeNoise] = obj.NoiseRemoval();
  429. obj.DataStoreColumnNames = [obj.DataStoreColumnNames,{'PriceMean_DeNoise'}];
  430. obj.DataStore.Data = [obj.DataStore.Data,PriceMean_DeNoise];
  431. end
  432. end
  433. function [Status] = TradeSignal(obj)
  434. if isempty(obj.DataStore);
  435. obj.LoadData();
  436. end
  437. [Status] = obj.CalcStatus('ChangeMarker');
  438. if strcmpi(Status,'RequireUpdate')
  439. Close = obj.GetColumn('Close');
  440. Open = obj.GetColumn('Open');
  441. High = obj.GetColumn('High');
  442. Low = obj.GetColumn('Low');
  443. [buy,sell,TradeSignal,ChangeMarker,PercentageChange]=obj.tradeguides();
  444. obj.DataStoreColumnNames = [obj.DataStoreColumnNames,{'TradeSignal','ChangeMarker'}];
  445. try
  446. obj.DataStore.Data = [obj.DataStore.Data,TradeSignal,ChangeMarker];
  447. catch
  448. x = 1;
  449. end
  450. end
  451. end
  452. end
  453. methods (Hidden = true) % Support functions
  454. function [Status] = CalcStatus(obj,Name)
  455. n = find(strcmpi(Name,obj.DataStoreColumnNames));
  456. [x] = size(n,2);
  457. switch x
  458. case 0
  459. Status = 'RequireUpdate';
  460. case 1
  461. Status = 'UpToDate';
  462. case 2
  463. Status = 'Overloaded';
  464. otherwise
  465. error('ERROR: Check Calc Status')
  466. end
  467. end
  468. function [DataStore,timedout,Info] = DownloadData(obj,DateRange)
  469. % DataRange = 'all' or [floor(now)-7,floor(now)];
  470. if ischar(DateRange)
  471. Range = 365*200; %Last 200 years
  472. StartDate = floor(now)-Range;
  473. EndDate = floor(now);
  474. else
  475. StartDate = DateRange(1);
  476. EndDate = DateRange(2);
  477. end
  478. timeout = 2;
  479. %Int Var
  480. timedout = false;
  481. time = 1;
  482. DataStore=[];
  483. complete = false;
  484. %Get Data
  485. %TODO: Exception workaround!
  486. if strcmpi(obj.Symbol,'CLF') %Exception call clf function!
  487. timedout = true;
  488. DataStore=[];
  489. else
  490. while complete == false
  491. if time == timeout
  492. timedout = true;
  493. break
  494. end
  495. if strcmpi(obj.ExternalCommObj,'sqq')
  496. try
  497. [date, close, open, low, high, volume, closeadj] = sqq(obj.Symbol,EndDate,StartDate,'d');
  498. DataStore = [date, close, open, low, high, volume, closeadj];
  499. complete = true;
  500. catch
  501. complete = false;
  502. end
  503. elseif strcmpi(obj.ExternalCommObj,'yahoo-fetch') %Discrete test suggest it take 4 times as long.
  504. try
  505. [data] = fetch(obj.conn,obj.Symbol,{'Close','Open','Low','High','Volume'},StartDate,EndDate);
  506. if isempty(data)
  507. complete = false;
  508. else
  509. complete = true;
  510. end
  511. catch
  512. complete = false;
  513. end
  514. if complete == true;
  515. DataStore = flipud(data);
  516. [i,j] = size(DataStore);
  517. % DataStore(1:i,j+1) = NaN;
  518. date = DataStore(:,1);
  519. end
  520. end
  521. time = time + 1;
  522. end
  523. end
  524. if timedout == false
  525. [y] = size(date,1);
  526. Info.Start_Date = datestr(date(1));
  527. Info.End_Date = datestr(date(y));
  528. Info.NoOfEntriesAdded = y;
  529. else
  530. Info.Start_Date = 'N/A';
  531. Info.End_Date = 'N/A';
  532. Info.NoOfEntriesAdded = 'N/A';
  533. end
  534. obj.DataStore = DataStore;
  535. if strcmpi(obj.DebugReport,'on')
  536. disp(['Downloading: ',obj.Symbol])
  537. disp('==========================')
  538. disp(['Date Range: ',datestr(StartDate),' to the ',datestr(EndDate)]);
  539. if isempty(DataStore)
  540. disp(['Extracted: ',num2str(0)])
  541. else
  542. disp(['Extracted: ',num2str(num2str(size(date,1)))])
  543. end
  544. end
  545. end
  546. function [Status] = DetermineDownloadState(obj)
  547. %local database state
  548. % Does stock require update or complete download
  549. % Status - 0 Full Download Required.
  550. % 1 Update Download Required.
  551. %DataStore is empty unless update download status is 1.
  552. %Written by: Bryan Taylor
  553. %Date Created: 4th January 2009
  554. path = [obj.Location,obj.DatabaseName,'\Download_mat\Data\'];
  555. [DataStore] = obj.LoadData();
  556. Status = 1;
  557. if isempty(DataStore)
  558. Status = 0;
  559. else
  560. Status = 1;
  561. end
  562. obj.DownloadStatus = Status;
  563. obj.DataStore = DataStore;
  564. if strcmpi(obj.DebugReport,'on')
  565. if Status == 1
  566. disp(['Symbol: ',obj.Symbol,' is Full in Local Database']);
  567. else
  568. disp(['Symbol: ',obj.Symbol,' is Empty in Local Database']);
  569. end
  570. end
  571. end
  572. function [Status] = RequireSync(obj)
  573. if isempty(obj.EndDate)
  574. obj.DateRange();
  575. end
  576. [Status,LastWorkingDay] = obj.Update2Date(obj.EndDate);
  577. obj.ReqUpdateStatus = Status;
  578. if strcmpi(obj.DebugReport,'on')
  579. disp('Required Sync Analysis');
  580. disp('======================');
  581. disp(['LocalDatabase.... EndDate: ',datestr(obj.EndDate),' StartDate: ',datestr(obj.StartDate)])
  582. disp(['floor(now) Date: ',datestr(floor(now)),' LastWorkingDay: ',datestr(LastWorkingDay),' Status: ',Status])
  583. disp(' ')
  584. end
  585. end
  586. function [Status,LastWorkingDay] = Update2Date(obj,Date)
  587. %Will return if stock is up to date. It understand the last working day.
  588. %%
  589. switch datestr(floor(now),8)
  590. case 'Mon'
  591. LastWorkingDay = floor(now) - 3;
  592. case 'Sun'
  593. LastWorkingDay = floor(now) - 2;
  594. otherwise
  595. LastWorkingDay = floor(now) - 1;
  596. end
  597. if LastWorkingDay == Date
  598. Status = 'UpToDate';
  599. else
  600. Status = 'OutOfDate';
  601. end
  602. end
  603. function [DataStore] = CombineArray(obj,DataStore,NewDataStore)
  604. %Combine the downloaded data with the data locally stored.
  605. %pad new data
  606. try
  607. DataStore.Data;
  608. [width] = size(DataStore.Data,2);
  609. catch
  610. [width] = size(DataStore,2);
  611. end
  612. [len,wid] = size(NewDataStore);
  613. NewData = nan(len,width);
  614. NewData(:,1:wid) = NewDataStore;
  615. %append
  616. try
  617. Data = DataStore.Data;
  618. catch
  619. Data = DataStore;
  620. end
  621. if isstruct(Data)
  622. Data = Data.Data;
  623. end
  624. Data = Data(:,1:6);
  625. warning off
  626. DataStore.Data = [Data;NewData];
  627. warning on
  628. end
  629. function [buy,sell,tradesignal,changemarker,pP]=tradeguides(obj)
  630. %Gives Buy and Sell signals for maximum practical profit.
  631. %Ignores small trend changes or flat days and follow biggest local trends.Profitable spikes are included.
  632. %Tradeguide signal offers practical trading benchmark training set for Neural Networks and other learning algorithms or TA.
  633. %
  634. %There are no hold signals generated.
  635. %buy=index for buy days
  636. %sell=index for sell days
  637. %Tradesignal is the composite buy and sell signal vector with 1= buy and 0=sell
  638. %Changemarker is a zero vector of the length of the time serie with 1
  639. %marking a change in trend.
  640. %
  641. %INPUTS:
  642. % C:- Stock Closing Price (Column-wise Data)
  643. % O:- Stock Opening Price (Column-wise Data)
  644. % L:- Stock Low Price (Column-wise Data)
  645. % H:- Stock High Price (Column-wise Data)
  646. %
  647. %OPTIONAL
  648. % 'Report':- logical. The report flag defaults to false.
  649. % 'NoiseThreshold':- This threshold is expressed as a percentage change.
  650. % The default is set to 0.005. This means that any daily change of less than
  651. % 0.5% will be ignored, and persumed as noise.
  652. %
  653. %Example:
  654. %Get a small amount of data from the local database
  655. % numberofreadings = 365;
  656. % [startdate,enddate] = StockDateRange('AAA');
  657. %
  658. % [DateNum] = GetData('AAA','datenum',[startdate,startdate+numberofreadings]);
  659. % [C] = GetData('AAA','close',[startdate,startdate+numberofreadings]);
  660. % [O] = GetData('AAA','open',[startdate,startdate+numberofreadings]);
  661. % [H] = GetData('AAA','high',[startdate,startdate+numberofreadings]);
  662. % [L] = GetData('AAA','low',[startdate,startdate+numberofreadings]);
  663. %
  664. %Get trade signals:
  665. % [buy,sell,tradesignal,changemarker]=tradeguide(C,O,H,L,'Report',true)
  666. %
  667. %Written by: Bryan Taylor
  668. %Date Created: 17th Feb 2007
  669. %Date Modified: 17th Feb 2007
  670. %
  671. % Copyright 2007, CoLogic, Inc
  672. NoiseThreshold = obj.NR_NoiseThreshold;
  673. report = obj.NR_Report;
  674. report = false;
  675. %take the mean of each price. 2 means rows. Hence for each day the average
  676. %is taken of the high, low, open and close price
  677. P = obj.GetColumn('PriceMean');
  678. l=length(P);
  679. if report == true
  680. if l>5
  681. disp('Take the average of the open, close, high low price for each day');
  682. disp('This will remove some noise from the data');
  683. disp('day_average = (open + close + high + low)/4');
  684. day_average = P(1:5)
  685. end
  686. end
  687. dP=[0;diff(P)];%2 day price difference
  688. if report == true
  689. if l>5
  690. disp('Find the day to day difference of the stock price');
  691. disp('DiffPrice = Price(n) - Price(n-1)');
  692. disp('where n is a date vector');
  693. diffPrice = dP(1:5)
  694. end
  695. end
  696. pP=dP./P;%percent change
  697. if report == true
  698. if l>5
  699. disp('this does tell us about profit therefore we then take the percentage change.')
  700. disp('PercentageChange = PriceChange/Price')
  701. PercentageChange = pP(1:5)
  702. end
  703. end
  704. spP=sign(pP);%sign of day to day % change
  705. if report == true
  706. if l>5
  707. disp('find the sign of each price diff')
  708. signP = spP(1:5)
  709. end
  710. end
  711. n=find(spP==0);%%find no change days
  712. %find returns all the location where the is no change between days
  713. spP(n)=sign(rand-.5);%%add small noise to no change days
  714. if report == true
  715. if l>5
  716. FixedSignChange = spP(1:5);
  717. end
  718. end
  719. spP=(spP+1)/2;%%convert to binary 0=down 1=up
  720. %%%%filter out flat days with changes less than .5%
  721. %%small noises and spikes are non-profitable neglected
  722. for i=2:l-1
  723. if abs(pP(i))<NoiseThreshold
  724. spP(i)=spP(i-1);%same as prior day
  725. end
  726. end
  727. % two 0.25 changes would result in a signed result
  728. if report == true
  729. if l>5
  730. FixedSignChange = spP(1:5);
  731. end
  732. end
  733. %%%%%%%%Mark signal change%%%%%%%%%%%%%%%%%%%%%%%%
  734. %%%%%%%%find buy signal%%
  735. n=find(spP(2:end)==1);%shift back by one day
  736. buy=n;
  737. %%%%%%%%find sell signal%%
  738. n=find(spP(2:end)==0);%shift back by one day
  739. sell=n;
  740. %%%%%%%%tradesignal
  741. try
  742. n = find(isnan(spP)==1);
  743. x = size(spP,1);
  744. spP = spP(n);
  745. changemarker = zeros(x-1,1);
  746. cm =xor(spP(1:end-1),spP(2:end));%finds changing signals
  747. changemarker(n) = cm;
  748. catch
  749. x = 1;
  750. end
  751. %%%%%%%%tradesignal
  752. tradesignal=zeros(l,1);
  753. tradesignal(buy)=1;
  754. changemarker = [NaN;changemarker];
  755. end
  756. function [P] = NoiseRemoval(obj)
  757. %This function removes daily noise. This function needs to be optimised but
  758. %when set up correctly will remove daily noise.
  759. %
  760. %Optional Inputs:
  761. % Noise Threshold:- If the daily variation is less than this value the
  762. % stock price will be assumed to be the same. This is expressed as a
  763. % factor. e.g 0.005 would be result in any change less than 0.5 % would
  764. % be ignore therefore would be overwritten by the previous value.
  765. %
  766. % SoftSwitch:- (Dampen Correction) This allows you to fade from completely corrected to
  767. % completely un-corrected. When set to one there is no correct, and when
  768. % it is set to 0, full correction will be observed.
  769. % This could be changed to the reverse sign.
  770. %
  771. % Report:- Will output a report to help with debug. This can also
  772. % help to understand the function.
  773. %
  774. % Plot:- This will plot the orginal data and the noise reduced data on
  775. % the same graph.
  776. %
  777. %Defaults: Noise Threshold 0.005
  778. % Softswitch 0; (Full correction)
  779. %
  780. %Example:
  781. %IntialiseDatabase;
  782. % [date,close,open,high,low,closeadj] ...
  783. % = StockQuote('AA',{'datenum';'close';'open';'high';'low';'closeadj'},[floor(now)-90,floor(now)]);
  784. % P=mean([close,open,high,low],2);
  785. % [price] = NoiseRemoval(P,'softswitch',0,'noisethreshold',0.01);
  786. % [AX,H1,H2] = plotyy(date,P,date,price,'plot');
  787. %
  788. %Please ensure axis are the same scale.
  789. % axes(AX(1))
  790. % axis([date(1),date(x),min(P),max(P)]);
  791. % axes(AX(2))
  792. % axis([date(1),date(x),min(P),max(P)]);
  793. %
  794. % Copyright 2007, CoLogic, Inc
  795. % TODO: Subsitute noise threshold for an adpative moving noise figure.
  796. NoiseThreshold = obj.NR_NoiseThreshold;
  797. SoftSwitch = obj.NR_SoftSwitch;
  798. report = obj.NR_Report;
  799. report = false;
  800. Plot = obj.NR_Plot;
  801. P = obj.GetColumn('PriceMean');
  802. l=length(P);
  803. %take the mean of each price. 2 means rows. Hence for each day the average
  804. %is taken of the high, low, open and close price
  805. if report == true
  806. if l>5
  807. Orginal_Data = P(1:5)
  808. end
  809. end
  810. dP=[0;diff(P)];%2 day price difference
  811. if report == true
  812. if l>5
  813. Difference_Data = dP(1:5)
  814. end
  815. end
  816. pP=dP./P;%percent change
  817. if report == true
  818. if l>5
  819. Percentage_Change = pP(1:5)
  820. end
  821. end
  822. %%%%filter out flat days with changes less than .5%
  823. %%small noises and spikes are non-profitable neglected
  824. oldP = P;
  825. for i=2:l
  826. if abs(pP(i))<obj.NR_NoiseThreshold
  827. pricediff(i) = P(i)-P(i-1);
  828. P(i)= P(i-1)+pricediff(i)*obj.NR_SoftSwitch;
  829. else
  830. P(i)=P(i);%no correction
  831. end
  832. end
  833. if report == true
  834. if l>5
  835. temp = [oldP,P];
  836. summary = temp(1:5,:)
  837. end
  838. end
  839. if Plot == true
  840. %generate date data
  841. [x] = size(P,1);
  842. date = [1:x];
  843. figure;
  844. [AX,H1,H2] = plotyy(date,oldP,date,P,'plot');
  845. % Please ensure axis are the same scale.
  846. axes(AX(1))
  847. axis([date(1),date(x),min(oldP),max(oldP)]);
  848. datetick
  849. axes(AX(2))
  850. axis([date(1),date(x),min(oldP),max(oldP)]);
  851. datetick
  852. end
  853. end
  854. function [obj] = LocalDatabase(varargin)
  855. % Arg ins
  856. [x] = size(varargin,2);
  857. for i = 1:2:x
  858. obj.(varargin{i}) = varargin{i+1};
  859. end
  860. % Load Comm object
  861. switch obj.ExternalCommObj
  862. case 'yahoo-fetch'
  863. obj.Connect2yahoo;
  864. case 'offline'
  865. otherwise
  866. end
  867. end
  868. function Connect2yahoo(obj)
  869. if obj.AutoRetry == true
  870. Time = 2;
  871. else
  872. Time = 1;
  873. end
  874. Timeout = 40;
  875. while Time < Timeout
  876. try
  877. obj.conn = yahoo;
  878. break
  879. catch
  880. if Time == 1
  881. ButtonName = questdlg( 'Do you want to retry or work offline?', ...
  882. 'Connection Failed', ...
  883. 'Retry', 'Offline', 'Retry');
  884. switch ButtonName
  885. case 'Retry'
  886. %Do nothing
  887. case 'Offline'
  888. break %Break out while loop
  889. otherwise
  890. end
  891. end
  892. PauseTime = 5*2^Time;
  893. disp(['Connection failed. Wait ',num2str(PauseTime),' secs'])
  894. pause(PauseTime);
  895. Time = Time + 1;
  896. end
  897. end
  898. if Time == Timeout
  899. msgbox('Could not connect to yahoo. Check connection')
  900. else
  901. disp('Connection established')
  902. end
  903. end
  904. end
  905. end