ข้ามไปที่เนื้อหา

วัตถุกราฟและการวาด

วัตถุกราฟ (การวาด) ช่วยให้สามารถวาดเส้นหรือรูปทรงเรขาคณิตบนกราฟ cTrader ได้ โดยการใช้วัตถุเหล่านี้ คุณสามารถวาดรูปแบบหรือแสดงเหตุการณ์บางอย่างบนกราฟตามข้อมูลของ cBot หรืออินดิเคเตอร์ของคุณได้

วัตถุกราฟใช้พิกัด X และ Y สำหรับการกำหนดตำแหน่ง

  • แกน X แทนเวลาหรือดัชนีแท่งเทียนของกราฟ
  • แกน Y คือราคาของสัญลักษณ์

วัตถุกราฟทั้งหมดสืบทอดมาจากคลาสพื้นฐาน ChartObject ซึ่งหมายความว่าวัตถุทั้งหมดจะสืบทอดคุณสมบัติพื้นฐานบางอย่าง

ตัวอย่างโค้ดของวัตถุกราฟ

การวาดภายในหน้าต่างอินดิเคเตอร์

เมื่อสร้างวัตถุกราฟ คุณไม่ได้จำกัดอยู่แค่กราฟสัญลักษณ์หลัก ที่จริงแล้ว คุณสามารถวาดวัตถุกราฟภายในหน้าต่างใดๆ ที่มีผลลัพธ์ของอินดิเคเตอร์ได้

คลาส Chart มีคอลเลกชัน IndicatorAreas ซึ่งประกอบด้วยหน้าต่างที่ไม่ใช่แบบ overlay หรือหน้าต่างแยกที่อินดิเคเตอร์สามารถแสดงผลลัพธ์ได้

คุณยังสามารถเข้าถึงพื้นที่อินดิเคเตอร์ปัจจุบันของคุณได้โดยใช้คุณสมบัติ IndicatorArea ของคลาส Indicator

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
using cAlgo.API;

namespace NewIndicator
{
    [Indicator(IsOverlay = false, AccessRights = AccessRights.None)]
    public class NewIndicator : Indicator
    {
        protected override void Initialize()
        {
            var verticalLine = IndicatorArea.DrawVerticalLine("line", Chart.LastVisibleBarIndex, Color.Red);
        }

        public override void Calculate(int index)
        {
        }
    }
}

เมื่อคุณรันอินสแตนซ์ของอินดิเคเตอร์ข้างต้น คุณควรจะเห็นเส้นสีแดงในหน้าต่างอินดิเคเตอร์แยก เมื่อสร้างกราฟในพื้นที่อินดิเคเตอร์แยก คุณสามารถใช้เมธอดการวาดทั้งหมดได้ เนื่องจากทั้ง Chart และ IndicatorArea สืบทอดมาจากคลาสพื้นฐาน ChartArea

ข้อความคงที่

แทนที่จะใช้พิกัด X และ Y สำหรับการกำหนดตำแหน่ง ข้อความคงที่จะใช้การจัดตำแหน่งแนวนอนและแนวตั้งแบบคงที่ ในการแสดงหรือวาดข้อความคงที่ ให้ใช้เมธอด DrawStaticText()

1
var staticText = Chart.DrawStaticText("static", "This is the text that will be shown", VerticalAlignment.Center, HorizontalAlignment.Center, Color.Red);

หากคุณแนบวัตถุกราฟนี้กับอินดิเคเตอร์และรันอินสแตนซ์ คุณจะเห็นข้อความต่อไปนี้ในกราฟหลัก

Image title

เส้นแนวตั้ง

ใช้เมธอด DrawVerticalLine() เพื่อวาดเส้นแนวตั้ง

1
2
3
var verticalLine = Chart.DrawVerticalLine("line", Chart.LastVisibleBarIndex, Color.Red);
// Or
var verticalLine = Chart.DrawVerticalLine("line", Bars.OpenTimes[Chart.LastVisibleBarIndex], Color.Red);

