예제 #1
0
def __WorkThread():
    """
    数据下载线程
    如果换成别的交易所,需要改这个函数里的下载那一行代码
    """
    global __exceptionTime,__exceptionCount, __terminated

    while(True):
        if __terminated:
            break
        try:
            startTime = time.time()
            
            depthData = HuobiServices.get_depth(__symbol,'step0')

            endTime = time.time()
            usedTime = endTime - startTime
            waitTime = 1 - usedTime - 0.1

            if depthData != None and depthData['status'] == 'ok':
                bid1 = depthData['tick']['bids'][0][0]
                ask1 = depthData['tick']['asks'][0][0]
                __ParseData(bid1,ask1)

            if waitTime > 0:
                time.sleep(waitTime)
        except Exception as e:
            if __exceptionTime < 0:
                __exceptionTime = int(time.time())

            __exceptionCount += 1
            Log.Print("Download Data Exception: ",str(e))
            Log.Info(__logFile,"Download Data Exception: " + str(e))
            time.sleep(1)
        finally:
            if __exceptionTime > 0:
                currTime = int(time.time())
                diffSeconds = currTime - __exceptionTime
                if diffSeconds >= 60:
                    #print("Exceptioin Count in 1Min:",__exceptionCount)
                    Log.Info(__logFile,"Exception Count in 1Min: {}".format(__exceptionCount))

                    if __exceptionCount > 10:
                        Log.Print("more than 15 times Exception in 1Min, Clear Data")
                        Log.Info(__logFile,"more than 15 times Exception in 1Min, Clear Data")
                        __InitData()

                    __exceptionTime = currTime
                    __exceptionCount = 0
    logStr = "!!!Terminated DataDownloader Stoped!"
    Log.Print(logStr)
    Log.Info(Const.logFile,logStr)
예제 #2
0
 def LockHold(self):
     """
     要卖的时候,本地调用此方法锁定一个持有
     """
     if self.state != 'hold':
         logStr = "HM - ##### FAILD! hold lock faild! " + self.__str__()
         Log.Print(logStr)
         Log.Info(Const.logFile,logStr)
         return False
     logStr = "HM - SUCCESS! hold lock successful! " + self.__str__()
     Log.Print(logStr)
     Log.Info(Const.logFile,logStr)
     self.state = 'lock'
     return True
예제 #3
0
def SendBuy(operationId, price, amount, cost):
    """
    直接在主线程中下买单,最多尝试2次
    买入下单
    operationId: 操作Id
    price: 买入价格
    amount: 买入数量
    cost: 买入总花费
    """
    global __tradeOperations
    for x in range(2):
        orderSended = False
        try:
            #orderData = HuobiServices.send_order(amount,'api','btcusdt','buy-limit',price)
            orderData = __DEBUG_ConstructTradeResult()
            status = orderData['status']
            orderId = orderData['data']
            if status == 'ok':
                orderSended = True
                buyOperation = TradeOperation(1, price, amount, operationId,
                                              orderId, cost)
                __tradeOperations.append(buyOperation)
                SaveTradeOperations()
                logStr = "OM - SUCCESS! Send Buy Order OK! operationId:{} price:{} amount:{} cost:{} orderId:{}".format(
                    operationId, price, amount, cost, orderId)
                Log.Print(logStr)
                Log.Info(Const.logFile, logStr)
                return
            else:
                logStr = "OM - ##### FAILD! Send Buy Order FAILD! operationId:{} price:{} amount:{} rawJson:{}".format(
                    operationId, price, amount, orderData)
                Log.Print(logStr)
                Log.Info(Const.logFile, logStr)
        except Exception as e:
            logStr = "OM - ##### EXCEPTION! Send Buy Order Exception! operationId:{} price:{} amount:{} Exception:{}".format(
                operationId, price, amount, e)
            Log.Print(logStr)
            Log.Info(Const.logFile, logStr)

            if orderSended == True:
                logStr = "OM - #### Buy FATAL ERROR!!!!!"
                Log.Print(logStr)
                Log.Info(Const.logFile, logStr)

            time.sleep(1)

    #走到这里,说明下买单失败,资金回滚
    BalanceManage.BuyFallback(cost)
