当前位置: 首页 > news >正文

在 Python 中使用 ADX 进行算法交易

在阅读本文前,可查阅以往文章: 技术指标-ATR

技术指标有几个分支,其中趋势指标使用最广泛。这些工具可帮助交易者确定市场趋势的方向和强度,使他们能够相应地调整交易。如果趋势指标得到有效应用,它们通常会产生积极的结果。

在本文中,将仔细研究最突出的趋势指标之一——平均方向指数 (ADX)。首先,将对 ADX 有一个基本的了解,包括其用途和计算。之后,将从头开始开发指标,并在 Python 中基于它实施交易策略。为了评估策略的有效性,将使用 Apple 股票对其进行回溯测试,并将其回报与跟踪标准普尔 500 指数的 SPY ETF 的回报进行比较。

平均真实范围 (ATR)

在深入研究平均方向指数 (ADX) 之前,了解平均真实范围 (ATR) 至关重要,因为它在计算 ADX 中起着关键作用。

ATR 是一种技术指标,用于通过确定资产的平均波动量来衡量资产的波动性。它是一个滞后指标,这意味着它使用过去的价格数据来计算当前值,但无法预测未来价格。然而,这种滞后不一定是缺点,因为 ATR 旨在更准确地跟踪市场波动。此外,ATR 是非方向性的,这意味着它的走势独立于市场方向。要计算 ATR,请执行以下步骤:

  1. 计算真实范围 (TR):真实范围是三个值中的最大值:
  • 市场最高价减去市场最低价
  • 市场最高价减去前一收盘价
  • 前一收盘价减去市场低点这可以表示为:

      TR = MAX[ {HIGH - LOW}, {HIGH - P.CLOSE}, {P.CLOSE - LOW} ]
  1. 计算 ATR:计算 TR 后,ATR 是通过取指定周期数的 TR 值的平滑平均值来确定的。虽然最初的 ATR 计算涉及 Wilder Wiles(指标的创建者)的自定义平滑平均线,但也可以使用其他移动平均线,例如 SMA 或 EMA。为简单起见,本文将使用 14 周期 SMA,计算公式如下:

      ATR 14 = SMA 14 [ TR ]

尽管 ATR 滞后,但它对于跟踪市场波动仍然非常有用。现在我们已经介绍了 ATR,让我们继续讨论本文的主要重点:平均方向指数 (ADX)

平均方向指数 (ADX)

ADX 是一种广泛使用的技术指标,用于衡量市场趋势的强度。虽然 ADX 没有指定趋势是看涨还是看跌,但它表明该趋势的强度。为了确定趋势方向,ADX 与正方向指数 (+DI) 和负方向指数 (-DI) 配对。顾名思义,+DI 衡量积极趋势(看涨),而 -DI 衡量消极趋势(看跌)。ADX 值通常介于 0 到 100 之间,使其成为振荡器。传统的 ADX 设置使用 14 周期回溯。

要使用 14 周期回溯计算 ADX,请执行以下步骤:

  1. 确定正向 (+DM) 和负向移动 (-DM):
  • +DM 计算为当前高点与前期高点之间的差值

  • -DM 计算为前一个低点与当前低点之间的差值

    +DM = CURRENT HIGH - PREVIOUS HIGH-DM = PREVIOUS LOW - CURRENT LOW
    
  1. 计算 ATR:如上一节所述计算 14 周期 ATR。

  2. 计算 +DI 和 -DI:要找到 +DI,请将 +DM 的 14 周期 EMA 除以 14 周期 ATR,然后乘以 100。对于 -DI,请使用 -DM 的 14 周期 EMA。这些公式是:

  +DI 14 = 100 * [ EMA 14 ( +DM ) / ATR 14 ]-DI 14 = 100 * [ EMA 14 ( -DM ) / ATR 14 ]
  1. 确定方向指数 (DI):方向指数的计算方法是将 +DI 和 -DI 之间的绝对差除以它们的总和,然后乘以 100。公式为:

  DI 14 = | (+DI 14) - (-DI 14) | / | (+DI 14) + (-DI 14) | * 100
  1. 计算 ADX:ADX 是通过取当前 DI 值和先前 DI 值的加权平均值来计算的。具体来说,前一个 DI 乘以 13(回溯期减 1)并添加到当前 DI 中。公式为:

  DX 14 = [ ( PREV DI 14 * 13 ) + DI 14 ] / 14

