搜尋

搜尋結果

測試即市交易系統的竅門
創富坊
程式交易 www.quants.hk (導師: 財經書藉作家: 麥振威)・2015-03-25

即市走勢中,一個升浪或跌浪究竟平均會運行多久,大家有統計過嗎? 很多Trader只會注意「空間」的止損,而不會考慮時間因素。只要價格跌到某個事前設定的價格,就會止蝕離場,這就是空間止損。空間止損法的好處在於,可以減低你的壓力,當帳面虧損到了你接受不到的程度時便平倉止損,但缺點在於即使到了止損的階段,因走勢突變,你的虧損也可以比預期更大。其實很多Trader都面對這個問題,為此,便需要引入時間止損的概念。時間止損是根據升浪或跌浪平均運行的時間來做止損,甚至更改為入市訊號。 不過首先要介紹運用時間加入個人交易系統的概念,其實在做back-tesing時大家可以統計一下,假設過去一百個交易日,每一個升浪運行的時間,即市走勢中,一個短的升浪可以運行數分鐘,也可以運行數小時,若然你發現在過去一百個交易日中,即市走勢中一個最長的升浪也只運行兩小時,那當某日你發現一個升浪已維持了接近兩小時,若然你已持有好倉,那便代表了已到達你需要平倉的時間,又或已是反手造淡的時間。 這種統計方法對提高交易的回報很有幫助,當然有經驗的Trader應立即想到一個問題,究竟應如何介定一個升浪完結? 升浪可以調整過後又再上升,那在即市走勢中,究竟如何去計算這個升浪維持的時間有多長? 最簡單的統計方法是,一個即市走勢中的升浪展開後,先計算由升浪底部計起所上升的幅度,若其後出現調整,調整幅度是升浪的「三分之一」以上,那便代表整個升浪已完結,其後即使在調整後再展升浪,也屬於第二個升浪的開始。當然,大家也可用同一種方式去介定一個跌浪已完結,並同時統計在過去一百個交易日中,跌浪維持的時間平均有多長,藉此判斷若持有淡倉應何時平倉,同時又應何時反手造好。用這種方式去計算一個升浪或跌浪究竟平均會維持多少時間,這比你繼續研究何時入市最好,不斷去尋找新的入市方法更有效! 例子(一): 請留意圖中如何介定升浪已完結 例子(二): 請留意圖中如何介定跌浪已完結 現在大家應有了對分析升浪或跌浪維持時間的概念,回說如何去避免只做「空間」止損,而需要加入「時間」止損。在做back-testing時,除了可以統計一下升浪或跌浪平均運行的時間外,也可以統計一下,每一個入市訊號後,究竟平均需要多少時間才會展開升浪或跌浪,比如你設計了一套交易系統,由MACD與STC這兩個技術指標組成,當兩個技術指標同時發出買入訊號時,你便會入市造好,但你入市後常會遇到一個問題,雖然交易訊號出現了,但市況並非立即上升,很可能只是在整固,又或很少幅度的調整,但你看到價格雖沒有上升,又有跌至你的止損價位,你運用的「空間」止損法,根本派不上用場。其後價格整固了一段時間後突然急跌,下跌的速度可以很快很快,當你決定止蝕時,很可能根本已錄得比你預期更大的虧損。 又或交易訊號出現後,你同樣按訊號入市造好,但市況只是在整固,整個的時間可能長達兩小時,甚至更久,你上午的市況中已買入,但就是不想持倉過午市,結果提早平倉離場,不過訊號的威力卻在下午市況中才發揮出來,你上午平倉之時可能錄得輕微虧損,但下午市況中的升浪你卻沒有把握得到,「一來一回」其實你的損失經已很大。 故此,我們要做的,除了統計交易訊號的獲利比率外,也要統計一下交易訊號出現後,究竟平均要多少時間才會展開較明顯的升浪或跌浪。例如,在過去一百個交易日中,出現了一百五十個造好的交易訊號,而這一百五十個造好的交易訊號,平均需要十至十五分鐘才會展開較明顯的升浪,那這個統計數據對你來說便很有參考價值,因為你入市後,若然市況只是在整固,即使出現帳面虧損,只要未到達你止損的程度便什麼也不用去做,但若然整固的時間已維持了達十五分鐘,由於已超過了你統計的平均時間,那便需要用「時間」止損的方式來止損平倉,這樣是避免冒上不必要的風險。 此外,在做back-testing時,最好是要同時統計一下,入市訊號出現後,雖然按預期出現升浪,但平均需要多少時間才會到達目標價。例如,在過去一百個交易日中,出現了三百次造好及造淡的訊號,究竟這三百個交易訊號中,平均需要多少時間才到達目標價。這點十分重要,因涉及你是否應該持倉過午市,同時你要考慮一點,由於你是Day Trader,若然你的統計結果是三百個交易訊號中,平均需要三十分鐘才會升或跌至目標價,而最長的一次則需要一小時才到達目標價,當交易訊號出現在三時四十六分,你便要十分小心,甚至應放棄入市,因為期指市場是在四時十五分收市,離收市根本不足三十分鐘,或許在你的統計中,曾有些交易訊號是在短短數分鐘便展開升浪並升至目標價,但這個不是一個平均數,你統計過一百個交易日,甚至更多的交易日後,取其平均數值才值得參考的,單憑一次或次的交易經驗不能作準,故此為了避免冒上不必要的風險,這種情況便應放棄入市。 那若然距離收市的時間有三十分鐘以上,但統計結果顯示最長的一次則需要一小時才到達目標價又應否入市? 答案是需要的,因為不能因少數出現的特殊數據而放棄一個獲利機會,但這種情況下,Day Trader只有緊記一點,必需堅持只做即市交易的原則,即使收市前仍未到達目標價也需要平倉離場。 將「時間」止損加入你的交易系統內是提高回報的最有效方法之一,特別是即市交易,這能避免了很多市況突然大逆轉所帶來的重大虧損。其實所謂的back-testing絕對並非只在尋找入市方法這樣簡單,需要統計的事項十分之多,但作為Trader與其他行業也是一樣,你付出越多,你的收穫便相對越多。

