:::warning # 🌱 韭菜是割還是哥!? ### 🌱 🌱 從零開始打造雲端交易機器人🤖 + dashboard app 👀 ::: ###### tags: `side project` ## 文件大綱(文長請由左側導覽bar跳轉至您有興趣的段落) 1. Project整體概覽 2. 尋覓合適交易演算法 3. 交易機器人實作(dataflow、DB設計..) 4. 交易機器人dashboard實作 5. AWS雲端部署與自動節能(省錢)設定 6. 其他重要連結如下: - [dashboard成品](http://15.165.161.231:8501/) - 我用了最新版的streamlit app,目前測試mac用chrome,iphone 11以上用chrome,android沒特別限制用chrome都可順利開啟此app,但windows目前會出錯,官方表示有在修復,若開不了請先看底下影片demo - 因近日交易低迷,各機器人僅有一日有做到交易(美國加息會議那天),故有先放一些pseudo data來demo app功能 - [雲端交易機器人影片demo](https://www.youtube.com/watch?v=CaWtj_EcH_4) - [dashboard app影片demo](https://www.youtube.com/watch?v=CyIGc61JsNw) - [Github連結](https://github.com/enchichen1107/trading_bot) ## 💁🏻‍♀️ Project整體概覽 * **製作動機** * 加密貨幣市場有個很大的優勢,就是交易門檻相對較低,幾十塊美金即可入場交易,這對於想練習投資的小白而言無疑是一大佳音。然而~加密貨幣市場瞬息萬變,幣圈一天、人間一年,如果沒有相當的心理素質,很容易追漲殺跌,成為被割下的韭菜。但人非聖賢,孰能100%理性?故,敝人將嘗試以交易機器人的方式,真正的、無情的落實戰術,並用dashboard app呈現機器人交易表現,來看看一季後的收成如何 * **整體實作流程** 1. 回測歷史資料找出合適的交易演算法 2. 實作交易機器人 3. 實作dashboard app 4. 雲端部署與自動節能設置 ![](https://i.imgur.com/wPRhWjv.jpg) ## 🐾 尋覓合適交易演算法 * **比特幣大盤概覽** * 首先,大家需要先知道,加密貨幣市場的大盤就是比特幣(簡稱btc,全名bitcoin),而比特幣對於技術分析來說也是比較好的標的。因為相對於其他山寨幣(小幣),比特幣比較不會被壟斷操作。故本篇都先以btc比特幣對usdt(一種對標美金的幣,1 usdt約等於1 usd)的交易對為主。 * 接下來我們正式來看比特幣大盤這三年的變化,探索一下所謂HODL(單純抱著比特幣沒有進一步操作)是否能獲利? * 如果你在2019年進入這個市場~Y軸會是你的累計收益率變化,此時的你應該會對比特幣抱持信仰,因為就算抱著不動三年,收益也有三.xx倍 ![](https://i.imgur.com/8SwYttW.png) * 如果你在2020年進入這個市場~Y軸會是你的累計收益率變化,此時的你應該會對比特幣抱持信仰,因為就算抱著不動兩年,收益也有三.xx倍 ![](https://i.imgur.com/VnedwuV.png) * 如果你在2021年進入這個市場~Y軸會是你的累計收益率變化,此時的你應該會對比特幣失去信仰,因為抱著不動一年,收益不增反減!!! ![](https://i.imgur.com/hjWpoNz.png) * 我們把這三個進場時間點的累計收益畫在一張圖比較一下,就能更深刻的感受到...HODL只有牛市可行啊! ![](https://i.imgur.com/xSh2TCd.png) * **交易演算法介紹** * 這邊跟大家介紹的是投資小白入門款breakout法則,它的概念很簡單,就是在價格有明顯向上突破且帶交易量時,預期後市看漲故買入,在價格有明顯向下突破且帶交易量時,預期後市看跌故賣出。一般來說價格是否有突破會以是否破過去15到20根K線的滾動平均最高/最低價來斷定,而有沒有帶交易量則是看有沒有大於過去15到20根K線的滾動平均最高交易量的n倍(n是個可調控的參數)。至於離開交易的時機點則利用上一根K線的收盤價+/-ATR來和這輪K線的最高/低價做比較來決定。舉例:如果是做買入,但本輪K線最低價已經低於上一根K線的收盤價-ATR,則表示行情可能要開始逆轉,需進行離場。 * 至於什麼是[ATR](https://www.tradingview.com/support/solutions/43000501823-average-true-range-atr/#:~:text=Definition,price%20gaps%20or%20limit%20moves.)?ATR為average true range的簡稱,它定義了幣價在某一時間區間內的真實波動。波動的計算是取下列三個數值的最大值,接著再依照想看的時間區間做滾動平均: * 1.今日最高價-最低價 * 2.今日最高價-昨日收盤價的絕對值 * 3.今日最低價-昨日收盤價的絕對值 * **Breakout演算法回測** * 以下這張圖是調用Binance(目前最大的現貨交易平台)的現貨API撈取比特幣歷史15minK線圖後,用預設20根K線和1.5倍交易量做的回測結果,並將其和HODL做比較。看完可明顯感受..痾,表現居然不如HODL!!! ![](https://i.imgur.com/gUFMGQr.png) * 因此我們需要來優化一下參數,試試不同組合的結果能否改善收益率,我們試著放入7到20根,1.2到2倍的各種可能性後,結果如下 * 累計收益率最高(6.42)的是八根+1.9倍交易量突破 ![](https://i.imgur.com/yGQxqxv.png) * CAGR([複合年均增長率](https://rich01.com/what-is-cagr/))最高(0.86)的是八根+1.9倍交易量突破 ![](https://i.imgur.com/9RKUiti.png) * sharpe([夏普比率](https://rich01.com/what-sharpe-ratio/#:~:text=%E5%A4%8F%E6%99%AE%E7%8E%87%E5%A4%A7%E7%B4%84%E8%90%BD%E5%9C%A8,%E9%82%A3%E5%B0%B1%E9%9D%9E%E5%B8%B8%E5%84%AA%E7%A7%80%E4%BA%86%E3%80%82))最高(2.38)的是九根+1.9倍交易量突破(一般來說1.5的夏普比率已經很不錯) ![](https://i.imgur.com/DgjfRQg.png) * Max drawdown([最大回撤](https://www.stockfeel.com.tw/%E6%9C%80%E5%A4%A7%E5%9B%9E%E6%92%A4-max-drawdown-%E7%AD%96%E7%95%A5%E7%AE%A1%E7%90%86/))最低(0.13)的是十三根+1.9倍交易量突破 ![](https://i.imgur.com/I65sHBN.png) * 綜合以上結果,這裡選定九根+1.9倍交易量突破作為優化解,雖然它的累計收益率和CAGR稍低於八根+1.9倍交易量突破,但最大回撤卻好很多(0.15 vs 0.2) * 下圖為優化後的版本和HODL比較,終於勝出啦!! ![](https://i.imgur.com/AfkjeXp.png) * 再看一張HODL vs 預設數值 vs 優化版本的比較圖 ![](https://i.imgur.com/loBMTYn.png) * 接下來呢,我們改用超短線5min K線 scalping(挖到一點小利潤就逃)來回測breakout的方式看看。因為用超短線,故用一年內的資料來回測,畢竟時間太久會很失真。下圖為預設數值(7根K線+1.5倍)回測結果,看來是比HODL好,但幾乎沒什麼獲利到,趨勢線幾乎是平的 ![](https://i.imgur.com/d1bci5q.png) * 一樣,來優化看看不同的組合。這裡有蠻明顯的勝出者,15根K線+2倍交易量突破,回撤小,收益又高,一年共有兩千多次的交易機會 ![](https://i.imgur.com/uv0Z944.png) * 接著來看看優化後的比較圖。簡直完勝HODL和預設值啊! ![](https://i.imgur.com/HV2Lqgw.png) * **回測小結論** * 優化後的版本交易表現都明顯勝出HODL與預設版本,這告訴我們沒有全仰賴預設,動點手優化是有好處的! * HODL基本上就是一個牛市中的懶人賺錢法,但像現在熊市開始後只能虧本離場QAQ即便是熊市中的現貨交易,幣價還是會有波動的時候,靠著技術分析還是有機會賺到錢的 * breakout還是適合波動大的投資標的,如果很穩健沒什麼波動反而賺不到錢。但以幣圈來說就很適合,幣圈沒有漲跌停板,波動起來很驚人的 * 最後,歷史資料回測能賺錢不見得代表未來也能賺錢,有可能只是overfit...故接下來我們來把演算法寫成交易機器人,並利用binance提供的testnet來做paper trading(假錢交易)來測試一季看看效果如何! ## 🤖 交易機器人實作 以下是整個系統的設計圖,我們的目標是拆成交易機器人、dashboard app、AWS雲端部署三個區塊來談完這張大圖。首先,我們來談黃色資料庫左半邊這一區 ![](https://i.imgur.com/2zVWb38.jpg) * **機器人功能概覽** * 機器人由演算法和資料驅動,其最重要的工作就是live stream幣價資料,做分析,一有進場時機點就透過binance testnet api下單 * 其他功能為停損寄信警示、完成交易時一併將交易資訊送進資料庫,以供未來dashboard app做視覺化處理 * **機器人dataflow設計** * **交易演算法所需資料** * **歷史幣價資料**:因為演算法會需要前幾根K線的資料才能啟動,故會需要先用api撈資料進來。然後這邊需要注意binance testnet雖然有幣價資料,但因為交易量少,它的最高、最低價與真實資料嚴重脫鉤,故還是建議用binance一般的幣價api撈就好。至於需不需要撈進資料庫放著,敝人認為是不需要,因為使用率極低,只有在第一輪K線的交易判斷中會用到,之後都會用實時幣價資料來分析 * **實時幣價資料**:這是資料流裡面我覺得比較難搞的部分。因為要實時交易,如果長時間一筆一筆用api打進來,我這ip可能會快就會因為binance api政策的api次數限制被ban掉。後來我找到binance有提供websocket可以實時串入幣價資料,它就沒有api call的次數限制,只是binance websocket的文件我覺得有點霧裡看花(可能功力太差ˊˋ),再後來我又找到一個好用的python binance api wrapper,但要注意它目前就1.0.15版本的websocket沒有問題可以用,新版本我測過會噴錯。以下附上我在弄live stream price data的重點參考資料 * [binance github](https://github.com/binance/binance-spot-api-docs/blob/master/user-data-stream.md) * [python binance github](https://github.com/sammchardy/python-binance/blob/master/docs/websockets.rst) * [python binance doc](https://python-binance.readthedocs.io/en/latest/_modules/binance/streams.html#ThreadedWebsocketManager.start_user_socket) * 以上資料梳理完畢後,演算法就可以實時分析幣價資料並在適當時機點call binance testnet api下單 * **交易資料庫設計** * 我其實蠻猶豫這一節要放在哪談,因為資料庫要放什麼還是基於應用端所需的資料邏輯。但因為資料是在機器人這邊打進去的,故還是決定先在這裡談一部分。 * **首先,建立資料庫的必要?** * 在此有必要,如果想看到testnet測試一個月以上的結果就會需要。因為testnet固定每個月會清空所有過去交易資訊... * **要放哪些資料?** * 根據dashboard的需要,我只放最根本的交易資訊進去。其他衍生資料,例如累計收益率等,全部不放,到dashboard要呈現時再算。這樣雖然到時候dashboard呈現會比較慢,但好處就是我隨時想要改交易表現的指標時,只要改完算法的code就了事。那最根本的資料有哪些呢? * 基本上所有交易表現指標都是用進出場的時間點的價位來做計算,所以我想最基本要存的就是交易時間、交易方向(買或賣)、交易對、交易價位。只要有這些資訊,那要算什麼都不會有太大問題。以上,我們有了第一張table:trade_record。 * 接下來還想放的就是交易帳戶的資產,透過dashboard看資產變化我覺得是很直覺、直接的呈現交易成果。這邊我想基本要存的也很直覺,資產更新時間、資產別、數量。以上,我們有了第二張table:asset。 * 再來這個問題就是我們有兩隻交易機器人,他們的交易資訊要存在同一張table,然後用一個column例如bot幾號來區別嗎?還是用不同張table來紀錄?我這邊是考慮到dashboard呈現時,我希望可以有各機器人的詳細交易表現數據分頁。基於這個應用,敝人認為分開保存會比較好,因為在調資料時少一層filter速度會比較快。所以,以上我們就有四張tables了,asset1, asset2, trade_record1, trade_record2。 * 最後,考慮到未來更有交易經驗時可能會想嘗試除了比特幣以外的交易對。但其他交易對,我比較不熟,但對全名會有印象,故也放上了交易對簡稱和全名的對照表names。 * 目前所有tables都為BCNF,就是簡單、乾淨的交易和資產紀錄為主。所有資料都為atomic,candidate key為交易/更新時間,只能從candidate key uniquely define其他fields。 * 到這裡,tables告一段落,以下為各table的截圖(因bot2與bot1的table基本雷同,故以bot1為例),應該看得到data type和pk。另外,search key這邊我沒有特殊要求就用default pk即可 * 交易對簡稱和全名的對照表names ![交易對簡稱和全名的對照表names](https://i.imgur.com/UTP4r8n.png) * trade_record1 ![](https://i.imgur.com/7rE9ftU.png) * asset1 ![](https://i.imgur.com/cGrLDKS.png) * **資料怎麼更新?** * 敝人認為流程上交易做完順便寫進去是最順的,而剛好binance也有user data的websocket,我就利用這個socket來即時更新資料庫。所以流程就是,機器人做交易,user data websocket回傳交易資訊json檔,篩出需要寫進資料庫的資訊,最後insert into各tables。詳細code請見[github link](https://github.com/enchichen1107/trading_bot)(either bot1.py或bot2.py皆可)。 * **資料怎麼調用?** * 這部分我們留待dashboard app討論 * **停損寄信警示** * 這個是user data websocket的第二個應用,一收到帳戶資產變化,就來順便檢查資產有沒有蒸發過頭,一有異常就寄信警告。我想python寄警示信的應用是蠻常見的,這裡附上我參考的[教學文](https://www.learncodewithmike.com/2020/02/python-email.html)。寄信的測試結果如下圖: ![](https://i.imgur.com/hN5vf9o.png) ## 📊 交易機器人dashboard實作 我們現在來談黃色資料庫右半邊的dashboard app ![](https://i.imgur.com/2zVWb38.jpg) * 這邊遇到第一個問題是用什麼方法呈現比較好?要寫前端三語嗎?還是有其他更適合的方式?後來我想到,像R有shiny可以視覺化呈現分析成果,那python應該也會有吧?結果一查就查到streamlit,它真的是可以美美的呈現分析結果!上手難度也還好,有一點前端基礎,跟著做完一輪tutorial就會了。唯一美中不足大概就是它的最新版本有些相容issue..但因為最新版本有multipages的功能,所以..我還是用下去了.. * [streamlit gallery](https://streamlit.io/gallery) * [streamlit tutorial](https://docs.streamlit.io/knowledge-base/tutorials) * **dashboard app運作流程** * **交易資料庫資料調用** * 基於app一打開的預設交易時間區間呈現就是從開始到末了,所以app一開頭就需要先進資料庫cur.fetchall(),select * from xxx table撈出交易和資產資訊。詳細code請見[github link](https://github.com/enchichen1107/trading_bot)(在app資料夾內的首頁,和app資料夾內的pages資料夾內的helper.py最一開始的段落就是資料調用)。 * **交易表現指標運算** * 撈完資料後自然是做一些運算,這些交易表現指標和歷史資料回測那部分有重疊,就不贅述,需要reference的話,回測那一part有附連結,可左邊選單跳過去看 * **指標呈現** * 由於本app主要user就是敝人,我看資料喜歡從各個角度切入,故呈現方式我用了數個方式~運算後的綜合指標、圖表、dataframe ## 💰 AWS雲端部署與自動節能(省錢)設定 終於,來談遍佈整張圖的AWS系列們(還有右下角那三個自動化設定),這裡會切成幾個部分 * AWS EC2部署機器人 * AWS EC2部署dashboard app * EC2與RDS的connection * 自動節能設定 ![](https://i.imgur.com/2zVWb38.jpg) * **AWS EC2部署機器人** * 首先,這裡先來決定一個問題,到底要開幾個EC2放機器人?我理想中是用一份2vcpu的EC2方案,然後同時run兩隻機器人,後來發現..不行,太貴啦!再加上,敝人的learner lab錢錢已所剩無幾,故還是選擇用兩個最便宜的方案各放一隻機器人。 * 再來處理code中各種秘密,DB秘密、api key秘密、信箱秘密..這裡是調用AWS的secret manager來處理這些秘密,[AWS秘密管理教學文](https://docs.aws.amazon.com/secretsmanager/latest/userguide/auth-and-access_examples.html)我覺得是蠻清楚的,我自己的做法是直接在製造秘密時把可以access此秘密的role放入Labrole,然後EC2建立時也用這個role,如此便能順利取得秘密 * 最後部署,我的作法基本上就是ssh從local連線到EC2之後,把code放過去,然後設定時讓它run(最後自動節能設定會提到) * **AWS EC2部署dashboard app** * steamlit其實有自己的[cloud](https://docs.streamlit.io/streamlit-cloud/get-started/deploy-an-app)可以部署,但為了熟悉AWS,我還是放AWS了,這篇[教學文](https://towardsdatascience.com/how-to-deploy-a-streamlit-app-using-an-amazon-free-ec2-instance-416a41f69dc3)算是很詳盡的寫了如何部署,這裡不贅述 * 這裡需要特別注意的點,我認為是ip..因為如果要固定public ip是要額外付費的Orz 基於learner lab快沒錢,我後來想了一個折衷方案,就是我額外申請了AWS的帳號,用它的免費方案來放EC2的app,這個免費方案基本上可以run一個最便宜的EC2一整年沒問題,換句話說就不用關EC2,意即它的public ip就不會變,只要沒有關掉又重開它 * **EC2與RDS的connection** * 這裏要來處理資料寫入與讀出資料庫的問題了,怎麼和AWS上的資料庫溝通,[看完這篇AWS教學文](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_ConnectToPostgreSQLInstance.html)我想就差不多。基本上要注意的就是,一開始建立資料庫時就要先想好你的資料庫有沒有要和AWS VPC(私有雲)以外的端點溝通,有的話建立時就要先選 <font color="#FF8733">***==public==***</font> * **自動節能(省錢)設定** * 這邊的節能設定是針對兩隻在EC2的交易機器人,因為RDS和app被我放到免費方案去了,故無須擔憂經費 * **自動排程開關EC2** * AWS在這塊也有出[教學文一](https://aws.amazon.com/premiumsupport/knowledge-center/start-stop-lambda-eventbridge/?nc1=h_ls)、[教學文二](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-create-rule-schedule.html#eb-cron-expressions)。如果是比較複雜的系統,牽動更多AWS instances,AWS還有出[instance scheduler](https://aws.amazon.com/tw/solutions/implementations/instance-scheduler/),但這要付費,所以我這邊還是用了cloudwatch+lambda的組合(很省經費)來達到自動排程開關EC2的目的 * 以下放個暫停EC2的lambda調用紀錄,讓大家看一下,截至今它真的已經run了四天(如果有看youtube demo影片就會知道我為何特別說這個..) ![](https://i.imgur.com/2Kdi92I.png) * **EC2內的自動排程** * EC2能自動定時開關後,我們還是需要在EC2內讓它定時自動啟動交易,這邊的方法就看EC2作業系統用什麼,用windows的話就有內建的工作排程器可以用,但windows比linux的EC2貴,故我選了linux,然後用[crontab來達到排程](https://blog.gtwang.org/linux/linux-crontab-cron-job-tutorial-and-examples/)目的。 * **啟動AWS費用預警** * 基本上這邊最重要的就是要意識到東西在雲端跑著跑著,不知不覺可能會費用突破天際,就算已經事先算好可能花費(茶~),因為有些錢會在不太容易注意到的地方...例如:AWS EC2已經暫停,但如果EC2有放EBS一樣會收錢錢。所以保險起見還是用個費用預警!而費用預警還蠻容易設置的,看看[AWS費用預警教學](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/monitor_estimated_charges_with_cloudwatch.html)即可~特別要注意的大概就是要去填寫的收取警示信箱啟動警示服務,搞定後就會在AWS Cloudwatch警示中看到這個囉~ ![費用預警圖](https://i.imgur.com/uOJuTV7.png) * 最後這一區放一些過程中有參考的資料們 * api相關 * https://stackoverflow.com/questions/70027278/how-to-extract-all-crypto-symbols-from-coinmarketcap * python相關 * https://stackoverflow.com/questions/71216795/calculate-sum-for-column-in-dataframe-using-pandas * https://www.delftstack.com/howto/python-pandas/how-to-create-dataframe-column-based-on-given-condition-in-pandas/ * streamlit做圖相關 * https://altair-viz.github.io/gallery/layered_area_chart.html * 技術指標相關 * https://www.freqtrade.io/en/stable/ * https://technical-analysis-library-in-python.readthedocs.io/en/latest/ * https://www.udemy.com/course/algorithmic-trading-with-python-and-machine-learning/ * https://www.udemy.com/course/algorithmic-trading-quantitative-analysis-using-python/