【炒股Zero To Hero】MACD金叉死叉到底是否有效,加上这个指标回报率增加197倍

移动平均收敛散度(MACD - Moving Average Convergence Divergence)是一种趋势跟踪动量指标,显示了证券价格的两个移动平均之间的关系。它用于识别趋势的方向和强度,属于技术分析中振荡器的一类。

MACD如何衡量股票及其趋势

有两条线和一个柱:

第一条叫DIF线(差离值)又叫快线,有时也称为MACD线:12周期指数移动平均线(EMA),减去26周期指数移动平均线(EMA),计算得出两个线的差距。

在持续的涨势中,12日EMA在26日EMA之上。其间的正差离值(+DIF)会愈来愈大。反之在下跌趋势中,差离值可能变负(-DIF),此时是绝对值愈来愈大。至于行情开始回转,正或负差离值要缩小到一定的程度,才真正是行情反转的信号。

第二条叫DEA线(信号线)又叫慢线:根据DIF值计算其指数9日移动平均值(EMA),即离差(DIF)的平均值。

除此之外,还有一个柱状图,即快线–慢线所得的值呈现出来的直方图。上图的绿色柱代表DIF在DEA上方运行,红色柱代表DIF在DEA下方运行。美股和A股可能颜色是相反的,但是不影响我们理解。

交易者可能会在DIF线穿越其DEA线以上时买入证券,并在DIF线穿越DEA线以下时卖出或做空证券。

为什么它可能有效

MACD之所以有效,是因为它将动量和趋势结合在一个指标中。MACD线和信号线之间的差异指示了价格运动的强度,使交易者能够识别趋势变化周围的潜在买入或卖出机会。其有效性基于动量往往会在价格之前改变方向的原理。因此,MACD可以提供趋势反转的早期信号。

举个例子,一个物体在加速运行的时候,它的动能是很大的,除非有很大的外力阻止它,否则它会受惯性影响一直运动下去,直到动能为0。

MACD背后的逻辑

MACD的逻辑在于其能够通过比较短期和长期价格趋势来监测动量变化。当短期价格趋势开始超过长期趋势时,它可以是价格运动动量增加的信号,可能标志着购买或出售的机会。相反,当短期趋势相对于长期趋势减弱时,它可以表明动量减少,可能标志着趋势的逆转或放缓。

使用MACD的有效交易模型

基于MACD指标,有几种有效的交易模型和策略:

  1. MACD交叉:当DIF线穿越DEA线以上时买入,当它穿越以下时卖出。
  2. MACD背离:寻找MACD趋势和价格趋势之间的差异作为可能的逆转信号。
  3. MACD超买/超卖条件:当MACD从零线延伸得太远时,标识潜在的买入或卖出点,指示超买或超卖条件。

以特斯拉股票为例,时间从2020.1.1 ~ 2024.1.1四年数据,初始资金为1万美元,以日线级别作为回测已经,假设条件触发就全仓买入或者全仓卖出,利用MACD金叉死叉策略回测结果。

a) 编写MACD金叉死叉策略:

当macd线穿越Singal线向上运行时,买入;相反,当macd线穿越Singal线往下运行时,卖出;

import os
import yfinance as yf
import backtrader as bt
from datetime import datetime
import matplotlib.pyplot as plt
import pandas as pd

%matplotlib inline

