仮想通貨の自動売買

bitflyerのライブラリをpipでインストールします
$ pip3 install pybitflyer

import pybitflyer
import time

api_key = ""
api_secret = ""

api = bitflyer.API(api_key=api_key, api_secret=api_secret)

base_price = api.ticker(product_code="BTC_JPY")["ltp"]
print("bot開始時の価格は"+str(base_price)+"です。")

while True:
	time.sleep(5)
	price_now = api.ticker(product_code="BTC_JPY")["ltp"]
	print("現在のBTCJPYは " + str(price_now) + " です。")
	if base_price*0.95 >= price_now:
		print("bitcoin価格が下落しています。成行きで買い注文を入れます。")
		print("bitflyerのサーバーからの応答は以下です。")
		print(api.sendchildorder(product_code="BTC_JPY", child_order_type="MARKET", side="BUY", size=0.005, minute_to_expire=10000,time_in_force="GTC"))
		base_price = price_now

	elif base_price * 1.05 <= price_now:
		print("bitcoin価格が下落しています。成行きで売り注文を入れます。")
		print("bitflyerのサーバーからの応答は以下です。")
		print(api.sendchildorder(product_code="BTC_JPY", child_order_type="MARKET", side="SELL", size=0.005, minute_to_expire=10000,time_in_force="GTC"))
		base_price = price_now

	else:
		print("bitcoin価格に大きな変動はありません")

なるほど、base_priceとnow_priceで自動注文するのね
でもこれ、上昇相場なら無限に損するし、下落相場でも無限に損するやん
box相場の時のみ儲かるってことか
ここで移動平均線とかも組み合わせるのかな…

なんか色々ロジックがありそうですね。

アルゴリズムトレードとは

FXの場合、MT4を使えばツール上で完結する
MT4のMQLを持ちいる
MT4のバックテストツールで検証できる
そのままMT4で実弾の入った口座にログインして自動取引モードにすると取引できるようになる

lang:filename
void OnTick(void){
if(なにか条件){
ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,ALLOW_SLIPPAGE,NULL,Ask+TakeProfit*Point,"comment",Magic,0,Green);
}
}

価格が変動するとOnTick()関数が走るので、その中にメインロジックを書いていく
売り買いの注文は用意されており、OrderSend()は注文を入れる
移動平均線、ボリンジャーバンドなど様々なツール

Rを用いて実装することも
Pythonで機械学習を実装する場合はAPI化するう
他人が作成したアルゴリズムが販売されている
https://www.metatrader4.com/en/signals/overview
https://www.gogojungle.co.jp/

なるほど、まずはMT4の環境構築からか
EAを購入してVPSのwindows環境で動かしている人が多いみたいですね

WordPressでPluginをゼロから作りたい

Pluginのフォルダにファイルを作成し、ライセンス情報を記載する

/*
	Plugin Name: CustomIndexBanner
	Plugin URI: http://hpscript.com/blog/
	Description: indexページに表示可能なバナーの設定
	Version: 1.0.0
	Author: Hpscript
	Author URI: http://hpscript.com/blog/
	License: MIt
*/

すると、プラグインとして自動で認識される

メニュー追加

add_action('init', 'CustomIndexBanner::init');

class CustomIndexBanner {

	static function init(){
		return new self();
	}

	function __construct(){
		if(is_admin() && is_user_logged_in()){
			add_action('admin_menu', [$this, 'set_plugin_menu']);
			add_action('admin_menu', [$this, 'set_plugin_sub_menu']);
		}
	}

	function set_plugin_menu(){
		add_menu_page (
			'カスタムバナー', // ページタイトル
			'カスタムバナー', // メニュータイトル
			'manage_options', // 権限
			'custom-index-banner', // ページを開いたときのURL
			[$this, 'show_about_plugin'], // メニューに紐づく画面を描画するcallback関数
			'dashicons-format-gallery', // アイコン
			99 // 表示位置オフセット
		);
	}
	function set_plugin_sub_menu(){
		add_submenu_page(
			'custom-index-banner',
			'設定',
			'設定',
			'manage_options',
			'custom-index-banner-config',
			[$this, 'show_config_form']
		);
	}
}

	function show_about_plugin(){
		$html = "<h1>カスタムバナー</h1>";
		$html .= "<p>トップページに表示するバナーを指定できます</p>";

		echo $html;
	}

	function show_config_form(){

?>
	<h1>カスタムバナーの設定</h1>
<?php
	}
}

