数字货币MACD指标自动化交易策略实现(含源代码)

数字货币MACD指标自动化交易策略实现(含源代码)

前情回顾

在前面我们实现了2中方法进行数字货币交易,同时还能获取到实时行情。数字货币交易接口实现(含源代码)

在此基础上,我们今天实现一个指标策略自动化交易的功能(以MACD指标为例),并进行2次优化,增加仓位管理以及风险控制的功能,实现一个完成的交易策略。

MACD 策略逻辑

  1. 获取 5 分钟的 K 线数据
  2. 计算 MACD 指标
  3. 买入条件:MACD 越过零线
  4. 卖出条件:MACD 低于零线

代码实现

python 复制代码
import ccxt
import pandas as pd
import ta
import time

# 初始化 Binance 交易所实例
exchange = ccxt.binance({
    'apiKey': 'YOUR_API_KEY',        # 替换为你的 API Key
    'secret': 'YOUR_SECRET_KEY',     # 替换为你的 Secret Key
})

# 获取 5 分钟的 K 线数据
def fetch_ohlcv(symbol, timeframe='5m', limit=100):
    ohlcv = exchange.fetch_ohlcv(symbol, timeframe, limit=limit)
    df = pd.DataFrame(ohlcv, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
    df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')
    df.set_index('timestamp', inplace=True)
    return df

# 计算 MACD 指标
def calculate_macd(df):
    macd = ta.trend.MACD(df['close'])
    df['macd'] = macd.macd()
    df['macd_signal'] = macd.macd_signal()
    df['macd_diff'] = macd.macd_diff()

# 检查交易信号
def check_trade_signals(df):
    last_row = df.iloc[-1]
    previous_row = df.iloc[-2]
    
    # 买入条件:MACD 越过零线
    if previous_row['macd'] < 0 and last_row['macd'] > 0:
        return 'buy'
    
    # 卖出条件:MACD 低于零线
    if previous_row['macd'] > 0 and last_row['macd'] < 0:
        return 'sell'
    
    return 'hold'

# 执行交易
def execute_trade(signal, symbol='BTC/USDT', amount=0.001):
    if signal == 'buy':
        order = exchange.create_market_buy_order(symbol, amount)
        print('Buy order executed:', order)
    elif signal == 'sell':
        order = exchange.create_market_sell_order(symbol, amount)
        print('Sell order executed:', order)

# 主循环
def main():
    symbol = 'BTC/USDT'
    while True:
        df = fetch_ohlcv(symbol)
        calculate_macd(df)
        calculate_ema(df)
        calculate_kdj(df)
        signal = check_trade_signals(df)
        execute_trade(signal)
        time.sleep(300)  # 每5分钟运行一次

if __name__ == "__main__":
    main()

代码说明

1、初始化 Binance 交易所实例:使用你的 API Key 和 Secret Key 初始化 ccxt 库中的 Binance 实例。

2、获取 5 分钟的 K 线数据:定义 fetch_ohlcv 函数,从 Binance 获取指定交易对的 5 分钟 K 线数据,并将其转换为 Pandas DataFrame。

3、计算 MACD 指标:定义相应的函数计算这些技术指标,并将其添加到 DataFrame 中。

4、检查交易信号:定义 check_trade_signals 函数,根据 MACD 越过零线和低于零线的条件检查交易信号。

5、执行交易:定义 execute_trade 函数,根据交易信号执行买入或卖出操作。

6、主循环:在 main 函数中,每隔5分钟获取最新数据,计算指标,检查信号,并执行交易。

请注意,这段代码仅为示例,实际交易时应考虑更多因素,例如交易量、手续费、风控等,后面分两步进行完善。

增加仓位管理逻辑

上述执行交易函数存在明显的漏洞,只有开仓动作,没有平仓动作。所以新增一条交易逻辑:当没有持有信号方向的持仓时才进行开仓;如果有信号方向的持仓就进行平仓。

这就需要增加仓位管理的逻辑,实现获取仓位的接口。

代码实现

python 复制代码
import ccxt
import pandas as pd
import ta
import time

# 初始化 Binance 交易所实例
exchange = ccxt.binance({
    'apiKey': 'YOUR_API_KEY',        # 替换为你的 API Key
    'secret': 'YOUR_SECRET_KEY',     # 替换为你的 Secret Key
})

# 获取 5 分钟的 K 线数据
def fetch_ohlcv(symbol, timeframe='5m', limit=100):
    ohlcv = exchange.fetch_ohlcv(symbol, timeframe, limit=limit)
    df = pd.DataFrame(ohlcv, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
    df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')
    df.set_index('timestamp', inplace=True)
    return df

# 计算 MACD 指标
def calculate_macd(df):
    macd = ta.trend.MACD(df['close'])
    df['macd'] = macd.macd()
    df['macd_signal'] = macd.macd_signal()
    df['macd_diff'] = macd.macd_diff()

# 检查交易信号
def check_trade_signals(df):
    last_row = df.iloc[-1]
    previous_row = df.iloc[-2]
    
    # 买入条件:MACD 越过零线
    if previous_row['macd'] < 0 and last_row['macd'] > 0:
        return 'buy'
    
    # 卖出条件:MACD 低于零线
    if previous_row['macd'] > 0 and last_row['macd'] < 0:
        return 'sell'
    
    return 'hold'

# 获取当前持仓方向和数量
def get_position(symbol):
    balance = exchange.fetch_balance()
    if symbol in balance['total']:
        return balance['total'][symbol]
    return 0

# 执行交易
def execute_trade(signal, symbol='BTC/USDT', amount=0.001):
    base_currency = symbol.split('/')[0]
    position = get_position(base_currency)
    
    if signal == 'buy':
        if position <= 0:
            order = exchange.create_market_buy_order(symbol, amount)
            print('Buy order executed:', order)
        else:
            print('Already holding a buy position. No action taken.')
    elif signal == 'sell':
        if position > 0:
            order = exchange.create_market_sell_order(symbol, amount)
            print('Sell order executed:', order)
        else:
            print('No buy position to sell. No action taken.')

# 主循环
def main():
    symbol = 'BTC/USDT'
    while True:
        df = fetch_ohlcv(symbol)
        calculate_macd(df)
        calculate_ema(df)
        calculate_kdj(df)
        signal = check_trade_signals(df)
        execute_trade(signal, symbol)
        time.sleep(300)  # 每5分钟运行一次

if __name__ == "__main__":
    main()

修改说明

1、获取当前持仓方向和数量:添加 get_position 函数,获取当前账户的持仓情况。如果持有目标资产(如 BTC),返回持有数量,否则返回 0。

2、修改交易逻辑:在 execute_trade 函数中,根据信号检查当前持仓:

  • 如果是买入信号('buy'),且当前没有持有或持有空头仓位,则进行买入操作。
  • 如果是卖出信号('sell'),且当前持有多头仓位,则进行卖出操作。

3、主循环:保持不变,每隔 5 分钟获取最新数据,计算指标,检查信号,并执行交易。

请注意,这段代码仍然是一个简化的示例。在实际交易中,还需要考虑更多的细节和异常处理,例如 API 调用失败、交易失败、网络问题等。另外,务必在模拟环境中进行充分测试,确保策略的可靠性和安全性。

增加风险控制功能

增加风险控制功能也就是止盈止损的逻辑:

  • 持仓盈利超过5%,则平仓
  • 持仓亏损超过3%,则平仓

代码实现

python 复制代码
import ccxt
import pandas as pd
import ta
import time

# 初始化 Binance 交易所实例
exchange = ccxt.binance({
    'apiKey': 'YOUR_API_KEY',        # 替换为你的 API Key
    'secret': 'YOUR_SECRET_KEY',     # 替换为你的 Secret Key
})

# 获取 5 分钟的 K 线数据
def fetch_ohlcv(symbol, timeframe='5m', limit=100):
    ohlcv = exchange.fetch_ohlcv(symbol, timeframe, limit=limit)
    df = pd.DataFrame(ohlcv, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
    df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')
    df.set_index('timestamp', inplace=True)
    return df

# 计算 MACD 指标
def calculate_macd(df):
    macd = ta.trend.MACD(df['close'])
    df['macd'] = macd.macd()
    df['macd_signal'] = macd.macd_signal()
    df['macd_diff'] = macd.macd_diff()

# 检查交易信号
def check_trade_signals(df):
    last_row = df.iloc[-1]
    previous_row = df.iloc[-2]
    
    # 买入条件:MACD 越过零线
    if previous_row['macd'] < 0 and last_row['macd'] > 0:
        return 'buy'
    
    # 卖出条件:MACD 低于零线
    if previous_row['macd'] > 0 and last_row['macd'] < 0:
        return 'sell'
    
    return 'hold'

# 获取当前持仓方向和数量
def get_position(symbol):
    balance = exchange.fetch_balance()
    base_currency = symbol.split('/')[0]
    if base_currency in balance['total']:
        return balance['total'][base_currency]
    return 0

# 计算持仓盈亏比例
def calculate_profit_loss(entry_price, current_price):
    return (current_price - entry_price) / entry_price

# 执行交易
def execute_trade(signal, symbol='BTC/USDT', amount=0.001, entry_price=None):
    base_currency = symbol.split('/')[0]
    position = get_position(symbol)
    
    if signal == 'buy':
        if position <= 0:
            order = exchange.create_market_buy_order(symbol, amount)
            print('Buy order executed:', order)
            entry_price = order['price']
        else:
            print('Already holding a buy position. No action taken.')
    elif signal == 'sell':
        if position > 0:
            order = exchange.create_market_sell_order(symbol, amount)
            print('Sell order executed:', order)
            entry_price = None
        else:
            print('No buy position to sell. No action taken.')

    # 止盈止损逻辑
    if entry_price:
        ticker = exchange.fetch_ticker(symbol)
        current_price = ticker['last']
        profit_loss_ratio = calculate_profit_loss(entry_price, current_price)

        if profit_loss_ratio >= 0.05:  # 止盈条件
            if position > 0:
                order = exchange.create_market_sell_order(symbol, amount)
                print('Take profit order executed:', order)
                entry_price = None
        elif profit_loss_ratio <= -0.03:  # 止损条件
            if position > 0:
                order = exchange.create_market_sell_order(symbol, amount)
                print('Stop loss order executed:', order)
                entry_price = None

# 主循环
def main():
    symbol = 'BTC/USDT'
    entry_price = None
    while True:
        df = fetch_ohlcv(symbol)
        calculate_macd(df)
        calculate_ema(df)
        calculate_kdj(df)
        signal = check_trade_signals(df)
        execute_trade(signal, symbol, entry_price=entry_price)
        time.sleep(300)  # 每5分钟运行一次

if __name__ == "__main__":
    main()

修改说明

1、计算持仓盈亏比例:添加 calculate_profit_loss 函数,计算当前持仓的盈亏比例。

2、止盈止损逻辑:在 execute_trade 函数中,添加止盈和止损逻辑:

  • 如果当前持仓的盈利比例大于等于 5% (profit_loss_ratio >= 0.05),则执行止盈平仓操作。
  • 如果当前持仓的亏损比例小于等于 -3% (profit_loss_ratio <= -0.03),则执行止损平仓操作。

3、更新 execute_trade 函数:在买入和卖出操作中记录或清除 entry_price,以便在止盈止损逻辑中使用。

4、主循环中传递 entry_price:在 main 函数中,每次调用 execute_trade 函数时传递 entry_price 参数。

如果说还要继续优化的话,可能增加动态止盈的功能,后面有时间在进一步优化。

相关推荐
Thanks_ks1 小时前
探索计算机互联网的奇妙世界:从基础到前沿的无尽之旅
物联网·云计算·区块链·tcp/ip协议·计算机互联网·万维网·未来科技
BlockOne111 小时前
应用链风口下,一键发链该如何选择?
区块链
Footprint_Analytics1 小时前
Footprint Analytics 助力 Sei 游戏生态增长
游戏·web3·区块链
BSV区块链1 小时前
如何在BSV区块链上实现可验证AI
人工智能·区块链
电报号dapp1192 小时前
DeFi 4.0峥嵘初现:主权金融时代的来临
金融·区块链
搬砖的小码农_Sky5 小时前
什么是零知识证明?
区块链·密码学·零知识证明
TinTin Land5 小时前
高活跃社区 Doge 与零知识证明的强强联手,QED 重塑可扩展性
区块链·零知识证明
Roun321 小时前
去中心化存储:Web3中的数据安全新标准
web3·去中心化·区块链
请不要叫我菜鸡1 天前
分布式——一致性模型与共识算法
分布式·后端·区块链·raft·共识算法·zab
BlockOne111 天前
Meme 币生态全景图分析:如何获得超额收益?
大数据·人工智能·区块链