예제 #4
0
def SendSell(operationId, price, amount, buyCost):
    """
    卖出持有
    operationId: 操作Id 
    price: 卖出价格
    amount: 卖出数量
    buyCost: 购买的时候花了多少钱,用于计算收益
    """
    global __tradeOperations
    for x in range(2):
        orderSended = False
        try:
            #orderData = HuobiServices.send_order(amount,'api','btcusdt','sell-limit',price)
            orderData = __DEBUG_ConstructTradeResult()
            status = orderData['status']
            orderId = orderData['data']
            if status == 'ok':
                orderSended = True
                sellOperation = TradeOperation(0, price, amount, operationId,
                                               orderId, buyCost)
                __tradeOperations.append(sellOperation)
                SaveTradeOperations()
                logStr = "OM - SUCCESS! Send Sell Order OK! operationId:{} price:{} amount:{} cost:{} orderId:{}".format(
                    operationId, price, amount, buyCost, orderId)
                Log.Print(logStr)
                Log.Info(Const.logFile, logStr)
                return
            else:
                logStr = "OM - ##### FAILD! Send Sell Order FAILD! operationId:{} price:{} amount:{} rawJson:{}".format(
                    operationId, price, amount, orderData)
                Log.Print(logStr)
                Log.Info(Const.logFile, logStr)
        except Exception as e:
            logStr = "OM - ##### EXCEPTION! Send Sell Order Exception! operationId:{} price:{} amount:{} Exception:{}".format(
                operationId, price, amount, e)
            Log.Print(logStr)
            Log.Info(Const.logFile, logStr)

            if orderSended == True:
                logStr = "OM - #### Sell FATAL ERROR!!!!!"
                Log.Print(logStr)
                Log.Info(Const.logFile, logStr)
                sys.exit()

            time.sleep(1)
    # 因为一些原因,卖出失败了,所以要回滚持有
    print("Ready Fallback ", operationId)
    HoldManager.FallbackHold(operationId)
예제 #5
0
def InitSystem():
    """
    加载密钥,初始化交易所服务
    获取Account id,赋值到交易所服务
    """
    configFile = "Config.json"

    try:
        configJsonStr = IOUtil.ReadTextFromFile(configFile)
        configData = json.loads(configJsonStr)
        access_key = configData['access_key']
        secret_key = configData['secret_key']
        HuobiServices.init_key(access_key, secret_key)

        accounts = HuobiServices.get_accounts()
        account_id = accounts['data'][0]['id']
        HuobiServices.init_account(account_id)

        HuobiServices.init_symbols()

    except Exception as e:
        logStr = "Fatal Error: Init System Faild!\n Exception:{}".format(e)
        Log.Print(logStr)
        Log.Info(Const.logFile, logStr)
        sys.exit()
예제 #6
0
def Start():
    t = threading.Thread(target=__WorkThread)
    t.setDaemon(True)
    t.start()
    logStr = "DataDownloader Started!"
    Log.Print(logStr)
    Log.Info(Const.logFile,logStr)
예제 #7
0
def Buy(price):
    """
    购买:根据价格和购买单位计算出需要花费多少 quote,把 quote 从原始资金拿到冻结资金中
    注意:这里的价格是已经加了0.3 usdt 后的价格
    """
    global __totalQuote, __tradePart, __quoteBalance, __frozeQuoteBalance

    # 计算每次买入多少 usdt 的 btc
    costQuote = MathUtil.GetPrecision(__totalQuote / __tradePart, 2)
    if __quoteBalance > costQuote:  # 资金足够,可以购买
        __LogBalance("Before Buy Action")
        __quoteBalance -= costQuote
        __frozeQuoteBalance += costQuote

        # 计算要花费的 usdt 按现在的价格能买多少 btc
        buyAmount = costQuote / price
        buyAmount = MathUtil.GetPrecision(buyAmount, 4)

        Log.Print("BM - Buy Info: price:{} costQuote:{} buyAmount:{}".format(
            price, costQuote, buyAmount))
        Log.Info(
            Const.logFile,
            "BM - Buy Info: price:{} costQuote:{} buyAmount:{}".format(
                price, costQuote, buyAmount))

        __SaveBalance()
        __LogBalance("After Buy Action")
        return costQuote, buyAmount  # 返回以 costQuote usdt 买入 buyAmount 的 btc
    return -1, -1
예제 #8
0
 def UnLockHold(self):
     """
     因为一些原因下单失败,需要回滚持有
     """
     logStr = "HM - UnLock Hold: " + self.__str__()
     Log.Print(logStr)
     Log.Info(Const.logFile,logStr)
     self.state = 'hold'