最后,使用 Wilder Wiles 设计的自定义移动平均线对 ADX 值进行平滑处理。此平滑过程可确保 ADX 值对于趋势分析是准确且一致的。

交易策略

在本文中,将构建一个简单的交叉策略。每当 ADX 线超过 25 且 +DI 线高于 -DI 线时,该策略就会发出买入信号。相反,当 ADX 线越过 25 以上,但 -DI 线高于 +DI 线时,会触发卖出信号。我们交易策略的逻辑可以表示为:

IF P.ADX < 25 AND C.ADX > 25 AND + DI LINE > - DI LINE ==> BUYIF P.ADX < 25 AND C.ADX > 25 AND + DI LINE < - DI LINE ==> SELL

将继续在 Python 中从头开始编写 ADX 指标,并基于该指标创建交易策略。然后,将使用 Apple 股票数据对其进行回溯测试,并将该策略的表现与 SPY ETF 进行比较,以评估我们的 ADX 交叉策略与基准相比的表现。让我们深入研究编码。

Python 中的实现

步骤 1:导入包

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
# from termcolor import colored as cl
from math import floor
# from eodhd import APIClient
# Suppress warnings for cleaner output
import warnings
warnings.filterwarnings("ignore")plt.rcParams['figure.figsize'] = (20,10)
plt.style.use('fivethirtyeight')

第 2 步:API 密钥激活

api_key = '<YOUR API KEY>'
client = APIClient(api_key)

步骤 3:提取历史数据

# EXTRACTING HISTORICAL DATAdef get_historical_data(ticker, start_date):json_resp = client.get_eod_historical_stock_market_data(symbol = ticker, period = 'd', from_date = start_date, order = 'a')df = pd.DataFrame(json_resp)df = df.set_index('date')df.index = pd.to_datetime(df.index)return dfdef get_stock_data_csv(filepath):stock = pd.read_csv(filepath,parse_dates=['Date'])stock['Date'] = pd.to_datetime(stock['Date'], utc=True).dt.tz_localize(None)stock = stock.set_index('Date')return stockaapl = get_stock_data_csv('./data.csv')
spy = get_stock_data_csv('./SPY.csv')
print(aapl.tail())
print(spy.tail())
# aapl = get_historical_data('AAPL', '2020-01-01')
# aapl.tail()
                           Open        High         Low       Close    Volume  \
Date                                                                            
2024-12-11 05:00:00  247.960007  250.800003  246.259995  246.490005  45205800   
2024-12-12 05:00:00  246.889999  248.740005  245.679993  247.960007  32777500   
2024-12-13 05:00:00  247.820007  249.289993  246.240005  248.130005  33155300   
2024-12-16 05:00:00  247.990005  251.380005  247.649994  251.039993  51694800   
2024-12-17 05:00:00  250.080002  253.830002  249.779999  253.479996  51321700   DividendsStockSplits
Date                                          
2024-12-11 05:00:00        0.0           0.0
2024-12-12 05:00:00        0.0           0.0
2024-12-13 05:00:00        0.0           0.0
2024-12-16 05:00:00        0.0           0.0
2024-12-17 05:00:00        0.0           0.0Close    Open    High     Low     Vol     涨跌幅
Date                                                      
2024-01-16  474.93  475.26  476.61  473.06  85.01M-0.37%
2024-01-12  476.68  477.84  478.60  475.23  58.03M   0.07%
2024-01-11  476.35  477.59  478.12  472.26  77.94M-0.04%
2024-01-10  476.56  474.16  477.45  473.87  67.31M   0.57%
2024-01-09  473.88  471.87  474.93  471.35  65.93M-0.15%

