執行専用EAの作成

執行専用EAはFXシステム(Python)から送られたシグナルに基づいて売買する。

メタエディターの設定

メタエディターを初めて使うときのみ、実行する。

①MT4のメニューバーで「ツール」をクリックする。

②「メタエディター」をクリックする。

メタエディターが起動する。

③メタエディターのメニューバーで「Tools」をクリックする。

④「Options...」をクリックする。

⑤「Options」で「Font」タブをクリックする。

⑥「Font:」で「Takao ゴシック」を選択する。

これは単なる好みである。

⑦「Script」:で「日本語」を選択する。

⑧「OK」ボタンをクリックする。

サンプルプログラムの作成

①メタエディターのツールバーで「New」ボタンをクリックする。

②「MQL Wizard」で「Expert Advisor (template)」が選択されているのを確認する。

③「次へ」ボタンをクリックする。

④「Name:」を「Experts\ExecutionOnly」で上書きする。

⑤「Author:」を消去する。

⑥「Link:」も消去する。

⑦「次へ」ボタンをクリックする。

⑧続けて「次へ」ボタンをクリックする。

⑨「完了」ボタンをクリックする。

⑩メタエディターで以下のプログラムをコピー&ペーストして「ExecutionOnly.mq4」ファイルを上書きする。

// ファイル名は必ず31文字以内にすること。
extern string Filename = "sample_strategy";
extern double Lot = 0.1;
extern int MaxPos = 5;

void OnTick() {
    // 変数を宣言する。
    bool check;
    int file_handle;
    int i;
    int signal;
    int total;
    int pos;
    int ticket;
    string comment = Filename;

    // シグナルをファイルから確認する。
    file_handle = FileOpen(Filename + ".csv", FILE_READ | FILE_CSV);
    if (file_handle != INVALID_HANDLE) {
        // シグナルには2が加えられているので2を減じて元に戻す。
        signal = FileReadNumber(file_handle) - 2;
        FileClose(file_handle);
    }

    // ポジション総数(このEA以外のものも含む)を確認する。
    total = OrdersTotal();

    // このEAのポジションを確認する。
    pos = 0;
    for (i = 0; i < OrdersTotal(); i++) {
        if (OrderSelect(i, SELECT_BY_POS) == TRUE) {
            if (OrderComment() == comment) {
                if (OrderType() == OP_BUY) {
                    pos = 1;
                }
                else if (OrderType() == OP_SELL) {
                    pos = -1;
                }
            }
        }
    }

    // ポジション総数が最大ポジション数以下である前提で、
    // ポジションが「なし」、かつ、
    if (total <= MaxPos && pos == 0) {
        RefreshRates();
        // シグナルが「買い」なら、新規買い注文を送信する。
        if (signal == 1) {
            ticket = OrderSend(Symbol(), OP_BUY, Lot, Ask, 3, 0, 0, comment);
        }
        // シグナルが「売り」なら、新規売り注文を送信する
        else if (signal == -1) {
            ticket = OrderSend(Symbol(), OP_SELL, Lot, Bid, 3, 0, 0, comment);
        }
    }
    // ポジションが「買い」、かつ、シグナルが「なし」、または「売り」なら、
    // 決済売り注文を送信する。
    else if (pos == 1 && (signal == 0 || signal == -1)) {
        for (i = OrdersTotal() - 1; i >= 0; i--) {
            if(OrderSelect(i, SELECT_BY_POS) == TRUE) {
                if (OrderComment() == comment && OrderType() == OP_BUY) {
                    check = OrderClose(OrderTicket(), OrderLots(), Bid, 3);
                }
            }
        }
    }
    // ポジションが「売り」、かつ、シグナルが「なし」、または「買い」なら、
    // 決済買い注文を送信する。
    else if (pos == -1 && (signal == 0 || signal == 1)) {
        for (i = OrdersTotal() - 1; i >= 0; i--) {
            if(OrderSelect(i, SELECT_BY_POS) == TRUE) {
                if (OrderComment() == comment && OrderType() == OP_SELL) {
                    check = OrderClose(OrderTicket(), OrderLots(), Ask, 3);
                }
            }
        }
    }

    // ポジション総数、ポジション、シグナルを出力する。
    Print("total = ", total);
    Print("pos = ", pos);
    Print("signal = ", signal);
}