เส้นแนวนอน

ใช้เมธอด DrawHorizontalLine() เพื่อวาดเส้นแนวนอน

1
2
3
/* We use the maximum of the high prices
of the last ten bars as the Y coordinate. */ 
var horizontalLine = Chart.DrawHorizontalLine("line", Bars.HighPrices.Maximum(10), Color.Red);

เส้นแนวโน้ม

เส้นแนวโน้มเริ่มต้นจากจุดหนึ่งในกราฟและสิ้นสุดที่อีกจุดหนึ่ง เส้นแนวโน้มมีประโยชน์สำหรับการสร้างรูปร่างต่างๆ หรือรูปแบบที่ซับซ้อน

ในการวาดเส้นแนวโน้ม ให้ใช้เมธอด DrawTrendLine()

1
2
3
4
5
6
7
/* We draw a line from the low price
 of the first visible bar to the high price
 of the last visible bar on the chart. */
var trendLine = Chart.DrawTrendLine("line", Chart.FirstVisibleBarIndex, Bars.LowPrices[Chart.FirstVisibleBarIndex], Chart.LastVisibleBarIndex, Bars.HighPrices[Chart.LastVisibleBarIndex], Color.Red);

// Alternatively, consider the following.
var trendLine = Chart.DrawTrendLine("line", Bars.OpenTimes[Chart.FirstVisibleBarIndex], Bars.LowPrices[Chart.FirstVisibleBarIndex], Bars.OpenTimes[Chart.LastVisibleBarIndex], Bars.HighPrices[Chart.LastVisibleBarIndex], Color.Red);

สี่เหลี่ยมผืนผ้า

ใช้เมธอด DrawRectangle() เพื่อวาดสี่เหลี่ยมผืนผ้า

1
2
3
4
5
6
7
var rectangle = Chart.DrawRectangle("rectangle", Chart.FirstVisibleBarIndex + 1, Bars.LowPrices[Chart.FirstVisibleBarIndex + 1], Chart.LastVisibleBarIndex, Bars.HighPrices[Chart.LastVisibleBarIndex], Color.Red);

/* We fill the rectangle with a transparent color.
By using its current color, we only change the alpha
channel. */
rectangle.IsFilled = true;
rectangle.Color = Color.FromArgb(80, rectangle.Color);

สามเหลี่ยม

ใช้เมธอด DrawTriangle() เพื่อวาดสามเหลี่ยม

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
var middleX = Chart.FirstVisibleBarIndex + (Chart.LastVisibleBarIndex - Chart.FirstVisibleBarIndex) / 2;
var middleY = Bars.LowPrices[Chart.FirstVisibleBarIndex] + (Bars.HighPrices[Chart.LastVisibleBarIndex] - Bars.LowPrices[Chart.FirstVisibleBarIndex]) / 2;

var triangle = Chart.DrawTriangle("triangle", Chart.FirstVisibleBarIndex, Bars.LowPrices[Chart.FirstVisibleBarIndex], middleX, middleY, Chart.LastVisibleBarIndex, Bars.LowPrices[Chart.FirstVisibleBarIndex], Color.Red);

// We fill the triangle with a transparent color
// by using it's current color, we change only the alpha channel

/* We fill the triangle with a transparent color.
By using its current color, we only change the alpha
channel. */
triangle.IsFilled = true;
triangle.Color = Color.FromArgb(80, triangle.Color);

วัตถุกราฟอื่นๆ

เพื่อความกระชับ เราไม่ได้กล่าวถึงวัตถุกราฟอื่นๆ อีกหลายอย่างในตัวอย่างโค้ดข้างต้น วัตถุเหล่านี้รวมถึงแต่ไม่จำกัดเพียง:

  • วงรี
  • ไอคอน
  • Andrews Pitchfork
  • Equidistant Channel
  • Fibonacci Expansion
  • Fibonacci Fan
  • Fibonacci Retracement

