見出し画像

配当

既存のインジケータ、配当利回りと一株配当金に、トレステ内にある実績(CR)データと予想(CE)データで計算して表示しているインジケータです
若干誤差があると思いますので、細かい正確な数値は決算短信や、IR情報、四季報等でご確認ください

※要注意!
現在、東証全件でのスキャンはトレステがクラッシュする不具合を確認しています!
アップデートで不具合が修正されるまで、業種や件数を絞った方法なら上手くいくかもしれませんが、なるべくスキャナーで使用しない方が無難です(°_°)
アップデートで修正され次第、この注意事項は削除します

@ - コピー

使用するトレステにあるデータ

・実績配当利回り=CR_Dividend_Yield
・予定配当利回り=CE_Dividend_Yield
・実績1株配当金=CR_DPS
・予定1株配当金=CE_DPS
・純資産=CR_Net_Asset
・配当性向=CR_Dividend_Payout_Ratio
・現金等=CR_Cash_or_Cash_Equivalents
・発行済株数=CAC_OUTS2

計算で求めるもの

・年間配当予定総額 = 発行済株数 × 予定1株配当金
・DOE = 年間配当予定総額  ÷ 純資産(株主資本)
 ※ DOE = 配当性向 × ROEでも可
・余力 = 現金等 ÷ 年間配当予定総額
 ※ 利益剰余金にあたるデータがないので現金等に置換え

プログラム

using tsdata.marketdata;
using elsystem;
using elsystem.collections;
inputs:
	int MonthsReported( 12 ) [DisplayName = "MonthsReported", ToolTip = "Enter the number of months in the reporting period for which data is desired.  Fundamental data usually covers a 3, 6 or 12 month period."],
	int ConsolidationLevel( 1 ) [DisplayName = "ConsolidationLevel", ToolTip = "Enter 1 if consolidated data is desired; enter any other value for non-consolidated data."],
	int AccountingStandard( 0 ) [DisplayName = "AccountingStandard", ToolTip = "Enter 1 for Japanese accounting standard; enter 2 for Securities and Exchange Commission (SEC) accounting standard; enter 3 for International Financial Reporting Standards (IFRS) accounting standard; enter 0 to use IFRS, SEC, or Japanese accounting standards, in that order, depending on which is available."];
variables:
	FundamentalQuotesProvider FQP( null ),
	Dictionary DataDict( null ),
	intrabarpersist bool OkayToPlotActual( false ),				//実績配当利回り
	intrabarpersist bool OkayToPlotForecast( false ),			//予定配当利回り
	intrabarpersist bool OkayToPlotActual2( false ),			//実績一株配当金
	intrabarpersist bool OkayToPlotForecast2( false ),			//予定一株配当金
	intrabarpersist bool OkayToPlotNetAssets( false ),			//純資産
	intrabarpersist bool OkayToPlotPayoutRatio( false ),		//配当性向
	intrabarpersist bool OkayToPlotCash( false ),				//現金等
	intrabarpersist string ConsLevel( "Consolidated" ),			//連結/単独
	intrabarpersist string AcctStdInputString( "" ),			//会計基準
	bool QuoteFound( false ),									//値存在判断
	double CRDividendYield( 0 ),								//実績配当利回り
	double CEDividendYield( 0 ),								//予定配当利回り
	double CRDPS( 0 ),											//実績一株配当金
	double CEDPS( 0 ),											//予定一株配当金
	double CRNetAssets( 0 ),									//純資産
	double CRDividendPayoutRatio( 0 ),							//配当性向
	double CRCashOrCashEquivalents( 0 );						//現金等
