またろうのシストレブログ

マネックス証券が提供しているトレードステーションと、MT4などシストレ関連について色々書きます。株と自動売買、EasyLanguageについても。

トレステでスクリーニングしてみるテスト(スキャナー)



今回はトレステでスクリーニングできる機能「スキャナー」を使ってみます。

f:id:tsukinowaapp:20180816132938p:plain

出来高が急上昇した銘柄をスクリーニングしてみる

スキャナー(スクリーニング)を開いたら、画面左下の「挿入」を押下

名前

f:id:tsukinowaapp:20180816135507p:plain

任意の名前を設定したら「進む」

シンボルユニバー

f:id:tsukinowaapp:20180816140718p:plain

「スキャンするシンボルの範囲を指定する」で検索する範囲を指定、
「除外する銘柄コードを選択」で検索から除外する銘柄コードを指定します。

設定したら「進む」

スキャン基準

f:id:tsukinowaapp:20180816174410p:plain

1から組んでも良いですが、条件を組むのが割と面倒なのでテンプレートを使います。
画面左上にある「V」を押下

f:id:tsukinowaapp:20180816174715p:plain

出来高急増」を選択

f:id:tsukinowaapp:20180816175141p:plain

このまま使ってもいいですが、条件を変えてみます。

出来高(本日)/出来高(1日前)> 2
出来高(本日)> 出来高平均(25日)
現在値 > 終値(1日前)

f:id:tsukinowaapp:20180816175440p:plain

条件を変更したら「実行」

f:id:tsukinowaapp:20180816175939p:plain

抽出した結果が表示されます。
(実行またはOKで設定した条件が保存されます)

定期的に実行する(スケジュール)

スクリーニングを一定周期で実行する設定ができます。
画面左下の「設定」を押下
「スケジュール」タブを押下

f:id:tsukinowaapp:20180816183822p:plain

「スキャンの自動実行スケジュール」にチェック
後は好みの時間設定を行います。
ザラ場時間中は常時実行したいのであれば上記の画像の通りにして
分設定だけ5分にするとよいかと思います。
(最短で5分です)

長所と欠点も

上手く扱うことができれば仕手株臭い銘柄を探すのに便利かと思います。

欠点は、現状仕様だとシンボルユニバースの除外銘柄設定が意外と面倒くさいです。
用意されている銘柄グループの括りが大雑把すぎて使えません。
ETFを除外したい場合、結局1銘柄ずつ指定していくしかないです)

ナイアガラの発生をトリガーにしてポジションを持つストラテジーを組んでみたがって話


命名「狼狽トリガー」

f:id:tsukinowaapp:20180816103044j:plain

いわゆるナイアガラ(突然の大暴落)の発生をトリガーにして
ショートポジションを握った後
反転したところでロングポジションに持ち替えるというストラテジーを組みました。

何か月か前の野崎印刷紙業[7919]でナイアガラが発生したので
それをテストデータにして組みました。

しかし、待っていると起こらないのがナイアガラで
実戦で拾えた試しがないんですよね。

自分には上手く使えそうにないので公開します。

  • 結構リスキーなストラテジーだと思うので、使用の際は自己責任でお願いします。

ストラテジー

[Intrabarordergeneration = true];

inputs: 
	MidAvg(25),
	LongAvg(100),
	TicksVolume(40000000),
	LossCutPrice(100),
	ProfitPrice(200),
	StartTime(0901);
	
vars: 
	Answer(0),
	StartFlgW(0),
	NowDateTime(NULL),
	NewUpTick(0),
	NewDownTick(0),
	UpTriger(false),
	DownTriger(false),
	AnswerSlow(0);

if date > date[1] then begin
	StartFlgW = 0;
	NewUpTick = 0;
	NewDownTick = 0;
	UpTriger = false;
	DownTriger = false;
end;

If TIME >= StartTime and TIME < 1450 then 
begin

	Answer = AverageFC(Close, MidAvg);
	AnswerSlow = AverageFC(Close, LongAvg);

	NowDateTime = BarDateTime.ELDate + BarDateTime.Hour + BarDateTime.Minute + BarDateTime.Second;

	//NewUpTick += UpTicks;
	NewDownTick += DownTicks;

	IF NowDateTime[1] <> NowDateTime then
	BEGIN
		//UpTriger = false;
		DownTriger = false;
		
		//IF (NewUpTick > TicksVolume) then 
		//BEGIN
		//	UpTriger = true;
		//end;
		
		IF (NewDownTick > TicksVolume) then 
		BEGIN
			DownTriger = true;
		end;
	
		//NewUpTick = 0;
		NewDownTick = 0;
	end;

	IF StartFlgW = 0 and MarketPosition = 0 then 
	begin
		//if UpTriger = true then 
		//BEGIN
			//StartFlg = 1;
			//Print(GetSymbolName, "緊急買いスタート", TIME);
			//Buy ( !( "緊急買いスタート" ) ) next bar at market;
		//END;
		
		if DownTriger = true then 
		BEGIN
			StartFlgW = 1;
			Print(GetSymbolName, "緊急空売りスタート", TIME);
			Sellshort ( !( "緊急空売りスタート" ) ) next bar at market;
		END;
	END;
	
	IF StartFlgW = 1 and MarketPosition <> 0 then 
	begin

		IF ContractProfit > ProfitPrice then
		BEGIN
			//if MarketPosition = 1 and Answer < Answer[1] and AnswerSlow < AnswerSlow[1] and Answer < AnswerSlow then 
			//BEGIN
			//	Print(GetSymbolName, "緊急ドテン空売り", TIME);
			//	Sellshort ( !( "緊急ドテン空売り" ) ) next bar at market;
			//END;
	
			if MarketPosition = -1 and Answer > Answer[1] and AnswerSlow > AnswerSlow[1] and Answer > AnswerSlow then 
			BEGIN
				Print(GetSymbolName, "緊急ドテン買い", TIME);
				Buy ( !( "緊急ドテン買い" ) ) next bar at market;
			END;
		END
		ELSE IF ContractProfit < -LossCutPrice then
		BEGIN
			if MarketPosition = 1 then 
			BEGIN
				StartFlgW += 1;
				Print(GetSymbolName, "緊急損切売り抜け", TIME);
				Sell ( "緊急損切売り抜け" ) next bar at market;
			END;
	
			if MarketPosition = -1 then 
			BEGIN
				StartFlgW += 1;
				Print(GetSymbolName, "緊急損切買い戻し", TIME);
				BuyToCover ( "緊急損切買い戻し" ) next bar at market;
			END;
		END;

	END;
	
	IF StartFlgW >= 2 and MarketPosition <> 0 then
	BEGIN
		if MarketPosition = 1 and AnswerSlow < AnswerSlow[1] and Answer < AnswerSlow then 
		BEGIN
			StartFlgW += 1;
			Print(GetSymbolName, "緊急反転売り抜け", TIME);
			Sell ( "緊急反転売り抜け" ) next bar at market;
		END;
	
		if MarketPosition = -1 and AnswerSlow > AnswerSlow[1] and Answer > AnswerSlow then 
		BEGIN
			StartFlgW += 1;
			Print(GetSymbolName, "緊急反転買い戻し", TIME);
			BuyToCover ( "緊急反転買い戻し" ) next bar at market;
		END;
	end;
