2017年8月19日 星期六

[C#] XML文件讀取、寫入方法

假日沒事在家用功,複習一些基本的東西順便記錄下來
有些太久沒用真得很容易忘記
內容參考《Professional C#6 and .Net Core 1.0》
================================================
XML文件

<?xml version='1.0'?>
<!-- This file represents a fragment of a book store inventory database -->
<bookstore>
  <book genre="autobiography" publicationdate="1991" ISBN="1-861003-11-0">
    <title>The Autobiography of Benjamin Franklin</title>
    <author>
      <first-name>Benjamin</first-name>
      <last-name>Franklin</last-name>
    </author>
    <price>8.99</price>
  </book>
  <book genre="novel" publicationdate="1967" ISBN="0-201-63361-2">
    <title>The Confidence Man</title>
    <author>
      <first-name>Herman</first-name>
      <last-name>Melville</last-name>
    </author>
    <price>11.99</price>
  </book>
  <book genre="philosophy" publicationdate="1991" ISBN="1-861001-57-6">
    <title>The Gorgias</title>
    <author>
      <name>Plato</name>
    </author>
    <price>9.99</price>
  </book>
</bookstore>
================================================
程式碼

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Xml;

namespace XmlExample
{
    class Program
    {
        static void Main(string[] args)
        {
            var doc = new XmlDocument();

            // 讀取xml
            using (FileStream stream = File.OpenRead("books.xml"))
            {
                doc.Load(stream);

                XmlNodeList priceNodes = doc.GetElementsByTagName("price");

                foreach (XmlNode node in priceNodes)
                {
                    // 修改內容
                    node.InnerText = "100";
                }
            }

            // 寫入xml
            var settings = new XmlWriterSettings
            {
                Indent = true,
                IndentChars = "\t",
                NewLineChars = Environment.NewLine
            };
            using (StreamWriter streamWriter = File.CreateText("newbooks.xml"))
            using (XmlWriter writer = XmlWriter.Create(streamWriter, settings))
            {
                doc.WriteContentTo(writer);
            }

            Console.WriteLine("Finish");
            Console.ReadLine();
        }
    }
}

[C#]等候異步任務回傳值

每次都忘記有Result可以用,一個簡單的紀錄



2017年4月24日 星期一

[股票投組]動能投組

股票投組對我來說是個半被動的交易方法,一開始選定一些概念後從此就不再管他,讓他自己跑自己的,就像ETF一樣,之後需要決定的只是「要不要使用這個投組」,就跟要不要使用這個ETF一樣,而不是「想辦法修改這個投組」。

以下分享一個現在自己有在使用的投組:動能投組。

這個投組組成元素有:
1. 通道突破(5週)
2. 篩選EPS>0的股票
3. 做漲最多的股票
4. 一次持有5檔

也就是說我只持有那個階段最會漲的股票,當他突破5週高點就買進,而任何一支股票跌破5週低點我就換股,換的股就是突破5週高點且最近漲最多的。

一個不知道以後有沒有辦法達成的回測績效:


可以看到10年漲了15倍,相對期貨策略來說比較少且DD也比較大,但似乎比較有可能達成。

這個投組實際上在做的時候會有一些問題:
1. 沒辦法確實將資金分為5等份,除非購買零股
2. 買最近很會漲的股票有可能開盤直接開在漲停根本買不到
3. 這個投組DD有到40%,資金管理很重要

另外一個有篩選過成交量的投組回測,績效下降但更接近真實情況:


2017年4月21日 星期五

Multicharts陣列排序函數

繼續之前的股票投組架構

Manager是一個決定誰要進場的管理員,例如Signal的條件是「破5週高點」就進場,篩選出來的股票池可能有5檔,但是資金有限或是不想一次擁有太多股票等等原因,我如果只想要進兩檔的話就需要有Manager來管理。而要決定這5檔到底最後誰要進場,可以用下方函數最排序。

函數名:StockPortfolio_Rank


用以下範例解釋此函數用法

股票排序範例



由範例可以知道在排序前StockArray是由代號依序組成的陣列:[1101,1102,1103,1104,1105],排序基準則存在另外一個ValueArray陣列裡面:[5,10,9,3,6],而排序後StockArray陣列改為由每檔股票相對應的Value依序組成:[1102,1103,1105,1101,1104],這時候如果想要進兩檔股票,則選擇StockArray[0],StockArray[1]就可以了

2017年4月14日 星期五

Multicharts實現股票投組的方法

股票投組(程式交易)決定哪檔股票進場可分為以下幾階段

階段A:篩選股票池
階段B:由股票池中選出進場標的,一般會要決定用哪個參數(EX:動能)當做排序條件,越大的越先進場

Multicharts的pmm指令可以在Portfolio Trader中讓變數互傳
藉由pmm指令達成股票投組回測具體做法可以是

1. 建立三個投組
2. 投組一(計算):專門計算進出場點、排名需要的值,傳給投組二
3. 投組二(管理):接收投組一的值,決定最後進場者,傳給投組三
4. 投組三(執行):最後執行進出場者


下次再來講程式碼...

2017年3月20日 星期一

[pmm指令] 全域變數

[前言]

Multicharts的Portfolio Trader現在有一些指令可以做投組的資金管理、變數互傳,以往的ADE只能做變數單向傳送,而現在的投組指令(因為都是pmm開頭以後就叫他pmm指令好了),可以做雙向傳送,也就是策略A傳給策略B,計算完後再傳給策略A,最近要做一些選股的模型,也把常用到的pmm指令寫在這當做給自己的一個複習。

[Pmm指令]

pmm_set_global_named_num:設定全域變數。
pmm_get_global_named_num:取得全域變數。

[觀念解釋]

<全域變數>

通常pmm_set_global_named_num、pmm_get_global_named_num是會一起使用的,只單獨使用一個沒有任何意義。全域變數的意思就是這個投組在跑的時後,這個變數可以被所有策略呼叫,也可以被所有策略修改,只要使用pmm_set_global_named_num("A",xxx),就是把全域變數「A」設定為xxx。使用pmm_get_global_named_num(A)則是取得全域變數的值。

[範利]



Test1程式碼:
========================================
pmm_set_global_named_num("GlobalVar", C);
========================================

Test2程式碼:
========================================
value1=pmm_get_global_named_num("GlobalVar");
Print(datestr(d)," TWSE:",value1," TXF:",C);
========================================

輸出結果:



2017年3月10日 星期五

閒聊2017.03.11

最近異想天開的想用機器學習篩選進場點位,我的想法是這樣:

Step1. 先用一個簡單的策略做進出場,並記錄當下特徵狀態

這邊說的特徵其實就是可以量化的各種東西,
RSI數值、Put Call Ratio、公債殖利率...等都可以拿來當做特徵

這樣整理後會出現類似下表


Step2. 將獲利做為分類目標,嘗試是否有特徵可良好完成分類

也就是看看是不是在某些特定情況下,該策略會有較良好的獲利
如果有的話,以後這些特定情況出現時,我也會較有信心進場

以上圖來說,RSI數值似乎可以當做一個不錯的特徵,
我可以選定以後RSI大於20的話我的口數進場兩倍

但真實世界沒這麼簡單,目前隨便嘗試一下,分類正確率都跟射飛鏢一樣。
這個結果也可能是我沒有真正學習過機器學習的關係,目前就是會使用一些現成套件,並把資料倒進去看看效果如何,看來要真正使用機器學習還是要先了解一下背後的原理才行。

關於套件

我使用的是python的sklearn,下圖是sklearn官網上用svm分類的例子



可以看出真得非常簡單使用,不到五行就可以用聽起來超厲害的SVM(Support vector machine;支持向量機)做完分類