예제 #9
0
def __WorkThread_CheckTradeFillState():
    """
    检查所有订单的成交状态
    """
    logStr = "OrderManager Started!"
    Log.Print(logStr)
    Log.Info(Const.logFile, logStr)
    global __tradeOperations, __terminated
    while (__terminated != True):
        tradeLen = len(__tradeOperations)
        for x in range(tradeLen - 1, -1, -1):
            trade = __tradeOperations[x]

            if trade.exchangerOrderId != '':
                try:
                    #jsonResult = HuobiServices.order_info(trade.exchangerOrderId)
                    if trade.tradeType == 1:
                        jsonResult = __DEBUG_ConstructBuyFillResult(
                            trade.tradePrice, trade.tradeAmount)
                    else:
                        jsonResult = __DEBUG_ConstructSellFillResult(
                            trade.tradePrice, trade.tradeAmount)

                    if jsonResult['status'] == 'ok':
                        state = jsonResult['data']['state']
                        if state == 'filled':
                            fieldAmount = jsonResult['data']['field-amount']
                            fieldCashAmount = jsonResult['data'][
                                'field-cash-amount']
                            fieldFees = jsonResult['data']['field-fees']
                            logStr = "OM - Exchanger Order FILLED! operationId:{} fieldAmount:{} fieldCashAmount:{} field-fees:{}".format(
                                trade.operationId, fieldAmount,
                                fieldCashAmount, fieldFees)
                            Log.Print(logStr)
                            Log.Info(Const.logFile, logStr)
                            OnTradeFilled(trade, fieldCashAmount)
                except Exception as e:
                    logStr = "OM - ##### EXCEPTION! Check Order State Faild! operationId:{} Exception:{}".format(
                        trade.operationId, e)
                    Log.Print(logStr)
                    Log.Info(Const.logFile, logStr)
            time.sleep(1)
        time.sleep(2)
    Log.Print("!!!Terminated OrderManager Stoped!")
    Log.Info(Const.logFile, "!!!Terminated OrderManager Stoped!")
예제 #10
0
 def SellFilled(self,filledPrice,filledCash):
     """
     当卖单成交时,调用此方法进行最终的结算
     """
     self.sellFilledPrice = filledPrice
     gainedQuote = filledCash
     profit = gainedQuote - self.buyCost
     profit = MathUtil.GetPrecision(profit,4)
     if profit <= 0:
         logStr = "HM - ##### FATAL ERROR! You are lose Money: !!!! " + self.__str__ + " filledPrice:{} filledCash:{}".format(filledPrice,filledCash)
         Log.Print(logStr)
         Log.Info(Const.logFile,logStr)
         sys.exit()
     self.state = 'selled'
     self.profit = profit
     logStr = "HM - Cool! Sell Filled: buyPrice:{} buyCost:{} holdAmount:{} sellPrice:{} filledCash:{} profit:{}".format(self.buyPrice,self.buyCost,self.holdAmount,self.sellFilledPrice,filledCash,profit)
     Log.Print(logStr)
     Log.Info(Const.logFile,logStr)
예제 #11
0
def OnTradeFilled(tradeOperation, fieldCash):
    """
    当一个订单成交时,从操作列表中找到对应的交易索引,然后从交易列表中删除,保存数据
    """
    global __tradeOperations
    index = -1
    for x in range(len(__tradeOperations)):
        trade = __tradeOperations[x]
        if trade.operationId == tradeOperation.operationId:
            index = x
            break

    if index >= 0:
        del __tradeOperations[index]

    SaveTradeOperations()

    if tradeOperation.tradeType == 1:  # 处理买入订单成交
        gainedBase = tradeOperation.tradeAmount * 0.997
        gainedBase = MathUtil.GetPrecision(gainedBase, 4)
        logStr = "OM - Buy Order Filled: operationId:{} gainedBase:{}".format(
            tradeOperation.operationId, gainedBase)
        Log.Print(logStr)
        Log.Info(Const.logFile, logStr)
        HoldManager.BuyFilled(tradeOperation.operationId,
                              tradeOperation.tradePrice, gainedBase,
                              tradeOperation.cost,
                              tradeOperation.exchangerOrderId)
        BalanceManager.BuyFilled(tradeOperation.cost, gainedBase)
    elif tradeOperation.tradeType == 0:  # 处理卖出订单成交
        # TODO: 这里要实际成交一单,查看一下最终收益和自己计算的收益是否一样
        fieldCash = float(fieldCash) * 0.997  # 这里为避免float交易不精确,所以往少里算一点
        profit = fieldCash - tradeOperation.cost
        logStr = "OM - Sell Order Filled: operationId:{} fieldCash:{} profit:{}".format(
            tradeOperation.operationId, fieldCash, profit)
        Log.Print(logStr)
        Log.Info(Const.logFile, logStr)
        HoldManager.SellFilled(tradeOperation.operationId,
                               tradeOperation.exchangerOrderId,
                               tradeOperation.tradePrice, fieldCash)
        BalanceManager.SellFilled(fieldCash, profit,
                                  tradeOperation.tradeAmount)