澳旅院研究生課程招生!
專題報導
Cheers!・2021-12-02

澳旅院研究生課程充分利用澳門旅遊教育獨特優勢及各種資源,協助提高澳門以至粵港澳大灣區旅遊從業人員的專業能力,推動粵港澳大灣區旅遊業持續發展。 課程亮點 專業方向: 設有不同專業方向,可按個人需要選擇合適課程。 無縫對接: 學士後文憑課程學分可全部轉換為碩士課程學分。 學分豁免: 於認可高等教育機構完成的學分可申請豁免,上限為9個學分。 授課語言: 全英授課,並由資深教員任教。 課程概覽 學士後文憑: 酒店管理 旅遊管理 國際酒店及旅遊管理 國際美食學管理 國際餐飲管理 *酒店及旅遊智慧科技 備註:學士後文憑課程不適用於內地考生 碩士學位: 國際酒店管理 國際旅遊管理 酒店及旅遊管理 國際美食學管理 國際餐飲管理 *酒店及旅遊智慧科技 *全新課程,計劃於2022/2023學年推出,有待最終審批。 博士學位: 酒店及旅遊管理 報名資訊 2022/2023學年學士後文憑及碩士學位課程於10月18日至明年5月31日期間招生,博士學位課程全年招生,對象為有志提升專業能力、為未來職涯發展創造更佳條件人士,歡迎前往招生官網了解更多資訊。 線上宣講活動 想了解更多課程及報名資訊? 請即「碼」上登記 (1) BMI Talk Global Study 日期:10月21日 時間:下午5時至9時 屆時我們將提供線上諮詢 (2) 澳旅院專場簡介會 日期:11月18日 時間:下午7時至8時 屆時學院的老師將為您分享課程及報名資訊 歡迎立即登記,踴躍參加 另外 學院樂意派員到 貴公司或以線上形式進行簡介會 歡迎聯絡我們 ,了解更多

Spring Boot 04 - 進入http json api 世代
科技新知
MacauYeah・2024-05-23

