{"cells": [{"metadata": {"trusted": true}, "cell_type": "code", "source": "var fmz = require(\"fmz\")                           // \u5f15\u5165\u540e\u81ea\u52a8\u5bfc\u5165 talib, TA, plot \u5e93\nvar task = fmz.VCtx({\nstart: '2019-04-09 17:49:00',\nend: '2019-04-09 18:00:00',\nperiod: '1m',\nexchanges: [{\"eid\":\"Huobi\",\"currency\":\"ETH_BTC\", \"balance\":1, \"stocks\":10,\"fee\":[0.04,0.04]},{\"eid\":\"OKEX\",\"currency\":\"ETH_USDT\",\"balance\":10000,\"stocks\":1,\"fee\":[0.04,0.04]}, {\"eid\":\"OKEX\",\"currency\":\"BTC_USDT\",\"balance\":10000,\"stocks\":1,\"fee\":[0.04,0.04]}]\n})", "execution_count": 1, "outputs": []}, {"metadata": {}, "cell_type": "markdown", "source": "\u663e\u793a\u6700\u521d\u4ea4\u6613\u6240\u8d26\u6237\u4fe1\u606f\u548c\u884c\u60c5\uff1a\n- A\u4ea4\u6613\u6240\u4ea4\u6613\u5bf9\u4e3a\uff1aETH_BTC\n- B\u4ea4\u6613\u6240\u4ea4\u6613\u5bf9\u4e3a\uff1aETH_USDT\n- C\u4ea4\u6613\u6240\u4ea4\u6613\u5bf9\u4e3a\uff1aBTC_USDT"}, {"metadata": {"trusted": true}, "cell_type": "code", "source": "var accA = exchanges[0].GetAccount()\naccA", "execution_count": 2, "outputs": [{"output_type": "execute_result", "execution_count": 2, "data": {"text/plain": "{ Balance: 1, FrozenBalance: 0, Stocks: 10, FrozenStocks: 0 }"}, "metadata": {}}]}, {"metadata": {"trusted": true}, "cell_type": "code", "source": "var accB = exchanges[1].GetAccount()\naccB", "execution_count": 3, "outputs": [{"output_type": "execute_result", "execution_count": 3, "data": {"text/plain": "{ Balance: 10000, FrozenBalance: 0, Stocks: 1, FrozenStocks: 0 }"}, "metadata": {}}]}, {"metadata": {"trusted": true}, "cell_type": "code", "source": "var accC = exchanges[2].GetAccount()\naccC", "execution_count": 4, "outputs": [{"output_type": "execute_result", "execution_count": 4, "data": {"text/plain": "{ Balance: 10000, FrozenBalance: 0, Stocks: 1, FrozenStocks: 0 }"}, "metadata": {}}]}, {"metadata": {"trusted": true}, "cell_type": "code", "source": "var initSumBTC = accA.Balance + accC.Stocks\ninitSumBTC", "execution_count": 5, "outputs": [{"output_type": "execute_result", "execution_count": 5, "data": {"text/plain": "2"}, "metadata": {}}]}, {"metadata": {"trusted": true}, "cell_type": "code", "source": "var initSumETH = accA.Stocks + accB.Stocks\ninitSumETH", "execution_count": 6, "outputs": [{"output_type": "execute_result", "execution_count": 6, "data": {"text/plain": "11"}, "metadata": {}}]}, {"metadata": {"trusted": true}, "cell_type": "code", "source": "var initSumUSDT = accB.Balance + accC.Balance\ninitSumUSDT", "execution_count": 7, "outputs": [{"output_type": "execute_result", "execution_count": 7, "data": {"text/plain": "20000"}, "metadata": {}}]}, {"metadata": {}, "cell_type": "markdown", "source": "\u53ef\u4ee5\u770b\u5230\uff0c\u521d\u59cbBTC\u603b\u6570\u662f2\u4e2a\uff0cETH\u603b\u6570\u662f11\u4e2a\uff0cUSDT\u603b\u6570\u662f20000\u4e2a\uff0c\u4e0b\u9762\u6211\u4eec\u83b7\u53d6\u4e00\u4e0b\u5f53\u524d\u7684\u5404\u4e2a\u4ea4\u6613\u5bf9\u7684\u884c\u60c5\u4fe1\u606f\u3002"}, {"metadata": {"trusted": true}, "cell_type": "code", "source": "var tickerA = exchanges[0].GetTicker()\ntickerA", "execution_count": 8, "outputs": [{"output_type": "execute_result", "execution_count": 8, "data": {"text/plain": "{ Time: 1554831960000,\n  High: 0.03396501,\n  Low: 0.03396499,\n  Sell: 0.03396501,\n  Buy: 0.03396499,\n  Last: 0.033965,\n  Volume: 4696.555,\n  OpenInterest: 0 }"}, "metadata": {}}]}, {"metadata": {"trusted": true}, "cell_type": "code", "source": "var tickerB = exchanges[1].GetTicker()\ntickerB", "execution_count": 9, "outputs": [{"output_type": "execute_result", "execution_count": 9, "data": {"text/plain": "{ Time: 1554831960000,\n  High: 175.08000001,\n  Low: 175.07999999,\n  Sell: 175.08000001,\n  Buy: 175.07999999,\n  Last: 175.08,\n  Volume: 20730.37,\n  OpenInterest: 0 }"}, "metadata": {}}]}, {"metadata": {"trusted": true}, "cell_type": "code", "source": "var tickerC = exchanges[2].GetTicker()\ntickerC", "execution_count": 10, "outputs": [{"output_type": "execute_result", "execution_count": 10, "data": {"text/plain": "{ Time: 1554831960000,\n  High: 5161.90000001,\n  Low: 5161.89999999,\n  Sell: 5161.90000001,\n  Buy: 5161.89999999,\n  Last: 5161.9,\n  Volume: 2109.9292,\n  OpenInterest: 0 }"}, "metadata": {}}]}, {"metadata": {}, "cell_type": "markdown", "source": "\u53ef\u4ee5\u770b\u5230A\u4ea4\u6613\u6240\uff0cB\u4ea4\u6613\u6240\uff0c\u4ea4\u6613\u7684\u6807\u7684\u7269\u90fd\u662fETH\uff0c\u5373A/B\u4ea4\u6613\u6240\u53ef\u4ee5\u8fdb\u884c\u95f4\u63a5\u5bf9\u51b2\u64cd\u4f5c\uff0c\u65e0\u6cd5\u76f4\u63a5\u5bf9\u51b2\u662f\u56e0\u4e3a\uff0c\u8ba1\u4ef7\u5e01\u79cd\u4e0d\u540c\u3002A\u4ea4\u6613\u6240\u8ba1\u4ef7\u5e01\u79cd\u662fBTC\uff0cB\u4ea4\u6613\u6240\u7684\u8ba1\u4ef7\u5e01\u79cd\u662fUSDT\u3002\n\u5047\u8bbe\u5bf9\u4e8eA\u4ea4\u6613\u6240\u505a\u4e70\u5165\u64cd\u4f5c```exchanges[0].Buy(price, amount)```\uff0c\u4e70\u5165\u65f6\u6839\u636e\u5bf9\u624b\u5356\u51fa\u7684\u4ef7\u683c\u4f5c\u4e3a\u4e0b\u5355\u4ef7\u683c\uff0c\u5373```tickerA.Sell```\uff0cB\u4ea4\u6613\u6240\u4e3a\u4e86\u5bf9\u51b2\uff0c\u5c31\u8981\u8fdb\u884c\u5356\u51fa\u64cd\u4f5c\uff0c\u5373```exchanges[1].Sell(price, amount)```\uff0c\u5356\u51fa\u65f6\u6839\u636e\u5bf9\u624b\u8981\u4e70\u5165\u7684\u4ef7\u683c\u4f5c\u4e3a\u4e0b\u5355\u4ef7\u683c\uff0c\u5373\uff1a```tickerB.Buy```\u3002\u56e0\u4e3aA\u4ea4\u6613\u6240\u4e70\u5165\u65f6\u6d88\u8017\u4e86```BTC```\uff0cB\u4ea4\u6613\u6240\u5356\u51fa\u65f6\u5f97\u5230\u4e86USDT\uff0c\u9700\u8981\u628a```USDT```\u6362\u6210BTC\uff0c\u8865\u7f3aA\u4ea4\u6613\u6240\u6d88\u8017\u4f7f\u7528\u7684BTC\uff0c\u5373C\u4ea4\u6613\u6240\u6267\u884c```exchanges[2].Buy(price, amount)```\uff0c\u628a```USDT```\u6362\u6210```BTC```\uff0cC\u4ea4\u6613\u6240\u8981\u4e70\u5165\uff0c\u9700\u8981\u770b\u5bf9\u624b\u7684\u5356\u51fa\u4ef7\u683c\uff0c\u5373```tickerC.Sell```\uff0cA\u4ea4\u6613\u6240\u4e70\u5165\u7684\u4ef7\u683c\u4e00\u5b9a\u8981\u6bd4B\u4ea4\u6613\u6240\u5356\u51fa\u7684\u4ef7\u683c\u4f4e\uff0c\u90a3\u4e48C\u4ea4\u6613\u6240\u53ea\u7528\u82b1\u5c11\u4e00\u4e9b\u7684USDT\u5c31\u80fd\u4e70\u56de\u6765A\u4ea4\u6613\u6240\u6d88\u8017\u6389\u7684BTC\u3002\u5c31\u8d5a\u5230\u4e86USDT\u91d1\u989d\u5dee\u3002\n\u6240\u4ee5\u5982\u4e0b\uff1a"}, {"metadata": {"trusted": true}, "cell_type": "code", "source": "var diffB2A = tickerA.Sell - tickerB.Buy / tickerC.Sell    // diffB2A \u5373 B\u4ea4\u6613\u6240\u5356\u51faETH\u5e01\uff0cA\u4ea4\u6613\u6240\u4e70\u5165ETH\u5e01\uff0c\u903b\u8f91\u4e0a\u76f8\u5f53\u4e8eETH\u4eceB\u4ea4\u6613\u6240\u8f6c\u79fb\u5230A\u4ea4\u6613\u6240\u3002\ndiffB2A", "execution_count": 11, "outputs": [{"output_type": "execute_result", "execution_count": 11, "data": {"text/plain": "0.000047266535449966285"}, "metadata": {}}]}, {"metadata": {}, "cell_type": "markdown", "source": "\u663e\u7136\uff0cA\u4ea4\u6613\u6240\u4e70\u5165\u7684\u4ef7\u683c\u6bd4B\u3001C\u4ea4\u6613\u6240\u7ec4\u5408\u6210\u7684\u4ef7\u683c\u8981\u9ad8\uff0c\u5bf9\u51b2\u663e\u7136\u662f\u4e8f\u94b1\u7684\u3002\n\u53e6\u5916\u4e00\u4e2a\u5bf9\u51b2\u65b9\u5411\u540c\u7406\uff0cA\u4ea4\u6613\u6240\u6267\u884c\u5356\u51faETH\u64cd\u4f5c\uff0cB\u4ea4\u6613\u6240\u6267\u884c\u4e70\u5165ETH\u64cd\u4f5c\uff0cC\u4ea4\u6613\u6240\u5356\u51faBTC\u6362\u56deUSDT\u3002\u8fbe\u5230\u5e01\u59cb\u7ec8\u662f\u5e73\u8861\uff0c\u53ea\u6709USDT\u589e\u51cf\uff08\u5373\u8d5a\u53d6\u7684\u5dee\u4ef7\uff09\u3002"}, {"metadata": {"trusted": true}, "cell_type": "code", "source": "var diffA2B = tickerA.Buy - tickerB.Sell / tickerC.Buy\ndiffA2B", "execution_count": 12, "outputs": [{"output_type": "execute_result", "execution_count": 12, "data": {"text/plain": "0.000047246531444007644"}, "metadata": {}}]}, {"metadata": {}, "cell_type": "markdown", "source": "\u6211\u4eec\u6267\u884c\u4e00\u6b21```tickerA.Buy - tickerB.Sell / tickerC.Buy```\u7684\u5bf9\u51b2\u64cd\u4f5c\uff0c\u5bf9\u5176\u4e2d\u7684\u5404\u4e2a\u6570\u503c\u53d8\u5316\u4e00\u63a2\u7a76\u7adf\u3002"}, {"metadata": {"trusted": true}, "cell_type": "code", "source": "var idA = exchanges[0].Sell(tickerA.Buy, 1)\nvar nowAccA = exchanges[0].GetAccount()\nnowAccA       // \u53ef\u4ee5\u770b\u51fa\u624b\u7eed\u8d39\u6263\u9664\u7684\u662fBTC", "execution_count": 13, "outputs": [{"output_type": "execute_result", "execution_count": 13, "data": {"text/plain": "{ Balance: 1.0339514,\n  FrozenBalance: 0,\n  Stocks: 9,\n  FrozenStocks: 0 }"}, "metadata": {}}]}, {"metadata": {"trusted": true}, "cell_type": "code", "source": "var orderA = exchanges[0].GetOrder(idA)\norderA", "execution_count": 14, "outputs": [{"output_type": "execute_result", "execution_count": 14, "data": {"text/plain": "{ Id: 1,\n  Price: 0.03396499,\n  Amount: 1,\n  DealAmount: 1,\n  AvgPrice: 0.03396499,\n  Type: 1,\n  Offset: 0,\n  Status: 1,\n  ContractType: 'ETH_BTC_Huobi' }"}, "metadata": {}}]}, {"metadata": {"trusted": true}, "cell_type": "code", "source": "var feeRatioA = 0.0004      // \u56de\u6d4b\u9ed8\u8ba4\u7684\u624b\u7eed\u8d39\u662f \u5343\u5206\u4e4b2\uff0c\u5373 0.002\nvar feeA = orderA.DealAmount * orderA.AvgPrice * feeRatioA   // A\u4ea4\u6613\u6240\u4ea4\u6613\u7684\u624b\u7eed\u8d39\uff0cBTC\u8ba1\u4ef7\nfeeA", "execution_count": 15, "outputs": [{"output_type": "execute_result", "execution_count": 15, "data": {"text/plain": "0.000013585996"}, "metadata": {}}]}, {"metadata": {"trusted": true}, "cell_type": "code", "source": "var idB = exchanges[1].Buy(tickerB.Sell, 1)\nvar nowAccB = exchanges[1].GetAccount()\nnowAccB", "execution_count": 16, "outputs": [{"output_type": "execute_result", "execution_count": 16, "data": {"text/plain": "{ Balance: 9824.84996798,\n  FrozenBalance: 0,\n  Stocks: 2,\n  FrozenStocks: 0 }"}, "metadata": {}}]}, {"metadata": {"trusted": true}, "cell_type": "code", "source": "var orderB = exchanges[1].GetOrder(idB)\norderB      // \u53ef\u4ee5\u770b\u51fa\u624b\u7eed\u8d39\u6263\u9664\u7684\u662fUSDT", "execution_count": 17, "outputs": [{"output_type": "execute_result", "execution_count": 17, "data": {"text/plain": "{ Id: 1,\n  Price: 175.08000001,\n  Amount: 1,\n  DealAmount: 1,\n  AvgPrice: 175.08000001,\n  Type: 0,\n  Offset: 0,\n  Status: 1,\n  ContractType: 'ETH_USDT_OKEX' }"}, "metadata": {}}]}, {"metadata": {"trusted": true}, "cell_type": "code", "source": "var feeRatioB = 0.0004\nvar feeB = orderB.DealAmount * orderB.AvgPrice * feeRatioB / tickerC.Last    // B\u4ea4\u6613\u6240\u7684\u624b\u7eed\u8d39,\u6362\u7b97\u6210BTC\u8ba1\u4ef7\nfeeB", "execution_count": 18, "outputs": [{"output_type": "execute_result", "execution_count": 18, "data": {"text/plain": "0.000013567097387396117"}, "metadata": {}}]}, {"metadata": {"trusted": true}, "cell_type": "code", "source": "var idC = exchanges[2].Sell(tickerC.Buy, nowAccA.Balance - accA.Balance)\nvar nowAccC = exchanges[2].GetAccount()\nnowAccC", "execution_count": 19, "outputs": [{"output_type": "execute_result", "execution_count": 19, "data": {"text/plain": "{ Balance: 10174.91841463,\n  FrozenBalance: 0,\n  Stocks: 0.9661,\n  FrozenStocks: 0 }"}, "metadata": {}}]}, {"metadata": {"trusted": true}, "cell_type": "code", "source": "var orderC = exchanges[2].GetOrder(idC)\norderC     // \u53ef\u4ee5\u770b\u51fa\u624b\u7eed\u8d39\u6263\u9664\u7684\u662f USDT", "execution_count": 20, "outputs": [{"output_type": "execute_result", "execution_count": 20, "data": {"text/plain": "{ Id: 1,\n  Price: 5161.89999999,\n  Amount: 0.0339,\n  DealAmount: 0.0339,\n  AvgPrice: 5161.89999999,\n  Type: 1,\n  Offset: 0,\n  Status: 1,\n  ContractType: 'BTC_USDT_OKEX' }"}, "metadata": {}}]}, {"metadata": {"trusted": true}, "cell_type": "code", "source": "var feeRatioC = 0.0004\nvar feeC = orderC.DealAmount * orderC.AvgPrice * feeRatioC / tickerC.Last      // C\u4ea4\u6613\u6240\u4ea4\u6613\u7684\u624b\u7eed\u8d39\uff0cBTC\u8ba1\u4ef7\nfeeC", "execution_count": 21, "outputs": [{"output_type": "execute_result", "execution_count": 21, "data": {"text/plain": "0.000013559999999973732"}, "metadata": {}}]}, {"metadata": {}, "cell_type": "markdown", "source": "\u8ba1\u7b97\u4e00\u4e0b\u5bf9\u51b2\u540e\u7684\u603b\u8d44\u4ea7\u4fe1\u606f\uff1a"}, {"metadata": {"trusted": true}, "cell_type": "code", "source": "var nowSumBTC = nowAccA.Balance + nowAccC.Stocks\nnowSumBTC", "execution_count": 22, "outputs": [{"output_type": "execute_result", "execution_count": 22, "data": {"text/plain": "2.0000514000000003"}, "metadata": {}}]}, {"metadata": {"trusted": true}, "cell_type": "code", "source": "var nowSumETH = nowAccA.Stocks + nowAccB.Stocks\nnowSumETH", "execution_count": 23, "outputs": [{"output_type": "execute_result", "execution_count": 23, "data": {"text/plain": "11"}, "metadata": {}}]}, {"metadata": {"trusted": true}, "cell_type": "code", "source": "var nowSumUSDT = nowAccB.Balance + nowAccC.Balance\nnowSumUSDT", "execution_count": 24, "outputs": [{"output_type": "execute_result", "execution_count": 24, "data": {"text/plain": "19999.76838261"}, "metadata": {}}]}, {"metadata": {"trusted": true}, "cell_type": "code", "source": "nowSumBTC - initSumBTC", "execution_count": 25, "outputs": [{"output_type": "execute_result", "execution_count": 25, "data": {"text/plain": "0.000051400000000256796"}, "metadata": {}}]}, {"metadata": {"trusted": true}, "cell_type": "code", "source": "tickerC.Buy * (nowSumBTC - initSumBTC)    // \u591a\u51fa\u7684BTC\u6362\u7b97\u6210USDT", "execution_count": 26, "outputs": [{"output_type": "execute_result", "execution_count": 26, "data": {"text/plain": "0.26532166000081153"}, "metadata": {}}]}, {"metadata": {"trusted": true}, "cell_type": "code", "source": "nowSumUSDT + tickerC.Buy * (nowSumBTC - initSumBTC) - initSumUSDT    // \u6839\u636e\u8d26\u6237\u8d44\u4ea7\u53d8\u52a8\u8ba1\u7b97\u76c8\u4e8f\uff0c\u8ba1\u4ef7\u5355\u4f4d\u4e3aUSDT", "execution_count": 27, "outputs": [{"output_type": "execute_result", "execution_count": 27, "data": {"text/plain": "0.0337042700011807"}, "metadata": {}}]}, {"metadata": {"trusted": true}, "cell_type": "code", "source": "(diffA2B - (feeA + feeB + feeC)) * tickerC.Buy     // \u6839\u636e\u5dee\u4ef7\u8ba1\u7b97\u7684\u76c8\u4e8f\uff0c\u8ba1\u4ef7\u5355\u4f4d\u4e3aUSDT", "execution_count": 28, "outputs": [{"output_type": "execute_result", "execution_count": 28, "data": {"text/plain": "0.03372495390449328"}, "metadata": {}}]}, {"metadata": {}, "cell_type": "markdown", "source": "\u53ef\u4ee5\u770b\u5230\uff0c\u5bf9\u51b2\u65f6\u7684\u5dee\u4ef7\u662f```diffA2B``` \uff1a 0.000047246531444007644\n\u4e09\u6b21\u5bf9\u51b2\u65f6\u7684\u624b\u7eed\u8d39\uff0c\u6362\u7b97\u6210BTC\u4e3a\uff1a```feeA + feeB + feeC```"}, {"metadata": {"trusted": true}, "cell_type": "code", "source": "feeA + feeB + feeC", "execution_count": 29, "outputs": [{"output_type": "execute_result", "execution_count": 29, "data": {"text/plain": "0.00004071309338736985"}, "metadata": {}}]}, {"metadata": {}, "cell_type": "markdown", "source": "\u53ef\u4ee5\u770b\u5230\u5728\u56de\u6d4b\u914d\u7f6e\u4e2d\u624b\u7eed\u8d39\u4fee\u6539\u4e3a```\"fee\":[0.04,0.04]```\u5373\u4e07\u5206\u4e4b\u56db\uff0c\u8fd9\u4e2a\u65f6\u5019```feeA + feeB + feeC```\u7b49\u4e8e0.00004071309338736985\uff0c\u57fa\u672c\u63a5\u8fd1\u5bf9\u51b2\u65f6\u7684\u5dee\u4ef7```diffA2B```\uff0c\u6700\u540e\u8ba1\u7b97\u51fa\u6765\u76c8\u4e8f\u5c31\u5f88\u5c0f\u4e86\u53ea\u6709\uff1a0.03372495390449328\uff0c\u5e76\u4e14\u901a\u8fc7\u8d26\u6237\u53d8\u52a8\u8ba1\u7b97\u51fa\u7684\u76c8\u4e8f\u548c\u901a\u8fc7\u5dee\u4ef7\u8ba1\u7b97\u51fa\u6765\u7684\u76c8\u4e8f\u6570\u503c\u57fa\u672c\u4e00\u81f4\u3002\u8ba1\u7b97\u4e09\u89d2\u5bf9\u51b2\u591a\u5c11\u5dee\u4ef7\u53ef\u4ee5\u5bf9\u51b2\uff0c\u53ef\u4ee5\u7528\u6b64\u7814\u7a76\u6587\u4ef6\u5206\u6790\u8ba1\u7b97\u3002"}], "metadata": {"kernelspec": {"name": "javascript", "display_name": "Javascript (Node.js)", "language": "javascript"}, "language_info": {"name": "javascript", "version": "8.10.0", "mimetype": "application/javascript", "file_extension": ".js"}}, "nbformat": 4, "nbformat_minor": 2}