#Only MACD
class MACDStrategy(bt.Strategy):
    params = (
        ('macd1', 12),
        ('macd2', 26),
        ('macdsignal', 9),
    )

    def log(self, txt, dt=None):
        ''' Logging function for this strategy'''
        dt = dt or self.datas[0].datetime.date(0)
        print(f'{dt.isoformat()}, {txt}')
    
    def __init__(self):
        self.macd = bt.indicators.MACD(self.data.close,
                                       period_me1=self.params.macd1,
                                       period_me2=self.params.macd2,
                                       period_signal=self.params.macdsignal)
        self.crossover = bt.indicators.CrossOver(self.macd.macd, self.macd.signal)
        self.order = None
        
        self.buy_signals = []
        self.sell_signals = []
        #self.macd_hist = self.macd.macd - self.macd.signal

    def notify_order(self, order):
        #print('notify_order')
        if order.status == order.Submitted:
            # Order has been submitted/accepted to/by broker
            self.log('Order Submitted')
            
        if order.status == order.Accepted:
            # Order has been submitted/accepted to/by broker
            self.log('Order Accepted')
            
        if order.status in [order.Completed]:
            if order.isbuy():
                self.log(f'BUY EXECUTED, Price: {order.executed.price}, Cost: {order.executed.value}, Commission: {order.executed.comm}')
                self.log(f'Cash after buying: {self.broker.getcash()}')
                self.buy_signals.append(self.datas[0].datetime.date(0))
            elif order.issell():
                self.log(f'SELL EXECUTED, Price: {order.executed.price}, Cost: {order.executed.value}, Commission: {order.executed.comm}')
                self.log(f'Cash after selling: {self.broker.getcash()}')
                self.sell_signals.append(self.datas[0].datetime.date(0))
        self.order = None
        
    def next(self):
        
        if self.order:  # Check if an order is pending, if so, we cannot send a 2nd one
            return
        cash_available = self.broker.getcash()  # Get the current cash level
        current_price = self.data.close[0]  # Current price of the stock
        size = int(cash_available / current_price)  # Number of shares you can buy
                
        #print(f'Current Close: {self.data.close[0]}')
        if not self.position:  # Not in the market
            if self.crossover > 0: # MACD crosses above signal line
                #self.log('BUY CREATE, %.2f' % self.data.close[0])
                #self.order = self.buy()  # MACD crosses above signal line
                if cash_available > current_price:  # Check if you have enough cash to buy at least one share
                    self.log(f'BUY CREATE, %.2f' % current_price)
                    self.order = self.buy(size=size)  # Adjust the size according to your strategy needs
                else:
                    self.log(f'Insufficient cash to buy. Available cash: {cash_available}, Current price: {current_price}')
  

        elif self.crossover < 0:  # MACD crosses below signal line
            self.log('SELL CREATE, %.2f' % self.data.close[0])
            self.order = self.close()
            #self.sell_signals.append(self.datas[0].datetime.date(0))


b) 开始回测:

#Back test only for one stock
cerebro = bt.Cerebro()
cerebro.addstrategy(MACDStrategy)
datapath = 'data.csv'

data_df = yf.download('TSLA', start="2020-01-01", end="2024-01-01")
#print(data_df)
data = bt.feeds.PandasData(dataname=data_df)
#data = bt.feeds.YahooFinanceData(dataname=, fromdate=datetime(2019, 1, 1), todate=datetime(2020, 12, 31))
cerebro.adddata(data)
cerebro.addsizer(bt.sizers.FixedSize, stake=100)
cerebro.broker.set_cash(10000)
cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name='sharpe_ratio')
cerebro.addanalyzer(bt.analyzers.DrawDown, _name='draw_down')
cerebro.addanalyzer(bt.analyzers.Returns, _name='returns')  # For Total and Annualized Returns
cerebro.addanalyzer(bt.analyzers.SQN, _name='sqn')  # System Quality Number can hint at the win rate
cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _name='trade_analyzer')  # For Win Rate, Profit-Loss Ratio

print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
results = cerebro.run()
strat = results[0]
buy_signals = strat.buy_signals
sell_signals = strat.sell_signals
# Sharpe Ratio
sharpe_ratio = strat.analyzers.sharpe_ratio.get_analysis()['sharperatio']
print(f"Sharpe Ratio: {sharpe_ratio}")

# Maximum Drawdown
max_drawdown = strat.analyzers.draw_down.get_analysis()['max']['drawdown']
print(f"Maximum Drawdown: {max_drawdown}%")

# Total Return
total_return = strat.analyzers.returns.get_analysis()['rtot']
print(f"Total Return: {total_return * 100}%")

# Annualized Return
annual_return = strat.analyzers.returns.get_analysis()['rnorm100']
print(f"Annualized Return: {annual_return}%")

# Sortino Ratio
#sortino_ratio = strat.analyzers.sortino_ratio.get_analysis()['sortino']
#print(f"Sortino Ratio: {sortino_ratio}")

# Win Rate and Profit-Loss Ratio
trade_analysis = strat.analyzers.trade_analyzer.get_analysis()
total_closed = trade_analysis.get('total', {}).get('closed', 0)

if total_closed > 0:
    win_rate = (trade_analysis.get('won', {}).get('total', 0) / total_closed) * 100
    won_avg = trade_analysis.get('won', {}).get('pnl', {}).get('average', 0)
    lost_avg = trade_analysis.get('lost', {}).get('pnl', {}).get('average', 0)
    profit_loss_ratio = abs(won_avg / lost_avg) if lost_avg != 0 else "undefined"
    print(f"Win Rate: {win_rate}%")
    print(f"Profit-Loss Ratio: {profit_loss_ratio}")
