2022年1月6日 星期四

VBA:如何畫出股票圖( k線圖、走勢圖) +交易量(錄製巨集教學+VBA教學版+VBA動態資料版)

單純VBA畫圖入門教學傳送門

股票分析很多,最基本的是畫出"K線圖"。

但怎樣用畫股票圖呢!!小編整理四套從初到進階等教學,希望有幫忙到。

首先請自行先準備資料,不管你資料出處是那裏來的,因為繪製股票圖需要最基本需要開盤、最高、最低與收盤等這幾個項目的資料,當然有日期更好,筆數資料不限,至於怎樣取得股票資料這邊小編另篇在討論瞜。

圖1.示意圖(不含日期)

圖2.示意圖(含日期)
先以錄製巨集方式試做一個看看,參GIF動畫。

圖3.GIF檔

流程:選取資料>點選插入圖表>選股票圖>產生>小編手動移動圖形位置
以下參VBA CODE長的如何...

節錄如下:

Sub 巨集3()

    Range("A1:E19").Select
    ActiveSheet.Shapes.AddChart.Select
    ActiveChart.ChartType = xlStockOHLC
    ActiveChart.SetSourceData SOURCE:=Range("還原股價!$A$1:$E$19")
    ActiveSheet.Shapes("圖表 8").IncrementLeft -456.4285826772
    ActiveSheet.Shapes("圖表 8").IncrementTop -12.1428346457
    
End Sub

重點說明: 
Shapes.AddChart. 新增圖表
ChartType 圖表種類
SOURCE:= 設定資料來源
ActiveSheet.Shapes("圖表 8") 中的圖表8會因為工作表內的圖表數量有差異。 

缺點:每次都要調整資料來源範圍,跟無法控制圖形大小跟位置。

VBA教學版一:
步驟:
1.預先資料收集
2.作一個activeX按鈕插入以下CODE內容

 

整體來說長的跟錄製沒兩樣。不過小編手動增加標籤部分。 
 
Private Sub CommandButton1_Click()

        Set myChart = ActiveSheet.ChartObjects.Add(20, 100, 600, 200)   '位置大小設定
      
        Set myRange = ActiveSheet.Range("A1:E100")    '資料來原設定    

  With myChart.Chart
    
        .SetSourceData SOURCE:=myRange, PlotBy:=xlColumns 
         
        .ChartType = xlStockOHLC
        
        '標籤設定

        .SeriesCollection(1).Name = "OPEN"
        
        .SeriesCollection(2).Name = "HIGH"
        
        .SeriesCollection(3).Name = "LOW"

        .SeriesCollection(4).Name = "CLOSE"

        .Axes(xlCategory, xlPrimary).HasTitle = True
        
        .Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "日期"
        
        .Axes(xlValue, xlPrimary).HasTitle = True
        
        .Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = "1101走勢"
                   
    End With

End Sub

VBA教學版二:
改進資料動態增加或異動情況時,可以考慮做以下調整:

原:
    Set myRange = ActiveSheet.Range("A1:E100")    '資料來原設定    

異動:

 N = Application.CountA(ActiveSheet.Range("A:A"))

Set myRange = ActiveSheet.Range("A1:E" & N)

透過application.countx來自動取得筆數,
但在畫圖上的建議,建議別超過250筆,阿無圖很密集。

VBA教學版三(動態版):

主要透過ScrollBar1物件來控制目前圖形顯示資料的區間控制。

步驟:
1.增加一個ScrollBar1的activeX物件。
2.增加一個ScrollBar1_Change的事件程序,並插入code如下:

Private Sub ScrollBar1_Change()

ScrollBar1.Min = 2

ScrollBar1.Max = Application.CountA(ActiveSheet.Range("A:A"))

If ScrollBar1.Value < 100 Then

    ScrollBar1.Value = 102

End If

Debug.Print ScrollBar1.Value

If  IsObject(myRange) = False Then

     Set myRange = ActiveSheet.Range("A" & ScrollBar1.Value - 100 & ":E" & ScrollBar1.Value)
     
     Set myRange_MAX_MIN = ActiveSheet.Range("B" & ScrollBar1.Value - 100 & ":E" & ScrollBar1.Value)
        
    With ActiveSheet.ChartObjects(ActiveSheet.ChartObjects.Count).Chart
    
        .SetSourceData SOURCE:=myRange, PlotBy:=xlColumns
        
        .SeriesCollection(1).Name = "OPEN"
        
        .SeriesCollection(2).Name = "HIGH"
        
        .SeriesCollection(3).Name = "LOW"

        .SeriesCollection(4).Name = "CLOSE"
        
    End With
    
 '設定資料(xlValue)座標軸格式的尺規最大最小值
    With ActiveSheet.ChartObjects(ActiveSheet.ChartObjects.Count).Chart.Axes(xlValue)         

             .MinimumScale = Application.Min(myRange_MAX_MIN) * 0.9
             
              Debug.Print .MinimumScale

             .MaximumScale = Application.Max(myRange_MAX_MIN) * 1.1
             
              Debug.Print .MaximumScale

    End With
             