end;

if TIME >= 1125 and TIME < 1130 then
Begin
	if MarketPosition = 1 then
	BEGIN 
		StartFlgW += 1;
		Print(GetSymbolName, "緊急指定時間売り抜け(午前)", TIME);
		Sell ( "緊急指定時間売り抜け(午前)" ) next bar at market;
	end;
	if MarketPosition = -1 then
	BEGIN
		StartFlgW += 1;
		Print(GetSymbolName, "緊急指定時間買い戻し(午前)", TIME);
		BuyToCover ( "緊急指定時間買い戻し(午前)" ) next bar at market;
	end;
End;

if TIME >= 1455 then
Begin
	if MarketPosition = 1 then
	BEGIN 
		StartFlgW += 1;
		Print(GetSymbolName, "緊急指定時間売り抜け", TIME);
		Sell ( "緊急指定時間売り抜け" ) next bar at market;
	end;
	if MarketPosition = -1 then
	BEGIN
		StartFlgW += 1;
		Print(GetSymbolName, "緊急指定時間買い戻し", TIME);
		BuyToCover ( "緊急指定時間買い戻し" ) next bar at market;
	end;
End;

チャート設定は1ティックです。

コード解説

現在時間を拾って、下降出来高が一定以上発生したらポジションを獲得するというロジックになってます。
反転は2種類の移動平均を見ています。

コメントアウトの箇所は逆ナイアガラ(一定以上の上昇)なので、必要だと思う人はコメント解除してください。

TicksVolume:発生出来高閾値
LossCutPrice:ロスカット値(1株当たりの損益)
ProfitPrice:利確とする値(1株当たりの損益)

上記は銘柄ごとに調整する必要があります。
特にTicksVolumeはどこが適正値なのか私でも分かりません。orz

使う前にバックテストをみっちりやってください。
なお、どうしても約定までラグが発生するので
シミュレーション通りの利益は出ないと思います。

思惑とは逆の方向に動いた場合の対策として損切ロジックを入れていますが
不要だと思う人は取っ払ってください。(自己責任)

所詮待ちぼうけ戦法

結局はどの銘柄に仕掛けるか?なので
仕手株や決算の情報などアンテナの敏感な人でないと使いこなせないでしょう。
もし上手く使えたらお返事ください。_(:3 」∠)_

トレンドラインを自動で引いてくれるインジケーターが普通にあったわって話



トレンドラインを手動で引くのは面倒くさいので、自動で引くインジケーターを作ろうとしたら
普通にインジケーターの中にありました。
「自動トレンドライン」っていうのが。

f:id:tsukinowaapp:20180807213315j:plain

チャートの波形を拾って、波の頂点から未来軸の頂点に向かって線を引いてくれます。
これで十分ですね。

ちなみに、スイングハイ・スイングローを見つける関数もあったりします。

Shigh = SwingHighBar(1, High, Strength, Length); 
Slow = SwingLowBar(1, Low, Strength, Length);

第一引数で発生時点の設定、(1で直近、2で...という感じ)
第二引数でバーで考慮する値
第三引数で左右いずれかに必要なバーの数
第四引数で調べるバーの数を指定します。


トレステ付属のSNSビューアがツイッター監視ツールとして結構優秀だって話



twitterではいわゆる「株名人」が毎日株に関するツイートをしています。
ツイートの影響は結構大きくて、突然トレンドが変化することがあります。
(倒れる方向の正確性は置いといて)

しかし自分が知っているだけでも名前を挙げてみると、
ウルフ村田さん、大魔神さん、KAZMAXさん、RINGさん、岡三マンさん、NEO株GODさん、久保優太さん?など...
結構な人数で追いきれないこともあります。
かと言ってフォローの人数を絞ったり、不要と思われる人をミュートしたりすると
重要なツイートを見逃すことも。
(ミュートの連発はアカウントの凍結を招いたりもします)

トレードステーションにはSNSビューアと言われる
twitterの監視ツールがあります。

f:id:tsukinowaapp:20180806101656p:plain

これは株に関するツイートをリアルタイムで抽出したり、キーワードを拾って銘柄コードに変換してくれたりするという便利なものです。

特徴

  • フォローごとのツイートを一覧表示してくれる(フォローリスト)
  • フォローからさらに取捨選択して必要なアカウントだけリストに登録できる(フォローリスト)
  • 株に関するキーワードを拾って覧表示してくれる(ホットワード)
  • ツイートに含まれる銘柄名称を拾って銘柄コードを表示してくれる(関連銘柄)
  • 同時に関連銘柄まで拾ってくれる(関連銘柄)
  • キーワードを設定して、該当ツイートを一覧表示してくれる(アラート)
  • 不要なデコレーションを削ってツイートの内容だけを表示してくれるので軽量

機能別に説明します。

フォローリスト

f:id:tsukinowaapp:20180806102003p:plain

