cAlgo Tips & Sample cTrader Tools (cBot インジケーター)

【cTrader】LineAlert【Tools】

2021年2月22日

ラインに価格が触れてから考えたい

水平線やトレンドラインを使ってトレードしてる方にはわかってもらえると思うのですが、こう目安となるラインを引いたところで現在の価格がまったくラインにからまないと何もしようがなかったりしますよね。

とりあえずライン触れるまで待つんだ、話はそれからだ」と自分に言い聞かせてそっとチャートを閉じるわけです。

でも結局ライン触れたかどうか気になってちょくちょくチャートを見てしまったり、見るたびに「ラインからは遠いけど入れそうだな」とか邪念が湧いてきたり・・・ばかばかしいことこの上ない。

もうね、こんな無意味なこと考えなくてもすむように、ライン触れたら自動でお知らせしてほしいわけですよ。

 

LineAlert

というわけで、水平線やトレンドラインに触れたら音鳴らして教えてくれるインジケーターを作成しました。単純なインジケーターなのでソースコードも公開します。好きなようにカスタマイズして使ってください。

 

機能概要

チャート上のすべての線を見張って、どれかに価格がタッチしたら音を鳴らしてお知らせします。

どの音を鳴らすか、水平線とトレンドラインどっちかだけを対象にするか両方対象にするかも選べます。

即時Alertの場合はローソク足当たり1回しか音が鳴りません。次にローソク足更新するまでは複数回タッチしても、別のラインにタッチしても鳴りませんのでご注意ください。

 

パラメータ

TrendLine

トレンドラインをアラートの対象にするか指定します。

HorizontalLine

水平線をアラートの対象にするか指定します。

SoundFile

サウンドファイル名を指定します。ファイル名のみの場合はC:\Windows\Mediaを探します。それ以外の場合は必ずフルパスで指定してください。また.wavじゃない場合は必ず拡張子まで指定してください。

BarWait

ローソク足確定を待つか、タッチ後即アラート出すか指定します。Yesならローソク足確定を待ちます。

 

ダウンロード

(2021/3/12 修正済み 下記参照)

 

ソースコード

using System;
using System.Linq;
using System.Collections.Generic;
using cAlgo.API;

namespace cAlgo {
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class LineAlert : Indicator {
        [Parameter(DefaultValue = true)]
        public bool TrendLine { get; set; }
        [Parameter(DefaultValue = true)]
        public bool HorizontalLine { get; set; }
        [Parameter(DefaultValue = "Alarm01")]
        public string SoundFile { get; set; }
        [Parameter(DefaultValue = false)]
        public bool BarWait { get; set; }

        private List<double> _targets;
        private string _soundFile;
        private bool _isTouched;
        private double _exBid;
        private DateTime _exOpenTime;

        //---------
        // init
        protected override void Initialize() {
            //--- soundFileセット
            if (SoundFile.Contains("\\")) {
                _soundFile = SoundFile;
            } else {
                _soundFile = "C:\\Windows\\Media\\" + SoundFile;
            }
            if (!_soundFile.Contains(".")) {
                _soundFile += ".wav";
            }

            // 最初はこうしようと思ったが、AccessRights.FileSystemが必要っぽいのでやめた
            //if (!File.Exists(_soundFile)) {
            //    _soundFile = Environment.GetFolderPath(Environment.SpecialFolder.Windows) + "\\Media\\" + _soundFile;
            //    if (!File.Exists(_soundFile)) {
            //        Print(_soundFile + " is not found!");
            //        throw new FileNotFoundException();
            //    }
            //}

            // --- ターゲット設定、更新
            _exBid = Bid;
            _exOpenTime = new DateTime();
            _updateTarget();
            Chart.ObjectAdded += _ => _updateTarget();
            Chart.ObjectRemoved += _ => _updateTarget();
            Chart.ObjectUpdated += _ => _updateTarget();
        }

        //------------------------
        // update target
        private void _updateTarget() {
            _targets = new Listt<double>();
            if (HorizontalLine) {
                var hls = Chart.FindAllObjectst<ChartHorizontalLine>();
                _targets.AddRange(hls.Select(hl => hl.Y));
            }
            if (TrendLine) {
                var tls = Chart.FindAllObjectst<ChartTrendLine>();
                _targets.AddRange(tls.Select(tl => tl.CalculateY(Bars.Count - 1)));
            }
        }

        //-----------------------
        // Calculate でタッチ判定
        public override void Calculate(int index) {
            if (!IsLastBar) return;
            // OnBar
            if(_exOpenTime != Bars.LastBar.OpenTime) {
                _exOpenTime = Bars.LastBar.OpenTime;
                if (_isTouched) {
                    _isTouched = false;
                    if (BarWait) Notifications.PlaySound(_soundFile);
                }
            }
            // OnTick
            if (!_isTouched && _targets.Any(t => ((_exBid < t && t <= Bid) || (_exBid > t && t >= Bid)))) {
                _isTouched = true;
                if (!BarWait) {
                    Notifications.PlaySound(_soundFile);
                }
            }
            _exBid = Bid;
        }
    }
}

本当は最初にサウンドファイルの存在確認したほうがいいです。今回はAccessRights.FileSystemが必要っぽかったのであきらめました。

ポイントらしいポイントもないんですが、線の追加、更新、削除時に対応するため、Chart.Object~のイベントでターゲット更新を行うようにしておきます。チャートオブジェクトを使う場合はこの辺の処理を忘れないようにしましょう。

あとはCalculateでOnBar的な部分を作ってるところでしょうか。最後のローソク足のOpenTimeで確認してます。TickVolumeは値が飛ぶことがあるのであてになりません。確かMT4のEAでも同じでしたよね。if(TickVolume==1)とかしないようにご注意ください。

 

(2021/3/12追記)

たぶんバグあります

申し訳ありません、アップデート用にいじってて気づいたのですが、このコードだとトレンドラインのアラートがうまく機能しないと思います。OnBarでのターゲット更新処理が抜けてます

上記のダウンロードリンクは修正済みです。すでに自分用に手を加えている場合は下記のように1行追加してください。

        public override void Calculate(int index) {
            if (!IsLastBar) return;
            // OnBar
            if(_exOpenTime != Bars.LastBar.OpenTime) {
                _exOpenTime = Bars.LastBar.OpenTime;
                _updateTarget();//←この行追加
                if (_isTouched) {
                    _isTouched = false;
                    if (BarWait) Notifications.PlaySound(_soundFile);
                }
            }

 

(2021/3/2追記)

他のツールにも組み込んでみた

この前作ったMTFストキャスティクスでも音なるようにしてみました。

【cTrader】MTF対応ストキャスティクスとか【Tools】

MTF_Stochastics マルチタイムフレーム対応のストキャスティクスが見当たらないと聞いてちょっと作ってみました。 あまりMTF系インジケーターを使ったことないので、こんなんで実際使ってる方の ...

続きを見る

-cAlgo Tips & Sample, cTrader Tools (cBot インジケーター)

© 2021 cTrader's Life Powered by AFFINGER5