constants:
	string MonthsReportedKey( "MonthsReported" ),				//期間
	string ConsolidatedKey( "ConsolidationLevel" ),				//連結/単独
	string AccountingKey( "AccountingStandard" ),				//会計基準
	string ActualFieldName( "CR_Dividend_Yield" ),				//実績配当利回り
	string ForecastFieldName( "CE_Dividend_Yield" ),			//予定配当利回り
	string ActualFieldName2( "CR_DPS" ),						//実績一株配当金
	string ForecastFieldName2( "CE_DPS" ),						//予定一株配当金
	string NetAssetsFieldName( "CR_Net_Asset" ),				//純資産
	string PayoutFieldName( "CR_Dividend_Payout_Ratio" ),		//配当性向
	string CashEqFieldName( "CR_Cash_or_Cash_Equivalents" ),	//現金等
	string ConsolidatedValue( "Consolidated" ),					//連結
	string NonConsolidatedValue( "NonConsolidated" ),			//単独
	string ValuesAdder( "_Values" ),							//辞書値アドレス
	string IFRSString( "IFRS" ),								//会計基準IFRS
	string SECString( "SEC" ),									//会計基準SEC
	string JSTDString( "JSTD" );								//会計基準JSTD
	
method void CreateFundamentalQuotesProvider()
begin
	FQP = new FundamentalQuotesProvider();
	FQP.Symbol = Symbol;
	FQP.Fields += ActualFieldName;
	FQP.Fields += ForecastFieldName;
	FQP.Fields += ActualFieldName2;
	FQP.Fields += ForecastFieldName2;
	FQP.Fields += NetAssetsFieldName;
	FQP.Fields += PayoutFieldName;
	FQP.Fields += CashEqFieldName;
	FQP.Realtime = false;
	FQP.TimeZone = tsdata.common.TimeZone.local;
	FQP.LoadProvider();
	Value99 = FQP.Count; { force provider to load }
end;{ FundamentalQuotesProvider method }
method bool GetQuoteAsOfDate( string FieldName, DateTime tempdt, int PeriodsAgo, out double QuoteVal )
variables:  
	int Counter,
	bool QuoteFound, bool SetVariable,
	DateTime VectDateTime,
	Vector QuoteDateTimeVector, Vector QuoteValuesVector;
begin
	if FieldName = "" or tempdt = null or DataDict = null or PeriodsAgo < 0 then return false;
		QuoteDateTimeVector = DataDict[FieldName] astype Vector;
		QuoteValuesVector = DataDict[FieldName + ValuesAdder] astype Vector;
		QuoteFound = false;
		SetVariable = false;
	for Counter = QuoteDateTimeVector.Count - 1 downto 0 begin
		SetVariable = false;
		VectDateTime = QuoteDateTimeVector[Counter] astype DateTime;
		if tempdt >= VectDateTime then begin { quote date is before date passed in }
			SetVariable = true;
		end else begin
			break;
		end;
		if SetVariable then begin
			if Counter + PeriodsAgo <= QuoteDateTimeVector.Count - 1 then begin			
				QuoteVal = QuoteValuesVector[Counter + PeriodsAgo] astype double;
				QuoteFound = true;
			end;
		end;
	end;{ for }
	return QuoteFound;
end;{ GetQuoteAsOfDate method }
method bool GetQuoteAsOfDate2( FundamentalQuote fq, DateTime tempdt, out double QuoteVal )
variables:  
	int Counter,
	bool QuoteFound, bool SetVariable,
	string AcctStd, string LastUsedAcctStd, 
	DateTime LastDateTime, DateTime fqDateTime;
begin
	if fq = null or tempdt = null then return false;
	QuoteFound = false;
	LastDateTime = DateTime.Create( 1900, 1, 1 );
	SetVariable = false;	
	for Counter = fq.Count - 1 downto 0 begin
		SetVariable = false;
		AcctStd = fq.ExtendedProperties[Counter][AccountingKey].StringValue;
		if fq.ExtendedProperties[Counter][MonthsReportedKey].IntegerValue = MonthsReported
			and fq.ExtendedProperties[Counter][ConsolidatedKey].StringValue	= ConsLevel
			and ( AccountingStandard = 0 or AcctStd = AcctStdInputString ) then begin
			fqDateTime = fq.PostDate[Counter];
			if tempdt >= fqDateTime and fqDateTime >= LastDateTime then begin
				if fqDateTime <> LastDateTime then begin { new PostDate }
					SetVariable = true;
				end else if AccountingStandard = 0 then begin { use hierarchy }
					if AcctStd = IFRSString then begin
						SetVariable = true;
					end else if AcctStd = SECString and LastUsedAcctStd <> IFRSString then begin
						SetVariable = true;
					end else if AcctStd = JSTDString 
						and LastUsedAcctStd <> IFRSString 
						and LastUsedAcctStd <> SECString then begin
						SetVariable = true;
					end;			
				end;
			end;		
		end;			
		if SetVariable then begin
			QuoteVal = fq.DoubleValue[Counter];
			LastUsedAcctStd = AcctStd;
			LastDateTime = fqDateTime;
			QuoteFound = true;
		end;	
	end;{ for }
	return QuoteFound;