フォローごとのツイートを一覧表示します。
「+」クリックで各フォローごとのツイート一覧が表示されます。
各ツイートをクリックで中央タイムラインとプレビューに詳細表示されます。

フォローリストは編集できます。
画面右上の歯車アイコンを押下

f:id:tsukinowaapp:20180806105421p:plain

左の画面にツイッターのフォロー一覧、右側にSNSビューアのフォローリストが表示されます。
左側の一覧からユーザーを選択状態にして「ユーザー追加」押下でSNSビューアに追加
右側の一覧からユーザーを選択状態にして「削除」押下でSNSビューアから削除できます。

また、特定アカウントのツイートだけ色を変えることもできます。
右側の一覧からユーザーを選択状態にして「背景色指定」で色指定します。

ホットワード

f:id:tsukinowaapp:20180806132906p:plain

株に関するキーワードで自動的に一覧化されます。
扱い方はフォローリストと同様です。

関連銘柄

f:id:tsukinowaapp:20180806133308p:plain

タイムラインにて選択しているツイートから銘柄を拾って
関連銘柄の名称と市場、銘柄コードを表示します。

アラート

f:id:tsukinowaapp:20180806133930p:plain

ホットワードでは拾ってくれないキーワードを手動で設定して一覧化します。
キーワードの追加は設定から行えます。

f:id:tsukinowaapp:20180806134445p:plain

抽出したツイートには左端にアラートマークが付加されます。

プレビュー

ツイートに付加されたリンクをクリックしてブラウザー上で表示できます。

変わった使い方も?

Webベースのツイッター関連のツールと違い、CSSなどの余計なデコレーションがないので動作が大変軽いです。
自らツイートする機能はありませんが、特定の人のツイートを監視するツールとしては優秀だと思います。
変な話株に拘らず、特定ジャンルのツイートをリアルタイムで抽出するツールと解釈することもできます。
(ホットワードと関連銘柄が無意味になるかもですが)

トレンドラインを日付時間指定で引くインジケーターを作ってみる



多くのチャートツールは手動で線を引く機能はありますが
割と面倒くさいのではと思います。
その辺を自動化できたら楽ですね。

なので今日はチャートにトレンドラインを引くインジケーターを作ってみます。

f:id:tsukinowaapp:20180727150108j:plain

トレステにはトレンドラインを引くための命令が用意されていますので、それを利用します。

inputs:
	SDate(1180727),
	Stime(0932),
	SPrice(High),
	EDate(1180727),
	Etime(1018),
	EPrice(High),
	LineColor(White);
	
vars:
	id(0),
	double STempPrice(0),
	double EtempPrice(0),
	TLid(0);

IF Date = SDate and time >= Stime and STempPrice = 0 then
BEGIN
	STempPrice = SPrice;
END;

IF Date = EDate and time >= Etime and EtempPrice = 0 then
BEGIN
	EtempPrice = EPrice;
	id = TL_New(SDate, Stime, STempPrice, Date, Time, EtempPrice);
	TL_SetColor(id, LineColor);
END;

IF id > 0 and TLid >= 0 then
BEGIN
	TLid = TL_SetExtRight(id, True);
END;

コード解説

TL_Newで指定した2か所の日付と時間、価格に渡って直線を引くことが可能です。
返値にてIDを取得できますが、
このIDを使って線を延長したり、色を変えたりできます。
TL_SetColorで色を変えてます。
TL_SetExtRightにて、右へ線を延長しています。

今回は高値基準の下降トレンドラインですが
SPrice、EPriceのHighをLowにすれば上昇トレンドでも使えます。

この線をストラテジーに組み込んで売買の基準にすることも可能なようです。(まだやってない)

今回はinputsにて開始・終了時間を入力する方式ですが
できたらこの辺も自動で設定したいですね。
(例えば一定期間での最高値を基準にするなど)

次回はその辺をやってみようかと思います。

上昇・下降出来高を分けて表示するインジケーターを作って分かった驚愕の事実



ワークスペースにチャート分析を入れ込むと
デフォルトの設定として売買高のインジケーターが設定されます。

f:id:tsukinowaapp:20180713182033p:plain

売買高というのは出来高とイコールなのですが
出来高というのは売り気配に買いをぶつける「上昇出来高」と
買い気配に売りをぶつける「下降出来高」があります。
デフォルトで表示される売買高インジケーターではそれが分からないので
お手製インジケーターを作ってみます。

コーディングとしてはたった3行の簡素なものです。

上昇・下降出来高インジケーター

Plot1(UPTICKS,"UpTicks", Magenta);
Plot2(-DOWNTICKS,"DownTicks", Cyan);
Plot3(0,"ZERO", White);

「分析テクニックの設定」→作成したインジケーターを選択して「設定」→「スタイル」タブをクリック
UpTicksとDownTicksのタイプを「ヒストグラム」に変更
ZEROの「現在値を表示」チェックを外す

f:id:tsukinowaapp:20180713184107p:plain

下降出来高をマイナスにすることで
中央のゼロラインを軸にして上下に出来高を表示する感じにしました。

DownTicksの謎

日中足(分足や秒足)ならこれで問題ないのです。

f:id:tsukinowaapp:20180713200528p:plain

ポップの表示も

f:id:tsukinowaapp:20180713205722p:plain

問題ないですね。

しかしこれを日足にすると...

f:id:tsukinowaapp:20180713200614p:plain

あるぇ~?

ちなみに、アプリを立ち上げた直後はこんな表示ですが
f:id:tsukinowaapp:20180713184943p:plain

一旦別の銘柄コードを入力してから戻すとこんな表示に...
f:id:tsukinowaapp:20180713194148p:plain

ちなみに新しく作ったインジケーターの表示と比較すると...
f:id:tsukinowaapp:20180713201306p:plain

売買高のコードを見てみましょう。

if BarType >= 2 and BarType < 5 then { Daily, Weekly, or Monthly bars }
	AnyVol = Volume 
else 
	AnyVol = Ticks;

現物のコードで19行目からです。
BarType は予約語で、この数字で現在の足種の設定を取得できます。
ヘルプを見ると

