EasyLanguage研究所

マネックス証券が提供する株式トレード&分析ツール「トレードステーション」専用のプログラミング言語、EasyLanguageについて。特にオブジェクト指向型EasyLanguage(OOEL)の情報を中心に。

レーダースクリーンに各銘柄の保有ポジション状況(取得価格、株数、未実現損益など)を表示させる方法

久々に、投稿。

レーダースクリーン上に、銘柄ごとの保有ポジション状況(「取得価格」「株数」「損益(P/L)」など)を表示させる、EasyLanguageコードを書いてみました。インジケーターとして作成しております。

表示する内容は、トレーディングアプリ『トレードマネージャー』の「ポジション」タブで表示されるものと同じようなものになります。以下、同じ時間にそれぞれを表示させた時の様子です。

(トレードマネージャーの「ポジション」タブ)
f:id:eltraders:20170907152021p:plain

(今回作成したレーダースクリーンの列)
f:id:eltraders:20170907152024p:plain

レーダースクリーンの列として追加できるので、自作の売買サインなどをレーダースクリーンに表示させている方は、その隣りの列に追加することで、銘柄ごとの損益などがすぐに確認できたりして便利かと思います。

具体的な実装としては、オブジェクト指向EasyLanguageのPositionsProviderクラスを使用することで、指定した銘柄の保有ポジション情報を取得しています。取得できる情報はいくつかあるのですが、とりあえずよく使いそうなものに絞って表示させています。順番入れ替えや削除はお好みでどうぞ。

また、レーダースクリーン側で必要な表示スタイルの設定と、PositionsProviderで取得する情報のちょっとしたクセについて、コードの後で解説します。

Easylanguageコード

using elsystem;
using tsdata.trading;

Vars:
    PositionsProvider oPP(NULL);
	
method void AnalysisTechnique_Initialized( elsystem.Object sender, elsystem.InitializedEventArgs args ) 
begin
    Try
        oPP = PositionsProvider.Create();
        oPP.Updated += PositionsProvider_Updated;
        oPP.Symbols.Add( Symbol );
        oPP.Load = true;
		
    Catch (Exception ex)
        Print( "Error: ", "	",  string.format("{0} | {1}[StackTrace]{2}", "	",  ex.Source, ex.Message, ex.StackTrace) );
    End;
end;

method void PositionsProvider_Updated( elsystem.Object sender, tsdata.trading.PositionUpdatedEventArgs args ) 
vars:
    int ColumnCount;
	
begin
    Try
        If oPP.Count > 0 then Begin
            
            If oPP.Position[0].Type = PositionType.LongPosition then Begin
                Plot1( "買い", "ポジション" );
                Plot8( oPP.Position[0].PercentPL/100, "損益率" );
            End Else If oPP.Position[0].Type = PositionType.ShortPosition then Begin
                Plot1( "新規売り", "ポジション" );
                Plot8( -1 * oPP.Position[0].PercentPL/100, "損益率" );
            End Else Begin
                NoPlot(1);
                NoPlot(8);
            End;
            Plot2( AbsValue(oPP.Position[0].Quantity), "株数" );
            Plot3( oPP.Position[0].AveragePrice, "取得価格" );
            Plot4( oPP.Position[0].TotalCost, "取得金額" );	
            Plot5( Close, "現在価格" );
            Plot6( AbsValue(oPP.Position[0].MarketValue), "現在金額" );
            Plot7( oPP.Position[0].OpenPL, "損益" );
            Plot9( oPP.Position[0].PLPerQuantity, "1株あたり損益" );
            
        End Else Begin
            
            For ColumnCount = 1 to 9 Begin
                NoPlot( ColumnCount );
            End;
        	
        End;
        
    Catch (Exception ex)
        Print( "Error: ", "	",  string.format("{0} | {1}[StackTrace]{2}", "	",  ex.Source, ex.Message, ex.StackTrace) );
    End;
end;

解説

事前設定について

今回はPositionsProviderオブジェクトをコード上で生成しておりますので、AnalysisTechnique_Initializedイベントのみ「プロパティ」からAnalysisTechniqueのInitializedイベントに設定してください。

f:id:eltraders:20170907150856p:plain

また、レーダースクリーンに挿入した後、本記事の「各列について」にある「表示スタイル」をそれぞれの列で設定してください。

処理の流れ

レーダースクリーンの各行が更新されるたびに、PositionsProvider_Updated が呼び出されます。

そして、その行の銘柄がポジションを保有している場合のみ、PositionsProviderからの情報を表示します。

各列について

「表示スタイル」は、レーダースクリーン側の「分析テクニックの設定」->「スタイル」タブで設定する内容です。

【列1】ポジション

[ 表示スタイル:銘柄コードと同じ ]
ポジションの方向。oPP.Position[0].Type が PositionType.LongPosition の時は買いポジション保有、PositionType.ShortPosition の時は売りポジション保有になるので、それに合わせて「買い」または「新規売り」を文字表示させています。

【列2】株数

