基于MT5的短线反向交易策略

本文介绍了在震荡行情下的一种量化交易策略,利用MT5平台,当短线行情出现快速上冲或下砸超过特定临界值时,反向开平仓。临界值随时间增长呈减函数,根据波动强度决定交易决策和数量,旨在捕捉主力洗盘行为。
摘要由CSDN通过智能技术生成

项目介绍

本文提供一种量化交易思路,震荡行情下表现优异。具体操作思路如下:
短线快速上冲或下砸时视为主力洗盘行为,超过临界值时反向开平仓,洗盘力度大小决定开平仓与否和数量。
临界值是一个随着时间增长的减函数,取值区间为1~60分钟,例如1分钟的临界值为2.5,5分钟的临界值约为4,而60分钟的临界值仅为10。如果行情波动超过这些临界值则计算多空指数。若指数大于预设值则发出开平仓指令。

import matplotlib.pyplot as plt
import pandas as pd
import MetaTrader5 as mt5
import pymt5
import time
from datetime import datetime
from datetime import timedelta
import pytz
import numpy as np
import math
import os


# 连接到MetaTrader 5
if not mt5.initialize():
    print("initialize() failed")

# 登陆mt5
authorized = mt5.login(39304351, "heniu1me", "MetaQuotes-Demo")
if authorized:
    print("MetaTrader5 package author: ", mt5.__author__)
    print("MetaTrader5 package version: ", mt5.__version__)
else:
    print("login failed")
    exit(0)

# 创建当前订单csv文件
if not os.path.exists("current orders.csv"):
    dataframe = pd.DataFrame(
        columns=("Time", "Type", "Volume", "Price", "sl", "tp", "Note")
    )
    dataframe.to_csv("current orders.csv", index=False)

# 创建平仓单csv文件
if not os.path.exists("history records.csv"):
    dataframe = pd.DataFrame(
        columns=(
            "Opentime",
            "Closetime",
            "Type",
            "Volume",
            "Openprice",
            "Closeprice",
            "sl",
            "tp",
            "Note",
        )
    )
    dataframe.to_csv("history records.csv", index=False)


class TradingStratege(object):
    """docstring for TradingStratege
    Args:
            symbol:交易品种
            timeframe:K线周期
            period:用于策略分析的时间序列长度(单位hours)
            target:止盈止损目标,与建仓价格的距离
            index1~index3:触发开平仓指令的指数水平
            vol1~vol3:对应的3个交易量
            max_position:最大仓位
    """

    def __init__(
        self,
        symbol,
        timeframe,
        period,
        sl_target,
        tp_target,
        index1,
        index2,
        index3,
        vol1,
        vol2,
        vol3,
        max_position,
    ):
        self.symbol = symbol
        self.timeframe = timeframe
        self.period = period
        self.sl_target = sl_target
        self.tp_target = tp_target
        self.index1 = index1
        self.index2 = index2
        self.index3 = index3
        self.vol1 = vol1
        self.vol2 = vol2
        self.vol3 = vol3
        self.max_position = max_position

    # 获取指定品种历史数据
    def get_data(self, symbol, timeframe, period):
        mt5_timeframe = mt5.TIMEFRAME_M1
        if timeframe == "M1":
            mt5_timeframe = mt5.TIMEFRAME_M1
        elif timeframe == "M5":
            mt5_timeframe = mt5.TIMEFRAME_M5
        elif timeframe == "M15":
            mt5_timeframe = mt5.TIMEFRAME_M15
        elif timeframe == "M30":
            mt5_timeframe = mt5.TIMEFRAME_M30
        elif timeframe == "H1":
            mt5_timeframe = mt5.TIMEFRAME_H1
        elif timeframe == "H4":
            mt5_timeframe = mt5.TIMEFRAME_H4
        elif timeframe == "D1":
            mt5_timeframe = mt5.TIMEFRAME_D1
        # 将时区设置为GMT-2
        timezone = pytz.timezone("Etc/GMT-2")
        # 调节时间与mt5上的now相对应
        now = datetime.now(timezone) + timedelta(hours=2)
        time_from = now - timedelta(hours=period)
        # 获取最新1小时内约60根一分钟K线数据
        rates = mt5.copy_rates_range(symbol, mt5_timeframe, time_from, now)
        # 获取指定品种最新报价
        lasttick = mt5.symbol_info_tick(symbol)
        # 将数据存储在数组中
        Last_price = []
        High_price = []
        Low_price = []
        for price_data in rates:
            last_price = lasttick.bid
            open_price = price_data[1]
            high_price = price_data[2]
            low_price = price_data[3]
            close_price = price_data[4]
            Last_price.append(last_price)
            High_price.append(high_price)
            Low_price.append(low_price)
        Lasttick = np.array([lasttick[0], lasttick[1], lasttick[2]])
        # 返回数组
        return Last_price, High_price, Low_price, Lasttick

    # 获取30s内最高和最低价,用于检查是否触发止损止盈
    def getticks(self):
        timezone = pytz.timezone("Etc/GMT-2")
        now = datetime.now(timezone) + timedelta(hours=2)
        time_from = now - timedelta(seconds=30)
        # request 100 XAUUSD ticks starting from 30s before.
        ticks = mt5.copy_ticks_from(self.symbol, time_from, 100, mt5.COPY_TICKS_ALL)
        Bid = []
        Ask = []
        for x in ticks:
            bid = x[1]
            ask = x[2]
            Bid.append(bid)
            Ask.append(ask)
        bid_min = min(Bid)
        bid_max = max(Bid)
        ask_min = min(Ask)
        ask_max = max(Ask)
        ticks = np.array([bid_min, bid_max, ask_min, ask_max])
        return ticks

    # 计算短线多空指数
    def checkprice(self, last_price, high_price, low_price):
        # 计算上涨和下跌幅度
        decrease = np.array(high_price) - np.array(last_price)
        increase = np.array(last_price) - np.array(low_price)
        # 创建一个以时间距离为变量的减函数拟合出正常波动范围
        refer = self.normal_fluctuation(increase)
        time_len1 = np.arange(len(increase), 0, -1)
        time_len2 = np.arange(len(decrease), 0, -1)
        # 筛选出符合条件的数据
        filter1 = increase > refer
        filter2 = decrease > refer
        fil_inc = increase[filter1]
        fil_dec = decrease[filter2]
        fil_time1 = time_len1[filter1]
        fil_time2 = time_len2[filter2]
        # 计算短线多空指数
        index_delta1 = self.inc_warn(fil_inc, fil_time1, time_len1)
        index_delta2 = self.dec_warn(fil_dec, fil_time2, time_len2)

        return index_delta1, index_delta2

    # 每个10分钟时间段选取一条提示信息,并返回短线做空指标
    def inc_warn(self, fil_inc, fil_time, time_len):
        # 判断是否为空数组
        if not np.size(fil_inc) == 0:
            i = 0
            z = int(len(time_len) / 10)
            index = 0
            index_delta = 0
            # 以10分钟为单位对时间进行切割
            while i < z + 1:
                # 将时间数组切割为z部分,得到索引数组
                mask = np.logical_and(fil_time <= (i + 1) * 10, fil_time > i * 10)
                j = fil_inc[mask]
                if not np.size(j) == 0:
                    maxx = np.max(j)
                    # 用索引公式查找时间数组中的元素
                    point = fil_time
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值