0 = ティック足
1 = Minute
2 = 日
3 = 週
4 = 月
5 = ポイントアンドフィギュア
6 = (予約済み)
7 = (予約済み)
8 = カギ足
9 = KASE
10 = 新値足
11 = モメンタム
12 = レンジ
13 = 練行足
14 = 秒

つまり2~4で日足~月足はVolume を参照して、それ以外はTicksを参照する作りになっています。
TicksはUpTicksとDownTicksの合計値です。なので日中足は問題ないです。

で、日足~月足にするとですが...

UpTicks は Volume と同値
DownTicks は 売買代金(千円)
になるってことです。

ちなみに売買代金というインジケーターがあるので比較してみます。

f:id:tsukinowaapp:20180713202857p:plain

一緒ですね。

実際に日足で(DownTicks * 1000) / UpTicks で計算すると、その日に取引された株価の平均値になる筈です。
つまりVWAPだこれ!(驚愕の事実)

ちなみに売買代金インジケーターでは、内部的にはTurnoverという予約語を使っています。
(ヘルプにも載っていない謎の予約語...)
日中足でもこれを使えばVWAP出せるんじゃないの?って思ったのですが
なんとこれ
Turnover = DownTicks
(日中足で使うと下降出来高になる)
でした。

_(┐「ε:)_

日中足で移動平均や指数加重移動平均を使う場合は改造が要るよって話



日足では特に意識する必要もないのですが
秒や分などの日中足で、移動平均などの過去データを参照するチャートを使う場合
前場寄り直後で大きめのGU(ギャップアップ)やGD(ギャップダウン)が発生すると
チャートの描写があまり宜しくない感じになります。

f:id:tsukinowaapp:20180711103037p:plain

理由は単純で、前日のデータまで平均の対象として吸い込んでしまっているからなんですね。
指数加重移動平均も同様です。

f:id:tsukinowaapp:20180711103850p:plain

なので、日付が変わったらリセットしてあげる必要がある訳です。

移動平均の改造

日付を跨いだらカウンターをリセットして
設定した本数より少ない場合はカウンターの数値で平均を出すというコードを書いてみます。

関数
AVG_KAI

inputs:
	Price(NumericSeries),
	Avg(NumericSimple);

vars:
	BarCount(0);

if date <> date[1] or CurrentBar <= 1 then 
BEGIN
	BarCount = 1;
	AVG_KAI = Price;
END
ELSE
BEGIN
	BarCount += 1;
	IF BarCount < Avg then
		AVG_KAI = Average(Price, BarCount)
	ELSE
		AVG_KAI = Average(Price, Avg);
END;

関数AverageFCとAverageの違い

一般的に移動平均を算出する関数は、処理が速い(と言われる)AverageFCを使いますが
AverageFCは二番目の引数(本数)を動的に変更すると正確な値を出力できないという問題があります。
なのでAverageを使用しています。

インジケーター

inputs:
	Price(Close),
	AvgColor(Yellow),
	Avg(25);

vars: 
	Answer(0);

Answer = AVG_KAI(Price, Avg);

Plot1(Answer, !( "移動平均改良" ), AvgColor);

f:id:tsukinowaapp:20180711114952p:plain

細い水色が25本、ピンクが75本です。

指数加重移動平均の改造

こちらの改造はもっと楽で、日付の切り替わりのタイミングでリセットするだけです。

関数
XAveKai

inputs: 
	Price( numericseries ), { price to average }
	Length( numericsimple ) ; { this input must be a constant >= 0 }

variables: 
	intrabarpersist SmoothingFactor( 0 ) ;

once
	begin
	if Length >= 0 then
		SmoothingFactor =  2 / ( Length + 1 )
	else
		RaiseRuntimeError( !( "The Length input of the XAverage function must be " +
		 "greater than or equal to 0." ) ) ;
	end ;

if CurrentBar = 1 or Date <> Date[1] then
	XAveKai = Price
else
	XAveKai = XAveKai[1] + SmoothingFactor * ( Price - XAveKai[1] ) ;

関数XAverageのソースをコピーして
if CurrentBar = 1 then
となっている箇所を
if CurrentBar = 1 or Date <> Date[1] then
と書き換えて
後は関数名をそれぞれ書き換えるだけです。

f:id:tsukinowaapp:20180711120919p:plain


ちなみに、改造関数は日足(週足、月足も)では使用できません。

トレステでVWAPを(頑張って近い値を)表示しようという話



今日はトレステでVWAPを(何とか頑張ってそれらしい値を)表示する方法を書きます。

EasyLanguageにはVWAPという予約語が用意されています。
なのでこれを単純に使えばよいのではと考えるのですが
どうもこれは板情報(買気配や売気配)と同じリアルタイムデータなんですね。
なので履歴としては残らないので、過去データのVWAP値を算出する目的では使えないってことです。

では他の手段を考えてみます。

ティックごとの出来高と価格を拾えたら計算できそうですが
インジケーターは足単位で処理を行うので(ストラテジーのようなイントラバー処理ができない)
ティックごとの株価(約定した値段)を拾いたい場合、チャートの設定を1ティックにするしかないんですね。
なので、正確なVWAP値は1ティックチャート以外生成できないってことです。

では分足や秒足ではVWAPは表示できないのかと言うとそうでもなく
完全には一致しないものの、極力近い数字を出すことは可能です。

VWAPのコードを書いてみる

関数
VWAP_HI

inputs:
	PmReset(NumericSimple);

vars:
	PriceW(0),
	ShareW(0),
	Answer(0.1),
	DayReset(0);

Once
begin
	PriceW = 0;
	ShareW = 0;
	Answer = OpenD(0);
end;

if date > date[1] then begin
	PriceW = 0;
	ShareW = 0;
	DayReset = 0;
	Answer = OpenD(0);
end;

IF PmReset <> 0 and TIME = 1230 and DayReset = 0 then
BEGIN
	PriceW = 0;
	ShareW = 0;
	DayReset = 1;
END;

//PriceW += (AvgPrice * Ticks);
PriceW += (High * UpTicks) + (Low * DownTicks);
ShareW += Ticks;
	
if ShareW > 0 then
	Answer = PriceW / ShareW;

VWAP_HI = Answer;

インジケーター

inputs: 
	DownColor(Cyan), 
	UpColor(Magenta);

vars: 
	Answer(0),
	NewColor(DarkGray);

Answer = VWAP_HI(0);

NewColor = DarkGray;

if Close > Answer then
	NewColor = UpColor
else if Close < Answer then
	NewColor = DownColor;

Plot1(Answer, "VWAP_1DAY", NewColor);

コード解説

関数の中にコメントアウトしてある箇所があるかと思います。
それが他のサイトなどで良く見るロジックです。
トレードステーションのヘルプにも
(「avgprice」xバー当たりの「取引された株数」)とか書かれていたりします。
しかしこれ上昇出来高と下降出来高の割合に関して考慮がありませんよね。

なので(高値 * 上昇出来高)+(安値 * 下降出来高)を総出来高で割るという計算式にしてみます。

まず良くあるロジックのほうでチャートを表示します。
f:id:tsukinowaapp:20180710113749p:plain

白い線がリアルタイムデータのVWAPで
シアンとマゼンタの線が自作のVWAPです。

f:id:tsukinowaapp:20180710113935p:plain
結構な誤差があるのが分かるかと思います。

次に改良ロジックでチャートを表示します。
f:id:tsukinowaapp:20180710114132p:plain

ほぼ重なって表示されていますね。

f:id:tsukinowaapp:20180710114245p:plain
誤差もこの位なら許容してほしいかな~?
如何でしょうか。

関数のおまけ機能

PmResetにゼロ以外をセットすると後場寄り前に一旦リセットします。

副産物

現在の価格がVWAPとどのぐらい差があるかをインジケーターにしてみます。

vars: 
	Answer(0);

Answer = Close - VWAP_HI(0);

Plot1(Answer,"VWAP_DIFF", Red);
Plot2(0,"ZERO", White);

f:id:tsukinowaapp:20180710115831p:plain

VWAPで反転する(こともある)ので
そういうの見るときに便利かなー?

TOPIXの値動きを見ながらETFを売買してみる



トレステは、マルチチャートと言って複数のチャートを一つの画面に表示して
それぞれのチャートの状態を見ながら特定の株の売買をするという芸当が出来ます。

今日はマルチチャートを使ってTOPIXの値動きを見ながら
ETF(今回は[1570]NEXT FUNDS 日経平均レバレッジ上場投信)を売買するストラテジーを組んでみます。

f:id:tsukinowaapp:20180709093109j:plain

何故TOPIX

[1570]NEXT FUNDS 日経平均レバレッジ上場投信は、
日経平均株価の上昇・下降に合わせて株価が変動するETFですが
日経平均株価は5秒ごとの更新に対し
TOPIXは1秒ごとの更新で、チャートの動きがほぼ一致しているのでこちらを採用しています。
もちろん日経平均株価を見ながらETFの売買をすることも可能です。

チャートの設定

ストラテジーを組み込む前に、ワークスペースの下準備が必要です。

ワークスペースにチャート分析を組み込んだら、取引したい銘柄コードを設定
今回は5秒足にしておきます。
(マルチチャートはティック足に対応していません)

「挿入」→「銘柄コード」を押下
銘柄コードにTOPIXのコード($0000-TS)を入力、「プロット」を押下

こんな感じになるかと思います。
f:id:tsukinowaapp:20180709093911j:plain

売買高は見ないので「分析テクニックの設定」で削除するか、「状態」押下でオフにしておきましょう。

マルチチャートに分析テクニックを設定する方法

多くの人はマルチチャートに分析テクニックを設定したいかと思います。
そのまま設定すると、最初に設定したチャート(一番上)に適用されるので
適用したいチャートを指定する必要があります。

「挿入」→「インジケーター」で任意のチャートを選択
画面右クリック→「分析テクニックの設定」で挿入したチャートを洗濯して「設定」
「一般」タブを押下して「参照チャート」のプルダウンをクリックして、設定したいほうのチャートを選択した上で「OK]
f:id:tsukinowaapp:20180709101555p:plain

これで切り替わります。

ストラテジー

ストラテジーは以前組んだものを改造して使ってみます。

tsukinowakabu.hatenablog.jp

[Intrabarordergeneration = false];

inputs: 
	AvgType(0),
	MAGeta(0.1),
	MALength1(5),
	MALength2(20),
	MALength3(40),
	MACD3SLength(20),
	MACD3LLength(40);
	
vars: 
	IntrabarPersist DaijunkanFlg(0),
	IntrabarPersist double MA1(0),
	IntrabarPersist double MA2(0),
	IntrabarPersist double MA3(0),
	IntrabarPersist macd3(0),
	IntrabarPersist CloseData(Close of Data2);

CloseData = Close of Data2;

//Daijunkan
macd3 = MACD(CloseData, MACD3SLength, MACD3LLength);

IF AvgType = 0 then
BEGIN
	MA1 = XAverage( CloseData, MALength1 );
	MA2 = XAverage( CloseData, MALength2 );			
	MA3 = XAverage( CloseData, MALength3 );
END
ELSE
BEGIN
	MA1 = AverageFC( CloseData, MALength1 );
	MA2 = AverageFC( CloseData, MALength2 );			
	MA3 = AverageFC( CloseData, MALength3 );
END;

DaijunkanFlg = 0;
IF MA1 > MA2 + MAGeta and MA2 > MA3 and MA1 > MA1[1] and MA2 > MA2[1] and MA3 > MA3[1] and macd3 > macd3[1] then DaijunkanFlg = 1;
IF MA1 < MA2 - MAGeta and MA2 < MA3 and MA1 < MA1[1] and MA2 < MA2[1] and MA3 < MA3[1] and macd3 < macd3[1] then DaijunkanFlg = -1;

//
If MarketPosition = 0 and ((0900 < time and TIME < 1120) or (1230 < TIME and TIME < 1450)) then  
BEGIN
	if DaijunkanFlg = 1 then 
	BEGIN
		Buy (!("買いスタート")) next bar at market;
	END;

	if DaijunkanFlg = -1 then
	BEGIN
		Sellshort (!("空売りスタート")) next bar at market;
	END;