else:
    print("No trades closed.")

print('Ending Portfolio Value: %.2f' % cerebro.broker.getvalue())

#cerebro.plot()

回测结果为:

  • 初始投资组合价值:10000.00元
  • 夏普比率:0.08717907196315927
  • 最大回撤:48.50573641490451%
  • 总回报率:-4.509942626137697%
  • 年化回报率:-1.1233697243742937%
  • 胜率:35.0%
  • 盈亏比:1.8030867851982686
  • 结束投资组合价值:9559.02元

注:每次触发条件一会我们会下单,但是并非每次都一定买到,有可能因为下单价格和实际价格有出入导致无法达成交易,但是不影响我们的回测结果。

我们发现,我们的回报率为负,初始资金未必能得到保障。我们展示下买入点:

# Assuming 'data' is a DataFrame with your price data and 'dates' as its index
plt.figure(figsize=(14, 7))
plt.plot(data_df['Close'], label='Close Price', alpha=0.5)

# Convert buy and sell signal dates from datetime.date to pandas timestamps for indexing
buy_signals_dt = pd.to_datetime(buy_signals)
sell_signals_dt = pd.to_datetime(sell_signals)

plt.scatter(buy_signals_dt, data_df.loc[buy_signals_dt, 'Close'], label='Buy Signal', marker='^', color='green')
plt.scatter(sell_signals_dt, data_df.loc[sell_signals_dt, 'Close'], label='Sell Signal', marker='v', color='red')

plt.title("MACD Strategy Backtest")
plt.legend()
plt.show()

下面我们引入RSI(相对强弱指数)是技术分析中广泛使用的一个强大指标,特别是在股票交易领域。它主要用于帮助交易者识别股票或其他资产价格中的超买或超卖条件,这些条件暗示着潜在的反转点。我们结合MACD金叉死叉策略进行再次尝试:

import os
import yfinance as yf
import backtrader as bt
from datetime import datetime
import matplotlib.pyplot as plt
import pandas as pd

%matplotlib inline

class MACD_RSI_Strategy(bt.Strategy):
    params = (
        ('macd1', 12),
        ('macd2', 26),
        ('macdsig', 9),
        ('rsi_period', 14),
        ('rsi_upper', 70),   # RSI overbought threshold
        ('rsi_lower', 30),   # RSI oversold threshold
    )

    def log(self, txt, dt=None):
        ''' Logging function for this strategy '''
        dt = dt or self.datas[0].datetime.date(0)
        print(f'{dt.isoformat()}, {txt}')
            
    def __init__(self):
        # Initialize MACD and RSI indicators
        self.macd = bt.indicators.MACD(self.data.close,
                                       period_me1=self.p.macd1,
                                       period_me2=self.p.macd2,
                                       period_signal=self.p.macdsig)
        self.rsi = bt.indicators.RSI(self.data.close, period=self.p.rsi_period)
        self.crossover = bt.indicators.CrossOver(self.macd.macd, self.macd.signal)
        
        # Attributes to track buy and sell signal dates
        self.buy_signals = []
        self.sell_signals = []
        
        # To keep track of pending orders
        self.order = None

    def notify_order(self, order):
        if order.status == order.Submitted:
             self.log('Order Submitted')
             
        if order.status == order.Accepted:
            self.log('Order Accepted')

        if order.status == order.Completed:
            if order.isbuy():
                self.log(f'BUY EXECUTED, Price: {order.executed.price}, Cost: {order.executed.value}, Commission: {order.executed.comm}')
                self.log(f'Cash after buying: {self.broker.getcash()}')
                self.buy_signals.append(self.datas[0].datetime.date(0))
            elif order.issell():
                self.log(f'SELL EXECUTED, Price: {order.executed.price}, Cost: {order.executed.value}, Commission: {order.executed.comm}')
                self.log(f'Cash after selling: {self.broker.getcash()}')
                self.sell_signals.append(self.datas[0].datetime.date(0))
        elif order.status in [order.Canceled, order.Margin, order.Rejected]:
            self.log('Order Canceled/Margin/Rejected')

    def next(self):
        if self.order:  # Check if an order is pending, if so, we cannot send a 2nd one
            return
        
        cash_available = self.broker.getcash()
        current_price = self.data.close[0]
        size = int(cash_available / current_price)  # Simplistic size calculation

        if not self.position:
            if self.crossover > 0 and self.rsi < self.p.rsi_upper:  # Buy condition
                if cash_available > current_price:  # Ensure sufficient cash
                    self.log(f'BUY CREATE, {current_price}')
                    self.order = self.buy(size=size)
                else:
                    self.log(f'Insufficient cash to buy. Available cash: {cash_available}, Current price: {current_price}')
        elif self.crossover < 0 or self.rsi > self.p.rsi_upper:  # Sell condition
            self.log(f'SELL CREATE, {current_price}')
            self.order = self.sell()  # Use self.close() if wanting to close the entire position

