昨日の記事では転けている箇所とその行数、およびその行が所属するメソッドを特定した。
how-to-make-stock-trading-system.dogwood008.com
今回は、標準で bt.feeds.YahooFinanceCSVData
に用意されているパーサである _loadline()
メソッドを上書きするための前準備として、そっくりそのままコピーしてきて、想定する場所で転けるかを確認する。
コピーする内容は、 bt.feeds.YahooFinanceCSVData
の _loadline()
メソッドの定義全てである。これを KabuPlusJPCSVData
クラス内で再定義する。
import itertools from datetime import date, datetime from backtrader.utils import date2num class KabuPlusJPCSVData(bt.feeds.YahooFinanceCSVData): ''' Parses pre-downloaded Yahoo Japan CSV Data Feeds (or locally generated if they comply to the Yahoo formatg) Specific parameters: - ``dataname``: The filename to parse or a file-like object - ``reverse`` (default: ``True``) It is assumed that locally stored files have already been reversed during the download process - ``adjclose`` (default: ``True``) Whether to use the dividend/split adjusted close and adjust all values according to it. - ``adjvolume`` (default: ``True``) Do also adjust ``volume`` if ``adjclose`` is also ``True`` - ``round`` (default: ``True``) Whether to round the values to a specific number of decimals after having adjusted the close - ``roundvolume`` (default: ``0``) Round the resulting volume to the given number of decimals after having adjusted it - ``decimals`` (default: ``2``) Number of decimals to round to - ``swapcloses`` (default: ``False``) [2018-11-16] It would seem that the order of *close* and *adjusted close* is now fixed. The parameter is retained, in case the need to swap the columns again arose. ''' params = ( ('reverse', True), ('adjclose', True), ('adjvolume', True), ('round', True), ('decimals', 2), ('roundvolume', False), ('swapcloses', False), ) def _loadline(self, linetokens): while True: nullseen = False for tok in linetokens[1:]: if tok == 'null': nullseen = True linetokens = self._getnextline() # refetch tokens if not linetokens: return False # cannot fetch, go away # out of for to carry on wiwth while True logic break if not nullseen: break # can proceed i = itertools.count(0) dttxt = linetokens[next(i)] dt = date(int(dttxt[0:4]), int(dttxt[5:7]), int(dttxt[8:10])) dtnum = date2num(datetime.combine(dt, self.p.sessionend)) self.lines.datetime[0] = dtnum o = float(linetokens[next(i)]) h = float(linetokens[next(i)]) # ここで失敗するはず l = float(linetokens[next(i)]) c = float(linetokens[next(i)]) self.lines.openinterest[0] = 0.0 # 2018-11-16 ... Adjusted Close seems to always be delivered after # the close and before the volume columns adjustedclose = float(linetokens[next(i)]) try: v = float(linetokens[next(i)]) except: # cover the case in which volume is "null" v = 0.0 if self.p.swapcloses: # swap closing prices if requested c, adjustedclose = adjustedclose, c adjfactor = c / adjustedclose # in v7 "adjusted prices" seem to be given, scale back for non adj if self.params.adjclose: o /= adjfactor h /= adjfactor l /= adjfactor c = adjustedclose # If the price goes down, volume must go up and viceversa if self.p.adjvolume: v *= adjfactor if self.p.round: decimals = self.p.decimals o = round(o, decimals) h = round(h, decimals) l = round(l, decimals) c = round(c, decimals) v = round(v, self.p.roundvolume) self.lines.open[0] = o self.lines.high[0] = h self.lines.low[0] = l self.lines.close[0] = c self.lines.volume[0] = v self.lines.adjclose[0] = adjustedclose return True
if __name__ == '__main__': cerebro = bt.Cerebro() data = KabuPlusJPCSVData( dataname=path_to_csv, fromdate=datetime(2020, 1, 1), todate=datetime(2020, 11, 30), reverse=False) cerebro.adddata(data) cerebro.run()
実行結果:
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-5-60db8dbbc6e2> in <module>() 9 10 cerebro.adddata(data) ---> 11 cerebro.run() 5 frames <ipython-input-4-791391b01568> in _loadline(self, linetokens) 63 self.lines.datetime[0] = dtnum 64 o = float(linetokens[next(i)]) ---> 65 h = float(linetokens[next(i)]) # ここで失敗するはず 66 l = float(linetokens[next(i)]) 67 c = float(linetokens[next(i)]) ValueError: could not convert string to float: 'SGホールディングス'
実際に実行すると、コメントを付けた場所できちんと失敗している。これにより、正しく上書きできたことが確認された。
次回は _loadline()
メソッドを修正していく。