サンプルプログラムの第1行にcsvファイルの名前を設定する(例として「sample_strategy」としてある)。

警告:csvファイルの名前は半角で必ず31文字以内にする。そうしないとOrderComment()関数に正しく読み込まれない。ファイル名でEAのポジションを識別するようにしているので、正しく読み込まれないと大変なことになる。例えば他のEAのポジションを自分のものと勘違いして決済し、本来の保有者であるEAはポジションが突然決済されてしまったので、再びポジションを持つ。すると、執行専用EAは決済したはずなのにまたポジションが出来てしまったので再び決済する。こうして新規注文、決済注文が繰り返されるが、コンピューターは非常に高速にこれを実行するので、その都度払うスプレッドだけで退場させられるだろう。

⑪ツールバーの「Compile」ボタンをクリックする。

「Toolbox」の「Description」に「0 error(s), 0 warning(s)」と表示されればOK。

空のcsvファイルの作成

シグナルのやり取りはcsvファイルを通じて行う。そこで、あらかじめ空のcsvファイルを作っておく。

上のサンプルプログラムに合わせて、「sample_strategy.csv」ファイルを作成する場合を例とする。また、MT4のインストール先は「~/.wine/drive_c/Program Files (x86)/OANDA - MetaTrader」であるとする。半角スペースのあるフォルダー名は「""」で囲む点に注意。

○端末に以下のコマンドをコピー&ペーストして「Enter」キーを押す。

touch ~/.wine/drive_c/"Program Files (x86)"/"OANDA - MetaTrader"/mql4/Files/sample_strategy.csv
(2017/01/08更新)

GitHubの使い方 (2017/01/07)

ここではユーザー名を「fxst24」、リモートリポジトリを「origin」として説明する。

GitHubの登録

注意:手順の一部は実際に登録してみないと分かりませんが、私はすでに登録済で、手順確認のためにまた別に登録するのもどうかと思いますので、以下の手順は不完全なものです。

①以下のアドレスをクリックする。

https://github.com/

②右上の「Sign up」ボタンをクリックする。

③「Create your personal account」で「Username」にユーザー名を入力する。

④「Email Address」でメールアドレスを入力する。

⑤「Password」でパスワードを入力する。

⑥「Create an account」ボタンをクリックする。

この後に「Step 2」、「Step 3」という手順があるようだが未確認のため、省略。

これより下の手順は私が実際に登録したとき(2016年7月ごろ)のメモに基づいています。仕様変更がなければそのまま使えると思います。特に「GitHubの更新」は普段から使っていますので大丈夫です。

初期設定

初期設定は1回やればいいようである。

○端末で以下のコマンドを入力して「Enter」キーを押す。

$ git config --global user.email ******@*****.com;git config --global user.name "fxst24"

メールアドレス、ユーザー名は登録したものを入力する。

ローカルリポジトリの作成

ここでは例として「ホーム」フォルダーに「fxst24」という名前のフォルダーを作成し、これをローカルリポジトリとすることにする。

○端末で以下のコマンドを入力して「Enter」キーを押す。

$ mkdir ~/fxst24

リモートリポジトリの作成

ユーザ名が「fxst24」のリモートリポジトリとして「origin」を作成する。

○端末で以下のコマンドを入力して「Enter」キーを押す。

$ cd ~/fxst24;git remote add origin https://github.com/fxst24/fxst24.git

GitHubの更新

ファイルを更新して、それをGitHubに反映させたい場合、①ローカルリポジトリの初期化、②追加、削除、修正したファイルすべてのインデックスへの追加、③ファイルのコミット、④リモートリポジトリへのプッシュ、という過程を経るようだが、ここでは1つのコマンドにまとめて実行する。

①端末で以下のコマンドを入力して「Enter」キーを押す。

$ cd ~/fxst24;git init;git add --all;git commit -m "update";git push origin master

②ユーザ名を入力して「Enter」キーを押す。

