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 / dealAmountif dealAmount > 0else 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.Close);
macd = TA.MACD(records, 12, 26, 9);
dif = macd;
dea = macd;
his = macd;
op = 0;
if (BuyInfo is None):
# 判断买入条件, macd柱由下翻上(由红转绿)
if (dif > 0 and his > ac1 and his < bc1):
op = 1;
else:
# 卖出条件,昨天跌、今天跌、今天低于昨天
if (records.Time > timeAtBuy and records.Close < records.Open - 0.5
and records.Close < records.Open - 0.5
and records.Close < records.Close - 0.5):
op = 2;
# 当前价跌破成本价、今天跌
elif (records.Time > timeAtBuy and BuyInfo['price'] > records.Close and records.Close < records.Open - 0.5):
op = 2;
# 成本价低于最新价 或者 dif 小于0、his小于0 ???
elif ((BuyInfo['price'] < ticker.Last or dif < 0) and his <= 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.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);
页:
[1]