第 4 步:ADX 计算

计算平均方向指数 (ADX) 值

def get_adx(high, low, close, lookback):plus_dm = high.diff()minus_dm = low.diff()plus_dm[plus_dm < 0] = 0minus_dm[minus_dm > 0] = 0tr1 = pd.DataFrame(high - low)tr2 = pd.DataFrame(abs(high - close.shift(1)))tr3 = pd.DataFrame(abs(low - close.shift(1)))frames = [tr1, tr2, tr3]tr = pd.concat(frames, axis = 1, join = 'inner').max(axis = 1)atr = tr.rolling(lookback).mean()plus_di = 100 * (plus_dm.ewm(alpha = 1/lookback).mean() / atr)minus_di = abs(100 * (minus_dm.ewm(alpha = 1/lookback).mean() / atr))dx = (abs(plus_di - minus_di) / abs(plus_di + minus_di)) * 100adx = ((dx.shift(1) * (lookback - 1)) + dx) / lookbackadx_smooth = adx.ewm(alpha = 1/lookback).mean()return plus_di, minus_di, adx_smoothaapl['plus_di'] = pd.DataFrame(get_adx(aapl['High'], aapl['Low'], aapl['Close'], 14)[0]).rename(columns = {0:'plus_di'})
aapl['minus_di'] = pd.DataFrame(get_adx(aapl['High'], aapl['Low'], aapl['Close'], 14)[1]).rename(columns = {0:'minus_di'})
aapl['adx'] = pd.DataFrame(get_adx(aapl['High'], aapl['Low'], aapl['Close'], 14)[2]).rename(columns = {0:'adx'})
aapl = aapl.dropna()
aapl.tail()

Open

High

Low

Close

Volume

Dividends

Stock Splits

plus_di

minus_di

adx

Date

2024-12-11 05:00:00

247.960007

250.800003

246.259995

246.490005

45205800

0.0

0.0

39.240212

10.421796

26.914880

2024-12-12 05:00:00

246.889999

248.740005

245.679993

247.960007

32777500

0.0

0.0

37.541729

11.235419

29.116418

2024-12-13 05:00:00

247.820007

249.289993

246.240005

248.130005

33155300

0.0

0.0

35.755395

10.344918

30.894996

2024-12-16 05:00:00

247.990005

251.380005

247.649994

251.039993

51694800

0.0

0.0

37.541790

9.560514

32.647216

2024-12-17 05:00:00

250.080002

253.830002

249.779999

253.479996

51321700

0.0

0.0

38.999477

8.626999

34.580789

首先定义一个名为 get_adx 的函数,该函数采用四个参数:股票的最高价 (high)、最低价 (low) 和收盘价 (close) 价格,以及回溯期 (lookback),它决定了计算时要考虑的周期数。

  • plus_dm 计算当前高点和前一高点之间的差值。任何负值都设置为零。
  • minus_dm 计算前一个低点和当前低点之间的差值。任何正值都设置为零
  • 真实范围 (TR)
  • 我们计算三个价格差值:当前最高价减去最低价,绝对最高价减去前一收盘价,绝对最低价减去前一收盘价。
  • 真实范围 (TR) 是每个时间段这三个差异中的最大值,我们将其存储在 tr 变量中。
  • ATR 计算为指定回溯期内真实范围 (tr) 的滚动平均值。我们将此值存储在 atr 变量中。
  • 方向指数 (DX)
  • 方向指数 (DX) 衡量 +DI 和 -DI 之间的差异。
  • DX 的计算方法是将 +DI 和 -DI 之间的绝对差除以它们的总和,然后乘以 100。DX 值存储在 dx 变量中。
  • ADX 是使用平滑技术计算的。当前 DX 乘以回溯期,之前的 ADX 乘以上一期计数。此平滑的 ADX 存储在 adx_smooth 变量中。

第 5 步:ADX 图

