量化交易學習筆記(十三)——第一個策略回測程序v11

量化交易學習筆記(十三)——第一個策略回測程序v11

v11是第一個策略回測程序的最後一個版本,將對策略參數進行優化。

很多財經書籍裡都指出,不同股票、不同書籍都有個各自的特點和節奏,因此使用同一策略參數應用於所有的交易是不明智的。

在之前的例子中,我們嘗試了使用了簡單移動均值指標,週期參數選定為15,v11將對這個參數進行優化,通過優化找出簡單移動均值的最佳週期數。程序的主要修改部分為在向cerebro添加策略時使用如下代碼:

<code>

strats

=

cerebro.optstrategy(

TestStrategy,

maperiod

=

range(10, 31))

/<code>

這樣backtrader就會將將簡單移動均值所選取的週期數從10到31進行逐個嘗試,通過計算最終收益,便可以選擇出最優的參數。

v11輸出為:

<code>

2020

-02

-04

,

(MA

Period

10

)

Ending

Value

99852.22

2020

-02

-04

,

(MA

Period

11

)

Ending

Value

99914.55

2020

-02

-04

,

(MA

Period

12

)

Ending

Value

99946.91

2020

-02

-04

,

(MA

Period

13

)

Ending

Value

99948.27

2020

-02

-04

,

(MA

Period

14

)

Ending

Value

99957.74

2020

-02

-04

,

(MA

Period

15

)

Ending

Value

99990.11

2020

-02

-04

,

(MA

Period

16

)

Ending

Value

99990.11

2020

-02

-04

,

(MA

Period

17

)

Ending

Value

100031.43

2020

-02

-04

,

(MA

Period

18

)

Ending

Value

100031.43

2020

-02

-04

,

(MA

Period

19

)

Ending

Value

99985.39

2020

-02

-04

,

(MA

Period

20

)

Ending

Value

100003.41

2020

-02

-04

,

(MA

Period

21

)

Ending

Value

99977.38

2020

-02

-04

,

(MA

Period

22

)

Ending

Value

99990.39

2020

-02

-04

,

(MA

Period

23

)

Ending

Value

99985.39

2020

-02

-04

,

(MA

Period

24

)

Ending

Value

100036.74

2020

-02

-04

,

(MA

Period

25

)

Ending

Value

100036.74

2020

-02

-04

,

(MA

Period

26

)

Ending

Value

100022.75

2020

-02

-04

,

(MA

Period

27

)

Ending

Value

100022.75

2020

-02

-04

,

(MA

Period

28

)

Ending

Value

100022.75

2020

-02

-04

,

(MA

Period

29

)

Ending

Value

100022.75

2020

-02

-04

,

(MA

Period

30

)

Ending

Value

99977.52

/<code>

通過上面的輸出信息我們就可以清晰地看到,選擇不同週期參數時最後的資產情況。本例中,當週期參數選擇為24和25時,可以獲得最大收益。

程序v10-優化:

<code>from __future_

_

import (absolute_import, division, print_function, unicode_literals) import datetime import os.path import sys import backtrader as bt

class

TestStrategy

(

bt

.

Strategy

):

params = ( (

'maperiod'

,

15

), (

'printlog'

, False), )

def

log

(

self

, txt, dt=None, doprint = False)

:

''

' 策略的日誌函數'

''

if

self

.params.printlog

or

doprint:

dt = dt

or

self

.datas[

0

].datetime.date(

0

) print(

'%s, %s'

% (dt.isoformat(), txt))

def

__init__

(

self

)

:

self

.dataclose =

self

.datas[

0

].close

self

.order = None

self

.buyprice = None

self

.buycomm = None

self

.sma = bt.indicators.SimpleMovingAverage(

self

.datas[

0

], period =

self

.params.maperiod)

def

notify_order

(

self

, order)

:

if

order.status

in

[order.Submitted, order.Accepted]:

return

if

order.status

in

[order.Completed]:

if

order.isbuy():

self

.log(

'BUY EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f'

% (order.executed.price, order.executed.value, order.executed.comm))

self

.buyprice = order.executed.price

self

.buycomm = order.executed.comm

else:

self

.log(

'SELL EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f'

% (order.executed.price, order.executed.value, order.executed.comm))

self

.bar_executed = len(

self

) elif order.status

in

[order.Canceled, order.Margin, order.Rejected]:

self

.log(

'Order Canceled/Margin/Rejected'

)

self

.order = None

def

notify_trade

(

self

, trade)

:

if

not

trade.

isclosed:

return

self

.log(

'OPERATION PROFIT, GROSS %.2f, NET %.2f'

% (trade.pnl, trade.pnlcomm))

def

next

(

self

)

:

self

.log(

'Close, %.2f'

%

self

.dataclose[

0

])

if

self

.

order:

return

if

not

self

.

position:

if

self

.dataclose[

0

] >

self

.sma[

0

]:

self

.log(

'BUY CREATE, %.2f'

%

self

.dataclose[

0

])

self

.order =

self

.buy()

else:

if

self

.dataclose[

0

]

self

.sma[

0

]:

self

.log(

'SELL CREATE, %.2f'

%

self

.dataclose[

0

])

self

.order =

self

.sell()

def

stop

(

self

)

:

self

.log(

'(MA Period %2d) Ending Value %.2f'

% (

self

.params.maperiod,

self

.broker.getvalue()), doprint = True) cerebro = bt.Cerebro() strats = cerebro.optstrategy( TestStrategy, maperiod = range(

10

,

31

)) modpath = os.path.dirname(os.path.abspath(sys.argv[

0

])) datapath = os.path.join(modpath,

'../../TQDat/day/stk/000001.csv'

) data = bt.feeds.GenericCSVData( dataname = datapath, fromdate = datetime.datetime(

2019

,

10

,

1

), todate = datetime.datetime(

2020

,

2

,

29

), nullvalue =

0

.

0

, dtformat = (

'%Y/%m/%d'

), datetime =

0

, open =

1

, high =

2

, low =

3

, close =

4

, volume =

5

, openinterest = -

1

) cerebro.adddata(data) cerebro.broker.setcash(

100000.0

) cerebro.addsizer(bt.sizers.FixedSize, stake =

100

) cerebro.broker.setcommission(commission=

0

.

001

) cerebro.run(maxcpus =

1

)/<code>


分享到:


相關文章: