TimeFrameから時間間隔をTimeSpan型で取得したい!
cAlgoのTimeFrameクラスって微妙に不便じゃないですか?例えば15分足だとしたらこの"15分"という数値を使いたいときがあるじゃないですか。
TimeFrameクラスでは"15Minute"という文字列を取得することはできますが、"15分"を数値で取得することはできません。TimeSpan型で取得できるメソッドがあれば便利なのに。
仕方ないので自分で作りましょう。方法は2つ。
方法1 Bar同士の間隔から計算する
もっとも単純お手軽な方法。Bar間のOpenTimeの差をとるだけです。ただしBarsの使えない場所(自作クラス内など)では使えません。あと月足のときに返ってくる数値は不定です。(28~31のどれか)
private TimeSpan GetTimeSpan() {
var span1 = Bars[1].OpenTime - Bars[0].OpenTime;
var span2 = Bars[2].OpenTime - Bars[1].OpenTime;
return (span1 < span2 ? span1 : span2);
}
Barsを使うため本体クラスのメソッドにしてあげましょう。
2通り計算して小さい方を返してるのは、万が一週末と週初めのBarを拾ってしまうと結果が誤ってしまうからです。ちなみにこの方法だと「3日足」は対応できません。(運悪く週末拾うと2日で返ってきてしまう)
それとPips足や練行足などの場合は使えない方法ですが、そもそも時間間隔を使用するようなcBotはこのような足を対象外としてると思いますので、特殊な足はOnStart内ではじいておきましょう。
if(TimeFrame > TimeFrame.Monthly || TimeFrame < TimeFrame.Minute) {
Print("この時間足には対応してません");
Stop();
}
TimeFrameの比較演算ではTick足は1分足以下、Range、Renko足は月足以上と判定されるため、このコードで特殊足を除外できます。(正式な仕様じゃないかもしれないのでちゃんとやりたいなら文字列で判断させてください。)
Indicatorの場合はStop()で止められない上、Printログも見えないので、Chart上にStaticTextでも表示してユーザーに知らせてあげると親切かもしれません。
方法2 TimeFrame.ToString()の文字列から解析
Barsを使わずTimeFrameのみから判断するなら文字列から解析しましょう。泥臭く見えますが、この方法の方が汎用的で確実だと思います。私はこんな風に自分で使うライブラリ内にTimeFrameクラスの拡張メソッドとして作っておいてます。
using System.Text.RegularExpressions;
public static class CAlgoExtendMethods {
///
/// Bar1本あたりの時間をTimeSpan型で返します。
/// 月足(Monthly)は31日間を返します。
/// 練行足など不定間隔のTimeFrameでは0を返します。
///
public static TimeSpan GetTimeSpan(this TimeFrame timeFrame) {
var tf = timeFrame.ToString();
int num;
if (!int.TryParse(Regex.Replace(timeFrame.ToString(), "[^0-9]", ""), out num)) num = 1;
if (tf.Contains("Minute")) {
return TimeSpan.FromMinutes(num);
} else if (tf.Contains("Hour")) {
return TimeSpan.FromHours(num);
} else if (tf.Contains("Day") || tf.Contains("Daily")) {
return TimeSpan.FromDays(num);
} else if (tf == "Weekly") {
return TimeSpan.FromDays(7);
} else if (tf == "Monthly") {
return TimeSpan.FromDays(31);
} else {
// ティック足 練行足 範囲足などその他
return TimeSpan.Zero;
}
}
}
単純に文字列を解析してBarの間隔を返してます。足の種類が少なければSwitchCaseで一つずつ処理してもいいんですが、cTraderは3分足とか7分足とか変な足がたくさんあるため、数字部分と文字列部分に分けて処理する方が楽です。
このように拡張メソッドとして作っておくと、TimeFrame.GetTimeSpan()で簡単に取得できます。たぶんこれで今のところ (cTrader v3.8) すべてのTimeFrameを網羅できているはずです。
コピペで使う場合は1行目のusingだけ冒頭に、その他はファイル一番下の}の上の行にでも貼り付けてください。pips足や連行足だった場合の処理は特定の値を返すなり、例外投げるなり、好きに変えてください。
お好きなほうをどうぞ
個人的には方法2をお勧めしますが、一時的に使うだけでちゃちゃっと書きたいなら方法1で十分かもしれません。どっちでもいいです。
よく使うなら切り出してライブラリ化しておく方がいいかもしれませんね。