将可视化计算出的 Apple (AAPL) 的 ADX 值,以更好地了解趋势强度和方向性运动。这里的主要目标是观察该图,以便更好地了解平均方向指数 (ADX) 以及正方向指标 (+DI) 和负方向指标 (-DI) 如何随时间变化。

ax1 = plt.subplot2grid((11,1), (0,0), rowspan = 5, colspan = 1)
ax2 = plt.subplot2grid((11,1), (6,0), rowspan = 5, colspan = 1)
ax1.plot(aapl['Close'], linewidth = 2, color = '#ff9800')
ax1.set_title('AAPL CLOSING PRICE')
ax2.plot(aapl['plus_di'], color = '#26a69a', label = '+ DI 14', linewidth = 3, alpha = 0.3)
ax2.plot(aapl['minus_di'], color = '#f44336', label = '- DI 14', linewidth = 3, alpha = 0.3)
ax2.plot(aapl['adx'], color = '#2196f3', label = 'ADX 14', linewidth = 3)
ax2.axhline(25, color = 'grey', linewidth = 2, linestyle = '--')
ax2.legend()
ax2.set_title('AAPL ADX 14')
plt.show()

图片

png

上图分为两个部分:顶部显示苹果的收盘价,而底部显示 ADX 指标的组成部分。在下方面板中,与 ADX 一起,您将看到一条设置为 25 级别的灰色虚线,用作阈值。如前所述,ADX 不衡量趋势方向,而是衡量趋势的强度。这在图表中很明显,因为 ADX 线在市场表现出强劲趋势(无论是向上还是向下)时上升,在市场盘整期间下跌。

这同样适用于方向索引 (+DI 和 -DI) 行。+DI 线往往在稳固的上升趋势中上升,在市场下跌时下降。相反,-DI 线在下降趋势中增加,在上升趋势中下降。

ADX 不仅可用于衡量趋势强度;它也是识别区间市场的绝佳工具(当一只股票在定义的高点和低点之间波动而没有明显的动量时)。当 +DI 和 -DI 线靠得更近时,市场通常是区间波动的。相反,这些线之间的差距越大,市场趋势的可能性就越大。对于那些不熟悉 ADX 图表的人来说,线条运动和市场方向之间的反比关系最初可能看起来令人困惑。

第 6 步:创建交易策略

首先定义函数 implement_adx_strategy,它采用四个参数:股票价格 (prices)、正方向指数 (pdi)、负方向指数 (ndi) 和平均方向指数 (adx)。

def implement_adx_strategy(prices, pdi, ndi, adx):buy_price = []sell_price = []adx_signal = []signal = 0for i in range(len(prices)):if adx[i-1] < 25and adx[i] > 25and pdi[i] > ndi[i]:if signal != 1:buy_price.append(prices[i])sell_price.append(np.nan)signal = 1adx_signal.append(signal)else:buy_price.append(np.nan)sell_price.append(np.nan)adx_signal.append(0)elif adx[i-1] < 25and adx[i] > 25and ndi[i] > pdi[i]:if signal != -1:buy_price.append(np.nan)sell_price.append(prices[i])signal = -1adx_signal.append(signal)else:buy_price.append(np.nan)sell_price.append(np.nan)adx_signal.append(0)else:buy_price.append(np.nan)sell_price.append(np.nan)adx_signal.append(0)return buy_price, sell_price, adx_signalbuy_price, sell_price, adx_signal = implement_adx_strategy(aapl['Close'], aapl['plus_di'], aapl['minus_di'], aapl['adx'])

第 7 步:绘制交易信号

将可视化生成的交易信号以及 Apple 的股票价格和 ADX 值。该图将帮助我们了解触发买入和卖出信号的点,以及市场趋势的整体强度。