วัตถุทั้งหมดเหล่านี้สามารถวาดได้โดยใช้เมธอด Draw...() ที่มีชื่อคล้ายกันและรับพารามิเตอร์ที่คล้ายกัน

ความเสี่ยง-ผลตอบแทน

อินเทอร์เฟซ ChartRiskReward มีประเภทที่ช่วยให้คุณสามารถสร้างและจัดการวัตถุความเสี่ยง-ผลตอบแทนบนกราฟได้โดยใช้โปรแกรม

โค้ดด้านล่างแสดงวิธีการสร้างอินดิเคเตอร์ที่วาดวัตถุความเสี่ยง-ผลตอบแทน:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
using System;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo
{
    [Indicator(AccessRights = AccessRights.None, IsOverlay = true)]
    public class SimpleRiskReward : Indicator
    {
        protected override void Initialize()
        {
            var type = new ChartRiskRewardFixedRiskType(
                ChartRiskRewardAmountType.BalancePercentage, 
                1                                            
            );
            var tradeType = TradeType.Buy;
            var orderType = OrderType.Market;

            var entryPrice = Chart.Bars.LastBar.Close;
            var time1 = Chart.LastVisibleBarIndex - 20; 
            var time2 = Chart.LastVisibleBarIndex;      

            var rr = Chart.DrawRiskReward(
                "SimpleRR",     
                time1,           
                time2,            
                entryPrice,       
                orderType,        
                tradeType,        
                type              
            );

            rr.IsInteractive = true;

            rr.RiskColor = Color.Yellow;
            rr.RiskLineStyle = LineStyle.DotsRare;
            rr.RiskThickness = 3;

            rr.RewardColor = Color.Blue;
            rr.RewardLineStyle = LineStyle.LinesDots;
            rr.RewardThickness = 2;

            PrintRRInfo(rr);
        }

        private void PrintRRInfo(ChartRiskReward rr)
        {
            Print($"Name: {rr.Name} | Type: {rr.Type.GetType().Name} | Order Type: {rr.OrderType} | Trade Type: {rr.TradeType} | Time 1: {rr.Time1:o} | Time 2: {rr.Time2:o} | Entry: {rr.EntryPrice} | SL: {rr.StopLossPrice} | TP: {rr.TakeProfitPrice} | RR: {rr.RiskRewardRatio} | Volume: {rr.VolumeInUnits}");
        }

        public override void Calculate(int index)
        {
        }
    }
}

ตั้งค่าออบเจ็กต์หลัก

การตั้งชื่อออบเจ็กต์บนกราฟ

เมื่อใดก็ตามที่คุณพยายามวาดออบเจ็กต์บนกราฟ คุณต้องระบุชื่อของมันเป็นอาร์กิวเมนต์สำหรับเมธอด draw

ชื่อของออบเจ็กต์บนกราฟทั้งหมดต้องไม่ซ้ำกัน หากไม่เป็นไปตามข้อกำหนดนี้ คุณเสี่ยงที่จะทำให้ออบเจ็กต์บนกราฟทับออบเจ็กต์ที่มีชื่อเดียวกันขึ้นอยู่กับเวลาการทำงานของพวกมัน คุณสามารถใช้ค่าดัชนีแท่งปัจจุบันหรือเวลาปัจจุบันเพื่อสร้างชื่อที่ไม่ซ้ำกันสำหรับแต่ละออบเจ็กต์

การเข้าถึงออบเจ็กต์บนกราฟ

ออบเจ็กต์บนกราฟทั้งหมดอยู่ภายในคอลเลกชัน Objects คอลเลกชันนี้รวมถึงออบเจ็กต์ที่ผู้ใช้วาด ดังนั้น คอลเลกชัน Objects สามารถเข้าถึงเพื่อลบออบเจ็กต์ออกจากกราฟหรือแก้ไขคุณสมบัติของพวกมัน

