ALGOGENE - A Trend Following Strategy Based On Volatility Approach

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 7

2023/2/10 15:49 ALGOGENE | A trend following strategy based on volatility approach

(/home)

  Categories


A trend following strategy based on volatility approach
tony (https://algogene.com/community/post/61)
lam
Trading Strategy Economy & Market 19

(/community/searchPost?

page=1&category=Economy+%26+Market)
In this article, we will introduce a simple trend following strategy using a volatility approach.
How it work (/community/searchPost? 28

page=1&category=How+it+work)

Volatility Decomposition: Upside vs Downside Programming (/community/searchPost? 38

page=1&category=Programming)
Volatility is used to reflect the magnitude of market fluctuation, and it is usually used to observe market
Quantitative Model 8
sentiment or predict market trends. In financial market, due to the behavior of "Market take the stairs up and the
elevator down", the volatility distribution is not symmetric. Therefore, it is necessary to distinguish upside and (/community/searchPost?
downside volatility. page=1&category=Quantitative+Model)

In this article, we take the opening price as the benchmark, the fluctuation above the opening price is defined as Trading Strategy 9

the upward volatility, otherwise it is the downward volatility. Under normal circumstances, the upward volatility (/community/searchPost?
is greater than the downward volatility when the market is in the upward trend, and vice versa in the downward
page=1&category=Trading+Strategy)
trend.

Calculation Hot Topic