ax1 = plt.subplot2grid((11,1), (0,0), rowspan = 5, colspan = 1)
ax2 = plt.subplot2grid((11,1), (6,0), rowspan = 5, colspan = 1)
ax1.plot(aapl['Close'], linewidth = 3, color = '#ff9800', alpha = 0.6)
ax1.set_title('AAPL CLOSING PRICE')
ax1.plot(aapl.index, buy_price, marker = '^', color = '#26a69a', markersize = 14, linewidth = 0, label = 'BUY SIGNAL')
ax1.plot(aapl.index, sell_price, marker = 'v', color = '#f44336', markersize = 14, linewidth = 0, label = 'SELL SIGNAL')
ax2.plot(aapl['plus_di'], color = '#26a69a', label = '+ DI 14', linewidth = 3, alpha = 0.3)
ax2.plot(aapl['minus_di'], color = '#f44336', label = '- DI 14', linewidth = 3, alpha = 0.3)
ax2.plot(aapl['adx'], color = '#2196f3', label = 'ADX 14', linewidth = 3)
ax2.axhline(25, color = 'grey', linewidth = 2, linestyle = '--')
ax2.legend()
ax2.set_title('AAPL ADX 14')
plt.show()

图片

第 8 步:创建位置

将创建一个头寸列表,该列表根据 ADX 策略生成的买入和卖出信号指示我们是否持有股票(用 1 表示)或不持有(用 0 表示)。

position = []
for i in range(len(adx_signal)):if adx_signal[i] > 1:position.append(0)else:position.append(1)for i in range(len(aapl['Close'])):if adx_signal[i] == 1:position[i] = 1elif adx_signal[i] == -1:position[i] = 0else:position[i] = position[i-1]close_price = aapl['Close']
plus_di = aapl['plus_di']
minus_di = aapl['minus_di']
adx = aapl['adx']
adx_signal = pd.DataFrame(adx_signal).rename(columns = {0:'adx_signal'}).set_index(aapl.index)
position = pd.DataFrame(position).rename(columns = {0:'adx_position'}).set_index(aapl.index)frames = [close_price, plus_di, minus_di, adx, adx_signal, position]
strategy = pd.concat(frames, join = 'inner', axis = 1)strategy

Close

plus_di

minus_di

adx

adx_signal

adx_position

Date

2024-01-09 05:00:00

184.237411

13.867265

43.053447

51.275152

0

1

2024-01-10 05:00:00

185.282288

16.287091

37.208587

50.824545

0

1

2024-01-11 05:00:00

184.685211

16.551815

33.924799

46.506508

0

1

2024-01-12 05:00:00

185.013611

15.624095

32.023333

43.140585

0

1

2024-01-16 05:00:00

182.734787

13.298633

40.283191

41.391108

0

1

...

...

...

...

...

...

...

2024-12-11 05:00:00

246.490005

39.240212

10.421796

26.914880

0

1

2024-12-12 05:00:00

247.960007

37.541729

11.235419

29.116418

0

1

2024-12-13 05:00:00

248.130005

35.755395

10.344918

30.894996

0

1

2024-12-16 05:00:00

251.039993

37.541790

9.560514

32.647216

0

1

2024-12-17 05:00:00

253.479996

38.999477

8.626999

34.580789

0

1

238 rows × 6 columns

第 9 步:回测

将使用 Apple (AAPL) 的历史股票数据为我们的平均方向指数 (ADX) 交易策略实施回溯测试流程。这将帮助我们评估我们的策略在选定时间段内的表现。让我们继续实施此过程。

aapl_ret = pd.DataFrame(np.diff(aapl['Close'])).rename(columns = {0:'returns'})
adx_strategy_ret = []for i in range(len(aapl_ret)):returns = aapl_ret['returns'][i]*strategy['adx_position'][i]adx_strategy_ret.append(returns)adx_strategy_ret_df = pd.DataFrame(adx_strategy_ret).rename(columns = {0:'adx_returns'})
investment_value = 100000
adx_investment_ret = []for i in range(len(adx_strategy_ret_df['adx_returns'])):number_of_stocks = floor(investment_value/aapl['Close'][i])returns = number_of_stocks*adx_strategy_ret_df['adx_returns'][i]adx_investment_ret.append(returns)adx_investment_ret_df = pd.DataFrame(adx_investment_ret).rename(columns = {0:'investment_returns'})
total_investment_ret = round(sum(adx_investment_ret_df['investment_returns']), 2)
profit_percentage = floor((total_investment_ret/investment_value)*100)
print('Profit gained from the ADX strategy by investing $100k in AAPL : {}'.format(total_investment_ret))
print('Profit percentage of the ADX strategy : {}%'.format(profit_percentage))
Profit gained from the ADX strategy by investing $100k in AAPL : 29391.81
Profit percentage of the ADX strategy : 29%