END;

//
IF MarketPosition <> 0 then 
BEGIN
	if MarketPosition = 1 then
	BEGIN
		IF MA1 < MA2 and MA1 < MA1[1] then
		BEGIN
			Sell (!("売り抜け")) next bar at market;
		END;
	END;
	
	if MarketPosition = -1 then 
	BEGIN
		IF MA1 > MA2 and MA1 > MA1[1] then
		BEGIN
			BuyToCover (!("買い戻し")) next bar at market;
		END;
	END;
END;

if TIME >= 1125 and TIME < 1130 then
Begin
	if MarketPosition = 1 then
	BEGIN 
		Print(GetSymbolName, "指定時間売り抜け(午前)", TIME);
		Sell ( "指定時間売り抜け(午前)" ) next bar at market;
	end;
	if MarketPosition = -1 then
	BEGIN
		Print(GetSymbolName, "指定時間買い戻し(午前)", TIME);
		BuyToCover ( "指定時間買い戻し(午前)" ) next bar at market;
	end;
End;

if TIME >= 1455 then
Begin
	if MarketPosition = 1 then
	BEGIN 
		Print(GetSymbolName, "指定時間売り抜け(午後)", TIME);
		Sell ( "指定時間売り抜け(午後)" ) next bar at market;
	end;
	if MarketPosition = -1 then
	BEGIN
		Print(GetSymbolName, "指定時間買い戻し(午後)", TIME);
		BuyToCover ( "指定時間買い戻し(午後)" ) next bar at market;
	end;
End;

ほぼ一緒ですが終値(Close)などの四本値を使用する場合、参照するチャートを指定する必要があります。

CloseData = Close of Data2;

(Close) of DataNで使用するチャートを指定します。
(末尾は数字です)
何番目のチャートを参照するか、を指定します。
チャートが3つ以上ある場合はData3、Data4...という感じです。
毎回指定するのは面倒なので
変数を用意して、Closeを代入してそれを使用するのが楽かと思います。

とりあえす20日分(2018/06/11~2018/07/06)のバックテストをしてみます。
単元数は100株で。

f:id:tsukinowaapp:20180709114857p:plain

どうしても間隔の早い足(5秒)にすると
取引だけ偉く増えて、大した利益にならない感じになりますね。
なので1分足にして、最適化してみます。

f:id:tsukinowaapp:20180709121826p:plain

取引の回数は大幅に減りましたが、買い取引が微妙な結果に。

マルチチャートを使う際の注意

チャートの制約

マルチチャートにする場合は、時間足(月~秒)のみで、ティック足は設定できません。
銘柄ごとに出来高が異なるので当然ではありますが。

取引の制約

取引は最初に設定した一番上の銘柄(Data1)のみ行えます。
1つのチャート分析で複数の銘柄に対して取引は行えません。

ストラテジーの制約

いわゆるイントラバー取引(ティックごとに判定し、条件成立したら発注する)は行えません。
足が完成したタイミングで判定し、条件が成立したら取引するロジックになります。
損切やトレールストップを織り込みたいなら
SetStopLossやSetPercentTrailingなどのコマンドを活用ください。
(こちらは足の途中でも発注されます)

そもそもTradeStationとは何ぞやという話



ひょっとしたら、検索からたまたま此処へ行き着いたかたもいるのではないかってことで
「そもそもTradeStationとは何ぞや」って所から書こうと思います。

f:id:tsukinowaapp:20180707190540p:plain

TradeStation - Wikipedia

元は米国が開発したトレーディングツール

(以下英語版ウィキペディアからの受け売り)
本来のTradeStation(米国仕様)はTradeStation Group, Inc.が開発したもので
原型自体は1991年から!あるそうです。

www.tradestation.com

2001年リリースのTradeStation6から
自動取引と株式取引の直接アクセス実行機能が搭載されました。

米国仕様は評価も高く、
アメリカの投資週刊誌「バロンズ」の
“Best for Frequent Traders”
“Best for International Traders”
で1位を獲得

「Technical Analysis of Stocks & Commodities magazine」の
”Best Trading System - Stocks"
"Best Trading System - Futures"
で11年連続1位を獲得しています。

その後2011年TradeStation Group, Inc.は日本のマネックスグループに買収され子会社化、
2016年にマネックス証券から日本株仕様トレードステーションがリリースされたという流れのようです。

なので、トレードステーションとは
アメリカの会社が開発したトレーディングツールを日本株仕様に書き直したもの」
なんですね。

トレードステーションの特徴

そしてTradeStationの他のトレーディングツールに(あまり)ない特徴として
「ストラテジーによる自動取引」と「EasyLanguageによるストラテジーの自作」と「自作したストラテジーのバックテスト」があります。

自動取引は予め用意したロジック(プログラム)に基づいて気配の状態を判断し、発注を入れていくので
感情に左右されないというメリットがあります。
また、条件が揃ったら即発注を入れるので、目視による手動で発注を入れるよりも、反応速度でより有利というのも強いメリットかと思います。

FXで言えばMT4というものがありますが、
MT4自体はフリーでダウンロード出来て証券会社を選べる感じですが、
TradeStationは前述の事情があって、マネックス証券でしか使えないようになってます。

また、株の自動取引といえば他に岡三RSSがありますが
こちらはExcelベースで動くのに対し
TradeStationは完全に独立したアプリケーションとなっています。

岡三RSSの場合、ロジックは関数あるいはマクロ(VBA)で書くのですが
取引を発注して、実際に発注されたかどうかの確認を岡三RSSだけで行うのはリスクだと感じます。
なので、結局は他のトレーディングツールと併用することになるので
正直不完全な印象があります。

また、システムトレードを謳っているツールの中には
「ストラテジーの自作」と「バックテスト」は出来ても
発注自体は行えないものがありますが
これでは余り意味がないと考えています。