end;{ GetQuoteAsOfDate2 method }
method void LoadFundDataVectors( string ifundField )
variables:  
	int Counter, Vector dateVect, Vector valuesVect, FundamentalQuote fq,
	string fqAcctStd, string LastAcctStd,
	bool LoadThisQuote, bool ReplaceLastValue, bool NumMonthsOkay, bool ConsLevelOkay,
	DateTime LastDateTime;
begin
	if DataDict = null then DataDict = new Dictionary();
	dateVect = new Vector();
	valuesVect = new Vector();
	DataDict.Add( ifundField, dateVect astype Vector );
	DataDict.Add( ifundField + ValuesAdder, valuesVect astype Vector );
	fq = FQP[ifundField];
	LastDateTime = DateTime.Create( 1900, 1, 1 );
	for Counter = 0 to fq.Count - 1 begin
		LoadThisQuote = false;
		ReplaceLastValue = false;
		fqAcctStd = fq.ExtendedProperties[Counter][AccountingKey].StringValue;
		NumMonthsOkay = fq.ExtendedProperties[Counter][MonthsReportedKey].IntegerValue = MonthsReported;
		ConsLevelOkay = fq.ExtendedProperties[Counter][ConsolidatedKey].StringValue = ConsLevel;
		if NumMonthsOkay and ConsLevelOkay and ( AccountingStandard = 0 or fqAcctStd = AcctStdInputString ) then begin	
			if fq.PostDate[Counter] <> LastDateTime then begin { new date }
				LoadThisQuote = true;
			end else begin { same date as last quote loaded }
				switch ( fqAcctStd ) begin
					case IFRSString:
						ReplaceLastValue = true;
					case SECString:
						if LastAcctStd <> IFRSString then ReplaceLastValue = true;
					case JSTDString:
						if LastAcctStd <> IFRSString and LastAcctStd <> SECString then ReplaceLastValue = true;
				end;
			end;
		end;
		if LoadThisQuote then begin
			dateVect.push_back( fq.PostDate[Counter] astype DateTime );
			valuesVect.push_back( fq.DoubleValue[Counter] astype double );
			LastAcctStd = fqAcctStd;
			LastDateTime = fq.PostDate[Counter];
		end else if ReplaceLastValue then begin
			valuesVect[Counter-1] = fq.DoubleValue[Counter] astype double;
			LastAcctStd = fqAcctStd;
		end;
	end;{ for }
end;{ LoadFundDataVectors method }
method bool DataHasPostDate( FundamentalQuote fq )
variables:  int Counter, DateTime MissingDT, int NumMissingDates;
begin
	NumMissingDates = 0;
	MissingDT = DateTime.Create( 1999, 11, 30 );
	for Counter = 0 to fq.Count - 1 begin
		if fq.PostDate[Counter] = MissingDT then
			NumMissingDates += 1;
	end;
	return NumMissingDates <> fq.Count;
end;{ DataHasPostDate method }
method string GetAcctStdString()
variables:  string AcctStdString;
begin
	switch ( AccountingStandard ) begin
		case 1: { JSTD } AcctStdString = JSTDString;
		case 2: { SEC } AcctStdString = SECString;
		case 3: { IFRS } AcctStdString = IFRSString;
	end;
	return AcctStdString;