第 10 步:SPY ETF 比较

将使用我们创建的“get_historical_data”函数检索 SPY ETF 数据,并将其回报与应用于 Apple 的平均方向指数策略的回报进行比较。

def get_benchmark(spy_holp, start_date, investment_value):#spy = get_historical_data('SPY', start_date)['Close']spy = spy_holp['Close']benchmark = pd.DataFrame(np.diff(spy)).rename(columns = {0:'benchmark_returns'})investment_value = investment_valuebenchmark_investment_ret = []for i in range(len(benchmark['benchmark_returns'])):number_of_stocks = floor(investment_value/spy[i])returns = number_of_stocks*benchmark['benchmark_returns'][i]benchmark_investment_ret.append(returns)benchmark_investment_ret_df = pd.DataFrame(benchmark_investment_ret).rename(columns = {0:'investment_returns'})return benchmark_investment_ret_dfbenchmark = get_benchmark(spy,'2024-01-09', 100000)investment_value = 100000
total_benchmark_investment_ret = round(sum(benchmark['investment_returns']), 2)
benchmark_profit_percentage = floor((total_benchmark_investment_ret/investment_value)*100)
print(('Benchmark profit by investing $100k : {}'.format(total_benchmark_investment_ret)))
print(('Benchmark Profit percentage : {}%'.format(benchmark_profit_percentage)))
print(('ADX Strategy profit is {}% higher than the Benchmark Profit'.format(profit_percentage - benchmark_profit_percentage)))
Benchmark profit by investing $100k : -23540.15
Benchmark Profit percentage : -24%
ADX Strategy profit is 53% higher than the Benchmark Profit

结论

在了解了理论和编码方面之后,我们对平均方向指数 (ADX) 以及如何使用 Python 构建基于 ADX 的基本交易策略有了深入的了解。

ADX 的真正潜力在于与其他技术指标(例如 RSI)相结合,以微调交易中的进入和退出点。因此,我鼓励您通过调整 ADX 策略,将其与其他指标集成,并对其进行广泛的回溯测试,从而进一步阅读本文。这样做有助于在实际交易场景中获得更精细的结果。

相关文章:

在 Python 中使用 ADX 进行算法交易

在阅读本文前&#xff0c;可查阅以往文章: 技术指标-ATR 技术指标有几个分支&#xff0c;其中趋势指标使用最广泛。这些工具可帮助交易者确定市场趋势的方向和强度&#xff0c;使他们能够相应地调整交易。如果趋势指标得到有效应用&#xff0c;它们通常会产生积极的结果。 在…...

Unity 3D 从入门到精通:开启游戏开发的奇幻之旅

一、引言 在当今数字化的时代&#xff0c;游戏产业蓬勃发展&#xff0c;成为了全球娱乐领域的重要支柱。Unity 3D 作为一款功能强大、跨平台的游戏开发引擎&#xff0c;凭借其易用性、高效性和丰富的资源&#xff0c;吸引了无数开发者投身于游戏创作的世界。无论是独立开发者怀…...

神经网络-VggNet

2014年VggNet被推出&#xff0c;获取了ILSVRC2014比赛分类项目的第二名&#xff0c;第一名是GoogleNet&#xff0c;该网络在下节介绍&#xff0c;本节主要介绍VggNet。 VggNet可以称为是一个家族&#xff0c;根据层数的不同包括了A、A-LRN、B、C、D等网络结构&#xff0c;其中…...