③パスワードを入力して「Enter」キーを押す。

テレビ視聴アプリの作成

Chinachuの録画予約機能には特に不満はないのだが、テレビ視聴機能が今一つ使い勝手が悪い。ふと、昔、自分でテレビ視聴アプリを作ったことがあったのを思い出し、コンパイルしてみたら、今でも使えるので驚いた。それは今から9年ほど前、私がプログラミングを学んで初めて作ったもので、なつかしい。

プログラムを見ると、関数に引数を渡すということを知らなかったようで、チャンネルごとに関数を作っていた。また、システムに与えるコマンドを直接、プログラムに書き込めばいいものを、わざわざスクリプトファイルを作って、それを呼び出していた。しかもコマンド1つごとにファイルを作っていた。そんなわけでプログラムがやたらと長く、ファイルが50近くもあった。

今から見ると稚拙にもほどがあると思うが、それでも何とかして作り上げてやるという熱意は感じる。それはさて、当時のプログラムに修正を加えたものが、これから作成する視聴アプリである。WindowsでTVTestなどを使っている人から見ると「なにこれ」といったレベルだが、単にテレビを視聴するだけなら十分かなと思う。

準備

①「Ubuntu 16.04 + Chinachu + PT2でテレビ」の記事に基づいて、recpt1で録画できる環境を作る(Chinachuはなくてもよい)。

②端末に以下のコマンドをコピー&ペーストして「Enter」キーを押す。

sudo apt-get -y install libgtk2.0-dev vlc

GUIツールキットとしてGTK+2を使う。

また、再生プレイヤーとしてVLCプレイヤーを使う。

③「[sudo] **** のパスワード:」でパスワードを入力して「Enter」キーを押す。

アプリの作成

①以下のプログラムをテキストエディターにコピー&ペーストし、ファイル名を「tv.c」としてデスクトップに保存する。

#include <gtk/gtk.h>

GtkWidget *table[4];

void system();

// 放送を選択する関数を定義する。
void select_broadcasting(GtkWidget *widget, gpointer data) {
    if (GPOINTER_TO_INT(data) == 0) {
        gtk_widget_show(table[1]);
        gtk_widget_hide(table[2]);
        gtk_widget_hide(table[3]);
    }
    else if (GPOINTER_TO_INT(data) == 1) {
        gtk_widget_show(table[2]);
        gtk_widget_hide(table[3]);
        gtk_widget_hide(table[1]);
    }
    else {  // GPOINTER_TO_INT(data) == 2
        gtk_widget_show(table[3]);
        gtk_widget_hide(table[1]);
        gtk_widget_hide(table[2]);
    }
}

// チャンネルを選択する関数を定義する。
void select_channel(GtkWidget *widget, gpointer data) {
    system("killall recpt1; killall cvlc");
    system("rm temp.ts");
    system(data);
    sleep(2);
    system("cvlc temp.ts &");
}

// ウィンドウを閉じたときの動作を設定する関数を定義する。
void destroy(GtkWidget *widget, gpointer data) {
    system("killall recpt1; killall cvlc");
    system("rm temp.ts");
    gtk_main_quit();
}