ตัวอย่างด้านล่างเข้าถึงสมาชิกของคอลเลกชัน Objects:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
using cAlgo.API;
using System.Linq;
namespace NewIndicator
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class NewIndicator : Indicator
    {
        protected override void Initialize()
        {
            foreach (var chartObject in Chart.Objects)
            {
                /* If the object is a trend line 
                we change its Y1/2 properties */
                if (chartObject is ChartTrendLine trendLine)
                {
                    trendLine.Y1 = Chart.BottomY;
                    trendLine.Y2 = Chart.TopY;
                }
            }

            /* Here, we filter all objects of the 'ChartRectangle'
            type. */
            var rectangles = from chartObject in Chart.Objects
                             where chartObject is ChartRectangle
                             select chartObject as ChartRectangle;

            /* We select only the chart objects with a name that
            begins with "MyObjects". */
            var myObjects = from chartObject in Chart.Objects
                            where chartObject.Name.StartsWith("MyObjects", System.StringComparison.OrdinalIgnoreCase)
                            select chartObject;

            /* We select only interactive objects. If an object
            is interactive, it will not be removed when the 
            indicator is removed or reloaded. */
            var interactiveObjects = from chartObject in Chart.Objects
                                     where chartObject.IsInteractive
                                     select chartObject;

            /* We remove all objects with a name 
            that begins with "ToRemove". */
            var chartObjectsCopy = Chart.Objects.ToArray();

            foreach (var chartObject in chartObjectsCopy)
            {
                if (chartObject.Name.StartsWith("ToRemove", System.StringComparison.OrdinalIgnoreCase))
                {
                    /* Chart 'RemoveObject' gets the object name
                    as a parameter. */
                    Chart.RemoveObject(chartObject.Name);
                }

            }
        }

        public override void Calculate(int index)
        {
        }
    }
}

เหตุการณ์

ออบเจ็กต์บนกราฟมีอีเวนต์หลายอย่างที่คุณสามารถใช้เพื่อทราบว่าออบเจ็กต์ใดถูกวาด อัปเดต หรือลบ:

  • ObjectsAdded - ทริกเกอร์เมื่อมีการเพิ่มออบเจ็กต์บนกราฟหนึ่งรายการหรือมากกว่าลงในกราฟ
  • ObjectsRemoved - ทริกเกอร์เมื่อมีการลบออบเจ็กต์บนกราฟหนึ่งรายการหรือมากกว่าออกจากกราฟ
  • ObjectsUpdated - ทริกเกอร์เมื่อมีการอัปเดตออบเจ็กต์บนกราฟหนึ่งรายการหรือมากกว่า (คุณสมบัติใดคุณสมบัติหนึ่งของพวกมันถูกเปลี่ยนโดยผู้ใช้หรืออินดิเคเตอร์หรือ cBot ที่ใช้งานอยู่)
  • ObjectsSelectionChanged - ทริกเกอร์เมื่อผู้ใช้เลือกออบเจ็กต์บนกราฟหนึ่งรายการหรือมากกว่า
  • ObjectHoverChanged - ทริกเกอร์เมื่อเคอร์เซอร์ของเมาส์อยู่เหนือออบเจ็กต์บนกราฟ

ตัวอย่างต่อไปนี้ใช้ประเภทอีเวนต์ทั้งห้า:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
using cAlgo.API;

