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);