So-net無料ブログ作成
検索選択

標準インジケーターの解析 [ファンダメンタル]

前々回に本決算のデータはヘルプの情報だけでは取得できないと書きました。
どうしても取得したいあるいは何個かの標準インジケーターを1つにまとめたいならば、実際に取得している標準インジケーターを解析する必要があります。
ただし、標準のインジケーターは著作権を主張しているため、個人の環境での利用改変は問題ないとしても、マネックスからの承諾がなければこれを引用改変したコードをブログ等で公表はすべきではないと現時点で考えています。


今回は具体的なコードを書かないのでわかりにくいと思いますが、標準インジケーターで本決算をどう判断しているかを、「売上高」のインジケーターを例に解析してみます。

売上高には、「入力」として1.期間 2.連結/単独 3.会計基準 と3つのパラメーター変更が可能です。
スクリーンショット 2017-01-22 10.58.22.png
期間は12か月と想像できるものの、残りの2つは何の数値を入力するのかわかりにくいです。

そこで、ヘルプを確認します。
本体のヘルプから「分析テクニック&ストラテジー」「インジケーター」を展開して、「売上高」のヘルプは見ておいてください。
わからないことがあれば、まずヘルプです!

ただし、ヘルプには「売上高」のパラメーターに関しては情報は書かれていません。
面白いことに、プロット3でコンセンサスが取得できると書いてあります。
これは、コードを見ればわかりますがPlot3はないので誤記(将来実装?)です。
ただ、実績、予想、コンセンサスに対応するフィールド名が書いてあり助かります。

それでは、パラメーターはどう指定するのか、プログラムの流れはどうなっているのかをコードを表示してみていきます。
スクリーンショット 2017-01-22 10.41.16.png
分析テクニックの設定ダイアログで、左の選択可能一覧で「売上高」を選択して「EasyLanguageを編集」をクリックするとコードが表示されます。
ファイル名は「Sales Jp」でプロパティは右クリックで確認できます。


まず、「inputs:」を見ると入力定数が宣言されています。
1. 「MonthsReported」は、3,6,12のいずれかを入力
2. 「ConsolidationLevel」は「1」以外が非連結
3. 「AccountingStandard」は、1:日本株スタンダード、2:SEC、3:IFRS(違い重要?)
ということがわかりました。

次に、「variables:」で変数「constants:」定数と宣言が続いています。
関数4つ
1. method void CreateFundamentalQuotesProvider()
2. method bool DataHasPostDate( FundamentalQuote fq )
3. method string GetAcctStdString()
4. method bool GetQuoteAsOfDate( FundamentalQuote fq, DateTime tempdt, out double QuoteVal )
Once ブロック
最後に、Plot1とPlot2でデータを表示しているようです。


実行される流れは、関数は飛ばしてOnceブロックを処理していきます。
Onceブロック
1. 入力2の「ConsolidationLevel」に応じて、変数「ConsLevel」に"Consolidated"または"NonConsolidated"を代入しています。
2. 関数3を実行して、入力3の数値に応じて文字列「AcctStdInputString」に代入。
3. 関数1を実行してFundamentalQuotesProviderの初期化
  • Fieldsの追加addでなくともカンマなしに追加できるようだ
  • LoadProvider()でもよい
  • Updatedイベント使わなくても、FQP.Countでデータが取得されるようだ
    (Value1-99は定義済み変数 ヘルプーEasyLanguage予約語&関数ーEasyLanguageについてーEasyLanguage構文ー変数を参照)

4. 関数2を実行してActualFieldName("CR_SALES")に対して、HasQuoteDataでデータ取得できるか及び関数2で発表日が取得できるかチェック。 取得可能であれば、「OkayToPlotActual」をtrueに設定。
5. ForecastFieldName("CE_SALES")についても、4同様にチェック。取得可能であれば、「OkayToPlotForecast」をtrueに設定。



Onceブロック外
1. 上記ブロック4がtrueで、関数4を実行してtrueが帰ってきたら、Plot1
2. 1と同様にして予想のPlot