예제 #12
0
def __LogBalance(actionName):
    global __baseBalance, __quoteBalance, __frozeQuoteBalance, __totalProfit, __totalQuote
    Log.Print(
        "BM - {}: baseBalance:{} quoteBalance:{} frozeQuote:{} totalProfit:{} totalQuote:{}"
        .format(actionName, __baseBalance, __quoteBalance, __frozeQuoteBalance,
                __totalProfit, __totalQuote))
    Log.Info(
        Const.logFile,
        "BM - {}: baseBalance:{} quoteBalance:{} frozeQuote:{} totalProfit:{} totalQuote:{}"
        .format(actionName, __baseBalance, __quoteBalance, __frozeQuoteBalance,
                __totalProfit, __totalQuote))
예제 #13
0
 def HoldOnSelling(self,sellOrderId):
     """
     当卖单下单成功后,调用此方法设置状态
     """
     if self.state != 'lock':
         logStr = "HM - ##### ERROR! hold state error for Sell! " + self.__str__()
         Log.Print(logStr)
         Log.Info(Const.logFile,logStr)
         
     self.state = 'selling'
     self.sellOrderId = sellOrderId
예제 #14
0
def FallbackHold(operationId):
    """
    卖出因为一些原因下单失败,回滚持有
    """
    for hold in holds:
        if hold.operationId == operationId:
            hold.UnLockHold()
            logStr = "HM - ##### Fallback Hold: " + hold.__str__()
            Log.Print(logStr)
            Log.Info(Const.logFile,logStr)
            break
    SaveHoldsData()
예제 #15
0
def HoldOnSelling(operationId,sellOrderId):
    """
    一个持有,卖出下单成功
    """
    for hold in holds:
        if hold.operationId == operationId:
            hold.HoldOnSelling(sellOrderId)
            logStr = "HM - Hold On Selling: " + hold.__str__()
            Log.Print(logStr)
            Log.Info(Const.logFile,logStr)
            break
    SaveHoldsData()
예제 #16
0
def BuyFallback(costQuote):
    """
    购买回滚,把当时要花费的 quote 从冻结资金拿到原始资金
    """
    global __quoteBalance, __frozeQuoteBalance
    __LogBalance("Before Buy Fallback")
    Log.Print("BM - Buy Fallback Info: costQuote:{}".format(costQuote))
    Log.Info(Const.logFile,
             "BM - Buy Fallback Info: costQuote:{}".format(costQuote))
    __frozeQuoteBalance -= costQuote
    __quoteBalance += costQuote
    __SaveBalance()
    __LogBalance("After Buy Fallback")
예제 #17
0
def LoadTradeOperations():
    global __tradeOperations
    if os.path.exists(Const.dataFile_orderManager):
        try:
            jsonStr = IOUtil.ReadTextFromFile(Const.dataFile_orderManager)
            __tradeOperations = json.loads(
                jsonStr, object_hook=__Json2TradeOperationObj)
        except Exception as e:
            logStr = "OM - ##### EXCEPTION! Load Trade Operations Faild! EXCEPTION:{}".format(
                e)
            Log.Print(logStr)
            Log.Info(Const.logFile, logStr)
            sys.exit()
예제 #18
0
def __LoadHoldsData():
    """
    加载所有的持有数据
    """
    global holds
    if os.path.exists(__dataFile):
        try:
            jsonStr = IOUtil.ReadTextFromFile(__dataFile)
            holds = json.loads(jsonStr,object_hook=__HoldJson2Obj)
        except Exception as e:
            logStr = "HM - ##### EXCEPTION! Load Hold Buy data exception: {}".format(e)
            Log.Print(logStr)
            Log.Info(Const.logFile,logStr)
            sys.exit()
예제 #19
0
def SellFilled(operationId, sellOrderId, filledPrice, filledCash):
    """
    一个卖出成交了
    """
    for x in range(len(holds)):
        hold = holds[x]
        if hold.operationId == operationId:
            hold.SellFilled(filledPrice,filledCash)
            del holds[x]
            ArchiveHold(hold)
            logStr = "HM - Sell Filled: " + hold.__str__()
            Log.Print(logStr)
            Log.Info(Const.logFile,logStr)
            break
    SaveHoldsData()
