昨日の記事で、一旦戦略は完成したものの、注文量の調整については未着手だった。
how-to-make-stock-trading-system.dogwood008.com
そこで bt.Sizer
を使用して注文量の調整を行う為、下記を参考に実装していた。
しかし、結果として、このアプローチは失敗だった。なぜなら、 Sizer
に渡される(= _getsizing()
が呼ばれる)時の引数が、下記の4つしか無く、注文しようとしている銘柄の単価を取得できないからである。
comminfo
:backtrader.comminfo.CommInfoBase
- コミッション(手数料)を算出するためのクラス
cash
:float
- 現金
data
:backtrader.feeds.AbstractDataBase
- CSVデータ
isbuy
:bool
- 買い注文なら
True
売り注文ならFalse
- 買い注文なら
途中まで作成したものが下記のソースコードになるが、もちろんこのままでは利用できない。供養のため載せておく。
import backtrader as bt from bt.comminfo import CommInfoBase from bt.feeds import AbstractDataBase class RangeSizer(bt.Sizer): ''' 決められた注文額に納まるように、注文数を調整する。 ''' params = ( ('min_order_price', 10 * 10000), # 最低購入金額(円) ('max_order_price', 50 * 10000), # 最高購入金額(円) ) def _getsizing(self, comminfo: CommInfoBase, cash: float, data: AbstractDataBase, isbuy: bool) -> int: ''' base: https://github.com/mementum/backtrader/blob/master/backtrader/sizer.py Parameters ---------------------- comminfo : bt.comminfo.CommInfoBase The CommissionInfo instance that contains information about the commission for the data and allows calculation of position value, operation cost, commision for the operation cash : float current available cash in the *broker* data : Any target of the operation isbuy : bool will be `True` for *buy* operations and `False` for *sell* operations Returns ----------------------- size : int The size of an order ''' issell = not isbuy if issell: # 売り注文なら、全量を指定 position = self.broker.getposition(data) if not position.size: return 0 # do not sell if nothing is open else: return position.size else: # TODO