最近の微信群での発明者定量化に関する議論print money
ロボットについて,非常に熱烈な議論が繰り広げられ,非常に古い戦略が再び広場客たちの視野に入ってきた.菜食機。
print money
ロボット取引の原理は,菜
[OKCoinを移植する菜
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)
}
}
一般的に,戦略を学ぶとき,読むとき,まず全体的なプログラム構造を見てください. この戦略コードはあまり多くありません,200行未満のコードで,非常に簡潔で,元のバージョンの戦略還元が非常に高く,基本的には同じです.main()
実行を開始します.main()
メディアは,LeeksReaper()
この関数は,LeeksReaper()
関数もよく理解できます. この関数は,カバノキの戦略論理モジュール (一つのオブジェクト) の構築関数として理解できます.LeeksReaper()
リンゴ刈り機の取引論理を構築する責任者.
キーワード:
戦略main
函数の一行目:var reaper = LeeksReaper()
ローカル変数を宣言します.reaper
LeeksReaper () が実行される場合,この LeeksReaper () は,reaper
。
戦略main
この関数は次のようになります.
while (true) {
reaper.poll()
Sleep(TickInterval)
}
移動するwhile
死のサイクル 絶え間ない実行reaper
オブジェクトの処理関数poll()
,poll()
函数が取引戦略の主要な論理であるとき,その戦略プロセスは取引の論理を絶えず実行するようになります.
についてSleep(TickInterval)
この行は,取引論理の回転頻度を制御するために,全体的な取引論理が実行されるたびに停止時間を制御することをよく理解しています.
LeeksReaper()
構造関数見てくださいLeeksReaper()
戦略論理オブジェクトをどのように構成するか.
LeeksReaper()
任意の項目を表示します.var self = {}
ありがとうございました.LeeksReaper()
この空のオブジェクトにいくつかの方法や属性を徐々に追加し,最終的にこのオブジェクトの構築を完了し,最終的にこのオブジェクトを返します.main()
この関数には,var reaper = LeeksReaper()
このステップでは,返されたオブジェクトの値がreaper
)。
self
オブジェクトの属性追加このビデオはself
多くの属性が追加され,それぞれの属性が説明され,その属性,変数の用途,意図,戦略を簡単に理解し,このコードの堆積物を見ないために,その属性をすぐに理解することができます.
self.numTick = 0 # 用来记录poll函数调用时未触发交易的次数,当触发下单并且下单逻辑执行完时,self.numTick重置为0
self.lastTradeId = 0 # 交易市场已经成交的订单交易记录ID,这个变量记录市场当前最新的成交记录ID
self.vol = 0 # 通过加权平均计算之后的市场每次考察时成交量参考(每次循环获取一次市场行情数据,可以理解为考察了行情一次)
self.askPrice = 0 # 卖单提单价格,可以理解为策略通过计算后将要挂卖单的价格
self.bidPrice = 0 # 买单提单价格
self.orderBook = {Asks:[], Bids:[]} # 记录当前获取的订单薄数据,即深度数据(卖一...卖n,买一...买n)
self.prices = [] # 一个数组,记录订单薄中前三档加权平均计算之后的时间序列上的价格,简单说就是每次储存计算得到的订单薄前三档加权平均价格,放在一个数组中,用于后续策略交易信号参考,所以该变量名是prices,复数形式,表示一组价格
self.tradeOrderId = 0 # 记录当前提单下单后的订单ID
self.p = 0.5 # 仓位比重,币的价值正好占总资产价值的一半时,该值为0.5,即平衡状态
self.account = null # 记录账户资产数据,由GetAccount()函数返回数据
self.preCalc = 0 # 记录最近一次计算收益时的时间戳,单位毫秒,用于控制收益计算部分代码触发执行的频率
self.preNet = 0 # 记录当前收益数值
self
オブジェクトの追加方法セルフにこれらの属性を追加すると,self
オブジェクトは,特定の作業や機能を行うために方法を追加します.
この関数には,次の関数があります.
self.updateTrades = function() {
var trades = _C(exchange.GetTrades) # 调用FMZ封装的接口GetTrades,获取当前最新的市场成交数据
if (self.prices.length == 0) { # 当self.prices.length == 0时,需要给self.prices数组填充数值,只有策略启动运行时才会触发
while (trades.length == 0) { # 如果近期市场上没有更新的成交记录,这个while循环会一直执行,直到有最新成交数据,更新trades变量
trades = trades.concat(_C(exchange.GetTrades)) # concat 是JS数组类型的一个方法,用来拼接两个数组,这里就是把“trades”数组和“_C(exchange.GetTrades)”返回的数组数据拼接成一个数组
}
for (var i = 0; i < 15; i++) { # 给self.prices填充数据,填充15个最新成交价格
self.prices[i] = trades[trades.length - 1].Price
}
}
self.vol = 0.7 * self.vol + 0.3 * _.reduce(trades, function(mem, trade) { # _.reduce 函数迭代计算,累计最新成交记录的成交量
// 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)
}
updateTrades
この関数の役割は,最新の市場取引データを入手し,そのデータに基づいていくつかの計算を行い,記録し,戦略のフォローアップの論理に使用することを提供する.
この記事へのトラックバック一覧です.
について_.reduce
プログラミングの知識のない生徒が困惑するかもしれません._.reduce
そうですUnderscore.jsこのデータベースの関数は,FMZJSのポリシーがサポートしているので,リターン計算は便利です.Underscore.js资料链接
簡単な意味もあります:
function main () {
var arr = [1, 2, 3, 4]
var sum = _.reduce(arr, function(ret, ele){
ret += ele
return ret
}, 0)
Log("sum:", sum) # sum 等于 10
}
解き放たれるでしょう.[1, 2, 3, 4]
この数字の合計は,すべての数字を合計します.trades
数列内の各取引記録データには,取引記録の取引総額を合計する.self.vol = 0.7 * self.vol + 0.3 * _.reduce(...)
ありがとうございました....
代用するコードの山.self.vol
この計算は,重度の平均である.つまり,最新の取引は総取引の30%を重み付け,前回の重み付けは70%を重み付けしている.この比率は,戦略の著者が設定したもので,おそらく市場法則の観察に関連している.
最近の取引データを取得したインターフェースが古いデータを復元したら どうなるか尋ねると,私は誤ったデータと意味のあるデータを得ています.
if ((trade.Id > self.lastTradeId) || (trade.Id == 0 && trade.Time > self.lastTradeId)) {
...
}
この判断は,取引記録の取引IDに基づいて判断することができ,IDが最後の記録のIDよりも大きい場合にのみ累積を誘発するか,または取引所のインターフェースがIDを提供していない場合,すなわち,trade.Id == 0
取引記録の時間軸を使って判断します.self.lastTradeId
取引記録の時間軸が保存されますが,IDではありません.
この関数には,次の関数があります.
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))
}
未来を見ようupdateOrderBook
この関数は,関数の名前の文字通りの意味からわかるように,この関数の役割は,命令薄を更新することです. そうそう,単に命令薄を更新するだけでなく,関数 FMZ のAPI関数を呼び出すことができます.GetDepth()
市場注文薄データ (売る1...売るn,買う1...買うn) を取得し,self.orderBook
中.次に,注文のデータ薄の購入・販売の注文が3個未満である場合は,無効関数を直接返す.
統計学者は,この2つの数字を計算した.
請求料の計算 請求書価格の計算は,また加重平均計算を用いて行われ,支払いを計算する際には,購入権は 61.8% ((0.618),売却権は余分な重量 38.2% ((0.382) となり,購入権は 61.8% ((0.618),売却権は 38.2% ((0.382) となり,購入権は 61.8% ((0.618),購入権は 61.8% ((0.382) となり,購入権は 61.8% ((0.618),売却権は 38.2% ((0.382). 請求書販売単価を計算する時も同じです. 販売単価と販売単価の権利は大きいです. なぜ0.618なのかは,著者が比較的に黄金の分割比率を好む可能性がある. 最後に追加したポイントを引いたポイントの価格 ((0.01) は,略微的に再び盘口正中央から少し偏りを取るためにです.
更新時間順序で注文薄前3列加重平均価格 注文薄の最初の3段の購入,販売单の価格を加重平均計算するために,最初の段重量0.7,第2段重量0.2,第3段重量0.1です. 計算してみましょう.
(买一 + 卖一) * 0.35 + (买二 + 卖二) * 0.1 + (买三 + 卖三) * 0.05
->
(买一 + 卖一) / 2 * 2 * 0.35 + (买二 + 卖二) / 2 * 2 * 0.1 + (买三 + 卖三) / 2 * 2 * 0.05
->
(买一 + 卖一) / 2 * 0.7 + (买二 + 卖二) / 2 * 0.2 + (买三 + 卖三) / 2 * 0.1
->
第一档平均的价格 * 0.7 + 第二档平均的价格 * 0.2 + 第三档平均的价格 * 0.1
この時点で,最終的に計算された価格は,実際に反当前市場における三階層の中間盤の価格位置であることがわかります.
この計算した価格で更新します.self.prices
この式は,この式で表される.shift()
更新されたデータ (※) を追加します.push()
函数,shift,push は,JS言語の行列オブジェクトの方法であり,具体的にはJS資料をクエリして作成することができる.self.prices
数列は時間配列の順序のデータストリームである.
咳,咳,口水を飲んで,ここで解剖して,次回はお会いしましょう.
ゆっくりと強くなる私Self.pricesは,先ず15の歴史的な取引価格を記入し,その後に,最初の3つのセットの重み付き平均価格を記入します.
スヌンプ"夢"を褒めたい
m0606悲しいことに,多くの取引所では, 取引先の価格が1つだけ残るようになっており, 取引先の価格が1つだけ残るようになっており, 取引先の価格が1つだけ残るようになっており, 取引先の価格が1つだけ残るようになっており, 取引先の価格が1つだけ残るようになっており, 取引先の価格が1つだけ残るようになっており,
ママありがとうございました. PythonのバージョンをXinjiangで実行してみました. 20枚も5分以内になくなってしまいました.
ブクシアック素晴らしい,夢の説明が全くないのに,本当に理解できない.
エディ金分割0.618 0.382は使用するフィーボ ドリーム総牛群
ほら ほら牛の群れは本当に
エヴァン1987ありがとうございました. ありがとうございました.
メイクビットドリーム総牛 p
シイイイイ牛の群れ! この記事へのトラックバック一覧です.
9つの太陽ドリーム・総,牛団!
発明者 量化 - 微かな夢ほら,もういいから
発明者 量化 - 微かな夢取引の頻度が高くなる可能性について知覚する.
発明者 量化 - 微かな夢低周波戦略は,いくつかのサポートを必要としている. 草神によって書かれた戦略原理分析の記事を参照してください.
発明者 量化 - 微かな夢ありがとうございました. 気に入ったらシェアしてください.
発明者 量化 - 微かな夢ありがとうございました!
発明者 量化 - 微かな夢ありがとうございました!
発明者 量化 - 微かな夢ありがとうございました!
発明者 量化 - 微かな夢学校に入学した頃,この黄金分割比を覚えたとき,特にはっきりと覚えているのは,この比が長方形の長方形の最も美しいことだと.
発明者 量化 - 微かな夢ありがとうございました.
発明者 量化 - 微かな夢この解説の比較は複雑ではなく,一行一行に可能な限り理解しやすい方法で説明されています.