1. accord

accord的判断
之前的固定比例来加仓的方式,实测来看无法应对大波动行情,遂思考使用指标的方式来作为加仓的依据,
思来想去,决定使用1H,4H,1D的K线趋势,来判断短期中期长期的趋势方向。

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
def update_direction_1d(self,side):
"""
更新1d级别趋势(长期)
参数:
- side: 策略的方向
"""
if side != self.strategy_direction_1d:
self.strategy_direction_1d = side.lower()
self.logger.info('\n{} ->变更1D趋势,方向:{}:'.format(self.timestamp,self.strategy_direction_1d))


def update_direction_4h(self,side):
"""
更新4h级别趋势(中期)
参数:
- size: 策略方向
"""
if side != self.strategy_direction_4h:
self.strategy_direction_4h = side.lower()
self.logger.info('\n{} ->变更4H趋势,方向:{}:'.format(self.timestamp,self.strategy_direction_4h))


def update_direction_1h(self,side):
"""
更新1h级别趋势(短期)
参数:
- size: 策略方向
"""

#### 趋势是否一致
self.accord = (side.lower() == self.strategy_direction_1d == self.strategy_direction_4h == self.strategy_direction_1d)

if side.lower() != self.strategy_direction_1h:
self.strategy_direction_1h = side.lower()
self.logger.info('\n{} ->变更1H趋势,方向:{},当前价格:{}:'.format(self.timestamp,self.strategy_direction_1h,self.last_price))

数据依次更新,accord的判断在最后的1H数据更新时判断。
拿到accord数据后,就可以在之前的基础上更新优化了。

  • 以acccord作为趋势的判断条件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    def update_price(self, price):
    """
    更新价格,1秒间隔
    根据价格和最新的策略方向,作用于止盈/止损/加仓
    参数:
    - price: 价格
    """
    if self.running_mode != 2:
    self.timestamp = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')

    if self.accord == True:
    self.strategy_direction = self.strategy_direction_1d
    else :
    if self.direction == 'none' :
    self.strategy_direction = 'none'

    在acccrd为true时,更新仓位为acccrd方向,以备下一步开仓。
    在有仓位的情况下,acccrd为false时,把趋势更新为无趋势,以备下一步调整。

  • 以accord作为开仓辅助条件

    1
    2
    3
    4
    ...
    if self.strategy_direction != 'none' and self.accord:
    self.open_position(self.strategy_direction,True)
    ...
  • 以acccord作为加仓条件

    1
    2
    3
    4
    ...
    elif self.accord == True: #未满仓并且方向一致,走加仓逻辑
    self.check_additional_entry()
    ...
  • 以accord作为辅助止盈条件

    1
    2
    3
    4
    5
    6
    7
    ...
    if self.accord and self.strategy_direction == self.strategy_direction_1d == 'buy':
    self.logger.info('\n{} ->(9)止盈保留首单:'.format(self.timestamp))
    self.open_position('buy',False)
    else:
    self.logger.info('\n{} ->(9)止盈清仓:'.format(self.timestamp))
    ...
  • 以accord作为辅助止损条件

    1
    2
    3
    4
    5
    6
    7
    ...
    if self.accord and self.strategy_direction == self.strategy_direction_1d:
    self.open_position('buy',False)
    self.logger.info('\n{} ->(11)止损并保留首单'.format(self.timestamp))
    else:
    self.logger.info('\n{} ->(11)止损清仓'.format(self.timestamp))
    ...

2. forced_closing

不按固定的比例加仓,自然就无法确定止损位了,遂增加引入了自定义的强制止损比例,作为最后的护城河。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
...
elif (self.direction == 'buy' and self.last_price < self.avg_price):
self.take_profit_loss = 'loss'
Forced_closing = (self.total_quantity - self.last_price * self.total_position ) > self.capital * self.forced_closing
if Forced_closing :
self.strategy_direction = 'none'
self.logger.info('\n{} ->1强制平仓>仓位成本:{},剩余价值:{},止损红线:{}!'.format(self.timestamp,self.total_quantity,self.last_price * self.total_position,self.capital * self.forced_closing))

elif (self.direction == 'sell' and self.last_price > self.avg_price):
self.take_profit_loss = 'loss'
Forced_closing = (self.last_price * self.total_position - self.total_quantity) > self.capital * self.forced_closing
if Forced_closing :
self.strategy_direction = 'none'
self.logger.info('\n{} ->2强制平仓>仓位成本:{},剩余价值:{},止损红线:{}!'.format(self.timestamp,self.total_quantity,self.last_price * self.total_position,self.capital * self.forced_closing))
...

3. max_sl

本次也引入一个重要的运行参数,最大浮亏比例max_sl

1
2
3
4
5
...
if (loss_ratio > 0.03) and (loss_ratio > self.max_sl2) and ((loss_ratio - self.max_sl2) > 0.005):
self.max_sl2 = loss_ratio
self.logger.info('\n{} ->(1)浮亏新高!{}'.format(self.timestamp,self.max_sl2))
...

4. 最后来看看最优的一个回测参数吧

(2023/09/12-2024年/04/20)
2.1总利润102%
2.1最大回撤7.1%