OKCoin을 이식하는 재배기

저자:제로, 날짜: 2017-01-30 19:38:25
태그:고주파

이식자:https://github.com/richox/okcoin-leeks-reaper

원작자는 절차에 대한 수수료가 부과된다고 말했습니다. 저는 이식만 했습니다. 실제 디스크 테스트가 없었고, 배우고 싶었습니다. 발명자 양적 Tick 레벨 재검토 Deepth와 Trades의 재생을 지원하여 직접 재검토 학습 전략 논리를 수행할 수 있습니다.

아래와 같이 설명합니다.

OKCoin 양배추 수확기

이 프로그램은 OKCoin 비트코인 거래소에서 하이프레크 트레이딩 로봇 프로그램으로, 2016년 6월 전략의 기본 모형화부터 2017년 1월 중순까지 초기 투입된 6000불을 250,000불로 성공적으로 닦아낸 전략이다. 최근 중앙은행의 비트코인에 대한 고압 정책으로 인해 주요 플랫폼이 배당을 중단하고 거래 수수료를 부과하기 시작하여 이 전략은 사실상 실패했다.

image

이 로봇 프로그램은 두 가지 주요 전략에 기반합니다.

  1. 트렌드 전략: 가격의 유동적인 변동이 발생했을 때 주문을 적시에 따라가기, 즉 말 그대로을 쫓아내기 위해
  2. 평형 전략: 지점이 50% 벗어날 때, 지점을 50%로 점차적으로 되돌릴 수 있도록 소매를 내보내고, 추세 말반의 반전이 회귀로 이어지는 것을 방지합니다.수익을 버리는 것, 꼬리를 먹지 않는 것

이 절차는 포지션의 균형, 즉 (자본 + 금융 = 금융) 을 요구하여 포지션의 50%에서 순자산이 가격 변동과 함께 변동하지 않고, 또한 유동적인 변동이 발생했을 때 보증합니다.돌고 돌고

다음 두 가지 프로젝트에 감사드립니다:

이 글은 오케이온에 대한 감사입니다.

BTC: 3QFn1qfZMhMQ4FhgENR7fha3T8ZVw1bEeU


/*backtest
start: 2019-09-05 00:00:00
end: 2019-09-05 22:00:00
period: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT","fee":[0,0]}]
mode: 1
*/