In above definition, the difference between upward and downward volatility is measured as:
哪裡可以查看algo運行情況?
(https://algogene.com/community/post/102)
difft := (Hight + Lowt ) / Opent - 2  22 1 0  2023-02-08

Quant Trader 究竟點樣入行


To smooth out the short-term fluctuations, a N-day moving average is applied. (https://algogene.com/community/post/101)
 38 1 1  2023-02-03

Smoothed Difft = (difft + difft-1 + difft-N+1 ) / N


Request for parameter optimization function
(https://algogene.com/community/post/100)
The market is said to be in an upward trend when the Smoothed Difft is calculated to be positive; and vice versa  83 2 1  2023-01-21
in a downward trend when its value is negative.
Connect Trading Account with Bitget
(https://algogene.com/community/post/99)
 209 4 6  2023-01-12
Trading Logic
Guideline to call App function in strategy
Suppose we take a 60-day moving average, and apply this strategy to the daily closing price of SP500 Index
script
CFD (i.e. SPXUSD) over the year of 2015.01 - 2016.12 (https://algogene.com/community/post/98)

Based on a sliding window approach to collect the previous 250 closing price  166 1 5  2023-01-04

Calculate the 60-day MA smoothed volatility difference


订阅策略后, 哪里可以更改止损水平?
Order open conditions: (https://algogene com/community/post/97)
if we have NO outstanding position,
if the smoothed difference >0, we open a buy order
if the smoothed difference <0, we open a sell order
Order close conditions:
if we have outstanding position,
if we previously submit a buy order and the smooted diff become negative, close the buy
order
if we previously submit a sell order and the smooted diff become positive, close the sell
order
Repeat the process until the backtest period end

Now, let's write down our trading algorithm step-by-step.

https://algogene.com/community/post/61 1/7
2023/2/10 15:49 ALGOGENE | A trend following strategy based on volatility approach

Step 1. Calculate smoothed up/down volatility difference


(/home)
First of all, we define 'ma_period' and 'symbol' at initialization.

1 from AlgoAPI import AlgoAPIUtil, AlgoAPI_Backtest


2 import pandas as pd
3
4 class AlgoEvent:
5 def __init__(self):
6 self.ma_period = 60
7 self.symbol = "SPXUSD"
8

We use the API function getHistoricalBar to collect historical observations. Then, we use the 'pandas' library to
calculate the simple moving average.

1 def on_marketdatafeed(self, md, ab):


2 # get historical data
3 res = self.evt.getHistoricalBar(
4 contract={"instrument": self.symbol},
5 numOfBar=250,
6 interval='D'
7 )
8
9 # calculate smoothed volatility difference
10 diff = [(res[t]['h']+res[t]['l'])/res[t]['o']-2 for t in res]
11 diff_ma = pd.Series(diff).rolling(self.ma_period).mean()
12
13 # extract the current diff_ma value
14 signal = diff_ma[self.ma_period-1]
15
16 # print result to console
17 self.evt.consoleLog(md.timestamp, signal)
18

Step 2. Order Entry Conditions


We create a function 'open_order' to handle order submissions.

1 def open_order(self, buysell):


2 order = AlgoAPIUtil.OrderObject(
3 instrument = self.symbol,
4 openclose = 'open',
5 buysell = buysell, #1=buy, -1=sell
6 ordertype = 0, #0=market, 1=limit
7 volume = 0.01
8 )
9 self.evt.sendOrder(order)

Now, we update the system's function 'on_marketdatafeed' for order open logic. We will use the API function
'getSystemOrders()' to get our outstanding order inventory. (refer to line #20 - #33 below)

https://algogene.com/community/post/61 2/7
2023/2/10 15:49 ALGOGENE | A trend following strategy based on volatility approach

1 def on_marketdatafeed(self, md, ab):


(/home) 2 # get historical data
3 res = self.evt.getHistoricalBar(
4 contract={"instrument": self.symbol},
5 numOfBar=250,
6 interval='D'
7 )
8
9 # calculate smoothed volatility difference
10 diff = [(res[t]['h']+res[t]['l'])/res[t]['o']-2 for t in res]
11 diff_ma = pd.Series(diff).rolling(self.ma_period).mean()
12
13 # extract the current diff_ma value
14 signal = diff_ma[self.ma_period-1]
15
16 # print result to console
17 self.evt.consoleLog(md.timestamp, signal)
18
19
20 # get current order inventory
21 positions, osOrders, _ = self.evt.getSystemOrders()
22 pos = positions[self.symbol]["netVolume"]
23
24 # open order condition
25 if pos==0:
26
27 # open buy order
28 if signal > 0:
29 self.open_order(buysell=1)
30
31 # open sell order
32 elif signal < 0:
33 self.open_order(buysell=-1)

Step 3. Order Close Condition


We continue to update the system's function 'on_marketdatafeed' for close order logic (refer to line #36 - #54
below).

https://algogene.com/community/post/61 3/7
2023/2/10 15:49 ALGOGENE | A trend following strategy based on volatility approach

1 def on_marketdatafeed(self, md, ab):


(/home) 2 # get historical data
3 res = self.evt.getHistoricalBar(
4 contract={"instrument": self.symbol},
5 numOfBar=250,
6 interval='D'
7 )
8
9 # calculate smoothed volatility difference
10 diff = [(res[t]['h']+res[t]['l'])/res[t]['o']-2 for t in res]
11 diff_ma = pd.Series(diff).rolling(self.ma_period).mean()
12
13 # extract the current diff_ma value
14 signal = diff_ma[self.ma_period-1]
15
16 # print result to console
17 self.evt.consoleLog(md.timestamp, signal)
18
19
20 # get current order inventory
21 positions, osOrders, _ = self.evt.getSystemOrders()
22 pos = positions[self.symbol]["netVolume"]
23
24 # open order condition
25 if pos==0:
26
27 # open buy order
28 if signal > 0:
29 self.open_order(buysell=1)
30
31 # open sell order
32 elif signal < 0:
33 self.open_order(buysell=-1)
34
35
36 # close order condition
37 else:
38 isClose = False
39
40 # outstanding position > 0 and signal < 0
41 if pos>0 and signal<0:
42 isClose = True
43 # outstanding position < 0 and signal > 0
44 elif pos<0 and signal>0:
45 isClose = True
46
47 # close all outstanding trade
48 if isClose:
49 for tradeID in osOrders:
50 order = AlgoAPIUtil.OrderObject(
51 tradeID=tradeID,
52 openclose = 'close'
53 )
54 self.evt.sendOrder(order)

Full Source Code


Combining all above, the full script is presented below.

https://algogene.com/community/post/61 4/7
2023/2/10 15:49 ALGOGENE | A trend following strategy based on volatility approach

1 from AlgoAPI import AlgoAPIUtil, AlgoAPI_Backtest


(/home) 2 import pandas as pd
3
4 class AlgoEvent:
5 def __init__(self):
6 self.ma_period = 60
7 self.symbol = "SPXUSD"
8
9 def start(self, mEvt):
10 self.evt = AlgoAPI_Backtest.AlgoEvtHandler(self, mEvt)
11 self.evt.start()
12
13 def on_marketdatafeed(self, md, ab):
14 # get historical data
15 res = self.evt.getHistoricalBar(
16 contract={"instrument": self.symbol},
17 numOfBar=250,
18 interval='D'
19 )
20
21 # calculate smoothed volatility difference
22 diff = [(res[t]['h']+res[t]['l'])/res[t]['o']-2 for t in res]
23 diff_ma = pd.Series(diff).rolling(self.ma_period).mean()
24
25 # extract the current diff_ma value
26 signal = diff_ma[self.ma_period-1]
27
28 # print result to console
29 self.evt.consoleLog(md.timestamp, signal)
30
31
32 # get current order inventory
33 positions, osOrders, _ = self.evt.getSystemOrders()
34 pos = positions[self.symbol]["netVolume"]
35
36 # open order condition
37 if pos==0:
38
39 # open buy order
40 if signal > 0:
41 self.open_order(buysell=1)
42
43 # open sell order
44 elif signal < 0:
45 self.open_order(buysell=-1)
46
47
48 # close order condition
49 else:
50 isClose = False
51
52 # outstanding position > 0 and signal < 0
53 if pos>0 and signal<0:
54 isClose = True
55 # outstanding position < 0 and signal > 0
56 elif pos<0 and signal>0:
57 isClose = True
58
59 # close all outstanding trade
60 if isClose:
61 for tradeID in osOrders:
62 order = AlgoAPIUtil.OrderObject(
63 tradeID=tradeID,
64 openclose = 'close'
65 )
66 self.evt.sendOrder(order)
67
68
69 def open_order(self, buysell):
70 order = AlgoAPIUtil.OrderObject(
71 instrument = self.symbol,
72 openclose = 'open',
73 buysell = buysell, #1=buy, -1=sell
74 ordertype = 0, #0=market, 1=limit
75 volume = 0.01
76 )
77 self.evt.sendOrder(order)

Results
Now, we are prepared to backtest this strategy.

Backtest Settings:

Instrument: SPXUSD
Period: 2015.01 - 2016.12
Initial Capital: US$10,000
Data Interval: 1-day bar
Leverage: 1

https://algogene.com/community/post/61 5/7
2023/2/10 15:49 ALGOGENE | A trend following strategy based on volatility approach
Allow Shortsell: True

(/home)

Backtest Result:

Final Thoughts
The result above does not perform well. Below are some ideas to improve this trading strategy:

The current entry condition solely based on a non-zero smoothed value which is easy to trigger. Filter the
value by a certain threshold may increase the trend signal's accuracy.
Adding take profit/ stop loss level may be helpful to cut lost/gain earlier.
The MA period in this example is taken to be 60-day. Different smoothing period could be more
appropriate.

 2  0   Posted on : 2022-05-09 07:05:19.367000

   827

 (/community/post/61?page=1) 1 (/community/post/61?page=1)

 (/community/post/61?page=1)

About
ALGOGENE is the next generation investment platform for learning, developing, testing, executing, and investing trading bots!

Contact Us (/home#divContactUs)
Terms & Conditions (/terms)
Privacy Policy (/privacy)
Download App (/community/post/10)
Career Opportunity (/career)

https://algogene.com/community/post/61 6/7
2023/2/10 15:49 ALGOGENE | A trend following strategy based on volatility approach

Trader & Developer


(/home)
API Documentation (/RestDoc)
Algo Trading Challenge (/contest)
Algo Research Lab (/services#divServicesBacktest)
Algo Live Simulator (/services#divServicesLiveDemo)
Integrated Trading Engine (/services#divServicesLiveTrade)
Market Data Solution (/services#divServicesAPI)
Algo Partnership (/community/post/19)
Trading App Store (/marketplace#app)
Open Data Collection (/marketplace#data)

Investor
Algo Marketplace (/marketplace#bot)
Community (/community)
Referral Program (/referral)
Robo-Trader (/community/post/16)
Robo-Advisor (/community/post/57)
Portfolio Builder (/services#divServicesPortfolio)
Enterprise Trading Solutions (/services#divServicesProject)


(https://www.linkedin.com/company/algogene-
financial-
 technology- 
(https://www.facebook.com/Algogene-
 company-   (https://github.com/algogene-
102449291574807) fintech)
(https://www.youtube.com/channel/UCKDkZCKPG3EBXnrPIUz6uMw)
limited)(https://www.instagram.com/algogene_fintech/)
(https://twitter.com/ALGOGENE_)

 English

© 2023 Copyright | ALGOGENE FINTECH CO. LTD. | All Right Reserved

https://algogene.com/community/post/61 7/7

You might also like