int main(int argc, char *argv[]) {
    GtkWidget *window;
    GtkWidget *box;
    GtkWidget *radio_button[3];
    GtkWidget *btn_gr[12], *btn_bs[12], *btn_cs[12];
    GSList *group = NULL;
    gpointer ch1_gr, ch2_gr, ch3_gr, ch4_gr, ch5_gr, ch6_gr, ch7_gr, ch8_gr,
        ch9_gr, ch10_gr, ch11_gr, ch12_gr;
    gpointer ch1_bs, ch2_bs, ch3_bs, ch4_bs, ch5_bs, ch6_bs, ch7_bs, ch8_bs,
        ch9_bs, ch10_bs, ch11_bs, ch12_bs;
    gpointer ch1_cs, ch2_cs, ch3_cs, ch4_cs, ch5_cs, ch6_cs, ch7_cs, ch8_cs,
        ch9_cs, ch10_cs, ch11_cs, ch12_cs;

    // 初期化する。
    gtk_init(&argc, &argv);

    // 地上デジタルの設定を行う。
    ch1_gr = "recpt1 --b25 --strip --sid hd 27 7200 temp.ts &";
    ch2_gr = "recpt1 --b25 --strip --sid hd 26 7200 temp.ts &";
    ch3_gr = "recpt1 --b25 --strip --sid hd 25 7200 temp.ts &";
    ch4_gr = "recpt1 --b25 --strip --sid hd 22 7200 temp.ts &";
    ch5_gr = "recpt1 --b25 --strip --sid hd 21 7200 temp.ts &";
    ch6_gr = "recpt1 --b25 --strip --sid hd 24 7200 temp.ts &";
    ch7_gr = "recpt1 --b25 --strip --sid hd 23 7200 temp.ts &";
    ch8_gr = "recpt1 --b25 --strip --sid hd 16 7200 temp.ts &";
    ch9_gr = "recpt1 --b25 --strip --sid hd 20 7200 temp.ts &";
    ch10_gr = "recpt1 --b25 --strip --sid hd 18 7200 temp.ts &";
    ch11_gr = "recpt1 --b25 --strip --sid hd 32 7200 temp.ts &";
    ch12_gr = "recpt1 --b25 --strip --sid hd 28 7200 temp.ts &";

    // BSの設定を行う。
    ch1_bs = "recpt1 --b25 --strip 101 7200 temp.ts &";
    ch2_bs = NULL;
    ch3_bs = "recpt1 --b25 --strip 103 7200 temp.ts &";
    ch4_bs = "recpt1 --b25 --strip 141 7200 temp.ts &";
    ch5_bs = "recpt1 --b25 --strip 151 7200 temp.ts &";
    ch6_bs = "recpt1 --b25 --strip 161 7200 temp.ts &";
    ch7_bs = "recpt1 --b25 --strip 171 7200 temp.ts &";
    ch8_bs = "recpt1 --b25 --strip 181 7200 temp.ts &";
    ch9_bs = NULL;
    ch10_bs = NULL;
    ch11_bs = "recpt1 --b25 --strip 211 7200 temp.ts &";
    ch12_bs = "recpt1 --b25 --strip 222 7200 temp.ts &";

    // CSの設定を行う。
    ch1_cs = NULL;
    ch2_cs = NULL;
    ch3_cs = NULL;
    ch4_cs = NULL;
    ch5_cs = NULL;
    ch6_cs = NULL;
    ch7_cs = NULL;
    ch8_cs = NULL;
    ch9_cs = NULL;
    ch10_cs = NULL;
    ch11_cs = NULL;
    ch12_cs = NULL;

    // ウィンドウを作成する。
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_widget_set_size_request(window, 140, 140);
    gtk_window_set_resizable(GTK_WINDOW (window), FALSE);
    gtk_window_set_keep_above(GTK_WINDOW(window), TRUE);

    // ボックスを作成する。
    box = gtk_vbox_new(FALSE, 0);
    gtk_container_add(GTK_CONTAINER(window), box);

    // 放送選択用のテーブルを作成する。
    table[0] = gtk_table_new(3, 1, FALSE);
    gtk_box_pack_start(GTK_BOX(box), table[0], FALSE, TRUE, 0);

    // 放送選択用のラジオボタンを作成する。
    radio_button[0] = gtk_radio_button_new_with_label(group, "GR");
    radio_button[1] = gtk_radio_button_new_with_label_from_widget(
        GTK_RADIO_BUTTON(radio_button[0]), "BS");
    radio_button[2] = gtk_radio_button_new_with_label_from_widget(
        GTK_RADIO_BUTTON(radio_button[0]), "CS");

    // 放送選択用のラジオボタンをテーブルに設置する。
    gtk_table_attach_defaults(GTK_TABLE(table[0]), radio_button[0],
                                        0, 1, 0, 1);
    gtk_table_attach_defaults(GTK_TABLE(table[0]), radio_button[1],
                                        1, 2, 0, 1);
    gtk_table_attach_defaults(GTK_TABLE(table[0]), radio_button[2],
                                        2, 3, 0, 1);
    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(radio_button[0]), TRUE);

    // チャンネル選択用のテーブルを作成する。
    table[1] = gtk_table_new(3, 4, FALSE);
    table[2] = gtk_table_new(3, 4, FALSE);
    table[3] = gtk_table_new(3, 4, FALSE);

    // チャンネル選択用のテーブルをボックスに設置する。
    gtk_box_pack_start(GTK_BOX(box), table[1], FALSE, TRUE, 0);
    gtk_box_pack_start(GTK_BOX(box), table[2], FALSE, TRUE, 0);
    gtk_box_pack_start(GTK_BOX(box), table[3], FALSE, TRUE, 0);

    // 地デジチャンネル選択用のボタンを作成する。
    btn_gr[0] = gtk_button_new_with_label("1");
    btn_gr[1] = gtk_button_new_with_label("2");
    btn_gr[2] = gtk_button_new_with_label("3");
    btn_gr[3] = gtk_button_new_with_label("4");
    btn_gr[4] = gtk_button_new_with_label("5");
    btn_gr[5] = gtk_button_new_with_label("6");
    btn_gr[6] = gtk_button_new_with_label("7");
    btn_gr[7] = gtk_button_new_with_label("8");
    btn_gr[8] = gtk_button_new_with_label("9");
    btn_gr[9] = gtk_button_new_with_label("10");
    btn_gr[10] = gtk_button_new_with_label("11");
    btn_gr[11] = gtk_button_new_with_label("12");

    // 地デジチャンネル選択用のボタンをテーブルに設置する。
    gtk_table_attach_defaults(GTK_TABLE(table[1]), btn_gr[0], 0, 1, 0, 1);
    gtk_table_attach_defaults(GTK_TABLE(table[1]), btn_gr[1], 1, 2, 0, 1);
    gtk_table_attach_defaults(GTK_TABLE(table[1]), btn_gr[2], 2, 3, 0, 1);
    gtk_table_attach_defaults(GTK_TABLE(table[1]), btn_gr[3], 0, 1, 1, 2);
    gtk_table_attach_defaults(GTK_TABLE(table[1]), btn_gr[4], 1, 2, 1, 2);
    gtk_table_attach_defaults(GTK_TABLE(table[1]), btn_gr[5], 2, 3, 1, 2);
    gtk_table_attach_defaults(GTK_TABLE(table[1]), btn_gr[6], 0, 1, 2, 3);
    gtk_table_attach_defaults(GTK_TABLE(table[1]), btn_gr[7], 1, 2, 2, 3);
    gtk_table_attach_defaults(GTK_TABLE(table[1]), btn_gr[8], 2, 3, 2, 3);
    gtk_table_attach_defaults(GTK_TABLE(table[1]), btn_gr[9], 0, 1, 3, 4);
    gtk_table_attach_defaults(GTK_TABLE(table[1]), btn_gr[10], 1, 2, 3, 4);
    gtk_table_attach_defaults(GTK_TABLE(table[1]), btn_gr[11], 2, 3, 3, 4);

    // BSチャンネル選択用のボタンを作成する。
    btn_bs[0] = gtk_button_new_with_label("1");
    btn_bs[1] = gtk_button_new_with_label("2");
    btn_bs[2] = gtk_button_new_with_label("3");
    btn_bs[3] = gtk_button_new_with_label("4");
    btn_bs[4] = gtk_button_new_with_label("5");
    btn_bs[5] = gtk_button_new_with_label("6");
    btn_bs[6] = gtk_button_new_with_label("7");
    btn_bs[7] = gtk_button_new_with_label("8");
    btn_bs[8] = gtk_button_new_with_label("9");
    btn_bs[9] = gtk_button_new_with_label("10");
    btn_bs[10] = gtk_button_new_with_label("11");
    btn_bs[11] = gtk_button_new_with_label("12");

    // BSチャンネル選択用のボタンをデーブルに設置する。
    gtk_table_attach_defaults(GTK_TABLE(table[2]), btn_bs[0], 0, 1, 0, 1);
    gtk_table_attach_defaults(GTK_TABLE(table[2]), btn_bs[1], 1, 2, 0, 1);
    gtk_table_attach_defaults(GTK_TABLE(table[2]), btn_bs[2], 2, 3, 0, 1);
    gtk_table_attach_defaults(GTK_TABLE(table[2]), btn_bs[3], 0, 1, 1, 2);
    gtk_table_attach_defaults(GTK_TABLE(table[2]), btn_bs[4], 1, 2, 1, 2);
    gtk_table_attach_defaults(GTK_TABLE(table[2]), btn_bs[5], 2, 3, 1, 2);
    gtk_table_attach_defaults(GTK_TABLE(table[2]), btn_bs[6], 0, 1, 2, 3);
    gtk_table_attach_defaults(GTK_TABLE(table[2]), btn_bs[7], 1, 2, 2, 3);
    gtk_table_attach_defaults(GTK_TABLE(table[2]), btn_bs[8], 2, 3, 2, 3);
    gtk_table_attach_defaults(GTK_TABLE(table[2]), btn_bs[9], 0, 1, 3, 4);
    gtk_table_attach_defaults(GTK_TABLE(table[2]), btn_bs[10], 1, 2, 3, 4);
    gtk_table_attach_defaults(GTK_TABLE(table[2]), btn_bs[11], 2, 3, 3, 4);

    // CSチャンネル選択用のボタンを作成する。
    btn_cs[0] = gtk_button_new_with_label("1");
    btn_cs[1] = gtk_button_new_with_label("2");
    btn_cs[2] = gtk_button_new_with_label("3");
    btn_cs[3] = gtk_button_new_with_label("4");
    btn_cs[4] = gtk_button_new_with_label("5");
    btn_cs[5] = gtk_button_new_with_label("6");
    btn_cs[6] = gtk_button_new_with_label("7");
    btn_cs[7] = gtk_button_new_with_label("8");
    btn_cs[8] = gtk_button_new_with_label("9");
    btn_cs[9] = gtk_button_new_with_label("10");
    btn_cs[10] = gtk_button_new_with_label("11");
    btn_cs[11] = gtk_button_new_with_label("12");

    // CSチャンネル選択用のボタンをデーブルに設置する。
    gtk_table_attach_defaults(GTK_TABLE(table[3]), btn_cs[0], 0, 1, 0, 1);
    gtk_table_attach_defaults(GTK_TABLE(table[3]), btn_cs[1], 1, 2, 0, 1);
    gtk_table_attach_defaults(GTK_TABLE(table[3]), btn_cs[2], 2, 3, 0, 1);
    gtk_table_attach_defaults(GTK_TABLE(table[3]), btn_cs[3], 0, 1, 1, 2);
    gtk_table_attach_defaults(GTK_TABLE(table[3]), btn_cs[4], 1, 2, 1, 2);
    gtk_table_attach_defaults(GTK_TABLE(table[3]), btn_cs[5], 2, 3, 1, 2);
    gtk_table_attach_defaults(GTK_TABLE(table[3]), btn_cs[6], 0, 1, 2, 3);
    gtk_table_attach_defaults(GTK_TABLE(table[3]), btn_cs[7], 1, 2, 2, 3);
    gtk_table_attach_defaults(GTK_TABLE(table[3]), btn_cs[8], 2, 3, 2, 3);
    gtk_table_attach_defaults(GTK_TABLE(table[3]), btn_cs[9], 0, 1, 3, 4);
    gtk_table_attach_defaults(GTK_TABLE(table[3]), btn_cs[10], 1, 2, 3, 4);
    gtk_table_attach_defaults(GTK_TABLE(table[3]), btn_cs[11], 2, 3, 3, 4);

    // ラジオボタンを選択したときの動作を設定する。
    g_signal_connect(G_OBJECT(radio_button[0]), "toggled",
                              G_CALLBACK(select_broadcasting),
                              GINT_TO_POINTER(0));
    g_signal_connect(G_OBJECT(radio_button[1]), "toggled",
                              G_CALLBACK(select_broadcasting),
                              GINT_TO_POINTER(1));
    g_signal_connect(G_OBJECT(radio_button[2]), "toggled",
                              G_CALLBACK(select_broadcasting),
                              GINT_TO_POINTER(2));

    // 地デジチャンネルボタンをクリックしたときの動作を設定する。
    g_signal_connect(G_OBJECT(btn_gr[0]), "clicked",
                              G_CALLBACK(select_channel), ch1_gr);
    g_signal_connect(G_OBJECT(btn_gr[1]), "clicked",
                              G_CALLBACK(select_channel), ch2_gr);
    g_signal_connect(G_OBJECT(btn_gr[2]), "clicked",
                              G_CALLBACK(select_channel), ch3_gr);
    g_signal_connect(G_OBJECT(btn_gr[3]), "clicked",
                              G_CALLBACK(select_channel), ch4_gr);
    g_signal_connect(G_OBJECT(btn_gr[4]), "clicked",
                              G_CALLBACK(select_channel), ch5_gr);
    g_signal_connect(G_OBJECT(btn_gr[5]), "clicked",
                              G_CALLBACK(select_channel), ch6_gr);
    g_signal_connect(G_OBJECT(btn_gr[6]), "clicked",
                              G_CALLBACK(select_channel), ch7_gr);
    g_signal_connect(G_OBJECT(btn_gr[7]), "clicked",
                              G_CALLBACK(select_channel), ch8_gr);
    g_signal_connect(G_OBJECT(btn_gr[8]), "clicked",
                              G_CALLBACK(select_channel), ch9_gr);
    g_signal_connect(G_OBJECT(btn_gr[9]), "clicked",
                              G_CALLBACK(select_channel), ch10_gr);
    g_signal_connect(G_OBJECT(btn_gr[10]), "clicked",
                              G_CALLBACK(select_channel), ch11_gr);
    g_signal_connect(G_OBJECT(btn_gr[11]), "clicked",
                              G_CALLBACK(select_channel), ch12_gr);

    // BSチャンネルボタンをクリックしたときの動作を設定する。
    g_signal_connect(G_OBJECT(btn_bs[0]), "clicked",
                              G_CALLBACK(select_channel), ch1_bs);
    g_signal_connect(G_OBJECT(btn_bs[1]), "clicked",
                              G_CALLBACK(select_channel), ch2_bs);
    g_signal_connect(G_OBJECT(btn_bs[2]), "clicked",
                              G_CALLBACK(select_channel), ch3_bs);
    g_signal_connect(G_OBJECT(btn_bs[3]), "clicked",
                              G_CALLBACK(select_channel), ch4_bs);
    g_signal_connect(G_OBJECT(btn_bs[4]), "clicked",
                              G_CALLBACK(select_channel), ch5_bs);
    g_signal_connect(G_OBJECT(btn_bs[5]), "clicked",
                              G_CALLBACK(select_channel), ch6_bs);
    g_signal_connect(G_OBJECT(btn_bs[6]), "clicked",
                              G_CALLBACK(select_channel), ch7_bs);
    g_signal_connect(G_OBJECT(btn_bs[7]), "clicked",
                              G_CALLBACK(select_channel), ch8_bs);
    g_signal_connect(G_OBJECT(btn_bs[8]), "clicked",
                              G_CALLBACK(select_channel), ch9_bs);
    g_signal_connect(G_OBJECT(btn_bs[9]), "clicked",
                              G_CALLBACK(select_channel), ch10_bs);
    g_signal_connect(G_OBJECT(btn_bs[10]), "clicked",
                              G_CALLBACK(select_channel), ch11_bs);
    g_signal_connect(G_OBJECT(btn_bs[11]), "clicked",
                              G_CALLBACK(select_channel), ch12_bs);

    // CSチャンネルボタンをクリックしたときの動作を設定する。
    g_signal_connect(G_OBJECT(btn_cs[0]), "clicked",
                              G_CALLBACK(select_channel), ch1_cs);
    g_signal_connect(G_OBJECT(btn_cs[1]), "clicked",
                              G_CALLBACK(select_channel), ch2_cs);
    g_signal_connect(G_OBJECT(btn_cs[2]), "clicked",
                              G_CALLBACK(select_channel), ch3_cs);
    g_signal_connect(G_OBJECT(btn_cs[3]), "clicked",
                              G_CALLBACK(select_channel), ch4_cs);
    g_signal_connect(G_OBJECT(btn_cs[4]), "clicked",
                              G_CALLBACK(select_channel), ch5_cs);
    g_signal_connect(G_OBJECT(btn_cs[5]), "clicked",
                              G_CALLBACK(select_channel), ch6_cs);
    g_signal_connect(G_OBJECT(btn_cs[6]), "clicked",
                              G_CALLBACK(select_channel), ch7_cs);
    g_signal_connect(G_OBJECT(btn_cs[7]), "clicked",
                              G_CALLBACK(select_channel), ch8_cs);
    g_signal_connect(G_OBJECT(btn_cs[8]), "clicked",
                              G_CALLBACK(select_channel), ch9_cs);
    g_signal_connect(G_OBJECT(btn_cs[9]), "clicked",
                              G_CALLBACK(select_channel), ch10_cs);
    g_signal_connect(G_OBJECT(btn_cs[10]), "clicked",
                              G_CALLBACK(select_channel), ch11_cs);
    g_signal_connect(G_OBJECT(btn_cs[11]), "clicked",
                              G_CALLBACK(select_channel), ch12_cs);

    // ウィンドウを閉じたときの動作を設定する。
    g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(destroy), NULL);

    // ウィンドウを表示する。
    gtk_widget_show_all(window);
    gtk_widget_hide(table[2]);
    gtk_widget_hide(table[3]);

    gtk_main();

    return 0;
}