再次回测结果为

#Back test only for one stock
cerebro = bt.Cerebro()
cerebro.addstrategy(MACD_RSI_Strategy)
datapath = 'data.csv'

data_df = yf.download('TSLA', start="2020-01-01", end="2024-01-01")
#print(data_df)
data = bt.feeds.PandasData(dataname=data_df)
#data = bt.feeds.YahooFinanceData(dataname=, fromdate=datetime(2019, 1, 1), todate=datetime(2020, 12, 31))
cerebro.adddata(data)
cerebro.addsizer(bt.sizers.FixedSize, stake=100)
cerebro.broker.set_cash(10000)
cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name='sharpe_ratio')
cerebro.addanalyzer(bt.analyzers.DrawDown, _name='draw_down')
cerebro.addanalyzer(bt.analyzers.Returns, _name='returns')  # For Total and Annualized Returns
cerebro.addanalyzer(bt.analyzers.SQN, _name='sqn')  # System Quality Number can hint at the win rate
cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _name='trade_analyzer')  # For Win Rate, Profit-Loss Ratio

print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
results = cerebro.run()
strat = results[0]
buy_signals = strat.buy_signals
sell_signals = strat.sell_signals
# Sharpe Ratio
sharpe_ratio = strat.analyzers.sharpe_ratio.get_analysis()['sharperatio']
print(f"Sharpe Ratio: {sharpe_ratio}")

# Maximum Drawdown
max_drawdown = strat.analyzers.draw_down.get_analysis()['max']['drawdown']
print(f"Maximum Drawdown: {max_drawdown}%")

# Total Return
total_return = strat.analyzers.returns.get_analysis()['rtot']
print(f"Total Return: {total_return * 100}%")

# Annualized Return
annual_return = strat.analyzers.returns.get_analysis()['rnorm100']
print(f"Annualized Return: {annual_return}%")

# Sortino Ratio
#sortino_ratio = strat.analyzers.sortino_ratio.get_analysis()['sortino']
#print(f"Sortino Ratio: {sortino_ratio}")

# Win Rate and Profit-Loss Ratio
trade_analysis = strat.analyzers.trade_analyzer.get_analysis()
total_closed = trade_analysis.get('total', {}).get('closed', 0)

if total_closed > 0:
    win_rate = (trade_analysis.get('won', {}).get('total', 0) / total_closed) * 100
    won_avg = trade_analysis.get('won', {}).get('pnl', {}).get('average', 0)
    lost_avg = trade_analysis.get('lost', {}).get('pnl', {}).get('average', 0)
    profit_loss_ratio = abs(won_avg / lost_avg) if lost_avg != 0 else "undefined"
    print(f"Win Rate: {win_rate}%")
    print(f"Profit-Loss Ratio: {profit_loss_ratio}")
else:
    print("No trades closed.")

print('Ending Portfolio Value: %.2f' % cerebro.broker.getvalue())

#cerebro.plot()
 

起始投资组合价值:10000.00

夏普比率:0.6716775968520321

最大回撤:73.56996064486884%

总回报:197.974046126522%

年化回报:64.20066841327395%

胜率:未平仓交易。  

结束时的投资组合价值:72408.63

初始和结束投资组合价值

  • MACD的策略起始和结束投资组合价值从10000元降低到9559.02元,表明在策略执行期间投资组合价值下降了。
  • MACD-RSI策略的投资组合价值从10000元增加到72408.63元,显示出显著的正回报。

夏普比率

  • MACD的夏普比率为0.087,表明每承担一单位总风险获得的额外回报较低。
  • MACD-RSI的夏普比率为0.672,显著高于MACD策略,意味着相对于风险而言,回报率更优。

