「売買ルールにトレンド判定を使用する その1,2,3」では、 銘柄自身が上昇or下降トレンドにあるかを売買ルールに盛り込みました。
今回は、市場全体が上昇トレンドor下降トレンドにあるかを、売買ルール判定に取り入れてみます。
・投資予算に制限を加える
・共通コードを関数化して可読性を向上させる その2
・共通コードを関数化して可読性を向上させる その3
・本ブログの内容において、正当性を保証するものではありません。
・本ブログを利用して損失を被った場合でも一切の責任を負いません。
・最終的な決定は、ご自身の判断(自己責任)でお願い致します。
値上がり銘柄をカウントする
やり方は こうです。
「昨日より値上がった名柄が〇〇以上になったとき 市場全体として上昇傾向にある。」
・・・
Protraにこのルールを取り込む場合、コードの構造を変える必要があります。
Protraでは基本的に銘柄ごとにルールの判定を行います。他の銘柄がどうなっているか、は考慮しません(※ String型@作用素を使用すれば、一応は考慮可能です)。
そのため、ルールを記述した関数 と 実際に売買を行う関数は独立させる必要があります。
実装
動作内容は単純で、売買を行う処理用に、関数とループを追加するだけです。こんな感じになりました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
#loop-type: date-only #-------------------------------------------------- # このシステムのルール # # <買い条件> # ・終値と移動平均(5日)との乖離率が-7%以下 # ・当日の終値が、昨日の終値より高い銘柄が60%以上 # を満たしたとき、翌日の始値で買う # # <売り条件> #・終値と移動平均(5日)との乖離率が0%以上 #・購入から10日経過 # を満たしたとき、翌日の始値で売る #-------------------------------------------------- # written by グコウ, 2018/8/16 #================================================== require "TIlib" require "Utility" require "TrendCheck" codes = CodeList if $code_num && $code_num != Length(codes) Print("前回と異なる銘柄リストでは実行できません。") Dummy end $code_num = Length(codes) #グローバル変数を初期化 if ! $__INIT__ $budgetIni = 10000000 $budget = $budgetIni #投資総額 (1000万円) $buyUnit = 1000000 #1回の購入資金 (100万円) $MaxHoldDay = 10 #最大保有日数 $Interest = 0 #無制限(0) / 単利(1) / 複利(2) #------------------------------------------------ $set = [$code_num] $buy = [$code_num] $hold = [$code_num] #------------------------------------------------ $BB5 = [$code_num] #------------------------------------------------ $buyflag = [$code_num] $sellflag = [$code_num] $cnt = 0 $__INIT__ = 1 end def Main(i) #================================================== # 条件(買条件, 売条件共通部分) #================================================== #まだ上場していない銘柄は株価データがないためnullが返る if Index == null return end if ! $BB5[i] #Tilibのオブジェクト生成 $BB5[i] = BB_new(5) #銘柄ごとのグローバル変数を初期化する $hold[i]=0 return end #指標の計算を1日進める BB_next($BB5[i]) ma5 = BB_value($BB5[i]) #------------------------------------------------- #計算 #------------------------------------------------- #指標の計算に必要な日数を経過していない場合は何もしない if ! ma5 return end #終値と5日移動平均線の乖離率を計算する r5 = 100*(Close - ma5)/ma5 #前日より値上がりしたか if Close > {-1}Close $cnt = $cnt+1 end #================================================== # 条件1 #================================================== if PricedataExistCheck(Close) return end #エントリーの条件を判定 if (! $hold[i] && r5 <= -7) #================================================== # 売買(買い) #================================================== //$long = 0 //$long = Num($buyUnit,Close) //Buying(i) $buyflag[i] = 1 #================================================== # 条件2 #================================================== elsif $hold[i] if PricedataExistCheck(Close) return end if $set[i] < 1 $set[i] = $set[i] + 1 return end $set[i] = $set[i] + 1 if (r5>0 || $set[i] > $MaxHoldDay) #================================================== # 売買(売り) #================================================== //Selling(i) $sellflag[i] = 1 end end end #==================== # 売買関数 #==================== def BuySell(j) if PricedataExistCheck(Close) return end if $buyflag[j] && (float)$cnt/(float)$code_num*100 >= 60 $long = 0 $long = Num($buyUnit,Close) Buying(j) $buyflag[j] = 0 elsif $sellflag[j] Selling(j) //Print($set[j]) $sellflag[j] = 0 end end #==================== # 銘柄コードを変えながらMain関数,BuySell関数を実行 #==================== i = -1 j = -1 while i + 1 < $code_num i = i + 1 {codes[i]}Main(i) end while j + 1 < $code_num j = j + 1 {codes[j]}BuySell(j) end $cnt=0 |
順番に見ていきます。
最初に新しいグローバル変数を準備します。それぞれ、買条件・売条件を満たした銘柄の記録と、今回の肝である値上がり銘柄のカウントに使用します。
1 2 3 |
$buyflag = [$code_num] $sellflag = [$code_num] $cnt = 0 |
当日の終値が、昨日の終値より高い場合、$cntを+1しています。
1 2 3 4 |
#前日より値上がりしたか if Close > {-1}Close $cnt = $cnt+1 end |
買い条件を満たしたとき、Main()関数のループの中では買いません。その代り、銘柄ごとに「条件を満たした」フラグを入れています。売りも同様です。
1 2 3 4 5 6 7 |
#================================================== # 売買(買い) #================================================== //$long = 0 //$long = Num($buyUnit,Close) //Buying(i) $buyflag[i] = 1 |
実際に売買を行っているのは、こちらの関数になります。$buyflg[j]
が1で、$cnt
が全銘柄数の60%を超える場合に、買いを行っています。60%は適当に設定しました。
$buyflg[j]
,$sellflg[j]
を0に戻すを忘れずに。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#==================== # 売買関数 #==================== def BuySell(j) if PricedataExistCheck(Close) return end if $buyflag[j] && (float)$cnt/(float)$code_num*100 >= 60 $long = 0 $long = Num($buyUnit,Close) Buying(j) $buyflag[j] = 0 elsif $sellflag[j] Selling(j) //Print($set[j]) $sellflag[j] = 0 end end |
最後、ループさせているwhile関数です。Main()
に加え、売買を扱うBuySell()
を追加しています。
最後に$cnt
を0に戻し、次の日に進みます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#==================== # 銘柄コードを変えながらMain関数,BuySell関数を実行 #==================== i = -1 j = -1 while i + 1 < $code_num i = i + 1 {codes[i]}Main(i) end while j + 1 < $code_num j = j + 1 {codes[j]}BuySell(j) end $cnt=0 |
効果の検証
いつものように、以下の逆張りルールを用います。
◆買い:以下を満たしたとき、翌日の始値が買う
・終値と移動平均(5日)との乖離率が-7%以下
◆売り:以下のいずれかを満たしたとき、翌日の始値で売る
・終値と移動平均(5日)との乖離率が0%以上
・購入から10日経過
●予算無制限、対象銘柄:売上上位500銘柄
はじめに、トレンド判定なし。
続いて、「昨日より値上がりした銘柄が、全体の75%以上の場合、市場全体が上昇トレンドにあると判断」を盛り込んだ場合です。
割と直線的に右肩上がりだったのが、階段状になりました。「昨日より値上がりした銘柄が、全体の75%以上」は中々発生しないからですね。
こういった市場のトレンドは、どちらかというと順張り系のルールで効果が出ます。色々検証してみてください。
応用
今回利用した、ルールと売買の関数を独立させる方法を用いると、以下のようなルールを作ることができます。
・売買ルールそのものを満たした銘柄が、〇〇以上のときに売買する
順張りで効果的です。買い条件を満たすような強いトレンドが発生していることを示しています。
・売買ルールを満たした銘柄の内、優先順位をつけて売買する
売買ルールを満たしたルールの内、株価が高い順,出来高が大きい順,RSIが小さい順 などをルールに組み込めます。
少しコードが複雑になりますが、予算が限定されているときに、どの銘柄を優先的に買うかを決めることができます。