西西河

主题:1-X技术分析测试程序代码帖 -- 牛义缂

共:💬31 🌺68
分页树展主题 · 全看首页 上页
/ 3
下页 末页
  • 家园 1-X技术分析测试程序代码帖

    考虑了一下,程序代码还是公布给大家好。也没有什么大用处,懂程序的看着玩吧。

    以后的代码都会贴在本帖下,不另开新帖了。

    小牛也不保留什么版权,也不保证程序没有错误。使用者自担风险吧!

    如果有人改进了代码,也可以贴在这儿给大家分享一下。

    顺便感谢自荐测试程序的河友!

    通宝推:工大流浪者,

    本帖一共被 2 帖 引用 (帖内工具实现)
    • 家园 【代码】KDJ(没有做J线)

      看到还有人对代码感兴趣,就把以前做的KDJ中的KD线的代码贴在这儿,其实是没什么用的。

      Option Compare Database

      Option Explicit

      '数组RD1()存储交易记录,如果程序提示下标越界,需要增加第二维的下标

      Public DP1 As Variant, RD1(2, 999) As Variant, U1 As Long, TIMES As Long, MA1() As Currency, MA2() As Currency, TRATE As Currency, CODE As String

      Sub INITIALIZE()

      Dim R1 As Variant, M1 As Long, M2 As Long, M3 As Long, B As Long, S As Long, ST As Date, ET As Date, TX As Currency, MX As Currency

      R1 = Array("DATE", "CLOSE", "OPEN", "HIGH", "LOW")

      'ST:测试区域的开始日期(注意您的机器上的日期格式)

      '注意:开始日期前面要留足计算均线的日期。例如,如果你要用到200日均线,开始日期前面要有至少200条数据。

      ST = #7/2/2005#

      'ET:测试区域的终止日期(注意您的机器上的日期格式)

      ET = #7/2/2010#

      'TX:总手续费(只作用于卖价)

      TX = 0.008

      'CODE:数据表名称

      CODE = "600649"

      Call READ1(R1)

      Debug.Print " RSV", "K", "D", "FROM", "TO", "手续费", "总收益", "交易次数"

      MX = 0

      B = 0

      S = 0

      'M3:RSV

      For M3 = 5 To 120 Step 5

      'M1:K线

      For M1 = 10 To 200 Step 10

      'M2:D线

      For M2 = 10 To 200 Step 10

      Call MACL(M1, M2, M3)

      Call DEAL(B, S, ST, ET, TX)

      '填True时显示所有结果,填False显示特定结果

      If False Then

      Debug.Print M3, M1, M2, ST, ET, TX * 100 & "%", TRATE, Int(TIMES / 2)

      Else

      'TRATE>MX:最后一行结果为总收益最大值

      'TRATE>5:显示所有总收益大于5的结果

      If TRATE > MX Then

      Debug.Print M3, M1, M2, ST, ET, TX * 100 & "%", TRATE, Int(TIMES / 2)

      MX = TRATE

      End If

      End If

      Next

      'If M1 = 1 Then M1 = 0

      Next

      Next

      '填True时显示循环中最后一对双均线的交易记录,填False不显示

      If False Then

      Debug.Print "日期", "正买负卖", "每次收益"

      For B = 0 To TIMES - 1

      For S = 0 To 2

      Debug.Print RD1(S, B),

      Next

      Debug.Print

      Next

      End If

      End Sub

      Sub READ1(R1 As Variant)

      Dim CN1 As ADODB.Connection, RST1 As ADODB.Recordset, SPath As String

      SPath = Application.VBE.ActiveVBProject.FileName

      Set CN1 = New ADODB.Connection

      Set RST1 = New ADODB.Recordset

      CN1.CursorLocation = adUseClient

      CN1.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & SPath & ";"

      RST1.Open "SELECT * FROM " & CODE & " ORDER BY DATE;", CN1, adOpenForwardOnly, adLockReadOnly, adCmdText

      RST1.MoveFirst

      DP1 = RST1.GetRows(, , R1)

      U1 = UBound(DP1, 2)

      RST1.Close

      CN1.Close

      Set RST1 = Nothing

      Set CN1 = Nothing

      End Sub

      Sub MACL(M1 As Long, M2 As Long, M3 As Long)

      Dim I As Long, T As Long, TMP1 As Long, LW As Currency, HT As Currency

      ReDim MA2(U1)

      'TEMP RSV-MA2()

      For T = 0 To M3 - 1

      HT = DP1(3, T)

      LW = DP1(4, T)

      For I = T To 0 Step -1

      If DP1(3, I) > HT Then HT = DP1(3, I)

      If DP1(4, I) < LW Then LW = DP1(4, I)

      Next

      MA2(T) = (DP1(1, T) - LW) / (HT - LW) * 100

      Next

      For T = M3 To U1

      If DP1(3, T) > HT Then

      HT = DP1(3, T)

      Else

      If DP1(3, T - M3) = HT Then

      HT = 0

      For I = T To T - M3 + 1 Step -1

      If DP1(3, I) > HT Then HT = DP1(3, I)

      Next

      End If

      End If

      If DP1(4, T) < LW Then

      LW = DP1(4, T)

      Else

      If DP1(4, T - M3) = LW Then

      LW = 99999

      For I = T To T - M3 + 1 Step -1

      If DP1(4, I) < LW Then LW = DP1(4, I)

      Next

      End If

      End If

      MA2(T) = (DP1(1, T) - LW) / (HT - LW) * 100

      Next

      ReDim MA1(U1)

      'K-MA1()

      MA1(0) = 50

      For I = 1 To U1

      MA1(I) = MA1(I - 1) * (M1 - 1) / M1 + MA2(I) / M1

      Next

      'D-MA2()

      MA2(0) = 50

      For I = 1 To U1

      MA2(I) = MA2(I - 1) * (M2 - 1) / M2 + MA1(I) / M2

      Next

      End Sub

      Sub DEAL(DBUY As Long, DSELL As Long, DT1 As Date, DT2 As Date, TAX As Currency)

      Dim I As Long, J As Long, D1 As Long, D2 As Long, DBOK As Boolean, DSOK As Boolean, BGT As Boolean

      If DT1 > DT2 Then

      MsgBox "日期错误!"

      Exit Sub

      End If

      BGT = False

      TIMES = 0

      TRATE = 1

      D1 = D2N(DT1, "S")

      D2 = D2N(DT2, "E")

      For I = D1 To D2 - 1

      If MA1(I - 1) <= MA2(I - 1) And MA1(I) > MA2(I) Then

      If Not BGT Then

      RD1(0, TIMES) = DP1(0, I + 1)

      RD1(1, TIMES) = DP1(2, I + 1)

      TIMES = TIMES + 1

      BGT = True

      Else

      'Stop

      End If

      Else

      If (MA1(I - 1) >= MA2(I - 1) And MA1(I) < MA2(I)) Then

      If BGT Then

      RD1(0, TIMES) = DP1(0, I + 1)

      RD1(1, TIMES) = -DP1(2, I + 1)

      RD1(2, TIMES) = DP1(2, I + 1) / RD1(1, TIMES - 1) * (1 - TAX)

      TRATE = TRATE * RD1(2, TIMES)

      TIMES = TIMES + 1

      BGT = False

      Else

      'Stop

      End If

      End If

      End If

      Next

      End Sub

      Function D2N(DT As Date, DR As String) As Long

      Dim J As Long, K As Long, M As Long

      J = 0

      K = U1

      M = Int((K - J) / 2) + J

      Do

      Select Case DT

      Case DP1(0, M)

      D2N = M

      Exit Function

      Case Is < DP1(0, M)

      K = M

      M = Int((K - J) / 2) + J

      Case Else

      J = M

      M = Int((K - J) / 2) + J

      End Select

      Loop Until K - J = 1

      If DR = "S" Then

      If DT > DP1(0, J) Then

      D2N = K

      Else

      D2N = J

      End If

      Else

      If DT < DP1(0, K) Then

      D2N = J

      Else

      D2N = K

      End If

      End If

      End Function

    • 家园 非常感谢!等周末看看如何转为Excel,

      因为我没有用过Access。

    • 家园 【代码】MACD的有效改进

      由于EMA的最优值测试结果比MA(SMA)差很多,小牛开始怀疑EMA均线的优点。于是就试着把MACD作一下改动,把其中的EMA均线全部换成MA均线。

      我们把这种新方法叫做MACD',那么它的公式就变成了:

      MACD'三个参数:A,B,C

      MACD'中的DIF' = 收盘价的MA(A) - 收盘价的MA(B)

      MACD'中的DEA' = DIF'的MA(C)

      MACD'中的柱线MACD' = (DIF' - DEA') x 2

      结果MACD'的最优值测试结果和MACD相比出人意料的好,谁能解释啊?

      ------------------------

      MACD'-DIF'/DEA'交叉方法描述:

      1.买入策略:MACD'的DIF'线金叉DEA'线时,第二天开盘买入。

      2.卖出策略:MACD'的DIF'线死叉DEA'线时,第二天开盘卖出。

      ------------------------

      注:

      1.通达信类软件中,可以通过修改/创建公式来显示MACD'。

      2.通达信类软件中,需要缩小K线图至显示全部历史数据,然后再放大到观察点,软件才能正确计算MACD'。

      ------------------------

      表结构

      字段名 类型 备注

      DATE 日期

      OPEN 货币 开盘价

      HIGH 货币 最高价

      LOW 货币 最低价

      CLOSE 货币 收盘价

      VOL 长整型 成交量

      ----------------------------------------

      'VBA模块1(要设置的参数都在INITIALIZE()子程序中注释出来了)

      Option Compare Database

      Option Explicit

      '数组RD1()存储交易记录,如果程序提示下标越界,需要增加第二维的下标

      Public DP1 As Variant, RD1(2, 499) As Variant, U1 As Long, TIMES As Long, MA1() As Currency, MA2() As Currency, TRATE As Currency, CODE As String

      Sub INITIALIZE()

      Dim R1 As Variant, M1 As Long, M2 As Long, M3 As Long, B As Long, S As Long, ST As Date, ET As Date, TX As Currency, MX As Currency

      R1 = Array("DATE", "CLOSE", "OPEN")

      'ST:测试区域的开始日期(注意您的机器上的日期格式)

      '注意:开始日期前面要留足计算均线的日期。例如,如果你要用到200日均线,开始日期前面要有至少200条数据。

      ST = #12/2/1997#

      'ET:测试区域的终止日期(注意您的机器上的日期格式)

      ET = #7/2/2010#

      'TX:总手续费(只作用于卖价)

      TX = 0.008

      'CODE:数据表名称

      CODE = "999999"

      Call READ1(R1)

      Debug.Print " MA1", "MA2", "MA3", "FROM", "TO", "手续费", "总收益", "交易次数"

      MX = 0

      B = 0

      S = 0

      'M3:DEA'均线值

      For M3 = 5 To 300 Step 5

      'M1:快MA均线值

      For M1 = 5 To 150 Step 5

      'M2:慢MA均线值

      For M2 = M1 + 15 To 300 Step 5

      Call MACL(M1, M2, M3)

      Call DEAL(B, S, ST, ET, TX)

      '填True时显示所有结果,填False显示特定结果

      If False Then

      Debug.Print M1, M2, M3, ST, ET, TX * 100 & "%", TRATE, Int(TIMES / 2)

      Else

      'TRATE>MX:最后一行结果为总收益最大值

      'TRATE>5:显示所有总收益大于5的结果

      If TRATE > MX Then

      Debug.Print M1, M2, M3, ST, ET, TX * 100 & "%", TRATE, Int(TIMES / 2)

      MX = TRATE

      End If

      End If

      Next

      Next

      Next

      '填True时显示循环中最后一对双均线的交易记录,填False不显示

      If False Then

      Debug.Print "日期", "正买负卖", "每次收益"

      For B = 0 To TIMES - 1

      For S = 0 To 2

      Debug.Print RD1(S, B),

      Next

      Debug.Print

      Next

      End If

      End Sub

      Sub READ1(R1 As Variant)

      Dim CN1 As ADODB.Connection, RST1 As ADODB.Recordset, SPath As String

      SPath = Application.VBE.ActiveVBProject.FileName

      Set CN1 = New ADODB.Connection

      Set RST1 = New ADODB.Recordset

      CN1.CursorLocation = adUseClient

      CN1.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & SPath & ";"

      RST1.Open "SELECT * FROM " & CODE & " ORDER BY DATE;", CN1, adOpenForwardOnly, adLockReadOnly, adCmdText

      RST1.MoveFirst

      DP1 = RST1.GetRows(, , R1)

      U1 = UBound(DP1, 2)

      RST1.Close

      CN1.Close

      Set RST1 = Nothing

      Set CN1 = Nothing

      End Sub

      Sub MACL(M1 As Long, M2 As Long, M3 As Long)

      Dim I As Long, T As Long, TMP1 As Currency

      ReDim MA1(U1)

      ReDim MA2(U1)

      'TEMP MA1()

      TMP1 = 0

      For I = 0 To M1 - 2

      TMP1 = TMP1 + DP1(1, I)

      MA1(I) = 0

      Next

      TMP1 = TMP1 + DP1(1, M1 - 1)

      MA1(M1 - 1) = TMP1 / M1

      For I = M1 To U1

      TMP1 = TMP1 + DP1(1, I) - DP1(1, I - M1)

      MA1(I) = TMP1 / M1

      Next

      'DIFF-MA1()

      TMP1 = 0

      For I = 0 To M2 - 2

      TMP1 = TMP1 + DP1(1, I)

      MA2(I) = 0

      MA1(I) = MA1(I) - MA2(I)

      Next

      TMP1 = TMP1 + DP1(1, M2 - 1)

      MA2(M2 - 1) = TMP1 / M2

      MA1(M2 - 1) = MA1(M2 - 1) - MA2(M2 - 1)

      For I = M2 To U1

      TMP1 = TMP1 + DP1(1, I) - DP1(1, I - M2)

      MA2(I) = TMP1 / M2

      MA1(I) = MA1(I) - MA2(I)

      Next

      'DEA-MA2()

      TMP1 = 0

      For I = 0 To M3 - 2

      TMP1 = TMP1 + MA1(I)

      MA2(I) = 0

      Next

      TMP1 = TMP1 + MA1(M3 - 1)

      MA2(M3 - 1) = TMP1 / M3

      For I = M3 To U1

      TMP1 = TMP1 + MA1(I) - MA1(I - M3)

      MA2(I) = TMP1 / M3

      Next

      End Sub

      Sub DEAL(DBUY As Long, DSELL As Long, DT1 As Date, DT2 As Date, TAX As Currency)

      Dim I As Long, J As Long, D1 As Long, D2 As Long, DBOK As Boolean, DSOK As Boolean, BGT As Boolean

      If DT1 > DT2 Then

      MsgBox "日期错误!"

      Exit Sub

      End If

      BGT = False

      TIMES = 0

      TRATE = 1

      D1 = D2N(DT1, "S")

      D2 = D2N(DT2, "E")

      For I = D1 To D2 - 1

      If MA1(I - 1) <= MA2(I - 1) And MA1(I) > MA2(I) Then

      If Not BGT Then

      RD1(0, TIMES) = DP1(0, I + 1)

      RD1(1, TIMES) = DP1(2, I + 1)

      TIMES = TIMES + 1

      BGT = True

      Else

      'Stop

      End If

      Else

      If (MA1(I - 1) >= MA2(I - 1) And MA1(I) < MA2(I)) Then

      If BGT Then

      RD1(0, TIMES) = DP1(0, I + 1)

      RD1(1, TIMES) = -DP1(2, I + 1)

      RD1(2, TIMES) = DP1(2, I + 1) / RD1(1, TIMES - 1) * (1 - TAX)

      TRATE = TRATE * RD1(2, TIMES)

      TIMES = TIMES + 1

      BGT = False

      Else

      'Stop

      End If

      End If

      End If

      Next

      End Sub

      Function D2N(DT As Date, DR As String) As Long

      Dim J As Long, K As Long, M As Long

      J = 0

      K = U1

      M = Int((K - J) / 2) + J

      Do

      Select Case DT

      Case DP1(0, M)

      D2N = M

      Exit Function

      Case Is < DP1(0, M)

      K = M

      M = Int((K - J) / 2) + J

      Case Else

      J = M

      M = Int((K - J) / 2) + J

      End Select

      Loop Until K - J = 1

      If DR = "S" Then

      If DT > DP1(0, J) Then

      D2N = K

      Else

      D2N = J

      End If

      Else

      If DT < DP1(0, K) Then

      D2N = J

      Else

      D2N = K

      End If

      End If

      End Function


      本帖一共被 1 帖 引用 (帖内工具实现)
    • 家园 【代码】MACD

      MACD-DIF/DEA交叉方法描述:

      1.买入策略:MACD的DIF线金叉DEA线时,第二天开盘买入。

      2.卖出策略:MACD的DIF线死叉DEA线时,第二天开盘卖出。

      ------------------------

      注:

      1.通达信类软件中,需要缩小K线图至显示全部历史数据,然后再放大到观察点,软件才能正确计算MACD。

      2.通达信类软件中,MACD的三个参数的默认设置最大值只有200。可以通过修改公式来设置更大的值。

      ------------------------

      表结构

      字段名 类型 备注

      DATE 日期

      OPEN 货币 开盘价

      HIGH 货币 最高价

      LOW 货币 最低价

      CLOSE 货币 收盘价

      VOL 长整型 成交量

      ----------------------------------------

      'VBA模块1(要设置的参数都在INITIALIZE()子程序中注释出来了)

      Option Compare Database

      Option Explicit

      '数组RD1()存储交易记录,如果程序提示下标越界,需要增加第二维的下标

      Public DP1 As Variant, RD1(2, 499) As Variant, U1 As Long, TIMES As Long, MA1() As Currency, MA2() As Currency, TRATE As Currency, CODE As String

      Sub INITIALIZE()

      Dim R1 As Variant, M1 As Long, M2 As Long, M3 As Long, B As Long, S As Long, ST As Date, ET As Date, TX As Currency, MX As Currency

      R1 = Array("DATE", "CLOSE", "OPEN")

      'ST:测试区域的开始日期(注意您的机器上的日期格式)

      '注意:开始日期前面要留足计算均线的日期。例如,如果你要用到200日均线,开始日期前面要有至少200条数据。

      ST = #12/2/1997#

      'ET:测试区域的终止日期(注意您的机器上的日期格式)

      ET = #7/2/2010#

      'TX:总手续费(只作用于卖价)

      TX = 0.008

      'CODE:数据表名称

      CODE = "999999"

      Call READ1(R1)

      Debug.Print " MA1", "MA2", "MA3", "FROM", "TO", "手续费", "总收益", "交易次数"

      MX = 0

      B = 0

      S = 0

      'M3:DEA均线值

      For M3 = 5 To 300 Step 5

      'M1:快EMA均线值

      For M1 = 5 To 150 Step 5

      'M2:慢EMA均线值

      For M2 = M1 + 15 To 300 Step 5

      Call MACL(M1, M2, M3)

      Call DEAL(B, S, ST, ET, TX)

      '填True时显示所有结果,填False显示特定结果

      If False Then

      Debug.Print M1, M2, M3, ST, ET, TX * 100 & "%", TRATE, Int(TIMES / 2)

      Else

      'TRATE>MX:最后一行结果为总收益最大值

      'TRATE>5:显示所有总收益大于5的结果

      If TRATE > MX Then

      Debug.Print M1, M2, M3, ST, ET, TX * 100 & "%", TRATE, Int(TIMES / 2)

      MX = TRATE

      End If

      End If

      Next

      Next

      Next

      '填True时显示循环中最后一对双均线的交易记录,填False不显示

      If False Then

      Debug.Print "日期", "正买负卖", "每次收益"

      For B = 0 To TIMES - 1

      For S = 0 To 2

      Debug.Print RD1(S, B),

      Next

      Debug.Print

      Next

      End If

      Debug.Print "运行完成!"

      End Sub

      Sub READ1(R1 As Variant)

      Dim CN1 As ADODB.Connection, RST1 As ADODB.Recordset, SPath As String

      SPath = Application.VBE.ActiveVBProject.FileName

      Set CN1 = New ADODB.Connection

      Set RST1 = New ADODB.Recordset

      CN1.CursorLocation = adUseClient

      CN1.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & SPath & ";"

      RST1.Open "SELECT * FROM " & CODE & " ORDER BY DATE;", CN1, adOpenForwardOnly, adLockReadOnly, adCmdText

      RST1.MoveFirst

      DP1 = RST1.GetRows(, , R1)

      U1 = UBound(DP1, 2)

      RST1.Close

      CN1.Close

      Set RST1 = Nothing

      Set CN1 = Nothing

      End Sub

      Sub MACL(M1 As Long, M2 As Long, M3 As Long)

      Dim I As Long, T As Long, TMP1 As Currency

      ReDim MA1(U1)

      'TEMP EMA1-MA1()

      MA1(0) = DP1(1, 0)

      For I = 1 To U1

      MA1(I) = MA1(I - 1) * (M1 - 1) / (M1 + 1) + DP1(1, I) * 2 / (M1 + 1)

      Next

      ReDim MA2(U1)

      'TEMP EMA2-MA2()

      MA2(0) = DP1(1, 0)

      'DIFF-MA1()

      MA1(0) = MA1(0) - MA2(0)

      For I = 1 To U1

      MA2(I) = MA2(I - 1) * (M2 - 1) / (M2 + 1) + DP1(1, I) * 2 / (M2 + 1)

      MA1(I) = MA1(I) - MA2(I)

      Next

      'DEA-MA2()

      MA2(0) = MA1(0)

      For I = 1 To U1

      MA2(I) = MA2(I - 1) * (M3 - 1) / (M3 + 1) + MA1(I) * 2 / (M3 + 1)

      Next

      End Sub

      Sub DEAL(DBUY As Long, DSELL As Long, DT1 As Date, DT2 As Date, TAX As Currency)

      Dim I As Long, J As Long, D1 As Long, D2 As Long, DBOK As Boolean, DSOK As Boolean, BGT As Boolean

      If DT1 > DT2 Then

      MsgBox "日期错误!"

      Exit Sub

      End If

      BGT = False

      TIMES = 0

      TRATE = 1

      D1 = D2N(DT1, "S")

      D2 = D2N(DT2, "E")

      For I = D1 To D2 - 1

      If MA1(I - 1) <= MA2(I - 1) And MA1(I) > MA2(I) Then

      If Not BGT Then

      RD1(0, TIMES) = DP1(0, I + 1)

      RD1(1, TIMES) = DP1(2, I + 1)

      TIMES = TIMES + 1

      BGT = True

      Else

      'Stop

      End If

      Else

      If (MA1(I - 1) >= MA2(I - 1) And MA1(I) < MA2(I)) Then

      If BGT Then

      RD1(0, TIMES) = DP1(0, I + 1)

      RD1(1, TIMES) = -DP1(2, I + 1)

      RD1(2, TIMES) = DP1(2, I + 1) / RD1(1, TIMES - 1) * (1 - TAX)

      TRATE = TRATE * RD1(2, TIMES)

      TIMES = TIMES + 1

      BGT = False

      Else

      'Stop

      End If

      End If

      End If

      Next

      End Sub

      Function D2N(DT As Date, DR As String) As Long

      Dim J As Long, K As Long, M As Long

      J = 0

      K = U1

      M = Int((K - J) / 2) + J

      Do

      Select Case DT

      Case DP1(0, M)

      D2N = M

      Exit Function

      Case Is < DP1(0, M)

      K = M

      M = Int((K - J) / 2) + J

      Case Else

      J = M

      M = Int((K - J) / 2) + J

      End Select

      Loop Until K - J = 1

      If DR = "S" Then

      If DT > DP1(0, J) Then

      D2N = K

      Else

      D2N = J

      End If

      Else

      If DT < DP1(0, K) Then

      D2N = J

      Else

      D2N = K

      End If

      End If

      End Function


      本帖一共被 1 帖 引用 (帖内工具实现)
    • 家园 【代码】EMA(EXPMA)双均线交叉方法

      以前谈的均线,都是最简单的一种均线,叫做简单平滑移动平均线(SMA)。对简单平均线的改进方法有多种,影响最大的一种是EXPMA(简称EMA),就是指数平滑移动平均线。这种方法对近期价格加高权重,远期价格加低权重,以更多的反映近期的趋势变化。

      注:在通达信类软件中(其它软件没用过),你需要缩小K线图至全部显示,然后再放大到要考察的日期,软件才能正确计算EMA均线。另外,通达信类软件中EMA参数最大只能设置到250日。

      ---------------------------------------

      双EMA均线交叉方法描述:

      1.买入策略:当小均线向上交叉大均线时(金叉),第二天开盘买入。

      2.卖出策略:当小均线向下交叉大均线时(死叉),第二天开盘卖出。

      ----------------------------------

      表结构

      字段名 类型 备注

      DATE 日期

      OPEN 货币 开盘价

      HIGH 货币 最高价

      LOW 货币 最低价

      CLOSE 货币 收盘价

      VOL 长整型 成交量

      ----------------------------------------

      'VBA模块1(要设置的参数都在INITIALIZE()子程序中注释出来了)

      Option Compare Database

      Option Explicit

      '数组RD1()存储交易记录,如果程序提示下标越界,需要增加第二维的下标

      Public DP1 As Variant, RD1(2, 499) As Variant, U1 As Long, TIMES As Long, MA1() As Currency, MA2() As Currency, TRATE As Currency, CODE As String

      Sub INITIALIZE()

      Dim R1 As Variant, M1 As Long, M2 As Long, B As Long, S As Long, ST As Date, ET As Date, TX As Currency, MX As Currency

      R1 = Array("DATE", "CLOSE", "OPEN")

      'ST:测试区域的开始日期(注意您的机器上的日期格式)

      '注意:开始日期前面要留足计算均线的日期。例如,如果你要用到200日均线,开始日期前面要有至少200条数据。

      ST = #12/2/1997#

      'ET:测试区域的终止日期(注意您的机器上的日期格式)

      ET = #7/2/2010#

      'TX:总手续费(只作用于卖价)

      TX = 0.008

      'CODE:数据表名称

      CODE = "999999"

      Call READ1(R1)

      Debug.Print " MA1", "MA2", "FROM", "TO", "手续费", "总收益", "交易次数"

      MX = 0

      B = 0

      S = 0

      'M1:小均线值

      For M1 = 5 To 125 Step 5

      'M2:大均线值

      For M2 = M1 + 5 To 250 Step 5

      Call MACL(M1, M2)

      Call DEAL(B, S, ST, ET, TX)

      '填True时显示所有结果,填False显示特定结果

      If False Then

      Debug.Print M1, M2, ST, ET, TX * 100 & "%", TRATE, Int(TIMES / 2)

      Else

      'TRATE>MX:最后一行结果为总收益最大值

      'TRATE>5:显示所有总收益大于5的结果

      If TRATE > MX Then

      Debug.Print M1, M2, ST, ET, TX * 100 & "%", TRATE, Int(TIMES / 2)

      MX = TRATE

      End If

      End If

      Next

      Next

      '填True时显示循环中最后一对双均线的交易记录,填False不显示

      If False Then

      Debug.Print "日期", "正买负卖", "每次收益"

      For B = 0 To TIMES - 1

      For S = 0 To 2

      Debug.Print RD1(S, B),

      Next

      Debug.Print

      Next

      End If

      End Sub

      Sub READ1(R1 As Variant)

      Dim CN1 As ADODB.Connection, RST1 As ADODB.Recordset, SPath As String

      SPath = Application.VBE.ActiveVBProject.FileName

      Set CN1 = New ADODB.Connection

      Set RST1 = New ADODB.Recordset

      CN1.CursorLocation = adUseClient

      CN1.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & SPath & ";"

      RST1.Open "SELECT * FROM " & CODE & " ORDER BY DATE;", CN1, adOpenForwardOnly, adLockReadOnly, adCmdText

      RST1.MoveFirst

      DP1 = RST1.GetRows(, , R1)

      U1 = UBound(DP1, 2)

      RST1.Close

      CN1.Close

      Set RST1 = Nothing

      Set CN1 = Nothing

      End Sub

      Sub MACL(M1 As Long, M2 As Long)

      Dim I As Long, T As Long, TMP1 As Currency

      ReDim MA1(U1)

      MA1(0) = DP1(1, 0)

      For I = 1 To U1

      MA1(I) = MA1(I - 1) * (M1 - 1) / (M1 + 1) + DP1(1, I) * 2 / (M1 + 1)

      Next

      ReDim MA2(U1)

      MA2(0) = DP1(1, 0)

      For I = 1 To U1

      MA2(I) = MA2(I - 1) * (M2 - 1) / (M2 + 1) + DP1(1, I) * 2 / (M2 + 1)

      Next

      End Sub

      Sub DEAL(DBUY As Long, DSELL As Long, DT1 As Date, DT2 As Date, TAX As Currency)

      Dim I As Long, J As Long, D1 As Long, D2 As Long, DBOK As Boolean, DSOK As Boolean, BGT As Boolean

      If DT1 > DT2 Then

      MsgBox "日期错误!"

      Exit Sub

      End If

      BGT = False

      TIMES = 0

      TRATE = 1

      D1 = D2N(DT1, "S")

      D2 = D2N(DT2, "E")

      For I = D1 To D2 - 1

      If MA1(I - 1) <= MA2(I - 1) And MA1(I) > MA2(I) Then

      If Not BGT Then

      RD1(0, TIMES) = DP1(0, I + 1)

      RD1(1, TIMES) = DP1(2, I + 1)

      TIMES = TIMES + 1

      BGT = True

      Else

      'Stop

      End If

      Else

      If (MA1(I - 1) >= MA2(I - 1) And MA1(I) < MA2(I)) Then

      If BGT Then

      RD1(0, TIMES) = DP1(0, I + 1)

      RD1(1, TIMES) = -DP1(2, I + 1)

      RD1(2, TIMES) = DP1(2, I + 1) / RD1(1, TIMES - 1) * (1 - TAX)

      TRATE = TRATE * RD1(2, TIMES)

      TIMES = TIMES + 1

      BGT = False

      Else

      'Stop

      End If

      End If

      End If

      Next

      End Sub

      Function D2N(DT As Date, DR As String) As Long

      Dim J As Long, K As Long, M As Long

      J = 0

      K = U1

      M = Int((K - J) / 2) + J

      Do

      Select Case DT

      Case DP1(0, M)

      D2N = M

      Exit Function

      Case Is < DP1(0, M)

      K = M

      M = Int((K - J) / 2) + J

      Case Else

      J = M

      M = Int((K - J) / 2) + J

      End Select

      Loop Until K - J = 1

      If DR = "S" Then

      If DT > DP1(0, J) Then

      D2N = K

      Else

      D2N = J

      End If

      Else

      If DT < DP1(0, K) Then

      D2N = J

      Else

      D2N = K

      End If

      End If

      End Function


      本帖一共被 1 帖 引用 (帖内工具实现)
      • 家园 ema,ma可以简单用

        可以这么简单来判断, 假设ma破掉 ema买没破,那么还会有走好。

        如果2个都破基本就挂了。

        实际短期均线干长期线的时候, ma比ema更早破掉,这样信号失误较多,所以可以拿ema辨识,以免被诱惑。

        • 家园 多谢提示,小牛有空测试一下你说的两者并用的方法

          不过小牛还是无法想明白,为什么单测EMA比MA差

          • 家园 解释

            MA算法和EMA算法你知道的

            MA累加后无法对近期平滑,因此最终影响线的是远期数据

            EMA对近期数据权重增加,使得更为平滑,但是也有点慢。

            这2个具体类似KDJ与KD的区别。

            所以当MA 5日叉10日可能 EMA还没反应, 于是如果作为下跌判断是否逃逸,就可以参考EMA,假设EMA最终5日没破10日,则MA发出信号为假。

            如果连EMA都破位虽然不敢说那不是诱空洗盘,但是起码要在恢复上涨不是几日就行,可能需要相对较长时间。 因此有这2个比较后你可以思考自己的进退。

    • 家园 数据是从哪儿来的呢?

      我原来也写过分析程序,不过自己录入数据太痛苦了,就作罢了

分页树展主题 · 全看首页 上页
/ 3
下页 末页


有趣有益,互惠互利;开阔视野,博采众长。
虚拟的网络,真实的人。天南地北客,相逢皆朋友

Copyright © cchere 西西河