### フォームの作成

	const VERSION = '1.0.0';
	const PLUGIN_ID = 'custom-index-banner';
	const CREDENTIAL_ACTION = self::PLUGIN_ID . '-nonce-action';
	const CREDENTIAL_NAME = self::PLUGIN_ID . '-nonce-key';
	const PLUGIN_DB_PREFIX = self::PLUGIN_ID . '_';


	function show_config_form(){
		// wp_optionsを引っ張る
		$title = get_option(self::PLUGIN_DB_PREFIX . "_title");
?>
	<div class="wrap">
		<h1>カスタムバナーの設定</h1>

		<form action="" method='post' id="my-submenu-form">
			<?php wp_nonce_field(self::CREDENTIAL_ACTION, self::CREDENTIAL_NAME) ?>

			<p>
				<label for="title">タイトル:</label>
				<input type="text" name="title" value="<?= $title ?>"/>
			</p>

			<p><input type="submit" value="保存" class="button button-primary button-large"></p>
		</form>
	</div>
<?php
	}
}


	const CONFIG_MENU_SLIG = self::PLUGIN_ID . '-config';
	function save_config(){

		if(isset($_POST[self::CREDENTIAL_NAME]) && $_POST[self::CREDENTIAL_NAME]){
			if(check_admin_referer(self::CREDENTIAL_ACTION, self::CREDENTIAL_NAME)){

				$key =
				$title = $_POST($value['title']) ? $_POST['title'] : "";

				update_option(self::PLUGIN_DB_PREFIX . $key, $title);
				$completed_text = "設定の保存が完了しました。管理画面にログインした状態で、トップページにアクセスし変更が正しく反映されたか確認してください。";

				set_transient(self::COMPLETE_CONFIG, $completed_text, 5);

				wp_safe_redirect(menu_page_url(self::CONFIG_MENU_SLUG), false);

			}
		}
	}

なんやこれは。。。 プラグインの実装はテーマエディタではなく、プラグインのソースコードでカスタマイズすんのか。 時間かかるな。

[WordPress] MTS Simple Bookingに決済処理をカスタマイズしたいが。。。

MTS Simple Bookingのプラグインの仕組みを検証する
まずファイル構造から
$ sudo yum install tree
$ tree
.
├── css
│   ├── mtssb-admin.css
│   └── mtssb-front.css
├── image
│   ├── ajax-loader.gif
│   ├── ajax-loaderf.gif
│   ├── system-stop.png
│   └── system-tick.png
├── js
│   ├── mtssb-article-admin.js
│   ├── mtssb-booking-admin.js
│   ├── mtssb-calendar-widget.js
│   └── mtssb-schedule-admin.js
├── languages
│   ├── ja.mo
│   └── ja.po
├── mts-simple-booking.php
├── mtssb-article-admin.php
├── mtssb-article.php
├── mtssb-booking-admin.php
├── mtssb-booking-form.php
├── mtssb-booking.php
├── mtssb-calendar-admin.php
├── mtssb-calendar-widget.php
├── mtssb-front.php
├── mtssb-list-admin.php
├── mtssb-mail.php
├── mtssb-schedule-admin.php
├── mtssb-settings-admin.php
└── uninstall.php

一つ一つ理解してカスタマイズするより前に、プラグインそのものを理解しないとあかんね。

[WordPress] MTS Simple Bookingを使う

MTS Simple Bookingのhpで、Dowloadページからzipファイルをダウンロードします。
http://mtssb.mt-systems.jp/downloadp/

そして、Wordpress管理画面のプラグインページでPluginのアップロードフォームから先ほどダウンロードしたzipファイルをuploadします。

すると、管理画面上に予約システムが表示されたことがわかります。

続いてスタートガイドを参考に各種設定をしていきます。

### 予約システム各種設定
「各種設定」のページで予約機能の設定をしていきます。
予約パラメータ、施設情報、予約メール、その他のタブメニューがあります。
施設情報は予約メールに記載される内容を書きます。
予約メールには、入力項目の設定と、メール後文には「施設情報」のタブで入力した変数を入力する。

### 予約品目
予約条件設定で、件数、人数などの条件を設定できる。時間割(スタートタイム)、制約タイプなども併せて設定する。
edit時のパラメータ post=${num} をコピーしておく。

### スケジュール登録
予約システムのスケジュールに表示する

### フロントページへの登録
固定ページにbooking-formとスラックを名付ける
併せて、booking-thanksの予約完了ページを作成する

### 管理画面側
予約リストで予約状況を確認できる。
ほう、中々凄い

パラメータのutm=1618826400はlinuxtimeですね。
問題はどうやってクレジットカード決済を導入するかだな。。
mtssb-booking-form.phpでbooking-formの処理を行なっているけど、submitせずに、決済画面にパラメータも一緒に飛ばしたい。