用AI生成PPT,告别繁琐,一键生成高效方案

用AI生成PPT&#xff0c;告别繁琐&#xff0c;一键生成高效方案&#xff01;制作PPT曾经是一件非常繁琐的工作。让人又爱又恨&#xff0c;爱的是它可以让你的想法可视化&#xff0c;恨的是&#xff0c;要做出一份精美的PPT&#xff0c;往往需要耗费大量时间和精力。现在AI技术的…...

基于 `android.accessibilityservice` 的 Android 无障碍服务深度解析

基于 android.accessibilityservice 的 Android 无障碍服务深度解析 目录 引言无障碍服务概述架构设计核心功能设计模式核心要点实现细节性能优化安全与隐私案例分析未来展望结论引言 在当今的移动应用生态系统中,无障碍服务(Accessibility Service)扮演着至关重要的角色。…...

UE5材质节点Frac/Fmod

Frac取小数 Fmod取余数 转场效果 TimeMultiplyFrac很常用 Timesin / Timecos 制作闪烁效果...

【微服务】【Sentinel】认识Sentinel

文章目录 1. 雪崩问题2. 解决方案3. 服务保护技术对比4. 安装 Sentinel4.1 启动控制台4.2 客户端接入控制台 参考资料: 1. 雪崩问题 微服务调用链路中的某个服务故障&#xff0c;引起整个链路中的所有微服务都不可用&#xff0c;这就是雪崩。动图演示&#xff1a; 在微服务系统…...

Kafka 性能提升秘籍:涵盖配置、迁移与深度巡检的综合方案

文章目录 1.1.网络和io操作线程配置优化1.2.log数据文件刷盘策略1.3.日志保留策略配置1.4.replica复制配置1.5.配置jmx服务1.6.系统I/O参数优化1.6.1.网络性能优化1.6.2.常见痛点以及优化方案1.6.4.优化参数 1.7.版本升级1.8.数据迁移1.8.1.同集群broker之间迁移1.8.2.跨集群迁…...

小程序租赁系统构建指南与市场机会分析

内容概要 在当今竞争激烈的市场环境中&#xff0c;小程序租赁系统正崭露头角&#xff0c;成为企业转型与创新的重要工具。通过这个系统&#xff0c;商户能够快速推出自己的小程序&#xff0c;无需从头开发&#xff0c;节省了大量时间和资金。让我们来看看这个系统的核心功能吧…...

SOME/IP 协议详解——远程过程调用(RPC)

文章目录 1. 传输协议绑定1.1 UDP 绑定1.2 TCP 绑定1.3 多服务实例&#xff08;重要&#xff09;1.4 通过 UDP 传输大型 SOME/IP 消息&#xff08;SOME/IP - TP&#xff09; 2. 请求 / 响应通信3. Fire&Forget 通信4. 通知事件5. 字段6. 错误处理6.1 返回码6.2 错误消息6.3…...

C++ 设计模式:命令模式(Command Pattern)

链接&#xff1a;C 设计模式 链接&#xff1a;C 设计模式 - 访问者模式 命令模式&#xff08;Command Pattern&#xff09;是一种行为型设计模式&#xff0c;它将请求封装成一个对象&#xff0c;从而使你可以用不同的请求对客户进行参数化&#xff0c;对请求排队或记录请求日志…...

安卓/system/bin下命令中文说明(AI)

ATFWD-daemon&#xff1a;AT指令转发守护进程&#xff0c;用于将AT指令从应用层转发到调制解调器。 PktRspTest&#xff1a;数据包响应测试工具。 StoreKeybox&#xff1a;存储密钥盒工具&#xff0c;用于安全地存储加密密钥。 WifiLogger_app&#xff1a;WiFi日志记录应用&…...

MATLAB程序转C# WPF,dll集成,混合编程