関数4が肝のようです。
関数4 method bool GetQuoteAsOfDate( FundamentalQuote fq, DateTime tempdt, out double QuoteVal )
の内容をみていきます。

この関数の第一パラメータは「FundamentalQuote 」で、FundamentalQuotestProviderのインスタンス(ここではFQP).Quote[""]で取得されます(コードではFQP[""]で取得しています)。

第2パラメーターは日付で、このコードでは「BarDateTime」を代入しています。
これは、現在のバーの日付のようです(ヘルプ確認)。
確認のため、1銘柄だけ登録したレーダースクリーンに、

Plot1(BarDateTime.ToString());
print(Symbol, BarDateTime.ToString());

を挿入して印刷ログで確認してください。
6758-TS 2017/01/20 15:01:00

とだけ表示されるので、Onceがなくてもレーダースクリーンでは直近終値足の日時が取得されるようです。
ザラ場は自分で確認してください。

第3パラメーターはダブルの数値変数ですが、先頭に「out」が付いています。
わからない場合は、ヘルプを検索してください。
ただ、outではHitしないかもしれません。
見つからなければ、methodで検索してください。
候補の6番目にOutが出てきました。


関数の内部コードをみていきます。

第1パラメーターと第2パラメーターがnullであればfalseを返して終了。

LastDateTimeに1900/1/1を設定

第1パラメータの「FundamentalQuote 」を逆順にループ。
*前回記事までのコードでわかると思いますが、「FundamentalQuote 」には最新の発表日を0として、過去に遡ってデータが存在しています。
したがって、逆順ループでは最も古いデータから順番に読み込む動作をしています。
**大から小への逆順でforループを使う場合は「to」ではなく「downto」で使うことがわかります。

ループの中をみていきます。

「SetVariable」にfalseを代入して初期化しているようです。
ちょっとズルして先の方を見てみます。
if SetVariable then ブロックがforループの最後に書かれています。
これを見ると、「SetVariable」がtrueになるたびに、methodの第3参照パラメーター「QuoteVal」が上書きされているようです。(trueの最終発表日のデータに変更される)

ループの最初に戻って、「SetVariable」がtrueに設定される条件をみていきます。