[ 表示スタイル:数字(小数0桁) ]
保有株数です。なぜか新規売りの時はマイナス値として取得されるので、AbsValue関数で絶対値を表示させています。

【列3】取得価格

[ 表示スタイル:通貨(小数1桁) ]
保有ポジションを取得した時の平均価格です。

【列4】取得金額

[ 表示スタイル:通貨(小数0桁) ]
保有ポジションを取得した時の合計金額です。【列2:株数】x【列3:取得価格】になるはず。

【列5】現在価格

[ 表示スタイル:通貨(小数0桁) ]
現在の価格です。単純に現在の終値を表示させています。

【列6】現在金額

[ 表示スタイル:通貨(小数0桁) ]
保有ポジションの現在における合計金額です。【列2:株数】x【列5:現在価格】になるはず。これも新規売りの時はマイナス値として取得されるので、AbsValue関数で絶対値を表示させています。

【列7】損益

[ 表示スタイル:通貨(小数0桁) ]
現在価格を元にしたリアルタイム損益金額です。【列6:現在金額】と【列4:取得金額】との差額になるはず。

【列8】損益率

[ 表示スタイル:パーセント(小数2桁) ]
取得金額に対する損益の比率。【列7:損益】÷【列4:取得金額】で計算されます。

損益率については2点補足があるのですが、1つは新規売りの時マイナス値になる点です。トレードマネージャーではマイナスのまま表示されていますが、今回のコードでは新規売りでも利益が出ていればプラスで表示されるようにしてみました。

またもう1点は、取得値の単位が「%」である点です。例えば oPP.Position[0].PercentPL が 2.23 という値だった場合、これは「2.23%」という意味になります。ただ今回はレーダースクリーン側の「パーセント表記」スタイルで%をつけて表示させたかったため、oPP.Position[0].PercentPLの結果を100で割ることで、割合の小数として取得しています。(レーダースクリーンの「パーセント表記」は、表示対象の数値を100倍して%をつける、というスタイル設定のため、PercentPLの値そのままでパーセント表記すると、223%などというトンデモナイ表示になってしまいます)

【列9】1株あたり損益

[ 表示スタイル:通貨(小数2桁) ]
保有株数1株あたりの損益です。【列7:損益】÷【列2:株数】になります。

まとめ

レーダースクリーンの分析テクニックはいくつでも横に追加でいるので、他の分析テクニックと合わせて使うことで、より運用しやすいレーダースクリーンが作成できます。

あまり列を増やしたくないという方は、たとえば「株数」「取得価格」「損益」だけ表示させてみる、というのもアリだと思います。

ぜひ色々試してみてください。

銘柄を変えただけで、チャートに適用している分析テクニックやストラテジーのパラメータも自動変更する方法

今回は、EasyLanguage全般に関する小ネタです。(小ネタといいつつ、結構使えると思います)

ストラテジーのバックテストで、複数の銘柄ごとに最適なパラメータを得られたけれど、以下のような悩みをお持ちの方、必見。

・チャートで銘柄を変えるごとにストラテジーのパラメータ値を変えなきゃいけないのが面倒
・ストラテジーとセットで使う分析テクニックのパラメータ値も手動で合わせなきゃいけないのが面倒

通常は、ストラテジーに入力パラメータを設定

例えば移動平均線を利用した分析テクニックやストラテジーを自作する場合、計算足数などのパラメータはInputsで入力パラメータ化する事が多いと思います。

Inputs:
    inLength(5);

Vars:
    varAvg(0);

varAvg = AverageFC( Close, inLength );
Plot1( varAvg, "移動平均線" );

基本的にはこれで良いのですが、バックテストで銘柄コードごとにinLengthの最適値が得られているなら、If記述を活用する事により、手作業で入力パラメータを設定しなくてもEasyLanguage上で現在適用中の銘柄を自動判断し、対応するパラメータを使ってくれます。

例えば、以下のように銘柄ごとの「移動平均線の計算足数」が決まっている場合・・

銘柄コード Length
1111-TS 5
2222-TS 14
3333-TS 99
(その他) 20

Symbolで現在適用されている銘柄コードを取得できるので、以下のようなEasyLanguageになります。

Vars:
    varLength(0),
    varAvg(0);

If Symbol = "1111-TS" then
    varLength = 5
Else If Symbol = "2222-TS" then
    varLength = 14
Else If Symbol = "3333-TS" then
    varLength = 99
Else
    varLength = 20;

varAvg = AverageFC( Close, varLength );
Plot1( varAvg, "移動平均線" );

こちらで書くメリットは、自作した分析テクニックやストラテジーを、どの銘柄でも、手作業による設定不要で、使える点です。

例えば、「1111-TS」の日足チャートにこの分析テクニックを適用すると、5日移動平均線が描画されますが、その状態で銘柄コードを「2222-TS」に変更すると、移動平均線が14日に自動で変更されるというわけです。

さらに、レーダースクリーンとチャートをカスタムシンボルリンクで繋げておけば、銘柄コードをクリックするごとに、最適化されたパラメータの分析テクニック&ストラテジーを適用したチャートが表示される・・といった事もできます。