End If

End Sub
操作動畫:
圖4.動態版操作

缺點是似乎尺規沒有跟著一起修正,那最後再加上控制y軸尺規的控制,這樣圖形顯示的走勢比例比較好掌握。

VBA教學版四(動態資料版+尺規自動調整+交易量):

另外作一個按鈕(CommandButton2_Click),插入以下代碼

Private Sub CommandButton2_Click()


        Set myChart = ActiveSheet.ChartObjects.Add(20, 100, 600, 200)
        
        Set myRange = ActiveSheet.Range("A1:E100")
        
    With myChart.Chart
    
        .SetSourceData SOURCE:=myRange, PlotBy:=xlColumns
         
        .ChartType = xlStockOHLC
        
        .HasTitle = False
                                                                                            
         .Legend.Position = xlLegendPositionTop
        
        .SeriesCollection(1).Name = "OPEN"
        
        .SeriesCollection(2).Name = "HIGH"
        
        .SeriesCollection(3).Name = "LOW"

        .SeriesCollection(4).Name = "CLOSE"

        .Axes(xlCategory, xlPrimary).HasTitle = True
        
        .Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "日期"
        
        .Axes(xlValue, xlPrimary).HasTitle = True
        
        .Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = "1101走勢"
        
                    With .ChartGroups(1)
                    
                         .UpBars.Format.Fill.ForeColor.RGB = RGB(255, 0, 0)
                         
                         .DownBars.Format.Fill.ForeColor.RGB = RGB(61, 145, 64)
                         
                    End With
        
'新增資料到圖形中
        .SeriesCollection.NewSeries
        
        .SeriesCollection(5).Values = ActiveSheet.Range("f2:f100")
                                                        
        .SeriesCollection(5).ChartType = xlColumnClustered
        
        .SeriesCollection(5).AxisGroup = xlSecondary
        
        .SeriesCollection(5).Name = "VOL(副)"
        
        .SeriesCollection(5).XValues = ActiveSheet.Range("a2:a100")
        
        .Axes(xlCategory).CategoryType = xlCategoryScale
            
       
    End With
                
End Sub

在插入一個卷軸物件名稱為ScrollBar2 插入以下code:

Private Sub ScrollBar2_Change()

ScrollBar1.Min = 2

ScrollBar1.Max = Application.CountA(ActiveSheet.Range("A:A"))

If ScrollBar1.Value < 100 Then

    ScrollBar1.Value = 102

End If

Debug.Print ScrollBar1.Value

If IsObject(myRange) = False Then

     Set myRange = ActiveSheet.Range("A" & ScrollBar1.Value - 100 & ":E" & ScrollBar1.Value)
     
     Set myRange_MAX_MIN = ActiveSheet.Range("B" & ScrollBar1.Value - 100 & ":E" & ScrollBar1.Value)
    
        
        
    With ActiveSheet.ChartObjects(ActiveSheet.ChartObjects.Count).Chart
    
        .SetSourceData SOURCE:=myRange, PlotBy:=xlColumns
        
        .SeriesCollection(1).Name = "OPEN"
        
        .SeriesCollection(2).Name = "HIGH"
        
        .SeriesCollection(3).Name = "LOW"

        .SeriesCollection(4).Name = "CLOSE"
        
        .SeriesCollection.NewSeries
        
        .SeriesCollection(5).Values = ActiveSheet.Range("f" & ScrollBar1.Value - 100 & ":f" & ScrollBar1.Value)
                                                        
        .SeriesCollection(5).ChartType = xlColumnClustered
        
        .SeriesCollection(5).AxisGroup = xlSecondary
        
        .SeriesCollection(5).Name = "VOL(副)"
        
        .SeriesCollection(5).XValues = ActiveSheet.Range("a" & ScrollBar1.Value - 100 & ":a" & ScrollBar1.Value)
        
    End With
      '設定資料(xlValue)座標軸格式的尺規最大最小值
    With ActiveSheet.ChartObjects(ActiveSheet.ChartObjects.Count).Chart.Axes(xlValue)        

             .MinimumScale = Application.Min(myRange_MAX_MIN) * 0.9
             
              Debug.Print .MinimumScale

             .MaximumScale = Application.Max(myRange_MAX_MIN) * 1.1
             
              Debug.Print .MaximumScale

    End With
End If

End Sub

操作動畫:
圖5.動態資料版+尺規自動調整+交易量





沒有留言:

張貼留言

打破人力資源最好的教案:川普

打破人力資源最好的教案: 川普 why? 過去討論人才       好用、解決問題,多少證照,還是產值? 現在討論人的重量?      重量如同金錢一樣      一公升92汽油多少錢?      淋在人身上跟加在車輛內會衍生多少"量化"? 對主管來說,人的重...