最大回撤

  • MACD策略的最大回撤为48.51%,指出最大的价值下降比例。
  • MACD-RSI策略有更高的最大回撤,为73.57%,表明其面临更高的价格波动和潜在的下跌风险。

总回报率和年化回报率

  • MACD策略的总回报率为-4.51%,年化回报率为-1.12%,表明投资组合在期间内亏损。
  • MACD-RSI策略的总回报率为197.97%,年化回报率为64.20%,显示出极高的盈利性。

胜率和盈亏比

  • MACD策略的胜率为35%,盈亏比为1.80,表明虽然盈利次数少,但盈利交易相对于亏损交易仍然具有较好的表现。
  • MACD-RSI策略的胜率未提供,但结束时投资组合的显著增值可能意味着高胜率或几笔大额盈利交易。

结论

比较这两种策略,MACD-RSI在总回报率和年化回报率方面表现显著优于单独使用MACD的策略。尽管MACD-RSI策略承受了更高的最大回撤,表明更大的价格波动和下行风险,但其显著的高夏普比率和总回报表明了其在风险调整后的回报方面的优越性。然而,投资者在选择策略时应考虑自己的风险容忍度和投资目标。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/535482.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

蜘蛛池规矩采集优化与运用技巧 什么是蜘蛛池/SEO蜘蛛池怎么养?

作为一名网络内容修改&#xff0c;我常常需求从各种网站上收集文章并转载到咱们的网站上。而在这个过程中&#xff0c;我深深感受到了蜘蛛池对我的帮助。今日&#xff0c;我就来共享一下我对蜘蛛池收集规矩的亲自感受。 本文 虚良SEO 原创&#xff0c;转载保留链接&#xff01…

【电子通识】热风枪的结构与使用方法

热风枪的结构 热风枪是专门用来拆焊、焊接贴片元器件和贴片集成电路的焊接工具&#xff0c;它主要由主机和热风焊枪两大部分构成。 热风枪主要有电源开关、风速设置、温度设置、热风连接等部件组成。根据不同品牌和价位的热风枪&#xff0c;有一些功能齐全的也集成了烙铁功能。…

绿联 安装火狐浏览器(Firefox),支持访问路由器

绿联 安装火狐浏览器&#xff08;Firefox&#xff09;&#xff0c;支持访问路由器 1、镜像 linuxserver/firefox:latest 前置条件&#xff1a;动态公网IP。 已知问题&#xff1a; 直接输入中文时&#xff0c;不能完整输入&#xff0c;也可能输入法无法切换到中文&#xff0c;可…

Post表单提交后端接不到参数

项目背景&#xff1a; 框架&#xff1a;Springboot 版本&#xff1a;1.5.6.REAEASE 问题描述 Postman通过表单提交请求时后端接不到值 原因分析&#xff1a; 启动项中注入其他Bean时取名叫dispatcherServlet&#xff0c;当发现http接口无法访问时&#xff0c;原开发人员又…

albef论文学习

首先要知道vit是啥东西。vit就是transformer模型在图像领域的运用。 transformer模型原本是用于自然语言的&#xff0c;encoder和decoder接受的都是文字。vit把图像分割成很多个小块&#xff0c;把各个小块拉长当成向量来用&#xff0c;接下来就是一样的。最后接一个全连接层做…

(学习日记)2024.04.12:UCOSIII第四十节:软件定时器函数接口讲解

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…

编程技巧(五) mysql中查询将行转为列逗号隔开拼接

让清单成为一种习惯 互联网时代的变革,不再是简单的开发部署上线,持续,正确,安全地把事情做好尤其重要;把事情做好的前提是做一个可量化可执行的清单,让工程师就可以操作的清单而不是专家才能操作: 设定检查点 根据节点执行检查程序操作确认或边读边做 二者选其一不要太…

CSS导读 (元素显示模式)

&#xff08;大家好&#xff0c;今天我们将继续来学习CSS的相关知识&#xff0c;大家可以在评论区进行互动答疑哦~加油&#xff01;&#x1f495;&#xff09; 目录 三、CSS的元素显示模式 3.1 什么是元素显示模式 3.2 块元素 3.3 行内元素 3.4 行内块元素 3.5 元素…

马斯克预言:下一代Grok 3模型将需10万Nvidia H100 GPU进行训练|TodayAI