end;{ GetAcctStdString method }
once begin
	if ConsolidationLevel = 1 then ConsLevel = ConsolidatedValue
	else ConsLevel = NonConsolidatedValue;
	AcctStdInputString = GetAcctStdString();
	CreateFundamentalQuotesProvider();
	if FQP.HasQuoteData( ActualFieldName ) then begin
		 OkayToPlotActual = true;
		 LoadFundDataVectors( ActualFieldName );
	end;
	if FQP.HasQuoteData( ForecastFieldName ) then begin
		OkayToPlotForecast = true;
		LoadFundDataVectors( ForecastFieldName );
	end;
	OkayToPlotActual = FQP.HasQuoteData( ActualFieldName )
	 and DataHasPostDate( FQP[ActualFieldName] );
	OkayToPlotForecast = FQP.HasQuoteData( ForecastFieldName )
	 and DataHasPostDate( FQP[ForecastFieldName] );
	OkayToPlotActual2 = FQP.HasQuoteData( ActualFieldName2 )
	 and DataHasPostDate( FQP[ActualFieldName2] );
	OkayToPlotForecast2 = FQP.HasQuoteData( ForecastFieldName2 )
	 and DataHasPostDate( FQP[ForecastFieldName2] );
	OkayToPlotNetAssets = FQP.HasQuoteData( NetAssetsFieldName )
	 and DataHasPostDate( FQP[NetAssetsFieldName] );
	OkayToPlotPayoutRatio = FQP.HasQuoteData( PayoutFieldName )
	 and DataHasPostDate( FQP[PayoutFieldName] );
	OkayToPlotCash = FQP.HasQuoteData( CashEqFieldName )
	 and DataHasPostDate( FQP[CashEqFieldName] );
end;{ once }
if OkayToPlotActual and GetQuoteAsOfDate( ActualFieldName, BarDateTime, 0, CRDividendYield ) then
	Plot1( CRDividendYield, !( "実利回%" ) );
if OkayToPlotForecast and GetQuoteAsOfDate( ForecastFieldName, BarDateTime, 0, CEDividendYield ) then
	Plot2( CEDividendYield, !( "予利回%" ) );
	
if OkayToPlotActual2 and GetQuoteAsOfDate2( FQP[ActualFieldName2], BarDateTime, CRDPS ) then
	Plot3( CRDPS, !( "実DPS" ) );
if OkayToPlotForecast2 and GetQuoteAsOfDate2( FQP[ForecastFieldName2], BarDateTime, CEDPS ) then
	Plot4( CEDPS, !( "予DPS" ) );
if OkayToPlotNetAssets and GetQuoteAsOfDate2( FQP[NetAssetsFieldName], BarDateTime, CRNetAssets ) then begin
	Value1 = CRNetAssets;																	// 純資産(株主資本)
	Value2 = GetFundData( "CAC_OUTS2", 0 );													// NOMURA 400 タイプの株式発行高数(発行済株数)
	Value3 = ( Value2 * CEDPS );															// 年間配当予定総額
	if Value1 <> 0 then Plot5(( Value3 / ( Value1 * 1000000 )*100 ), !( "DOE" ));			// DOE(Dividend on equity ratio)(株主資本配当率)(年間配当総額/(株主資本×100万円)*100end;																						// DOE = 年間配当予定総額 ÷ 株主資本 = 配当性向 × ROE
if OkayToPlotPayoutRatio and GetQuoteAsOfDate2( FQP[PayoutFieldName], BarDateTime, CRDividendPayoutRatio ) then
	Plot6( CRDividendPayoutRatio, !( "性向" ) );
if OkayToPlotCash and GetQuoteAsOfDate2( FQP[CashEqFieldName], BarDateTime, CRCashOrCashEquivalents ) then begin
	if Value3 <> 0 then Plot7(( CRCashOrCashEquivalents * 1000000 / Value3 ), !( "余力" ));	// 利益剰余金 ÷ 配当予定総額(予定配当金×発行済み株数) = 配当余力
end;																						// 現金等(利益剰余金と仮定)
Plot8( CRCashOrCashEquivalents, !( "現金等" ) );												// 現金等
Plot9( Value3 / 1000000 , !( "配当総額" ));													// 年間配当予定総額 ÷ 100万円

サポートされると喜んでアイスを買っちゃいます!٩(๑❛ᴗ❛๑)۶