第1パラメータの「FundamentalQuote 」インスタンスfpから.ExtendedPropertiesでプロパティに文字列定数「AccountingKey("AccountingStandard")」を設定して、これから文字列データを取得して「AcctStd」に代入しています。
AccountingStandardは定数と変数から推測して、決算方法のプロパティ名と考えられます。
「FundamentalQuote」のヘルプには、「ExtendedProperties」というプロパティは記載されていませんが、 (FundamentalQuote 」インスタンス).ExtendedProperties[counter].StringValueで決算方法が取得できそうです。
さらに、直後のifブロックでも、
ExtendedPropertiesに「[MonthsReportedKey("MonthsReported")」を設定して決算期間と比較、及び「ConsolidatedKey("ConsolidationLevel")」を設定してConsLevel( "Consolidated" or "NonConsolidated" )と比較するために、ExtendedPropertiesを使用しています。

これから、決算期間、連結非連結、決算方法はExtendedPropertiesにそれぞれ、"MonthsReported"、"ConsolidationLevel"、"AccountingStandard"を代入して、IntegerValue、StringValue、StringValueで取得できることがわかりました。

この部分のifブロックの条件は、決算期間を入力値と比較、連結非連結を入力値と比較、決算基準が標準(0)または入力値と比較している」ということだと思います。

さらにこのブロックの内部で、発表日がラストバーの日付以前で「LastDateTime」よりも大きい時に「SetVariable」をtrueにしています。
ただし、前回と発表日が同じ場合には決算基準を調べて判定しているようですが、ここら辺は会計基準の違いを理解していないのでよくわかりません。


非常に分かりづらい説明だったとは思いますが、面倒になってきたのでこれで終了です。
自分は興味ありませんが、コンセンサス予想も標準インジケータをちょっと変更すると取得できると思います。


業績関係の記事もこれで終了と考えています。


最後に、前回の記事ではあまりにも古い決算日が出ていることがあったので、変更したものを追加しておきます。
Updatedイベントの部分を書き換えてみてください。

method void Fundamental_Updated( elsystem.Object sender, tsdata.marketdata.FundamentalQuoteUpdatedEventArgs args ) 
Vars: double sales, double psr, double zika, int counter
	, DateTime dd
	, int d1		//DateTimeはnullcheck必要なのでeldateに変換する
	, int counter2
	, int d0, double sales0	//psrが0の場合過去データを検索するので見つからなかったときのために最初を保管
	;
begin
	If fundamental.HasQuoteData(0) and fundamental.HasQuoteData(1) then	//0:予想売上
	Begin
		For counter = 0 to fundamental.Quote[0].Count -1 
		Begin
			sales = fundamental.Quote[0].DoubleValue[counter];
			If sales > 0 then
			Begin
				d1 = fundamental.Quote[0].PostDate[counter].ELDate;
				//売上予想と予想PSRの日付は一致する様だ
				//一致していなければ、売上予想>0 PSR = 0で表示されるので要チェック
				If fundamental.Quote[1].PostDate[counter].ELDate = d1 then
					psr = fundamental.Quote[1].DoubleValue[counter];	//1:PSR
				counter2 += 1;
				If psr > 0 or counter2 > 4  then
					Break;		//psr 0 の場合のみmax4回psr > 0 を過去検索
						// 今村証券3 6627テラプローブ4が必要
				If counter2 = 1 then 
				Begin		//psr=0で過去検索のためにcounter2が1になったら最初のデータのみ一時保存
					sales0 = sales;
					d0 = d1;
				End; 
			End;
		End;
		If psr = 0 then
		Begin	//4回過去検索してもpsr=0であれば、最初(最新)売上予想と発表日に戻す
			sales = sales0;
			d1 = d0;
		End;
	End;

		
	If d1 = 0 then
	Begin
		Plot5("予想なし?", "発表日", lightgray, GetBackgroundColor );
		//Noplot(1);
	End
	Else
	Begin
		dd = DateTime.Create(d1);
		If dd.Year < DateTime.Now.Year - 2 then
		Begin
			Plot5("予想なし?", "発表日", lightgray, GetBackgroundColor );
		End
		Else
		Begin
			Plot5(dd.ToString(), "発表日", white, GetBackgroundColor );
		//ReitはPSR 0の様だ
		zika = sales * psr;
		Switch(zika)
		Begin
		Case 0:
			Plot1( zika, "時価総額", DarkGray, GetBackgroundColor );
		Case is < 5000:
			Plot1( zika, "時価総額", Red, GetBackgroundColor );
		Case is < 10000:
			Plot1( zika, "時価総額", Yellow, GetBackgroundColor );
		Default:
			Plot1( zika, "時価総額", default, GetBackgroundColor );
		End;
		If zika > 0 then
			Plot4( zika / Close * 100, "株数(万)", default , GetBackgroundColor )
		else
			Plot4( zika / Close * 100, "株数(万)", DarkGray , GetBackgroundColor );
		Switch(psr)
		Begin
			Case 0 :
				Plot2(psr, "PSR(予)", DarkGray, GetBackgroundColor );
			Case is < 0.5:
				Plot2( psr, "PSR(予)", Red, GetBackgroundColor );
			Case is < 2.5:
				Plot2( psr, "PSR(予)", Yellow, GetBackgroundColor );
			Default:
				Plot2( psr, "PSR(予)", Default, GetBackgroundColor );
		End;

		If sales > 0 then
			Plot3(sales, "売上高(予)", white, GetBackgroundColor )
		else
			Plot3(sales, "売上高(予)", DarkGray, GetBackgroundColor );
		End;
	End;
		
End;


nice!(0)  コメント(0)  トラックバック(0) 
共通テーマ:

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。