namespace NewIndicator
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class NewIndicator : Indicator
    {
        protected override void Initialize()
        {
            Chart.ObjectsAdded += Chart_ObjectsAdded;
            Chart.ObjectsRemoved += Chart_ObjectsRemoved;
            Chart.ObjectsUpdated += Chart_ObjectsUpdated;
            Chart.ObjectsSelectionChanged += Chart_ObjectsSelectionChanged;
            Chart.ObjectHoverChanged += Chart_ObjectHoverChanged;
        }

        private void Chart_ObjectHoverChanged(ChartObjectHoverChangedEventArgs obj) => throw new System.NotImplementedException();

        private void Chart_ObjectsSelectionChanged(ChartObjectsSelectionChangedEventArgs obj) => throw new System.NotImplementedException();

        private void Chart_ObjectsUpdated(ChartObjectsUpdatedEventArgs obj) => throw new System.NotImplementedException();

        private void Chart_ObjectsRemoved(ChartObjectsRemovedEventArgs obj) => throw new System.NotImplementedException();

        private void Chart_ObjectsAdded(ChartObjectsAddedEventArgs obj) => throw new System.NotImplementedException();

        public override void Calculate(int index)
        {
        }
    }
}

ออบเจ็กต์แบบโต้ตอบและไม่โต้ตอบ

เมื่อทำงานกับออบเจ็กต์แบบโต้ตอบ ผู้ใช้สามารถเปลี่ยนคุณสมบัติของพวกมันได้ เช่น ตำแหน่งของออบเจ็กต์ สี ความคิดเห็น ฯลฯ ออบเจ็กต์ที่ผู้ใช้วาดทั้งหมดเป็นแบบโต้ตอบโดยค่าเริ่มต้น

หมายเหตุ

คุณสมบัติ ChartStaticText ไม่สามารถเปลี่ยนแปลงได้ไม่ว่าออบเจ็กต์ที่เกี่ยวข้องจะเป็นแบบโต้ตอบหรือไม่ก็ตาม

เพื่อทำให้ออบเจ็กต์เป็นแบบโต้ตอบ ให้ตั้งค่าคุณสมบัติ IsInteractive เป็น true ดังที่แสดงด้านล่าง:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
using cAlgo.API;

namespace NewIndicator
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class NewIndicator : Indicator
    {
        protected override void Initialize()
        {
            var verticalLine = Chart.DrawVerticalLine("line", Chart.LastVisibleBarIndex, Color.Red);

            verticalLine.IsInteractive = true;
        }

        public override void Calculate(int index)
        {
        }
    }
}

ออบเจ็กต์บนกราฟทั้งหมดมีคุณสมบัติ IsInteractive ค่าเริ่มต้นของมันคือ false

หากออบเจ็กต์บนกราฟเป็นแบบโต้ตอบ มันจะไม่ถูกลบเมื่อมีการลบหรือหยุดอินสแตนซ์ของอินดิเคเตอร์หรือ cBot ในทางตรงกันข้าม ออบเจ็กต์ที่ไม่โต้ตอบจะถูกลบโดยอัตโนมัติเมื่ออินดิเคเตอร์หรือ cBot หยุดทำงาน

เพื่อหลีกเลี่ยงความยุ่งเหยิง ตรวจสอบให้แน่ใจว่าได้ล้างออบเจ็กต์แบบโต้ตอบหลังจากที่อินสแตนซ์ที่เกี่ยวข้องถูกลบโดยใช้เมธอด Destroy ของอินดิเคเตอร์หรือเมธอด OnStop ของ cBot

หากออบเจ็กต์บนกราฟไม่ใช่แบบโต้ตอบ มันจะไม่ปรากฏในรายการและคอลเลกชันของออบเจ็กต์บนกราฟด้วย

ออบเจ็กต์ที่ล็อกและปลดล็อก

การล็อกออบเจ็กต์บนกราฟป้องกันไม่ให้ผู้ใช้แก้ไขหรืออัปเดตมัน คุณสามารถทำได้ผ่านกล่อง Trader (คุณสมบัติของกราฟ) หรือโดยการตั้งค่าคุณสมบัติ IsLocked เป็น true ค่าเริ่มต้นคือ false

คุณสามารถใช้การล็อกเพื่อทำให้ออบเจ็กต์เป็นแบบโต้ตอบแต่ในขณะเดียวกันก็ป้องกันไม่ให้ผู้ใช้อัปเดตมัน ตัวอย่างต่อไปนี้ล็อกออบเจ็กต์เส้นแนวตั้ง:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
using cAlgo.API;