Pythonで自然言語処理(mecab)

$ python3 –version
Python 3.6.8
$ pip3 –version
pip 9.0.3 from /usr/lib/python3.6/site-packages (python 3.6)

$ sudo pip3 install mecab-python3
$ sudo pip3 install unidic-lite

単語と単語を分けるのを分かち書きという
$ python3
>>> import MeCab
>>> wakati=MeCab.Tagger(“-Owakati”)
>>> sentence_wakati = wakati.parse(“私は今システム開発を行なっています”).split()
>>> print(sentence_wakati)
[‘私’, ‘は’, ‘今’, ‘システム’, ‘開発’, ‘を’, ‘行なっ’, ‘て’, ‘い’, ‘ます’]

ん?
“行なって” + “います” が正の様に思うが。。

自然言語処理ってことは、検索エンジン周りかチャットボット関連か。
もしくは文章の中から特定のキーワードを見つける e.g. 技術トレンドが入っている用語
RSSから、自然言語処理で内容を評価して、カテゴライズを自動化する など

何をやるかやな。

D4を更に理解しよう

ORDA: Object Relational Data Access

Table, field, and relation names are mapped to object property names. Make sure that such names comply with general object naming rules, as explained in the object naming conventions section.
A datastore only references tables with a single primary key. The following tables are not referenced:
Tables without a primary key
Tables with composite primary keys.
BLOB type attributes are not managed in the datastore. BLOB type attributes are returned as Null in entities and cannot be assigned.

$mydatastore:=OB Copy(ds) 
 ARRAY TEXT($prop;0)
 OB GET PROPERTY NAMES(ds;$prop)

こりゃハードル高いというか、時間がかかるな。。

D4を使ってみよう

4D Product DownloadのページからDLします。
https://us.4d.com/product-download/Feature-Release

4D Documentationを見ながらやっていきます。

Projectを作ります。

Architecture of project
– components
– data
L logs
L settings
– documentation
– plugins
– project
L derivedData
L sources
L trash
– resources
– settings
– userPreferences.username
– WebFolder

Project folder
– sources
L classes, databaseMethods, Methods, Forms, TableForms, Triggers
– DerivedData
– Trash

${appname}.4DProject: 4D, 4D server

設定ファイルはXMLやJSONで書かれてますね。
メソッドを作って、ドキュメントを書く。

<!-- This method returns a different logo depending on the size parameter -->


GetLogo (size) -> logo


| Parameter | Type   | in/out | Description |
| --------- | ------ | ------ | ----------- |
| size      | Longint | in | Logo style selector (1 to 5)  |
| logo      | Picture | out | Selected logo |


## Description

This method returns a logo of a specific size, depending on the value of the *size* parameter value.
1 = smallest size, 5 = largest size.

## Example

C_PICTURE($logo)
C_LONGINT($size)

//Get the largest logo
$logo:=GetLogo(5)

ちょっとだけ理解した。

JANコードの作成手順

JANコードは、どの事業者のどの商品かを表す世界共通の商品識別番号
日本では45もしくは49から始まる9桁の事業者番号から始まる

JANコード(標準13桁)
①最初の9桁:GS1事業者コード ②次の3桁:商品アイテムコード ③最後の1桁:チェックデジット(入力ミス防止用)

JANコードの作成手続き
– GS1事業者コードの新規登録手続き
– 商品アイテムコードの作成(001から順番に作成)

チェックデジットの計算方法
1. 全ての偶数桁の数字を加算
2. 1の結果を3倍
3. 全ての奇数桁の数字を加算
4. 2の結果と3の結果を加算
5. 4の結果の下1桁の数字を10から引いたものがチェックデジット

JANシンボルを印刷

なるほどー
プログラムでできるのね。

スクレイピングでページが更新されたかのスクリプト

$file_name = 'amzn.txt';
$fp = fopen($file_name,'w');

foreach($names as $n){
	fputs($fp, $n. "\n");
}
fclose($fp);

– copyで amzn_cp.txt を作ります。
– file_get_contents()で中身を取得して比較

copy('amzn.txt', 'amzn_cp.txt');

// スクレイピング

$file_name = 'amzn.txt';
$fp = fopen($file_name,'w');

foreach($names as $n){
	fputs($fp, $n. "\n");
}
fclose($fp);

$old = file_get_contents('amzn.txt');
$new = file_get_contents('amzn_cp.txt');

if($old !== $new){
	echo "changed";
     // 更新があった場合の処理
} else {
	echo "not changed";
}

凄い単純だけど、これで良いのかな〜