```python

import math

MACD辅助BotVS趋势交易策略研究

import time

import datetime

def precise_round(value):

return math.floor(value * 1000) / 1000

# 延迟取消特定订单

def await_orderCancellation(exchange, orderId, cancellationTimeout):

current_time = time.time()

startTime = int(round(current_time * 1000))

while True:

time.sleep(3)

orderDetails = exchange.GetOrder(orderId)

if not orderDetails:

continue

if orderDetails.Status in [ORDER_STATE_CLOSED, ORDER_STATE_CANCELED]:

return orderDetails

current_time = time.time()

if (int(round(current_time * 1000)) - startTime) > cancellationTimeout:

exchange.CancelOrder(orderId)

# 执行购买操作

def execute_purchase(exchange, ceilingPrice, offsetPrice, balancePercentage, timeout):

currentTime = time.time()

startTime = int(round(currentTime * 1000))

accountBalance = None

tradeVolume = 0.0

fundsUsed = 0.0

maxFundsUse = 0.0

isFirstIteration = True

while True:

if isFirstIteration:

isFirstIteration = False

else:

time.sleep(3)

marketData = exchange.GetTicker()

if not marketData:

continue

purchasePrice = marketData.Sell + offsetPrice

if purchasePrice > ceilingPrice:

continue

if accountBalance is None:

accountBalance = exchange.GetAccount()

if not accountBalance:

continue

maxFundsUse = accountBalance.Balance * balancePercentage

purchaseQuantity = precise_round((maxFundsUse - fundsUsed) / purchasePrice)

if purchaseQuantity < exchange.GetMinStock():

break

orderNumber = exchange.Buy(purchasePrice, purchaseQuantity)

if not orderNumber:

log(purchasePrice, purchaseQuantity, maxFundsUse, fundsUsed)

continue

orderDetails = await_orderCancellation(exchange, orderNumber, timeout)

tradeVolume += orderDetails.DealAmount

fundsUsed += orderDetails.Price * orderDetails.DealAmount

if orderDetails.Status == ORDER_STATE_CLOSED:

break

currentTime = time.time()

if (int(round(currentTime * 1000)) - startTime) < timeout:

break

return {'amount': tradeVolume, 'price': (fundsUsed / tradeVolume if tradeVolume > 0 else 0)}

# 执行卖出操作

def execute_sale(exchange, saleVolume, offsetPrice):

accountInfo = exchange.GetAccount()

while not accountInfo:

time.sleep(2)

accountInfo = exchange.GetAccount()

saleVolume = min(saleVolume, accountInfo.Stocks)

proceeds = 0.0

remainingVolume = saleVolume

while remainingVolume >= exchange.GetMinStock():

marketData = exchange.GetTicker()

if not marketData:

time.sleep(2)

continue

salePrice = marketData.Buy - offsetPrice

saleOrderNumber = exchange.Sell(salePrice, remainingVolume)

if not saleOrderNumber:

time.sleep(2)

continue

orderDetails = await_orderCancellation(exchange, saleOrderNumber, 10000)

remainingVolume -= orderDetails.DealAmount

proceeds += orderDetails.Price * orderDetails.DealAmount

return {'amount': saleVolume, 'price': (proceeds / saleVolume if saleVolume > 0 else 0)}

# 主交易逻辑

BuyInfo = None

BalanceRatio = 1.0

Profit = 0.0

timeOfPurchase = 0

def onMarketTick(exchange):

global BuyInfo, BalanceRatio, Profit, timeOfPurchase

marketData = exchange.GetTicker()

tradeRecords = exchange.GetRecords()

if not marketData or not tradeRecords or len(tradeRecords) < 45:

return

priceTicks = [record.Close for record in tradeRecords]

technicalAnalysisResult = TA.MACD(tradeRecords, 12, 26, 9)

dif = technicalAnalysisResult[0]

dea = technicalAnalysisResult[1]

macdHistogram = technicalAnalysisResult[2]

tradeAction = 0

if not BuyInfo:

if dif[-1] > 0 and macdHistogram[-1] > 0 and macdHistogram[-2] < 0:

tradeAction = 1

else:

if (tradeRecords[-2].Time > timeOfPurchase and tradeRecords[-1].Close < tradeRecords[-1].Open - 0.5 and

tradeRecords[-2].Close < tradeRecords[-2].Open - 0.5 and tradeRecords[-1].Close < tradeRecords[-2].Close - 0.5):

tradeAction = 2

elif (tradeRecords[-2].Time > timeOfPurchase and BuyInfo['price'] > tradeRecords[-1].Close and

tradeRecords[-1].Close < tradeRecords[-1].Open - 0.5):

tradeAction = 2

elif ((BuyInfo['price'] < marketData.Last or dif[-1] < 0) and macdHistogram[-1] <= 0):

tradeAction = 2

elif ((BuyInfo['price'] > marketData.Last) and ((BuyInfo['price'] - marketData.Last) / BuyInfo['price'] > TrailingStop)):

tradeAction = 2

if tradeAction == 1: # 执行买入

tradeDetails = execute_purchase(exchange, marketData.Sell + (SlidePrice * 3), SlidePrice, BalanceRatio, orderTimeout * 1000)

if tradeDetails['amount'] > 0:

BuyInfo = tradeDetails

timeOfPurchase = tradeRecords[-1].Time

elif tradeAction == 2: # 执行卖出

tradeDetails = execute_sale(exchange, BuyInfo['amount'], SlidePrice)

if tradeDetails['amount'] > 0:

Profit += tradeDetails['amount'] * (tradeDetails['price'] - BuyInfo['price'])

BuyInfo = None

def main():

accountInfo = exchange.GetAccount()

if accountInfo:

log(exchange.GetName(), exchange.GetCurrency(), accountInfo)

while True:

onMarketTick(exchange)

time.sleep(30)

```