function LeeksReaper() {
    var self = {}
    self.numTick = 0
    self.lastTradeId = 0
    self.vol = 0
    self.askPrice = 0
    self.bidPrice = 0
    self.orderBook = {Asks:[], Bids:[]}
    self.prices = []
    self.tradeOrderId = 0
    self.p = 0.5
    self.account = null
    self.preCalc = 0
    self.preNet = 0

    self.updateTrades = function() {
        var trades = _C(exchange.GetTrades)
        if (self.prices.length == 0) {
            while (trades.length == 0) {
                trades = trades.concat(_C(exchange.GetTrades))
            }
            for (var i = 0; i < 15; i++) {
                self.prices[i] = trades[trades.length - 1].Price
            }
        }
        self.vol = 0.7 * self.vol + 0.3 * _.reduce(trades, function(mem, trade) {
            // Huobi not support trade.Id
            if ((trade.Id > self.lastTradeId) || (trade.Id == 0 && trade.Time > self.lastTradeId)) {
                self.lastTradeId = Math.max(trade.Id == 0 ? trade.Time : trade.Id, self.lastTradeId)
                mem += trade.Amount
            }
            return mem
        }, 0)

    }
    self.updateOrderBook = function() {
        var orderBook = _C(exchange.GetDepth)
        self.orderBook = orderBook
        if (orderBook.Bids.length < 3 || orderBook.Asks.length < 3) {
            return
        }
        self.bidPrice = orderBook.Bids[0].Price * 0.618 + orderBook.Asks[0].Price * 0.382 + 0.01
        self.askPrice = orderBook.Bids[0].Price * 0.382 + orderBook.Asks[0].Price * 0.618 - 0.01
        self.prices.shift()
        self.prices.push(_N((orderBook.Bids[0].Price + orderBook.Asks[0].Price) * 0.35 +
            (orderBook.Bids[1].Price + orderBook.Asks[1].Price) * 0.1 +
            (orderBook.Bids[2].Price + orderBook.Asks[2].Price) * 0.05))
    }
    self.balanceAccount = function() {
        var account = exchange.GetAccount()
        if (!account) {
            return
        }
        self.account = account
        var now = new Date().getTime()
        if (self.orderBook.Bids.length > 0 && now - self.preCalc > (CalcNetInterval * 1000)) {
            self.preCalc = now
            var net = _N(account.Balance + account.FrozenBalance + self.orderBook.Bids[0].Price * (account.Stocks + account.FrozenStocks))
            if (net != self.preNet) {
                self.preNet = net
                LogProfit(net)
            }
        }
        self.btc = account.Stocks
        self.cny = account.Balance
        self.p = self.btc * self.prices[self.prices.length-1] / (self.btc * self.prices[self.prices.length-1] + self.cny)
        var balanced = false
        
        if (self.p < 0.48) {
            Log("开始平衡", self.p)
            self.cny -= 300
            if (self.orderBook.Bids.length >0) {
                exchange.Buy(self.orderBook.Bids[0].Price + 0.00, 0.01)
                exchange.Buy(self.orderBook.Bids[0].Price + 0.01, 0.01)
                exchange.Buy(self.orderBook.Bids[0].Price + 0.02, 0.01)
            }
        } else if (self.p > 0.52) {
            Log("开始平衡", self.p)
            self.btc -= 0.03
            if (self.orderBook.Asks.length >0) {
                exchange.Sell(self.orderBook.Asks[0].Price - 0.00, 0.01)
                exchange.Sell(self.orderBook.Asks[0].Price - 0.01, 0.01)
                exchange.Sell(self.orderBook.Asks[0].Price - 0.02, 0.01)
            }
        }
        Sleep(BalanceTimeout)
        var orders = exchange.GetOrders()
        if (orders) {
            for (var i = 0; i < orders.length; i++) {
                if (orders[i].Id != self.tradeOrderId) {
                    exchange.CancelOrder(orders[i].Id)
                }
            }
        }
    }

    self.poll = function() {
        self.numTick++
        self.updateTrades()
        self.updateOrderBook()
        self.balanceAccount()
        
        var burstPrice = self.prices[self.prices.length-1] * BurstThresholdPct
        var bull = false
        var bear = false
        var tradeAmount = 0
        if (self.account) {
            LogStatus(self.account, 'Tick:', self.numTick, ', lastPrice:', self.prices[self.prices.length-1], ', burstPrice: ', burstPrice)
        }
        
        if (self.numTick > 2 && (
            self.prices[self.prices.length-1] - _.max(self.prices.slice(-6, -1)) > burstPrice ||
            self.prices[self.prices.length-1] - _.max(self.prices.slice(-6, -2)) > burstPrice && self.prices[self.prices.length-1] > self.prices[self.prices.length-2]
            )) {
            bull = true
            tradeAmount = self.cny / self.bidPrice * 0.99
        } else if (self.numTick > 2 && (
            self.prices[self.prices.length-1] - _.min(self.prices.slice(-6, -1)) < -burstPrice ||
            self.prices[self.prices.length-1] - _.min(self.prices.slice(-6, -2)) < -burstPrice && self.prices[self.prices.length-1] < self.prices[self.prices.length-2]
            )) {
            bear = true
            tradeAmount = self.btc
        }
        if (self.vol < BurstThresholdVol) {
            tradeAmount *= self.vol / BurstThresholdVol
        }
        
        if (self.numTick < 5) {
            tradeAmount *= 0.8
        }
        
        if (self.numTick < 10) {
            tradeAmount *= 0.8
        }
        
        if ((!bull && !bear) || tradeAmount < MinStock) {
            return
        }
        var tradePrice = bull ? self.bidPrice : self.askPrice
        while (tradeAmount >= MinStock) {
            var orderId = bull ? exchange.Buy(self.bidPrice, tradeAmount) : exchange.Sell(self.askPrice, tradeAmount)
            Sleep(200)
            if (orderId) {
                self.tradeOrderId = orderId
                var order = null
                while (true) {
                    order = exchange.GetOrder(orderId)
                    if (order) {
                        if (order.Status == ORDER_STATE_PENDING) {
                            exchange.CancelOrder(orderId)
                            Sleep(200)
                        } else {
                            break
                        }
                    }
                }
                self.tradeOrderId = 0
                tradeAmount -= order.DealAmount
                tradeAmount *= 0.9
                if (order.Status == ORDER_STATE_CANCELED) {
                    self.updateOrderBook()
                    while (bull && self.bidPrice - tradePrice > 0.1) {
                        tradeAmount *= 0.99
                        tradePrice += 0.1
                    }
                    while (bear && self.askPrice - tradePrice < -0.1) {
                        tradeAmount *= 0.99
                        tradePrice -= 0.1
                    }
                }
            }
        }
        self.numTick = 0
    }
    return self
}

function main() {
    var reaper = LeeksReaper()
    while (true) {
        reaper.poll()
        Sleep(TickInterval)
    }
}