工作中遇到一个需求&#xff0c;有一部分算法的代码需要MATLAB来进行处理&#xff0c;而最后需要集成到C#中的wpf项目中去&#xff0c;选择灵活性更高的dll&#xff0c;去进行集成。&#xff08;可以简单理解为&#xff1a;将MATLAB的函数&#xff0c;变为C#中类的函数成员&…...

【SpringBoot3】Spring Boot 3.0 集成 Mybatis Plus

文章目录 一、什么是 Mybatis Plus 特性 二、Spring Boot 3.0 集成 Mybatis Plus三、Mybatis Plus 查询示例 1、普通查询2、分页查询 参考 一、什么是 Mybatis Plus MyBatis-Plus&#xff08;简称 MP&#xff09;是一个 MyBatis 的增强工具&#xff0c;在 MyBatis 的基础上只…...

nvidia_gpu_exporter 显卡监控

导入 grafana/dashboard.json https://github.com/utkuozdemir/nvidia_gpu_exporter/blob/master/grafana/dashboard.json参考 nvidia_gpu_exporter...

WebSocket 的封装使用

import { ElMessage } from "element-plus";// 全局WebSocket实例 let ws null; let isConnected false; let currentWsUrl ; // 用于存储当前的wsUrl let baseURL ws://XXX.com:8081;const initWebSocket (wsUrl, sendData) > {return new Prom…...

SqlSession的线程安全问题源码分析

&#x1f3ae; 作者主页&#xff1a;点击 &#x1f381; 完整专栏和代码&#xff1a;点击 &#x1f3e1; 博客主页&#xff1a;点击 文章目录 SqlSession 是线程安全的吗&#xff1f;为什么说是线程不安全的&#xff1f;事务管理问题 数据库连接的共享问题 一级缓存线程安全问题…...

Java 8 及经典面试题全解析

Java 是目前非常流行的编程语言之一&#xff0c;其强大的生态系统和丰富的功能使得它在企业级开发中占据重要地位。在面试中&#xff0c;Java 的基础知识、集合框架、多线程、JVM&#xff0c;以及 Java 8 的新特性是重点考查内容。本文将结合 Java 8 和经典知识点&#xff0c;为…...

MySQL:安装配置(完整教程)

这里写目录标题 一、MySQL 简介二、下载 MySQL三、安装 MySQL四、配置环境变量五、配置 MySQL5.1 初始化 MySQL5.2 启动 MySQL 服务 六、修改 MySQL 密码七、卸载 MySQL八、结语 一、MySQL 简介 MySQL 是一款广泛使用的开源关系型数据库管理系统&#xff08;RDBMS&#xff09;…...

Java - 日志体系_Apache Commons Logging(JCL)日志接口库_桥接Logback 及 源码分析

文章目录 PreApache CommonsApache Commons ProperLogging &#xff08;Apache Commons Logging &#xff09; JCL 集成logbackPOM依赖配置文件 logback.xml使用 源码分析jcl-over-slf4j 的工作原理1. LogFactory 的实现2. SLF4JLogFactory 和 Log 的实例化过程3. SLF4JLog 和 …...

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框&#xff0c;很难让人不联想到SQL注入&#xff0c;但提示都说了不是SQL注入&#xff0c;所以就不往这方面想了 ​ 先查看一下网页源码&#xff0c;发现一段JavaScript代码&#xff0c;有一个关键类ctfs…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

Spring是如何解决Bean的循环依赖:三级缓存机制

1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间‌互相持有对方引用‌,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

面向无人机海岸带生态系统监测的语义分割基准数据集

描述&#xff1a;海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而&#xff0c;目前该领域仍面临一个挑战&#xff0c;即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...

tomcat入门

1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效&#xff0c;稳定&#xff0c;易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...

LOOI机器人的技术实现解析:从手势识别到边缘检测

LOOI机器人作为一款创新的AI硬件产品&#xff0c;通过将智能手机转变为具有情感交互能力的桌面机器人&#xff0c;展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家&#xff0c;我将全面解析LOOI的技术实现架构&#xff0c;特别是其手势识别、物体识别和环境…...