②端末に以下のコマンドをコピー&ペーストして「Enter」キーを押す。

gcc -Wall -g ~/デスクトップ/tv.c -o ~/デスクトップ/tv `pkg-config --cflags gtk+-2.0` `pkg-config --libs gtk+-2.0`

デスクトップに「tv」ファイルが生成する。これが視聴アプリである。

使い方

起動

○デスクトップの「tv」ファイル(「tv.c」ファイルではない)をダブルクリックする。

視聴アプリが起動する。

視聴

①見たい放送を選択する。

地デジとBSには私が住んでいる地域に合わせた設定がしてある。CSの設定はしていない。

②見たいチャンネルをクリックする。

デスクトップに「temp.ts」ファイルが生成され、VLCプレイヤーで再生される。録画している番組をリアルタイムで再生することによって視聴の代用としているわけである。

終了

○視聴アプリの「×」ボタンをクリックする。

VLCプレイヤーも終了し、デスクトップの「temp.ts」ファイルも削除される。

(2017/01/07更新)

週単位、月単位で勝つための1日当たりのトレード数

週単位、月単位で勝つ(例えば週単位、月単位で損益がプラスとなる確率が80%以上)には勝率どのくらいのトレードを1日に何回行えばよいかということを考えてみる。ここでは単純化して1トレード当たりの利益/損失は常に一定で「1.0」と見なしてプログラムを組んでいる。

損益プラス確率で勝ちと見なす閾値を80%、1トレード当たりの勝率を55%とした場合を例とする。

○以下のコマンドをSpyderの「IPython console」にコピー&ペーストして「Enter」キーを2回押す。

threshold = 0.8
wp = 0.55

def func(n, r):
    if n == 0 or r == 0:
        return 1
    else:
        return func(n, r - 1) * (n - r + 1) / r

prob = 0.0
n_trade = -1
while (prob < threshold):
    n_trade = n_trade + 2 # 必ず奇数にする
    prob = 0.0
    for i in range(int((n_trade + 1) / 2), n_trade + 1):
        r = i
        temp = func(n_trade, r) * wp**r * (1 - wp)**(n_trade - r)
        prob = prob + temp
print("週単位で勝つための1日当たりのトレード数 = ", n_trade / 5.0)
print("月単位で勝つための1日当たりのトレード数 = ", n_trade / 20.0)

出力

週単位で勝つための1日当たりのトレード数 =  14.2
月単位で勝つための1日当たりのトレード数 =  3.55
(2017/01/05更新)