namespace NewIndicator
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class NewIndicator : Indicator
    {
        protected override void Initialize()
        {
            var verticalLine = Chart.DrawVerticalLine("line", Chart.LastVisibleBarIndex, Color.Red);

            verticalLine.IsLocked = true;
        }

        public override void Calculate(int index)
        {
        }
    }
}

แสดงและซ่อน

คุณสามารถวาดออบเจ็กต์บนกราฟและซ่อนมันในภายหลังได้ แม้ว่าออบเจ็กต์จะยังคงอยู่บนกราฟ แต่มันจะมองไม่เห็นโดยสิ้นเชิง

เพื่อทำเช่นนี้ ให้ตั้งค่าคุณสมบัติ IsHidden เป็น true

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
using cAlgo.API;

namespace NewIndicator
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class NewIndicator : Indicator
    {
        protected override void Initialize()
        {
            var verticalLine = Chart.DrawVerticalLine("line", Chart.LastVisibleBarIndex, Color.Red);

            verticalLine.IsHidden = true;
        }

        public override void Calculate(int index)
        {
        }
    }
}

การใช้ทรัพยากรเป็นข้อพิจารณาหลักสำหรับการใช้ฟีเจอร์นี้ หากมีออบเจ็กต์ที่ควรปรากฏบนกราฟบ่อยๆ (แต่ไม่ใช่ตลอดเวลา) จะดีกว่าที่จะซ่อนมันแทนที่จะลบและวาดใหม่ทุกครั้งที่ต้องการ

การเลือกออบเจ็กต์และดัชนีการปรากฏ (ZIndex)

ตามธรรมชาติ อาจมีกรณีที่ออบเจ็กต์หลายอันตัดกันบนกราฟ ทำให้การเลือกออบเจ็กต์เฉพาะอันใดอันหนึ่งเป็นเรื่องยากหรือเป็นไปไม่ได้เลย เฉพาะออบเจ็กต์ที่ถูกวาดล่าสุดเท่านั้นที่จะสามารถเลือกได้เมื่อเลื่อนเคอร์เซอร์เมาส์ไปเหนือกลุ่มของออบเจ็กต์บนกราฟที่ตัดกัน

เพื่อเปลี่ยนพฤติกรรมนี้ คุณสามารถใช้คุณสมบัติ ZIndex มันสามารถเป็นประโยชน์เมื่อพยายามแสดงรูปแบบที่ซับซ้อนของออบเจ็กต์บนกราฟ

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using cAlgo.API;

namespace NewIndicator
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class NewIndicator : Indicator
    {
        protected override void Initialize()
        {
            var firstVerticalLine = Chart.DrawVerticalLine("line1", Chart.LastVisibleBarIndex, Color.Red);

            firstVerticalLine.IsInteractive = true;

            var secondVerticalLine = Chart.DrawVerticalLine("line2", Chart.LastVisibleBarIndex, Color.Yellow);

            secondVerticalLine.IsInteractive = true;

            firstVerticalLine.ZIndex = secondVerticalLine.ZIndex + 1;
        }

        public override void Calculate(int index)
        {
        }
    }
}

เมื่อแนบกับกราฟแล้ว อินดิเคเตอร์ด้านบนจะแสดงเส้นแนวตั้งสีแดงแทนที่จะเป็นสีเหลือง เนื่องจากค่าของคุณสมบัติ ZIndex ของเส้นแรกสูงกว่าค่าที่สอดคล้องกันของเส้นที่สอง มันจึงมีความสำคัญเหนือเส้นที่สอง (สีเหลือง)

กล่าวอีกนัยหนึ่ง คุณสมบัติ ZIndex กำหนดว่าออบเจ็กต์บนกราฟใดจะแสดงก่อนเมื่อพวกมันทับซ้อนกัน ออบเจ็กต์บนกราฟที่วาดทั้งหมดจะถูกกำหนดค่าสำหรับคุณสมบัติ ZIndex โดยอัตโนมัติ