特斯拉首席执行官兼xAI创始人埃隆马斯克对人工通用智能&#xff08;AGI&#xff09;的发展做出了一些大胆的预测&#xff0c;并讨论了AI行业面临的挑战。他预测&#xff0c;AGI可能在明年或2026年之前超越人类智能&#xff0c;但训练AGI将需要极大数量的处理器&#xff0c;进而…

priority_queue的使用以及模拟实现

前言 上一期我们对stack和queue进行了使用的介绍&#xff0c;以及对底层的模拟实现&#xff01;以及容器适配器做了介绍&#xff0c;本期我们在来介绍一个容器适配器priority_queue&#xff01; 本期内容介绍 priority_queue的使用 仿函数介绍 priority_queue的模拟实现 什么…

2024年人工智能路线图

今天分享的是人工智能专题系列深度研究报告&#xff1a;《人工智能专题&#xff1a;2024年人工智能路线图》。 秘书制定部门的人工智能战略优先事项和政策&#xff0c;并且是关键的对话者与私营部门、联邦机构、州官员&#xff0c;以及主要的国际同行。这部长在白宫人力资源委员…

C/C++基础----运算符

算数运算符 运算符 描述 例子 两个数字相加 两个变量a b得到两个变量之和 - 两个数字相减 - * 两个数字相乘 - / 两个数字相除 - % 两个数字相除后取余数 8 % 3 2 -- 一个数字递减 变量a&#xff1a;a-- 、--a 一个数字递增 变量a: a 、 a 其中递…

如何在 7 天内掌握C++?

大家好&#xff0c;我是小康&#xff0c;今天我们来聊下如何快速学习 C 语言。 本篇文章适合于有 C 语言编程基础的小伙伴们&#xff0c;如果还没有学习过 C&#xff0c;请看这篇文章先入个门&#xff1a;C语言快速入门 引言&#xff1a; C&#xff0c;作为一门集面向过程和…

精彩回顾 | 「AI 驱动增长,研发数智化升级」分享沙龙成功举办

AI 应用元年&#xff0c;人工智能技术将如何助力企业发展新质生产力&#xff0c;构建增长动能&#xff1f; 日前&#xff0c;LigaAI 与深圳市企业联合会、西云数据联合举办了「AI 驱动增长&#xff0c;研发数智化升级」技术专题沙龙。本次活动围绕「AI」应用实践&#xff0c;邀…

2024-基于人工智能的药物设计方法研究-AIDD

AIDD docx 基于人工智能的药物设计方法研究 AI作为一种强大的数据挖掘和分析技术已经涉及新药研发的各个阶段&#xff0c;有望推动创新药物先导分子的筛选、设计和发现&#xff0c;但基于AI的数据驱动式创新药物设计和筛选方法仍存在若干亟待解决的问题。我们课题组的核心研究…

Kali中间人攻击

中间人攻击 中间人攻击&#xff08;Man-in-the-Middle Attack&#xff0c;简称MITM&#xff09;是一种网络安全攻击&#xff0c;其中攻击者插入自己&#xff08;作为“中间人”&#xff09;在通信的两个端点之间&#xff0c;以窃取或篡改通过的数据。攻击者可以监视通信&#x…

我为什么选择成为程序员?

前言&#xff1a; 我选择成为程序员不是兴趣所在&#xff0c;也不是为了职业发展&#xff0c;全是生活所迫&#xff01; 第一章&#xff1a;那年&#xff0c;我双手插兜&#xff0c;对外面的世界一无所知 时间回到2009年&#xff0c;时间过得真快啊&#xff0c;一下就是15年前…

多线程回答的滚瓜烂熟,面试官问我虚线程了解吗?我说不太了解!

Java虚拟线程&#xff08;Virtual Threads&#xff09;标志着Java在并发编程领域的一次重大飞跃&#xff0c;特别是从Java 21版本开始。这项新技术的引入旨在克服传统多线程和线程池存在的挑战。 多线程和线程池 在Java中&#xff0c;传统的多线程编程依赖于Thread类或实现Ru…

Green Hills 自带的MULTI调试器查看R7芯片寄存器

Green Hills在查看芯片寄存器时需要导入 .grd文件。下面以R7为例&#xff0c;演示一下过程。 首先打开MULTI调试器&#xff0c;如下所示View->Registers&#xff1a; 进入如下界面&#xff0c;选择导入寄存器定义文件.grd&#xff1a; 以当前R7芯片举例&#xff08;dr7f7013…