在 Python 中使用 ADX 进行算法交易
在阅读本文前,可查阅以往文章: 技术指标-ATR
技术指标有几个分支,其中趋势指标使用最广泛。这些工具可帮助交易者确定市场趋势的方向和强度,使他们能够相应地调整交易。如果趋势指标得到有效应用,它们通常会产生积极的结果。
在本文中,将仔细研究最突出的趋势指标之一——平均方向指数 (ADX)。首先,将对 ADX 有一个基本的了解,包括其用途和计算。之后,将从头开始开发指标,并在 Python 中基于它实施交易策略。为了评估策略的有效性,将使用 Apple 股票对其进行回溯测试,并将其回报与跟踪标准普尔 500 指数的 SPY ETF 的回报进行比较。
平均真实范围 (ATR)
在深入研究平均方向指数 (ADX) 之前,了解平均真实范围 (ATR) 至关重要,因为它在计算 ADX 中起着关键作用。
ATR 是一种技术指标,用于通过确定资产的平均波动量来衡量资产的波动性。它是一个滞后指标,这意味着它使用过去的价格数据来计算当前值,但无法预测未来价格。然而,这种滞后不一定是缺点,因为 ATR 旨在更准确地跟踪市场波动。此外,ATR 是非方向性的,这意味着它的走势独立于市场方向。要计算 ATR,请执行以下步骤:
- 计算真实范围 (TR):真实范围是三个值中的最大值:
- 市场最高价减去市场最低价
- 市场最高价减去前一收盘价
- 前一收盘价减去市场低点这可以表示为:
TR = MAX[ {HIGH - LOW}, {HIGH - P.CLOSE}, {P.CLOSE - LOW} ]
- 计算 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,请执行以下步骤:
- 确定正向 (+DM) 和负向移动 (-DM):
-
+DM 计算为当前高点与前期高点之间的差值
-
-DM 计算为前一个低点与当前低点之间的差值
+DM = CURRENT HIGH - PREVIOUS HIGH-DM = PREVIOUS LOW - CURRENT LOW
-
计算 ATR:如上一节所述计算 14 周期 ATR。
-
计算 +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 ]
- 确定方向指数 (DI):方向指数的计算方法是将 +DI 和 -DI 之间的绝对差除以它们的总和,然后乘以 100。公式为:
DI 14 = | (+DI 14) - (-DI 14) | / | (+DI 14) + (-DI 14) | * 100
- 计算 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 进行算法交易
在阅读本文前,可查阅以往文章: 技术指标-ATR 技术指标有几个分支,其中趋势指标使用最广泛。这些工具可帮助交易者确定市场趋势的方向和强度,使他们能够相应地调整交易。如果趋势指标得到有效应用,它们通常会产生积极的结果。 在…...
Unity 3D 从入门到精通:开启游戏开发的奇幻之旅
一、引言 在当今数字化的时代,游戏产业蓬勃发展,成为了全球娱乐领域的重要支柱。Unity 3D 作为一款功能强大、跨平台的游戏开发引擎,凭借其易用性、高效性和丰富的资源,吸引了无数开发者投身于游戏创作的世界。无论是独立开发者怀…...

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

用AI生成PPT,告别繁琐,一键生成高效方案
用AI生成PPT,告别繁琐,一键生成高效方案!制作PPT曾经是一件非常繁琐的工作。让人又爱又恨,爱的是它可以让你的想法可视化,恨的是,要做出一份精美的PPT,往往需要耗费大量时间和精力。现在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. 雪崩问题 微服务调用链路中的某个服务故障,引起整个链路中的所有微服务都不可用,这就是雪崩。动图演示: 在微服务系统…...

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.跨集群迁…...

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

SOME/IP 协议详解——远程过程调用(RPC)
文章目录 1. 传输协议绑定1.1 UDP 绑定1.2 TCP 绑定1.3 多服务实例(重要)1.4 通过 UDP 传输大型 SOME/IP 消息(SOME/IP - TP) 2. 请求 / 响应通信3. Fire&Forget 通信4. 通知事件5. 字段6. 错误处理6.1 返回码6.2 错误消息6.3…...
C++ 设计模式:命令模式(Command Pattern)
链接:C 设计模式 链接:C 设计模式 - 访问者模式 命令模式(Command Pattern)是一种行为型设计模式,它将请求封装成一个对象,从而使你可以用不同的请求对客户进行参数化,对请求排队或记录请求日志…...

安卓/system/bin下命令中文说明(AI)
ATFWD-daemon:AT指令转发守护进程,用于将AT指令从应用层转发到调制解调器。 PktRspTest:数据包响应测试工具。 StoreKeybox:存储密钥盒工具,用于安全地存储加密密钥。 WifiLogger_app:WiFi日志记录应用&…...

MATLAB程序转C# WPF,dll集成,混合编程
工作中遇到一个需求,有一部分算法的代码需要MATLAB来进行处理,而最后需要集成到C#中的wpf项目中去,选择灵活性更高的dll,去进行集成。(可以简单理解为:将MATLAB的函数,变为C#中类的函数成员&…...
【SpringBoot3】Spring Boot 3.0 集成 Mybatis Plus
文章目录 一、什么是 Mybatis Plus 特性 二、Spring Boot 3.0 集成 Mybatis Plus三、Mybatis Plus 查询示例 1、普通查询2、分页查询 参考 一、什么是 Mybatis Plus MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 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的线程安全问题源码分析
🎮 作者主页:点击 🎁 完整专栏和代码:点击 🏡 博客主页:点击 文章目录 SqlSession 是线程安全的吗?为什么说是线程不安全的?事务管理问题 数据库连接的共享问题 一级缓存线程安全问题…...
Java 8 及经典面试题全解析
Java 是目前非常流行的编程语言之一,其强大的生态系统和丰富的功能使得它在企业级开发中占据重要地位。在面试中,Java 的基础知识、集合框架、多线程、JVM,以及 Java 8 的新特性是重点考查内容。本文将结合 Java 8 和经典知识点,为…...

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

Java - 日志体系_Apache Commons Logging(JCL)日志接口库_桥接Logback 及 源码分析
文章目录 PreApache CommonsApache Commons ProperLogging (Apache Commons Logging ) JCL 集成logbackPOM依赖配置文件 logback.xml使用 源码分析jcl-over-slf4j 的工作原理1. LogFactory 的实现2. SLF4JLogFactory 和 Log 的实例化过程3. SLF4JLog 和 …...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘
美国西海岸的夏天,再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至,这不仅是开发者的盛宴,更是全球数亿苹果用户翘首以盼的科技春晚。今年,苹果依旧为我们带来了全家桶式的系统更新,包括 iOS 26、iPadOS 26…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...