관련

더 많은

힙합의 대왕이 전략은 실패했고, 수익은 0%의 절차 수수료의 높은 빈도 소액 수익에서 비롯되었다.

콩바이979 self.vol到底是个啥?是一个ticker期间内所有交易量的总和吗?

dayTrader2018for (var i = 0; i < 15; i++) { self.prices[i] = trades[trades.length - 1].Price }; 여기 조금 문제가 있지는 않나요, 그래서 prices 행렬의 모든 요소가 최신 거래 가격이 아닌가요?

코유 7035저는 몇 개의 거래소에서 수수료 없이 거래가 깊고 좋은 거래소를 가지고 있습니다. 이 전략을 시도해 볼 수 있나요?

비자수오정말 멋지네요. 이제 사용할 수 있나요?

스카이프파이어참고판 판매 가격: 2000개, 비공식, 연락이 가능합니다.

라자야크어떤 사람이 테스트를 해본 적이 있고, 그 결과에 대해 논의해 본 적이 있나요?

발렌언제 논문판이 나올까요?

우치안밍어떻게 botvs가 지원하지 않는, 거래 무료 거래소에서 실행, 어떻게 거래소 API를 작성해야합니까?

J이런 좋은 전략을 공유해 주셔서 감사합니다. exchange.CancelOrder ((orders[i].Id) 에서 주문 취소 코드는 약간의 문제가 있습니다. 아래의 코드를 보시면 10초 후에 삭제해야 합니다. 다른 것들은 거의 문제없고, 나는 그것을 수정하고 무료 거래소에서 실행했습니다.

Kmstudio 66行prices需加.length

스노우페어이 언어는 어떤 언어일까요?

제로 平衡那里下单忘加上Price属性了。。已更正,有发现bug请及时提交.

수생물이 모든 것은 우리가 돈을 벌기 위한 전략으로 보입니다.

1213761768그리고 그 다음에는

이비음, 음, 음, 음, 음.

부탁드립니다. 사격 가격과 수요 가격을 계산할 때, 사격 가격이 수요 가격보다 크다고 판단하지 않은 것처럼 주문합니다. 그래서 만약 구매가 판매에 매우 가깝다면, 계산은 아마도 높은 구매가 낮은 판매가 될 것입니다.

저는 을 좋아합니다.저는 이 글에 대한 해설을 썼고, 모든 사람들이 Hoo_tongxue를 추가할 수 있어야 합니다. 가장 중요한 것은 무료입니다.

저는 을 좋아합니다.진짜 얼굴은 뚱뚱합니다.

작은 석탄공어떤 거래소?

제로이 값은 최신 가격으로 초기화되어야 합니다.

재구매는 기적이다이 모든 것은 이미 실패했습니다.

수스키네, 이 바늘은 더 잘 잘라요^_^

스카이프파이어판매자가 팔고 구매자가 사면, 당신은 논쟁하지 않습니다.

신부도 마찬가지입니다.모든 사람들이 소스 코드를 공개했습니다. 2000을 판매하는 것에 대해 논평하세요? 정말 죄송합니다.

아케 请问zaif.jp现在还是免手续费吗?怎么通过认证呢

시아오후안001아이디를 보세요.

J 在Zaif.jp上测试,买一卖一间经常就没有空间,用这个策略有什么问题吗?

J진짜야? 나가서 강의를 해봐

시아오후안001기괴한 원작자

J좋은, 몇 가지 질문이 있습니다, 다른 게시물을 만들 수 있습니다: https://www.botvs.com/bbs-topic/677

제로이 전략에 대한 학습 내용이나 의문을 공유하고 싶다면 포럼에 게시하십시오.

제로추천 감사합니다, 나는 매개 변수를 추가했습니다, 균형 주문 대기 시간, 동시 처리를 원한다면, 주문 시기와 함께 각 주문의 ID를 기록하고 선택적으로 취소 할 수 있습니다. 이것은 지연을 줄일 수 있습니다.

시아오후안001이 전략이 이상해 보이는데, 저는 이 방법을 좋아합니다.

제로제가 시도한 것도 아닙니다. 여러분들이 직접 연구해 보셔야 합니다.

오리온1708어려운 Z 대移植~. 자, 정책 파라미터 기본값의 변경이 정책에 큰 영향을 미치나요?

제로哈哈, 감사합니다, 추가되었습니다.

제로자바스크립트

제로거래 빈도가 높습니다.

작은 꿈이 글의 원작자 역시 그 날 공수료를 받다가 공개되었다는 것이다.

시아오후안001왜 트렌드 전략가들은 충격 비용을 두려워합니까?