なによりこの手の「自称シストレツール」の中には結構な利用料を請求するものがありますが
トレステは「取引しなければタダ」です。
アカウント作って試して、「自分には合わない」と思ったら入金しなければ良いわけです。
マネックス証券的には面白くないと思われますが)

なので現状、日本株で自動取引を行いたいとする場合トレードステーション一択になるだろうなというのが私の結論です。

トレステで使える指数・先物・為替一覧



トレードステーションで株式を表示する分には、単に4桁の銘柄コード(証券コード)を入力するだけなので
さして問題はないかと思います。

しかし、これが日経平均などの指数や、為替、先物を表示したいとなると途端に面倒臭いことになります。
トレステが独自に制定している銘柄コードを調べて入力するか、検索しないといけないんですね。

「銘柄コードの設定」→「検索」
で、「株式」「先物」「為替」「指数」という感じでタブがあるので
目的に応じでタブを選択、検索します。

f:id:tsukinowaapp:20180705113533p:plain

なのですが、これが正直使い辛い。
何故かというと、使用できない指数がいっぱいあるんですね。
(使えないなら初めから表示しなければいいのにって話なのですが)
f:id:tsukinowaapp:20180705113810p:plain

使えない指数はこんな感じで怒られてしまいます。
どうもTradeStationネイティブインデックスに分類されるものは全部だめっぽいですね。

さらに言うと先物は全数検索ができないので、全体でどんなパラメーターがあるのかも分からないっていう。
正直不便です。

なので、現状でどのパラメーターが使えるのか一覧にしてみようかと思います。
(おそらく不完全です)

銘柄コード一覧

指数

$MNK 日経平均株価
$0000-TS TOPIX
$0001-TS 東証二部
$0002-TS 大型株
$0003-TS 中型株
$0004-TS 小型株
$0028-TS TOPIX Core30
$0029-TS TOPIX Large70
$002A-TS TOPIX 100
$002B-TS TOPIX Mid400
$002C-TS TOPIX 500
$002D-TS TOPIX Small
$002E-TS TOPIX 1000
$0040-TS 水産・農林業
$0041-TS 鉱業
$0042-TS 建設業
$0043-TS 食料品
$0044-TS 繊維製品
$0045-TS パルプ・紙
$0046-TS 化学
$0047-TS 医薬品
$0048-TS 石油・石炭製品
$0049-TS ゴム製品
$004A-TS ガラス・土石製品
$004B-TS 鉄鋼
$004C-TS 非鉄金属
$004D-TS 金属製品
$004E-TS 機械
$004F-TS 電気機器
$0050-TS 輸送用機器
$0051-TS 精密機器
$0052-TS その他製品
$0053-TS 電気・ガス業
$0054-TS 陸運業
$0055-TS 海運業
$0056-TS 空運業
$0057-TS 倉庫・運輸関連業
$0058-TS 情報・通信
$0059-TS 卸売業
$005A-TS 小売業
$005B-TS 銀行業
$005C-TS 証券業
$005D-TS 保険業
$005E-TS その他金融業
$005F-TS 不動産業
$0060-TS サービス業
$0070-TS マザーズ総合
$0075-TS REIT総合
$0076-TS TOPIXコンポジット
$0077-TS TOPIXコンポジット1500
$0078-TS 二部コンポジット
$0079-TS マザーズコンポジット
$0080-TS TOPIX-17 食品
$0081-TS TOPIX-17 エネルギー資源
$0082-TS TOPIX-17 建設・資材
$0083-TS TOPIX-17 素材・化学
$0084-TS TOPIX-17 医薬品
$0085-TS TOPIX-17 自動車・輸送機
$0086-TS TOPIX-17 鉄鋼・非鉄
$0087-TS TOPIX-17 機械
$0088-TS TOPIX-17 電機・精密
$0089-TS TOPIX-17 情報通信・サービスその他
$008A-TS TOPIX-17 電気・ガス
$008B-TS TOPIX-17 運輸・物流
$008C-TS TOPIX-17 商社・卸売
$008D-TS TOPIX-17 小売
$008E-TS TOPIX-17 銀行
$008F-TS TOPIX-17 金融(除く銀行)
$0090-TS TOPIX-17 不動産
$0091-TS JASDAQ INDEX
$0092-TS JASDAQ INDEX(スタンダード)
$0093-TS JASDAQ INDEX(クローズ)
$0094-TS J-Stock Index
$1000-TS TOPIXレバレッジ(2倍)
$1001-TS TOPIXインバース(-1倍)
$1002-TS TOPIXダブルインバース(-2倍)
$1003-TS JPX 日経400レバレッジ(2倍)
$1004-TS JPX 日経400インバース(-1倍)
$1005-TS JPX 日経400ダブルインバース(-2倍)
$1A00-TS JASDAQ TOP20
$1A01-TS ジャスダック平均株価
$8000-TS 東証株価指数
$8100-TS TOPIX バリュー
$812C-TS TOPIX 500 バリュー
$812D-TS TOPIX Small バリュー
$8200-TS TOPIX グロース
$822C-TS TOPIX 500 グロース
$822D-TS TOPIX Small グロース
$8500-TS 東証配当フォーカス100指数
$8501-TS 東証REITオフィス指数
$8502-TS 東証REIT住宅指数
$8503-TS 東証REIT商業・物流等指数
$8504-TS TOPIXアジア関連指数
$8505-TS 東証マザーズCore指数
$8506-TS TOPIX Ex-Financials
$8507-TS JPX 日経インデックス400
$M000001 上海総合指数
$M000003 上海B株指数
$MHSI 香港ハンセン指数
$MHSCCI 香港レッドチップ指数
$MRTSI ロシアRTS指数
$DJI ダウ指数
$SPX.X S&P500指数
$COMPX ナスダック指数
$VIX.X CBOEボラティリティ指数(VIX指数)
$TRCCRB TR/CC CRB商品指数
$BRTI CMEビットコイン指数
$MWTIND 台湾加権指数
$MCOMPOSITE ジャカルタ総合指数
$MVNX ベトナムVN指数
$MSENSEX30 インドSENSEX30指数
$MXAO ASX普通株指数
$MCAC40 仏CAC40指数
$MSSIP スイスSMI指数
$MXU100 トルコISEナショナル100指数
$MJ200 アフリカTOP40指数
$MBVSP ブラジルボベスパ指数
$MERVAL アルゼンチンメルバル指数