本節,我們將會建立一個http服務,提供json api讓程式訪問。 下戴模版 我們跟上節一樣,使用Spring Initializr (Maven) 下載模版,但細節筆者就不再講啦。Dependency主要選擇 Spring Web Spring Boot DevTools 下載後,可以直接運行測試,可以用指令 mvn test 或經IDE運行。Spring會至少測試下能不能成功取用預設的8080端口。 Controller 我們若要實作 http json api,需要在 spring 中加入一個類,附註為 @RestController ,那方便起見,類名我們也命名為 XXXController 吧。作為示範,我們弄一個 HomeController.java ,裏面有最常見的 http GET, POST功能。 // src/main/java/io/github/macauyeah/springboot/tutorial/springbootwebapibasic/controller/HomeController.java import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; // ... other import @RestController @RequestMapping("/api") public class HomeController { @GetMapping("/someRecord/{uuid}") public Map readSomeRecord(@PathVariable String uuid) { return Map.of("ret", "your uuid:" + uuid); } @PostMapping("/someRecord") public Map createSomeRecord(@RequestBody Map requestBody) { HashMap ret = new HashMap(requestBody); ret.put("ret", "got your request"); return ret; } } HomeController裏,完整的URL 其實為: GET http://localhost:8080/api/someRecord/{uuid} POST http://localhost:8080/api/someRecord URL中的api之後的路徑,都是定義在 HomeController 中,而前半的8080及context path,是使用預設值。在正式環境下,可能隨時會被重新定義。但我們做本地測試,只需要驗證預設值就可以了。 我們真的運行起程式mvn clean compile spring-boot:run,再使用最簡測試工具進行測試。Windows的朋友,可以選擇Postman作為測試,它有圖形介面。而linux的朋友,請用curl,預設安裝都會有。下列為方便表示測試參數,筆者選用curl。 測試GET,其中1234會自動對應到spring裏的uuid。 curl http://localhost:8080/api/someRecord/1234 # return {"ret":"your uuid:1234"} 測試 POST,其中的 -d 參數,會對應 spring裏的 @RequestBody, -H 參數則是設定 http header 的意思,我們就使用約定俗成的 json 作為 header 。 curl -X POST http://localhost:8080/api/someRecord -H "Content-Type: application/json" -d '{"requst":"did you get it?"}' # return {"requst":"did you get it?","ret":"got your request"} 上面的兩個操作,都回傳了我們輸入的資訊,這代表了我們成功用spring架起了http json api,而且正常讀入資訊。 Test Case 雖然我們可以正常地架起 api,但每次開發都要 postman / curl這種工具額外試一次,其實也有一些成本。而且 api 數量變大,或經多次修改後,就重複人手執行,就變得相當討厭。 面對這個問題,筆者會建議寫測試用例,即是Test Case,而且用Spring內置的@SpringBootTest來寫。 產生一個空的Test類,vscode中,最簡單可以Source Action => Generate Test,然後加入這次要測試的參數。 // src/test/java/io/github/macauyeah/springboot/tutorial/springbootwebapibasic/controller/HomeControllerTest.java import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.RequestBuilder; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.result.MockMvcResultHandlers; import org.springframework.test.web.servlet.result.MockMvcResultMatchers; @SpringBootTest @AutoConfigureMockMvc public class HomeControllerTest { @Autowired private MockMvc mockMvc; @Test void testGetSomeRecord() throws Exception { RequestBuilder requestBuilder = MockMvcRequestBuilders.get("/api/someRecord/1234") .contentType(MediaType.APPLICATION_JSON); this.mockMvc.perform(requestBuilder) .andExpect(MockMvcResultMatchers.jsonPath("$.ret").value("your uuid:1234")) .andDo(MockMvcResultHandlers.print()); } @Test void testPostSomeRecord() throws Exception { String request = """ {"requst":"did you get it?"} """; RequestBuilder requestBuilder = MockMvcRequestBuilders.post("/api/someRecord") .contentType(MediaType.APPLICATION_JSON) .content(request); this.mockMvc.perform(requestBuilder) .andExpect(MockMvcResultMatchers.jsonPath("$.requst").value("did you get it?")) .andExpect(MockMvcResultMatchers.jsonPath("$.ret").value("got your request")) .andDo(MockMvcResultHandlers.print()); } } 最後就是執行 mvn test 或經IDE運行,應該都會得到所有測試都通過的結果。 mvn test # other test result ... [INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.368 s -- in io.github.macauyeah.springboot.tutorial.springbootwebapibasic.controller.HomeControllerTest # other test result ... 上面的程式碼很多,我們逐一來。 @SpringBootTest 寫在類的外面,代表執行這個測試類時,需要運行起整個Spring程序,當然也包括http的部份。 @AutoConfigureMockMvc 寫在類的外面,代表執行這個測試類時,可以模擬一些發向自己的 http 請求。 @Autowired private MockMvc mockMvc 寫在類的裏面,因為之前有定義了可以模擬 http 的請求,Spring在運行時為大家提供了那個所謂的模擬http client的實例。 MockMvcRequestBuilders,則是建造要測試的URL及Header參數。 MockMvcResultMatchers,則是檢查回傳的結果是否如遇期的一樣。 為何這個http client叫模擬 - Mock ? 因為在測試用例中,可能連Controller 內部依賴組件也需要進一步模擬,這樣才能把測試目標集中在Controller裏,這也是單元測試的原意。只是本次的例子看不出模擬與否的差別。 MockMvcResultMatchers.jsonPath(),這是用來檢測json的結構是否跟預期一樣。有些網路上的其他例子會簡寫成 jsonPath() ,但因為vscode IDE的自動import功能比較差,筆者還是保留傳統的寫法。 如果大家覺得@SpringBootTest很難,想折衷地把其他測試方法,那麼把 postman / curl好好管理起來,每次修改完程式,都完整地執行一次 postman / curl ,也可以達到測試的效果。只不過大家還是要好好學會整合 postman / curl,知道如何檢測json結構,什麼時候有錯,什麼時候叫測試通過,所以也要花一樣功夫來實現。 最後,大家千萬不要因為測試難寫而逃課,因為寫測試絕對地可以減輕日後重執行的工作量。除非你的程式碼即用即棄,否則都建議寫測試。(測試跟寫文檔不一樣,有了測試也不能沒有文檔。好消息的是,文檔現在越來越多自動生成的工具,我們日後再找機會介紹。) Source Code spring boot web api basic