예제 #20
0
def BuyFilled(costQuote, baseAmount):
    """
    买入成交,从冻结资金中减去当时的花费,然后把购买的 base 数量加到原始资金中
    注意:传到这里的 baseAmount 是已经去掉手续费的了
    """
    global __frozeQuoteBalance, __baseBalance
    __LogBalance("Before Buy Filled")
    Log.Print("BM - Buy Filled Info: costQuote:{} filledAmount:{}".format(
        costQuote, baseAmount))
    Log.Info(
        Const.logFile,
        "BM - Buy Filled Info: costQuote:{} filledAmount:{}".format(
            costQuote, baseAmount))
    __frozeQuoteBalance -= costQuote
    __baseBalance += baseAmount
    __SaveBalance()
    __LogBalance("After Buy Filled")
예제 #21
0
def SellFilled(filledQuote, profit, selledAmount):
    """
    如果卖出成交了,则把获得的 quote 资金加到原始资金中
    """
    global __baseBalance, __quoteBalance, __totalQuote, __totalProfit
    __LogBalance("Before Sell Filled")
    Log.Print(
        "BM - Sell Filled Info: filledQuote:{} profit:{} selledAmount:{}".
        format(filledQuote, profit, selledAmount))
    Log.Info(
        Const.logFile,
        "BM - Sell Filled Info: filledQuote:{} profit:{} selledAmount:{}".
        format(filledQuote, profit, selledAmount))
    __baseBalance -= selledAmount
    __quoteBalance += filledQuote
    __totalProfit += profit
    __totalQuote += profit
    __SaveBalance()
    __LogBalance("After Sell Filled")
예제 #22
0
def SetProbe(price, probeType, lastTriggeredProbe=None):
    if probeType == 0:
        # 设置下降探针
        if lastTriggeredProbe != None and lastTriggeredProbe.probeType == 0:
            lastProbeLevel = lastTriggeredProbe.probeLevel
            currProbeLevel = lastProbeLevel * 1.2
        else:
            currProbeLevel = 150

        p = Probe(probeType, price - currProbeLevel, currProbeLevel)
    else:
        # 布置上升探针
        if lastTriggeredProbe != None and lastTriggeredProbe.probeType == 1:
            lastProbeLevel = lastTriggeredProbe.probeLevel
            currProbeLevel = lastProbeLevel * 1.1
        else:
            currProbeLevel = 100
        p = Probe(probeType, price + currProbeLevel, currProbeLevel)
    logStr = "Set Probe: probeType:{} price:{} probeLevel:{} probePrice:{}".format(
        probeType, price, currProbeLevel, p.probePrice)
    Log.Print(logStr)
    Log.Info(Const.logFile, logStr)
    return p
예제 #23
0
def __LoadBalance():
    """
    加载资产数据,如果数据文件不存在,则初始化资产数据
    """
    global __baseBalance, __quoteBalance, __frozeQuoteBalance, __totalProfit, __totalQuote

    if os.path.exists(__balanceFile):
        try:
            jsonStr = IOUtil.ReadTextFromFile(__balanceFile)
            jsonData = json.loads(jsonStr)
            __baseBalance = jsonData['baseBalance']
            __quoteBalance = jsonData['quoteBalance']
            __frozeQuoteBalance = jsonData['frozeQuoteBalance']
            __totalProfit = jsonData['totalProfit']
            __totalQuote = jsonData['totalQuote']
        except Exception as e:
            Log.Print("BM - ##### Fatal Error , can not load balance file! ",
                      e)
            Log.Info(
                Const.logFile,
                "BM - ##### Fatal Error, Can not load balance file! " + str(e))
            sys.exit()
    else:
        __SaveBalance()
예제 #24
0
def Terminated():
    if os.path.exists("terminated"):
        return True
    return False


declineProbe = None
riseProbe = None

if __name__ == '__main__':
    InitSystem()
    StartSystem()
    logStr = "All System Started!"
    Log.Print(logStr)
    Log.Info(Const.logFile, logStr)
    while (True):
        if Terminated():
            break

        if DataDownloader.DataValid() and len(DataDownloader.realTimeBids) > 0:
            currBidPrice = DataDownloader.realTimeBids[-1]
            TryToSell(currBidPrice)

            currAskPrice = DataDownloader.realTimeAsks[-1]
            if declineProbe == None and riseProbe == None:
                declineProbe = SetProbe(currAskPrice, 0)
                riseProbe = SetProbe(currAskPrice, 1)
            else:
                if len(DataDownloader.realTimeAsks) < 60:
                    time.sleep(0.5)