ทราบว่าออบเจ็กต์ถูกลบหรือไม่

ออบเจ็กต์บนกราฟทั้งหมดสืบทอดคุณสมบัติ IsAlive จากคลาสพื้นฐาน ChartObject ค่าของคุณสมบัตินี้คือ true ตราบใดที่ออบเจ็กต์ยังคงอยู่บนกราฟ (ไม่ว่าจะมองเห็นหรือมองไม่เห็นก็ตาม) ค่าจะถูกตั้งเป็น false ทันทีที่ออบเจ็กต์ถูกลบออกจากกราฟ

หากคุณบันทึกการอ้างอิงถึงออบเจ็กต์บนกราฟและออบเจ็กต์นี้ถูกลบโดยผู้ใช้ คุณสามารถตรวจสอบคุณสมบัติ IsAlive เพื่อตรวจสอบว่าออบเจ็กต์ยังมีชีวิตอยู่หรือตายแล้ว

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
using cAlgo.API;

namespace NewIndicator
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class NewIndicator : Indicator
    {
        private ChartVerticalLine _verticalLine;

        protected override void Initialize()
        {
            _verticalLine = Chart.DrawVerticalLine("line1", Chart.LastVisibleBarIndex, Color.Red);
            _verticalLine.IsInteractive = true;

            Chart.ObjectsRemoved += Chart_ObjectsRemoved;

            Print(_verticalLine.IsAlive);
        }

        private void Chart_ObjectsRemoved(ChartObjectsRemovedEventArgs obj)
        {
            Print(_verticalLine.IsAlive);

            /* If the object is removed, we should rid of its
            reference. Otherwise, it will remain in memory. */
            if (_verticalLine.IsAlive is false)
            {
                _verticalLine = null;

                Print("Object reference removed");
            }
        }

        public override void Calculate(int index)
        {
        }
    }
}

หากคุณเรียกใช้อินสแตนซ์ของอินดิเคเตอร์นี้ ให้คลิกขวาที่เส้นสีแดงและลบมัน บันทึกควรแสดงข้อความ "Object reference removed"

หากคุณเก็บการอ้างอิงถึงออบเจ็กต์กราฟ (ที่ไม่ใช้งานแล้ว) จะเกิดการรั่วไหลของหน่วยความจำ ในระหว่างการเก็บขยะ ออบเจ็กต์ของคุณจะยังคงถูกพิจารณาว่ามีชีวิตอยู่ ซึ่งหมายความว่ามันจะรอดพ้นจากกระบวนการเก็บขยะ

เพื่อหลีกเลี่ยงปัญหานี้ ให้ใช้อีเวนต์ ObjectsRemoved ร่วมกับคุณสมบัติ IsAlive

ดัชนีแท่งเทียนหรือเวลา

เมื่อเขียนโค้ดออบเจ็กต์กราฟ คุณสามารถใช้เวลาของกราฟหรือดัชนีแท่งเทียนสำหรับแกน X

ในความเห็นของเรา เวลาของกราฟเป็นตัวเลือกที่ดีกว่า เมื่อใช้ดัชนีแท่งเทียน คุณไม่สามารถวางแผนสำหรับค่าในอนาคตได้ (เนื่องจากดัชนีที่ต้องการยังไม่มีอยู่) และไม่สามารถคำนวณช่องว่างระหว่างแท่งเทียนได้ อย่างไรก็ตาม ดัชนีแท่งเทียนอาจใช้งานง่ายกว่า โดยเฉพาะในกรณีของออบเจ็กต์กราฟที่ค่อนข้างง่าย

เมธอด Chart.Draw ทั้งหมดมี overload ที่แตกต่างกันสำหรับดัชนีแท่งเทียนและเวลาของกราฟ