zoukankan      html  css  js  c++  java
  • BotVS趋势交易策略-MACD

     MACD低买高卖自动跟单滑动止损策略 , 基于Python实现。

    交叉后前一柱指金叉后的第一柱的值, 交叉后前一柱指金叉前的最后一个柱的值, 滑动价格指下单时加的价格,比如买单会现价加上这个价格,卖单会减去这个价格

    参数

    代码

    import math
    import time
    import datetime
    
    
    def Fixed(v):
        return math.floor(v*1000)/1000
    
    
    # 取消指定ID号的订单
    def WaitOrder(exchange, orderId, timeoutToCancel):
        t = time.time()
        ts = int(round(t * 1000))
        while True:
            Sleep(3000);
            orderInfo = exchange.GetOrder(orderId);
            if (not orderInfo):
                continue;
    
            if (orderInfo.Status == ORDER_STATE_CLOSED or orderInfo.Status == ORDER_STATE_CANCELED):
                return orderInfo;
    
            t = time.time()
            if ((int(round(t * 1000)) - ts) > timeoutToCancel):
                exchange.CancelOrder(orderId);
    
    
    # 买入
    def Buy(exchange, maxPrice, slidePrice, balanceRatio, timeoutS):
        t = time.time()
        ts = int(round(t * 1000))
        account = None;
        dealAmount = 0.0;
        usedBlance = 0.0;
        maxBalanceUse = 0.0;
        isFirst = True;
        while True:
            if (isFirst):
                isFirst = False;
            else:
                Sleep(3000);
    
            ticker = exchange.GetTicker();
            if (not ticker):
                continue;
    
            buyPrice = ticker.Sell + slidePrice;
    
            # Price too high, wait...
            if (buyPrice > maxPrice):
                continue;
    
            # Initialize at first
            if (account is None):
                account = exchange.GetAccount();
                if (not account):
                    continue;
    
                # Initialize maxBalanceUse
                maxBalanceUse = account.Balance * balanceRatio;
    
    
            buyAmount = Fixed((maxBalanceUse - usedBlance) / buyPrice);
            if (buyAmount < exchange.GetMinStock()):
                break;
    
    
            orderId = exchange.Buy(buyPrice, buyAmount);
            if (not orderId):
                Log(buyPrice, buyAmount, maxBalanceUse, usedBlance);
                continue;
    
            orderInfo = WaitOrder(exchange, orderId, timeoutS);
            dealAmount += orderInfo.DealAmount;
            usedBlance += orderInfo.Price * orderInfo.DealAmount;
            if (orderInfo.Status == ORDER_STATE_CLOSED):
                break;
    
            t = time.time()
            if ((int(round(t * 1000)) - ts) < timeoutS):
                break
    
        return {'amount': dealAmount, 'price': (usedBlance / dealAmount  if dealAmount > 0  else 0)};
    
    # 卖出
    def Sell(exchange, sellAmount, slidePrice):
        # Account info must set
        account = exchange.GetAccount();
        while (not account):
            Sleep(2000);
            account = exchange.GetAccount();
    
        sellAmount = min(sellAmount, account.Stocks);
    
        cash = 0.0;
        remain = sellAmount;
    
        while (remain >= exchange.GetMinStock()):
            ticker = exchange.GetTicker();
            if (not ticker):
                Sleep(2000);
                continue;
    
            sellPrice = ticker.Buy - slidePrice;
            sellOrderId = exchange.Sell(sellPrice, remain);
            if (not sellOrderId):
                Sleep(2000);
                continue;
    
            orderInfo = WaitOrder(exchange, sellOrderId, 10000);
            remain -= orderInfo.DealAmount;
            cash += orderInfo.Price * orderInfo.DealAmount;
    
        return {'amount': sellAmount, 'price': (cash / sellAmount if sellAmount > 0 else 0)};
    
    
    BuyInfo = None;
    BanlanceRatio = 1.0;
    Profit = 0.0;
    timeAtBuy = 0;
    
    def onTick(exchange):
        global BuyInfo, BanlanceRatio, Profit, timeAtBuy
        ticker = exchange.GetTicker();
        records = exchange.GetRecords();
        if (not ticker or not records or len(records) < 45):
            return;
    
    
        ticks = [];
        for i in range(len(records)):
            ticks.append(records[i].Close);
    
        macd = TA.MACD(records, 12, 26, 9);
        dif = macd[0];
        dea = macd[1];
        his = macd[2];
    
        op = 0;
        if (BuyInfo is None):
            # 判断买入条件, macd柱由下翻上(由红转绿)
            if (dif[len(ticks)-1] > 0 and his[len(ticks)-1] > ac1 and his[len(ticks)-2] < bc1):
                op = 1;
        else:
            # 卖出条件,昨天跌、今天跌、今天低于昨天
            if (records[len(records)-2].Time > timeAtBuy and records[len(records)-1].Close < records[len(records)-1].Open - 0.5
                    and records[len(records)-2].Close < records[len(records)-2].Open - 0.5
                    and records[len(records)-1].Close < records[len(records)-2].Close - 0.5):
                op = 2;
            # 当前价跌破成本价、今天跌
            elif (records[len(records)-2].Time > timeAtBuy and BuyInfo['price'] > records[len(records)-1].Close and records[len(records)-1].Close < records[len(records)-1].Open - 0.5):
                op = 2;
            # 成本价低于最新价 或者 dif 小于0  、his小于0 ???
            elif ((BuyInfo['price'] < ticker.Last or dif[len(ticks)-1] < 0) and his[len(ticks)-1] <= 0):
                op = 2;
            # 当前价跌破成本价、达到止损点
            elif ((BuyInfo['price'] > ticker.Last) and ((BuyInfo['price'] - ticker.Last) / BuyInfo['price'] > TrailingStop)):
                op = 2;
    
    
    
        if (op == 1):       # 买入
            info = Buy(exchange, ticker.Sell + (SlidePrice * 3), SlidePrice, BanlanceRatio, orderTimeout * 1000);
            # Log(info);
            # Log(ticker);
            # Log(type(info));
            # Log(type(ticker));
            if (info['amount'] > 0):
                BuyInfo = info;
                timeAtBuy = records[len(records)-1].Time;
      
        elif (op == 2):    # 卖出
            info = Sell(exchange, BuyInfo['amount'], SlidePrice);
            if (info['amount'] > 0):
                Profit += info['amount'] * (info['price'] - BuyInfo['price']);
                LogProfit(Profit);
                BuyInfo = null;
    
    
    
    
    def main():
        account = exchange.GetAccount();
        if (account):
            Log(exchange.GetName(), exchange.GetCurrency(), account);
    
        while (True):
            onTick(exchange);
            Sleep(30000);
  • 相关阅读:
    MyBatis 基础搭建及架构概述
    Effective Java
    Effective Java
    Spring注解?啥玩意?
    Spring 中的Null-Safety
    Spring Resource框架体系介绍
    内部类的用法
    一文了解ConfigurationConditon接口
    详解状态压缩动态规划算法
    【硬核】使用替罪羊树实现KD-Tree的增删改查
  • 原文地址:https://www.cnblogs.com/bitquant/p/botvs-strategy-macd.html
Copyright © 2011-2022 走看看