使えない指数が一杯ありすぎて全数チェックとかやってられないので
ひょっとしたら他にも使える指数があるかもしれません。
超絶暇人なかた探してみてください。orz

先物

@OSENK 大阪日経平均先物
@SGXNK シンガポール(SGX)日経平均先物
@NIY CME日経平均先物
@GC COMEX金先物
@CL WTI原油先物

それっぽいキーで検索かけてもヒットしないので、これで全部かは分かりません。

為替

BTCUSD Bitcoin/US Dollar
BCHUSD Bitcoin Cash/US Dollar
ETHUSD Ethereum/US Dollar
LTCUSD Litecoin/US Dollar
EURUSD ユーロ/米ドル
USDJPY 米ドル/円
EURJPY ユーロ/円
GBPJPY 英ポンド/円
HKDJPY 香港ドル/円
AUDJPY 豪ドル/円
TRYJPY トルコリラ/円
CHFJPY スイスフラン/円
ZARJPY 南アフリカランド/円
CADJPY カナダドル/円
SGDJPY シンガポールドル/円
NZDJPY ニュージーランドドル/円
BRLJPYLITE ブラジルレアル/円(ライト)
CNYJPYLITE 人民元(CNY)/円(ライト)
MXNJPYLITE メキシコペソ/円(ライト)

各貨幣単位ごとに組み合わせがありますが
全部列挙してもきりがないので必要なら検索から探してください(無責任)
最後の3つは(ライト)とそうでないのがあって、
ライト無しのほうはエラーで使えないという謎仕様...


魅惑のスキャルピングトレード



今回は前回作った板チャート(ITA_AVG)でストラテジーを組んでみます。

ロジックは移動平均線大循環分析でストラテジーを組んだ時とほぼ一緒です。

関数ITA_AVGが必要です。
tsukinowakabu.hatenablog.jp

[Intrabarordergeneration = true];

inputs: 
	ShortAvg(5),
	MidAvg(25),
	LongAvg(50),
	Geta(10);
	
vars: 
	IntrabarPersist Answer(0),
	IntrabarPersist AnswerMid(0),
	IntrabarPersist AnswerSlow(0),
	IntrabarPersist UpFlg(0),
	IntrabarPersist DownFlg(0);

Answer = ITA_AVG(ShortAvg);
AnswerMid = ITA_AVG(MidAvg);
AnswerSlow = ITA_AVG(LongAvg);

UpFlg = 0;
IF Answer > AnswerMid + Geta and AnswerMid > AnswerSlow and Answer > Answer[1] and AnswerMid > AnswerMid[1] and AnswerSlow > AnswerSlow[1] then UpFlg = 1;

DownFlg = 0;
if Answer < AnswerMid - Geta and AnswerMid < AnswerSlow and Answer < Answer[1] and AnswerMid < AnswerMid[1] and AnswerSlow < AnswerSlow[1] then DownFlg = 1;

If MarketPosition = 0 and ((0900 < TIME and TIME < 1120) or (1230 < TIME and TIME < 1450)) then 
begin

	IF UpFlg = 1 then
	BEGIN
		Print(GetSymbolName, "買い", TIME);
		Buy ( !( "買い" ) ) next bar at market;
	end;

	IF DownFlg = 1 then
	BEGIN
		Print(GetSymbolName, "空売り", TIME);
		Sellshort ( !( "空売り" ) ) next bar at market;
	end;
	
end;

IF MarketPosition = 1 then
BEGIN
	IF Answer < AnswerMid and Answer < Answer[1] and AnswerMid < AnswerMid[1] then
	BEGIN
		Print(GetSymbolName, "売り抜け", TIME);
		Sell ( !( "売り抜け" ) ) next bar at market;
	end;
end;

IF MarketPosition = -1 then
BEGIN
	IF Answer > AnswerMid and Answer > Answer[1] and AnswerMid > AnswerMid[1] then
	BEGIN
		Print(GetSymbolName, "買い戻し", TIME);
		BuyToCover ( !( "買い戻し" ) ) next bar at market;
	end;
end;	

if TIME >= 1125 and TIME < 1130 then
Begin
	if MarketPosition = 1 then
	BEGIN 
		Print(GetSymbolName, "指定時間売り抜け(午前)", TIME);
		Sell ( "指定時間売り抜け(午前)" ) next bar at market;
	end;
	if MarketPosition = -1 then
	BEGIN
		Print(GetSymbolName, "指定時間買い戻し(午前)", TIME);
		BuyToCover ( "指定時間買い戻し(午前)" ) next bar at market;
	end;
End;

if TIME >= 1455 then
Begin
	if MarketPosition = 1 then
	BEGIN 
		Print(GetSymbolName, "指定時間売り抜け(午後)", TIME);
		Sell ( "指定時間売り抜け(午後)" ) next bar at market;
	end;
	if MarketPosition = -1 then
	BEGIN
		Print(GetSymbolName, "指定時間買い戻し(午後)", TIME);
		BuyToCover ( "指定時間買い戻し(午後)" ) next bar at market;
	end;
End;

スキャルピングなのでチャート分析の足種設定を1ティックにします。
(それ以外の設定でも使えないこともないですが)

f:id:tsukinowaapp:20180704102940j:plain

例によって任天堂[7974]で前場一杯回してみますが...
f:id:tsukinowaapp:20180704113436p:plain
手数料考えたら駄目だこれ。

欠点が…

困ったことに欠点がいくつかあります。

バックテストができない

売り気配買い気配の情報はリアルタイムデータと言って
ログに残らない仕様になってます。
なので、過去のデータを使ったバックテストはできません。

手数料が高い

放置しておくと時間まで際限なく取引を行うので、
前場だけで取引100回とか)
手数料が半端ないことになります。
取引回数をカウントして規定回数以上は行わないようなロジックを追加した方が良いかもしれません。

一日信用導入されないかなー? :-)