色々と応用が利くので、ぜひ試してみてください。

口座の残高や買付可能額を取得できるAccountsProviderクラスについて

オブジェクト指向EasyLanguageで利用可能なAccountsProviderクラスを使うと、口座の情報を取得できます。

具体的には、トレードステーションに初期搭載されている「トレードマネージャー」の「口座状況」タブで確認できる情報が中心、といえば分かりやすいと思います。

以下、AccountsProviderクラスを使って取得できる情報をPrint出力してみた結果です。(Updateされるごとに出力しているので見辛いかもしれませんが・・)

using elsystem;
using tsdata.trading;

Vars:
	AccountsProvider oAP(NULL);
	
method void AnalysisTechnique_Initialized( elsystem.Object sender, elsystem.InitializedEventArgs args ) 
begin
	Try
		oAP = AccountsProvider.Create();
		oAP.Updated += AccountsProvider_Updated;
		oAP.Load = true;
		
	Catch (Exception ex)
		Print( "Error: ", "	",  string.format("{0} | {1}[StackTrace]{2}", "	",  ex.Source, ex.Message, ex.StackTrace) );
	End;
end;

method void AccountsProvider_Updated(  elsystem.Object sender, tsdata.trading.AccountUpdatedEventArgs args ) 
vars:
	Account oAccount;
	
begin
	Try

		oAccount = oAP.Account[0];
		
		ClearPrintLog();
		
		Print("=======================");
		Print("口座情報");
		Print("=======================");
		Print("口座ID", "	", oAccount.AccountID);
		Print("口座名", "	",  oAccount.Name);
		Print("口座ステータス", "	",  oAccount.Status);
		Print("口座タイプ", "	",  oAccount.Type.ToString());
		Print();
		Print("=======================");
		Print("営業日開始時点");
		Print("=======================");
		Print("現金残高", "	",  oAccount.BDCashBalance);
		Print("未実現損益", "	",  oAccount.BDUnrealizedPL);
		Print("有効証拠金", "	",   oAccount.BDAccountEquity);
		Print("純資産額", "	",  oAccount.BDAccountNetWorth);
		Print("デイトレード 取引限度額", "	",  oAccount.BDDayTradingBuyingPower);
		Print("オプション取引限度額", "	",  oAccount.BDOptionBuyingPower);
		Print("オプション清算額", "	",  oAccount.BDOptionLiquidationValue);
 		Print("オーバーナイト買付可能額", "	",  oAccount.BDOvernightBuyingPower);
 		Print();
		Print("=======================");
 		Print("リアルタイム");
		Print("=======================");
		Print("口座エクイティ", "	",  oAccount.RTAccountEquity);
		Print("純資産額", "	",  oAccount.RTAccountNetWorth);
		Print("現金残高", "	",  oAccount.RTCashBalance);
		Print("約定金額合計 (保有分) ", "	",  oAccount.RTCostOfPositions);
		Print("デイトレード取引限度額", "	",  oAccount.RTDayTradingBuyingPower);
		Print("リアルタイム必要証拠金", "	",  oAccount.RTInitialMargin);
		Print("最低必要保証金額", "	",  oAccount.RTMaintenanceMargin);
		Print("オプション買付可能額", "	",  oAccount.RTOptionBuyingPower);
		Print("オプション清算価値", "	",  oAccount.RTOptionLiquidationValue);
		Print("オーバーナイト買付可能額", "	",  oAccount.RTOvernightBuyingPower);
		Print("買付可能額", "	",  oAccount.RTPurchasingPower);
		Print("実現損益", "	",  oAccount.RTRealizedPL);
		Print("未実現損益", "	",  oAccount.RTUnrealizedPL);
		Print();
		Print("=======================");
		Print("その他");
		Print("=======================");
		Print("今日のリアルタイム取引エクイティ", "	",  oAccount.TodaysRTTradeEquity);
		Print("入金予定額", "	",  oAccount.UnclearedDeposits);
		Print("未受渡金", "	",  oAccount.UnsettledFund);
		Print("口座でデイトレードが許可されるか?", "	",  oAccount.CanDayTrade);
		Print("トレーダーがパターンデイトレーダーか?", "	",  oAccount.IsDayTrader);
		Print("オプショントレード許可レベル", "	",  oAccount.OptionsApprovalLevel);
		Print("過去4日間の取引数", "	",  oAccount.FourDaysTradeCount);
		
	Catch (Exception ex)
		Print( "Error: ", "	",  string.format("{0} | {1}[StackTrace]{2}", "	",  ex.Source, ex.Message, ex.StackTrace) );
	End;
End;

リアルタイムの資金残高や買付可能額が取得できるのが使えそうなポイントかなと思います。

AccountsProviderクラスは、オブジェクトさえ用意してあげれば通常のストラテジー用EasyLanguageでも使う事ができるので、例えば資金管理も考慮に入れたストラテジー開発がしたい場合などに活用できそうです。

気になる方は、ぜひ使ってみてください。